PageSourceSearch

https://www.food-service.de/assets/36a60b54e4d6eed72fc561727a0a6fc9.js

js food-service.de collected 2026-09-24 20:02:47 UTC 1,019,211 bytes, 20,590 lines download raw bytes

vendor: 37,045 bytes, lines 1-7
1/*!
2 * Bootstrap v3.3.7 (http://getbootstrap.com)
3 * Copyright 2011-2016 Twitter, Inc.
4 * Licensed under the MIT license
5 */
6if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
7this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
7
vendor: 33,966 bytes, lines 8-11
8/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
9!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
10
11return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;
vendor: 5,438 bytes, line 11
11return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{}
vendor: 1,726 bytes, line 11
11,e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>
vendor: 11,646 bytes, line 11
11=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if
vendor: 14,046 bytes, lines 11-12
11(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){
12return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"n
vendor: 4,347 bytes, line 12
12one"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}}
vendor: 9,859 bytes, line 12
12,function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];
vendor: 4,387 bytes, line 12
12function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);
vendor: 10,546 bytes, lines 12-13
12if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m});
13//# 
vendor: 2,045 bytes, lines 13-20
13
14/*
15 Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
16*/
17(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k));
18if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("<div />"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q,
19u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),e<F&&(m=!1,c=q,null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),
20h.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(t).trigger("sticky_kit:unstick")),B&&(b=f.height(),u+q>b&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>
20C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}),
21a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize",
22y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n<K;n++)d=this[n],J(b(d));return this}}).call(this);
23
24/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
25!function(a,b){a(function(){"use strict";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d<e;++d)if(c===a[d].toLowerCase())return!0;return!1}function d(a){for(var b in a)h.call(a,b)&&(a[b]=new RegExp(a[b],"i"))}function e(a,b){this.ua=a||"",this._cache={},this.maxPhoneWidth=b||600}var f={};f.mobileDetectRules={phones:{iPhone:"\\biPhone\\b|\\biPod\\b",BlackBerry:"BlackBerry|\\bBB10\\b|rim[0-9]+",HTC:"HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m",Nexus:"Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6",Dell:"Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",Motorola:"Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b",Samsung:"\\bSamsung\\b
vendor: 5,343 bytes, line 25
25|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C
25",LG:"\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)",Sony:"SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533",Asus:"Asus.*Galaxy|PadFone.*Mobile",NokiaLumia:"Lumia [0-9]{3,4}",Micromax:"Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",Palm:"PalmSource|Palm",Vertu:"Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",Pantech:"PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",Fly:"IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",Wiko:"KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLI
25M|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",iMobile:"i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",SimValley:"\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",Wolfgang:"AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",Alcatel:"Alcatel",Nintendo:"Nintendo 3DS",Amoi:"Amoi",INQ:"INQ",GenericPhone:"Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"},tablets:{iPad:"iPad|iPad.*Mobile",NexusTablet:"Android.*Nexus[\\s]+(7|9|10)",SamsungTablet:"SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y",Kindle:"Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)",SurfaceTablet:"Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",HPTablet:"HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",AsusTablet:"^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b",BlackBerryTablet:"PlayBook|RIM Tablet",HTCtablet:"HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",MotorolaTablet:"xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",NookTablet:"Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",AcerTablet:"Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30",ToshibaTablet:"Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",LGTablet:"\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",FujitsuTablet:"Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",PrestigioTablet:"PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",LenovoTablet:"Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)",DellTablet:"Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",YarvikTablet:"Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",MedionTablet:"Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",ArnovaTablet:"97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",IntensoTablet:"INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",IRUTablet:"M702pro",MegafonTablet:"MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",EbodaTablet:"E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",AllViewTablet:"Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",ArchosTablet:"\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",AinolTablet:"NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",NokiaLumiaTablet:"Lumia 2520",SonyTablet:"Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31",PhilipsTablet:"\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",CubeTablet:"Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",CobyTablet:"MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",MIDTablet:"M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MI
25D810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",MSITablet:"MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",SMiTTablet:"Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",RockChipTablet:"Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",FlyTablet:"IQ310|Fly Vision",bqTablet:"Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris [E|M]10)|Maxwell.*Lite|Maxwell.*Plus",HuaweiTablet:"MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim",NecTablet:"\\bN-06D|\\bN-08D",PantechTablet:"Pantech.*P4100",BronchoTablet:"Broncho.*(N701|N708|N802|a710)",VersusTablet:"TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",ZyncTablet:"z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900",PositivoTablet:"TB07STA|TB10STA|TB07FTA|TB10FTA",NabiTablet:"Android.*\\bNabi",KoboTablet:"Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",DanewTablet:"DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",TexetTablet:"NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",PlaystationTablet:"Playstation.*(Portable|Vita)",TrekstorTablet:"ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",PyleAudioTablet:"\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",AdvanTablet:"Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",DanyTechTablet:"Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",GalapadTablet:"Android.*\\bG1\\b",MicromaxTablet:"Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",KarbonnTablet:"Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",AllFineTablet:"Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",PROSCANTablet:"\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",YONESTablet:"BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",ChangJiaTablet:"TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",GUTablet:"TX-A1301|TX-M9002|Q702|kf026",PointOfVie
25wTablet:"TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",OvermaxTablet:"OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)",HCLTablet:"HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",DPSTablet:"DPS Dream 9|DPS Dual 7",VistureTablet:"V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",CrestaTablet:"CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",MediatekTablet:"\\bMT8125|MT8389|MT8135|MT8377\\b",ConcordeTablet:"Concorde([ ]+)?Tab|ConCorde ReadMan",GoCleverTablet:"GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",ModecomTablet:"FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",VoninoTablet:"\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",ECSTablet:"V07OT2|TM105A|S10OT1|TR10CS1",StorexTablet:"eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",VodafoneTablet:"SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497",EssentielBTablet:"Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",RossMoorTablet:"RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",iMobileTablet:"i-mobile i-note",TolinoTablet:"tolino tab [0-9.]+|tolino shine",AudioSonicTablet:"\\bC-22Q|T7-QC|T-17B|T-17P\\b",AMPETablet:"Android.* A78 ",SkkTablet:"Android.* (SKYPAD|PHOENIX|CYCLOPS)",TecnoTablet:"TECNO P9",JXDTablet:"Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",iJoyTablet:"Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",FX2Tablet:"FX2 PAD7|FX2 PAD10",XoroTablet:"KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",ViewsonicTablet:"ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",OdysTablet:"LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",CaptivaTablet:"CAPTIVA PAD",IconbitTablet:"NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",TeclastTablet:"T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",OndaTablet:"\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+",JaytechTablet:"TPC-PA762",BlaupunktTablet:"Endeavour 800NG|Endeavour 1010",DigmaTablet:"\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",EvolioTablet:"ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",LavaTablet:"QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",AocTablet:"MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",MpmanTablet:"MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",CelkonTablet:"CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",WolderTablet:"miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",MiTablet:"\\bMI PAD\\b|\\bHM NOTE 1W\\b",
25NibiruTablet:"Nibiru M1|Nibiru Jupiter One",NexoTablet:"NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",LeaderTablet:"TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",UbislateTablet:"UbiSlate[\\s]?7C",PocketBookTablet:"Pocketbook",KocasoTablet:"\\b(TB-1207)\\b",HisenseTablet:"\\b(F5281|E2371)\\b",Hudl:"Hudl HT7S3|Hudl 2",TelstraTablet:"T-Hub2",GenericTablet:"Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b"},oss:{AndroidOS:"Android",BlackBerryOS:"blackberry|\\bBB10\\b|rim tablet os",PalmOS:"PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",SymbianOS:"Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",WindowsMobileOS:"Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;",WindowsPhoneOS:"Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",iOS:"\\biPhone.*Mobile|\\biPod|\\biPad",MeeGoOS:"MeeGo",MaemoOS:"Maemo",JavaOS:"J2ME/|\\bMIDP\\b|\\bCLDC\\b",webOS:"webOS|hpwOS",badaOS:"\\bBada\\b",BREWOS:"BREW"},uas:{Chrome:"\\bCrMo\\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?",Dolfin:"\\bDolfin\\b",Opera:"Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+",Skyfire:"Skyfire",Edge:"Mobile Safari/[.0-9]* Edge",IE:"IEMobile|MSIEMobile",Firefox:"fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",Bolt:"bolt",TeaShark:"teashark",Blazer:"Blazer",Safari:"Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari",UCBrowser:"UC.*Browser|UCWEB",baiduboxapp:"baiduboxapp",baidubrowser:"baidubrowser",DiigoBrowser:"DiigoBrowser",Puffin:"Puffin",Mercury:"\\bMercury\\b",ObigoBrowser:"Obigo",NetFront:"NF-Browser",GenericBrowser:"NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",PaleMoon:"Android.*PaleMoon|Mobile.*PaleMoon"},props:{Mobile:"Mobile/[VER]",Build:"Build/[VER]",Version:"Version/[VER]",VendorID:"VendorID/[VER]",iPad:"iPad.*CPU[a-z ]+[VER]",iPhone:"iPhone.*CPU[a-z ]+[VER]",iPod:"iPod.*CPU[a-z ]+[VER]",Kindle:"Kindle/[VER]",Chrome:["Chrome/[VER]","CriOS/[VER]","CrMo/[VER]"],Coast:["Coast/[VER]"],Dolfin:"Dolfin/[VER]",Firefox:["Firefox/[VER]","FxiOS/[VER]"],Fennec:"Fennec/[VER]",Edge:"Edge/[VER]",IE:["IEMobile/[VER];","IEMobile [VER]","MSIE [VER];","Trident/[0-9.]+;.*rv:[VER]"],NetFront:"NetFront/[VER]",NokiaBrowser:"NokiaBrowser/[VER]",Opera:[" OPR/[VER]","Opera Mini/[VER]","Version/[VER]"],"Opera Mini":"Opera Mini/[VER]","Opera Mobi":"Version/[VER]","UC Browser":"UC Browser[VER]",MQQBrowser:"MQQBrowser/[VER]",MicroMessenger:"MicroMessenger/[VER]",baiduboxapp:"baiduboxapp/[VER]",baidubrowser:"baidubrowser/[VER]",SamsungBrowser:"SamsungBrowser/[VER]",Iron:"Iron/[VER]",Safari:["Version/[VER]","Safari/[VER]"],Skyfire:"Skyfire/[VER]",Tizen:"Tizen/[VER]",Webkit:"webkit[ /][VER]",PaleMoon:"PaleMoon/[VER]",Gecko:"Gecko/[VER]",Trident:"Trident/[VER]",Presto:"Presto/[VER]",Goanna:"Goanna/[VER]",iOS:" \\bi?OS\\b [VER][ ;]{1}",Android:"Android [VER]",BlackBerry:["BlackBerry[\\w]+/[VER]","BlackBerry.*Version/[VER]","Version/[VER]"],BREW:"BREW [VER]",Java:"Java/[VER]","Windows Phone OS":["Windows Phone OS [VER]","Windows Phone [VER]"],"Windows Phone":"Windows Phone [VER]","Windows CE":"Windows CE/[VER]","Windows NT":"Windows NT [VER]",Symbian:["SymbianOS/[VER]","Symbian/[VER]"],webOS:["webOS/[VER]","hpwOS/[VER];"]},utils:{Bot:"Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom",MobileBot:"Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2",DesktopMode:"WPDesktop",TV:"SonyDTV|HbbTV",WebKit:"(webkit)[ /]([\\w.]+)",Console:"\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\\b",Watch:"SM-V700"}},f.detectMobileBrowsers={fullPattern:/(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/i,shortPattern:/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 )|
vendor: 5,620 bytes, lines 25-26
25sy(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,
26tabletPattern:/android|ipad|playbook|silk/i};var g,h=Object.prototype.hasOwnProperty;return f.FALLBACK_PHONE="UnknownPhone",f.FALLBACK_TABLET="UnknownTablet",f.FALLBACK_MOBILE="UnknownMobile",g="isArray"in Array?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},function(){var a,b,c,e,i,j,k=f.mobileDetectRules;for(a in k.props)if(h.call(k.props,a)){for(b=k.props[a],g(b)||(b=[b]),i=b.length,e=0;e<i;++e)c=b[e],j=c.indexOf("[VER]"),j>=0&&(c=c.substring(0,j)+"([\\w._\\+]+)"+c.substring(j+5)),b[e]=new RegExp(c,"i");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),f.findMatch=function(a,b){for(var c in a)if(h.call(a,c)&&a[c].test(b))return c;return null},f.findMatches=function(a,b){var c=[];for(var d in a)h.call(a,d)&&a[d].test(b)&&c.push(d);return c},f.getVersionStr=function(a,b){var c,d,e,g,i=f.mobileDetectRules.props;if(h.call(i,a))for(c=i[a],e=c.length,d=0;d<e;++d)if(g=c[d].exec(b),null!==g)return g[1];return null},f.getVersion=function(a,b){var c=f.getVersionStr(a,b);return c?f.prepareVersionNo(c):NaN},f.prepareVersionNo=function(a){var b;return b=a.split(/[a-z._ \/\-]/i),1===b.length&&(a=b[0]),b.length>1&&(a=b[0]+".",b.shift(),a+=b.join("")),Number(a)},f.isMobileFallback=function(a){return f.detectMobileBrowsers.fullPattern.test(a)||f.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},f.isTabletFallback=function(a){return f.detectMobileBrowsers.tabletPattern.test(a)},f.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var g,h,i;return(h=f.findMatch(f.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(g=f.findMatch(f.mobileDetectRules.phones,c))?(a.mobile=a.phone=g,void(a.tablet=null)):void(f.isMobileFallback(c)?(i=e.isPhoneSized(d),i===b?(a.mobile=f.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=f.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null)):f.isTabletFallback(c)?(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},f.mobileGrade=function(a){var b=null!==a.mobile();return a.os("iOS")&&a.version("iPad")>=4.3||a.os("iOS")&&a.version("iPhone")>=3.1||a.os("iOS")&&a.version("iPod")>=3.1||a.version("Android")>2.1&&a.is("Webkit")||a.version("Windows Phone OS")>=7||a.is("BlackBerry")&&a.version("BlackBerry")>=6||a.match("Playbook.*Tablet")||a.version("webOS")>=1.4&&a.match("Palm|Pre|Pixi")||a.match("hp.*TouchPad")||a.is("Firefox")&&a.version("Firefox")>=12||a.is("Chrome")&&a.is("AndroidOS")&&a.version("Android")>=4||a.is("Skyfire")&&a.version("Skyfire")>=4.1&&a.is("AndroidOS")&&a.version("Android")>=2.3||a.is("Opera")&&a.version("Opera Mobi")>11&&a.is("AndroidOS")||a.is("MeeGoOS")||a.is("Tizen")||a.is("Dolfin")&&a.version("Bada")>=2||(a.is("UC Browser")||a.is("Dolfin"))&&a.version("Android")>=2.3||a.match("Kindle Fire")||a.is("Kindle")&&a.version("Kindle")>=3||a.is("AndroidOS")&&a.is("NookTablet")||a.version("Chrome")>=11&&!b||a.version("Safari")>=5&&!b||a.version("Firefox")>=4&&!b||a.version("MSIE")>=7&&!b||a.version("Opera")>=10&&!b?"A":a.os("iOS")&&a.version("iPad")<4.3||a.os("iOS")&&a.version("iPhone")<3.1||a.os("iOS")&&a.version("iPod")<3.1||a.is("Blackberry")&&a.version("BlackBerry")>=5&&a.version("BlackBerry")<6||a.version("Opera Mini")>=5&&a.version("Opera Mini")<=6.5&&(a.version("Android")>=2.3||a.is("iOS"))||a.match("NokiaN8|NokiaC7|N97.*Series60|Symbian/3")||a.version("Opera Mobi")>=11&&a.is("SymbianOS")?"B":(a.version("BlackBerry")<5||a.match("MSIEMobile|Windows CE.*Mobile")||a.version("Windows Mobile")<=5.2,"C")},f.detectOS=function(a){return f.findMatch(f.mobileDetectRules.oss0,a)||f.findMatch(f.mobileDetectRules.oss,a)},f.getDeviceSmallerSide=function(){return window.screen.width<window.screen.height?window.screen.width:window.screen.height},e.prototype={constructor:e,mobile:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.mobile},phone:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.phone},tablet:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.tablet},userAgent:function(){return this._cache.userAgent===b&&(this._cache.userAgent=f.findMatch(f.mobileDetectRules.uas,this.ua)),this._cache.userAgent},userAgents:function(){return this._cache.userAgents===b&&(this._cache.userAgents=f.findMatches(f.mobileDetectRules.uas,this.ua)),this._cache.userAgents},os:function(){return this._cache.os===b&&(this._cache.os=f.detectOS(this.ua)),this._cache.os},version:function(a){return f.getVersion(a,this.ua)},versionStr:function(a){return f.getVersionStr(a,this.ua)},is:function(b){return c(this.userAgents(),b)||a(b,this.os())||a(b,this.phone())||a(b,this.tablet())||c(f.findMatches(f.mobileDetectRules.utils,this.ua),b)},match:function(a){return a instanceof RegExp||(a=new RegExp(a,"i")),a.test(this.ua)},isPhoneSized:function(a){return e.isPhoneSized(a||this.maxPhoneWidth)},mobileGrade:function(){return this._cache.grade===b&&(this._cache.grade=f.mobileGrade(this)),this._cache.grade}},"undefined"!=typeof window&&window.screen?e.isPhoneSized=function(a){return a<0?b:f.getDeviceSmallerSide()<=a}:e.isPhoneSized=function(){},e._impl=f,e.version="1.3.7 2017-09-06",e})}
26(function(a){if("undefined"!=typeof module&&module.exports)return function(a){module.exports=a()};if("function"==typeof define&&define.amd)return define;if("undefined"!=typeof window)return function(a){window.MobileDetect=a()};throw new Error("unknown environment")}());
27/*! jQuery slabtext plugin v2.2 MIT/GPL2 @freqdec */
28(function($){$.fn.slabText=function(options){var settings={fontRatio:0.78,forceNewCharCount:true,wrapAmpersand:true,headerBreakpoint:null,viewportBreakpoint:null,noResizeEvent:false,resizeThrottleTime:300,maxFontSize:999,postTweak:true,precision:3,minCharsPerLine:0};$("body").addClass("slabtexted");return this.each(function(){if(options){$.extend(settings,options);}var $this=$(this),keepSpans=$("span.slabtext",$this).length,words=keepSpans?[]:String($.trim($this.text())).replace(/\s{2,}/g," ").split(" "),origFontSize=null,idealCharPerLine=null,fontRatio=settings.fontRatio,forceNewCharCount=settings.forceNewCharCount,headerBreakpoint=settings.headerBreakpoint,viewportBreakpoint=settings.viewportBreakpoint,postTweak=settings.postTweak,precision=settings.precision,resizeThrottleTime=settings.resizeThrottleTime,minCharsPerLine=settings.minCharsPerLine,resizeThrottle=null,viewportWidth=$(window).width(),headLink=$this.find("a:first").attr("href")||$this.attr("href"),linkTitle=headLink?$this.find("a:first").attr("title"):"";if(!keepSpans&&minCharsPerLine&&words.join(" ").length<minCharsPerLine){return;}var grabPixelFontSize=function(){var dummy=jQuery('<div style="display:none;font-size:1em;margin:0;padding:0;height:auto;line-height:1;border:0;">&nbsp;</div>').appendTo($this),emH=dummy.height();dummy.remove();return emH;};var resizeSlabs=function resizeSlabs(){var parentWidth=$this.width(),fs;$this.removeClass("slabtextdone slabtextinactive");if(viewportBreakpoint&&viewportBreakpoint>viewportWidth||headerBreakpoint&&headerBreakpoint>parentWidth){$this.addClass("slabtextinactive");return;}fs=grabPixelFontSize();if(!keepSpans&&(forceNewCharCount||fs!=origFontSize)){origFontSize=fs;var newCharPerLine=Math.min(60,Math.floor(parentWidth/(origFontSize*fontRatio))),wordIndex=0,lineText=[],counter=0,preText="",postText="",finalText="",slice,preDiff,postDiff;if(newCharPerLine!=idealCharPerLine){idealCharPerLine=newCharPerLine;while(wordIndex<words.length){postText="";while(postText.length<idealCharPerLine){preText=postText;postText+=words[wordIndex]+" ";if(++wordIndex>=words.length){break;}}if(minCharsPerLine){slice=words.slice(wordIndex).join(" ");if(slice.length<minCharsPerLine){postText+=slice;preText=postText;wordIndex=words.length+2;}}preDiff=idealCharPerLine-preText.length;postDiff=postText.length-idealCharPerLine;if((preDiff<postDiff)&&(preText.length>=(minCharsPerLine||2))){finalText=preText;wordIndex--;}else{finalText=postText;}finalText=$("<div/>").text(finalText).html();if(settings.wrapAmpersand){finalText=finalText.replace(/&amp;/g,'<span class="amp">&amp;</span>');}finalText=$.trim(finalText);lineText.push('<span class="slabtext">'+finalText+"</span>");}$this.html(lineText.join(" "));if(headLink){$this.wrapInner('<a href="'+headLink+'" '+(linkTitle?'title="'+linkTitle+'" ':"")+"/>");}}}else{origFontSize=fs;}$("span.slabtext",$this).each(function(){var $span=$(this),innerText=$span.text(),wordSpacing=innerText.split(" ").length>1,diff,ratio,fontSize;if(postTweak){$span.css({"word-spacing":0,"letter-spacing":0});}ratio=parentWidth/$span.width();fontSize=parseFloat(this.style.fontSize)||origFontSize;$span.css("font-size",Math.min((fontSize*ratio).toFixed(precision),settings.maxFontSize)+"px");diff=!!postTweak?parentWidth-$span.width():false;if(diff){$span.css((wordSpacing?"word":"letter")+"-spacing",(diff/(wordSpacing?innerText.split(" ").length-1:innerText.length)).toFixed(precision)+"px");}});$this.addClass("slabtextdone");};resizeSlabs();if(!settings.noResizeEvent){$(window).resize(function(){if($(window).width()==viewportWidth){return;}viewportWidth=$(window).width();clearTimeout(resizeThrottle);resizeThrottle=setTimeout(resizeSlabs,resizeThrottleTime);});}});};})(jQuery);
29/*! jQuery Lazy 1.6.7 - MIT & GPL-2.0 license - Copyright 2012-2016 Daniel 'Eisbehr' Kern */
30!function(e,t,a,r){"use strict";function n(a,r,n,o){function i(){p=t.devicePixelRatio>1,l(n),r("delay")>=0&&setTimeout(function(){u(!0)},r("delay")),(r("delay")<0||r("combined"))&&(o.e=m(r("throttle"),function(e){"resize"===e.type&&(b=v=-1),u(e.all)}),o.a=function(e){l(e),n.push.apply(n,e)},o.g=function(){return n=e(n).filter(function(){return!e(this).data(r("loadedName"))})},u(),e(r("appendScroll")).on("scroll."+a.name+" resize."+a.name,o.e))}function l(t){if(t=e(t).filter(function(){return!e(this).data(r("handledName"))&&(e(this).attr(r("attribute"))||e(this).attr(r("loaderAttribute")))}).data("plugin_"+a.name,a),r("defaultImage")||r("placeholder"))for(var n=0;n<t.length;n++){var o=e(t[n]),i=t[n].tagName.toLowerCase(),l="background-image";"img"==i&&r("defaultImage")&&!o.attr("src")?o.attr("src",r("defaultImage")):"img"==i||!r("placeholder")||o.css(l)&&"none"!=o.css(l)||o.css(l,"url("/js/vendor/jquery-lazy/+r("placeholder")+")")}}function u(t){if(!n.length)return void(r("autoDestroy")&&a.destroy());for(var o=!1,i=r("imageBase")?r("imageBase"):"",l=0;l<n.length;
30l++)(function(a){if(c(a)||t){var n,l=e(a),u=a.tagName.toLowerCase(),f=l.attr(r("attribute"));l.data(r("handledName"))||r("visibleOnly")&&!l.is(":visible")||!(f&&("img"==u&&i+f!=l.attr("src")||"img"!=u&&i+f!=l.css("background-image"))||(n=l.attr(r("loaderAttribute"))))||(o=!0,l.data(r("handledName"),!0),d(l,u,i,n))}})(n[l]);o&&(n=e(n).filter(function(){return!e(this).data(r("handledName"))}))}function d(t,a,n,o){++h;var i=function(){A("onError",t),g()};if(A("beforeLoad",t),o)t.off("error").one("error",i),t.one("load",function(){r("removeAttribute")&&t.removeAttr(r("loaderAttribute")),t.data(r("loadedName"),!0),A("afterLoad",t),g()}),A(o,t,function(e){e?t.load():t.error()})||t.error();else{var l=e(new Image);l.one("error",i),l.one("load",function(){t.hide(),"img"==a?t.attr("src",l.attr("src")):t.css("background-image","url('"+l.attr("src")+"')"),t[r("effect")](r("effectTime")),r("removeAttribute")&&t.removeAttr(r("attribute")+" "+r("retinaAttribute")),t.data(r("loadedName"),!0),A("afterLoad",t),l.remove(),g()}),l.attr("src",n+t.attr(r(p&&t.attr(r("retinaAttribute"))?"retinaAttribute":"attribute"))),l.complete&&l.load()}}function c(e){var t=e.getBoundingClientRect(),a=r("scrollDirection"),n=r("threshold"),o=s()+n>t.top&&-n<t.bottom,i=f()+n>t.left&&-n<t.right;return"vertical"==a?o:"horizontal"==a?i:o&&i}function f(){return b>=0?b:b=e(t).width()}function s(){return v>=0?v:v=e(t).height()}function m(e,t){var n,o=0;return function(i,l){function u(){o=+new Date,t.call(a,i)}var d=+new Date-o;n&&clearTimeout(n),d>e||!r("enableThrottle")||l?u():n=setTimeout(u,e-d)}}function g(){--h,n.length||h||A("onFinishedAll")}function A(e,t,n){return(e=r(e))?(e.apply(a,[].slice.call(arguments,1)),!0):!1}var h=0,b=-1,v=-1,p=!1;!function(){"event"==r("bind")?i():e(t).on("load."+a.name,i)}()}function o(a,o){var i=this,l=e.extend({},i.configuration,o),u={};return i.config=function(e,t){return t===r?l[e]:(l[e]=t,i)},i.addItems=function(t){return u.a&&u.a("string"===e.type(t)?e(t):t),i},i.getItems=function(){return u.g?u.g():{}},i.update=function(e){return u.e&&u.e({},!e),i},i.loadAll=function(){return u.e&&u.e({all:!0},!0),i},i.destroy=function(){return e(i.config("appendScroll")).off("."+i.name,u.e),e(t).off("."+i.name),u={},r},n(i,i.config,a,u),i.config("chainable")?a:i}e.fn.Lazy=e.fn.lazy=function(e){return new o(this,e)},e.extend(o.prototype,{name:"lazy",configuration:{chainable:!0,autoDestroy:!0,bind:"load",threshold:500,visibleOnly:!1,appendScroll:t,scrollDirection:"both",imageBase:null,defaultImage:"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",placeholder:null,delay:-1,combined:!1,attribute:"data-src",retinaAttribute:"data-retina",loaderAttribute:"data-loader",removeAttribute:!0,handledName:"handled",loadedName:"loaded",effect:"show",effectTime:0,enableThrottle:!0,throttle:250,beforeLoad:null,afterLoad:null,onError:null,onFinishedAll:null}})}(jQuery,window,document);
31$(function() {
32    if ($('div.StageVoting_groupId').length) {
33        var vid    = $('div.StageVoting_groupId').data('voting');
34        var detail = $('div.StageVoting_groupId').data('detail');
35        $.ajax({
36            url: '/_votings/arena/last.voting.php',
37            type: 'GET',
38            data: {
39                location: $(location).attr('href'),
40                select: 'id',
41                id:vid,
42                detail: detail
43            },
44            dataType: 'html',
45            success: function (data) {
46                $('div.StageVoting_groupId').html(data);
47
48            }
49        })
50    }
51    if($('div.StageVoting_groupAuto').length) {
52        $.ajax({
53            url: '/_votings/arena/last.voting.php',
54            type: 'GET',
55            data: {
56                location: $(location).attr('href'),
57                select: 'last'
58            },
59            dataType: 'html',
60            success: function (data) {
61                $('div.StageVoting_groupAuto').html(data);
62
63            }
64        })
65    }
66    var request;
67    $(document).on('submit','form.StageVoting_form',function(e){
68        e.preventDefault();
69        var hash = $("input[name='i_vhash']:checked").val();
70        if( typeof hash === "undefined"){
71            $(".StageVoting_info").text("Bitte treffen Sie eine Auswahl");
72        } else {
73            var $form = $(this);
74            var $inputs = $form.find("input, select, button, textarea");
75            var serializedData = $form.serialize();
76            $inputs.prop("disabled", true);
77
78            request = $.ajax({
79                type: "POST",
80                url: "/_votings/arena/post.php",
81                data: serializedData,
82             });
83            request.done(function (response, textStatus, jqXHR){
84                // Log a message to the console
85                if($('div.StageVoting_groupAuto').length) {
86                    $('div.StageVoting_groupAuto').html(response);
87                }
88                if($('div.StageVoting_groupId').length) {
89                    $('div.StageVoting_groupId').html(response);
90                }
91
92            });
93            request.fail(function (jqXHR, textStatus, errorThrown){
94                // Log the error to the console
95                console.error(
96                    "The following error occurred: "+
97                    textStatus, errorThrown
98                );
99            });
100            request.always(function () {
101                // Reenable the inputs
102                $inputs.prop("disabled", false);
103            });
104        }
105    })
106
107});
108$(document).ready(function() {
109    /**
110     * ersetzt das Carousel
111     * durch ein swipen beim neu Laden der Seite
112     * in data-ride wird onPageLoad getsetzt
113     * die Ids des Elements muessen eindeutig sein !!!
114     */
115    $.each($("[data-ride]"), function (k, v) {
116        if ($(this).data('ride') == 'onPageLoad') {
117            var id = $(this).attr('id');
118            var store_name = 'onPageLoad' + id;
119            var stack = [];
120            var count_elm = $(this).children(".carousel-inner").children(".item").length;            
121            var random_stack_index = Math.floor(Math.random() * ((count_elm -1) + 1));                
122            
123            if (sessionStorage.getItem(store_name)) {
124                stack = JSON.parse(sessionStorage.getItem(store_name));
125            }
126            if (stack.length !== count_elm) {
127                stack = [];
128                for (var i = 0; i < count_elm; i++) {
129                    stack[i] = 0;
130                }
131                stack[random_stack_index] = 1;
132            } else {
133                stack.unshift('0');
134                if (stack.pop() == 1) {
135                    stack[0] = 1;
136                }
137            }
138            $.each($(this).children(".carousel-inner").children(".item"), function (i, x) {
139                if (stack[i] == 0) {
140                    $(this).removeClass('active');
141                } else {
142                    $(this).addClass('active');
143                }
144            })
145            sessionStorage.setItem(store_name, JSON.stringify(stack));
146        }
147    });
148});
149
150    /* Click auf Logo nicht scrollen */
151    $(".Logo").on("click", function () {
152        localStorage.setItem('click','Logo');
153    });
154
155/* ----- Pop-up Banner für NL-Anmeldung (FST-389) ------- */
156if (typeof popup_nl !== "undefined") {
157  $(window).scroll(function() {
158    $("#popup_nl" ).animate({
159      bottom: "0",
160    }, 1500, function() {
161      // nothing
162    });
163  });
164  
165}
166
167
168$("#close_nl_popup").on("click", function () {
169    $("#popup_nl" ).hide();
170});
171
172/* ----- Pop-up User-Umfrage FOOD SERVICE (FST-628) ------- */
173if (typeof popup_img !== "undefined") {
174  $(window).scroll(function() {
175    $("#flyoutbox" ).animate({
176      bottom: "0",
177    }, 1500, function() {
178      // nothing
179    });
180  });
181}
182
183$("#closeflyoutbox").on("click", function () {
184    $("#flyoutbox" ).hide();
185});
186    
187    /* ----- Bannerspezifische Events ------- */
188$(window).on("webskin",function(){
189  if ( $("#superbanner .ad_superbanner").length) {
190
191   var superheight  = $("#superbanner .ad_superbanner").css("height");
192   var superleft    = $("#superbanner").offset().left;
193   var sky_right    = $("#superbanner .ad_right_skyscraper").attr("id");
194   var sky_left     = ($("#superbanner .ad_left_skyscraper").length) ? $("#superbanner .ad_left_skyscraper").attr("id") : 0;
195   var sky_fixed    = ($(".ad_right_skyscraper").css("position") == "fixed") ? true : false;
196
197    if(sky_fixed == false){    
198      var rsky_left = $('.main.container').css('width');
199      if($("#" + sky_left).length){
200        var lsky_left = 0 - $("#"+sky_left).width();
201      }
202    } 
203
204    if(sky_fixed == true){
205      var rsky_left   = superleft + parseInt($('.main.container').css('width'));
206      if($("#" + sky_left).length){
207        var lsky_left = superleft - $("#" + sky_left).width();
208      }
209     }
210     
211     $(document).trigger("pos_webskin", [sky_right, sky_left, superheight, superleft, sky_fixed, lsky_left, rsky_left]);
212   }
213});
214
215$(document).on("pos_webskin", function(event, sky_right, sky_left, superheight, superleft, sky_fixed, lsky_left, rsky_left){
216     var inner_super_height = $("#superbanner .ad_superbanner div").css("height");
217     // inner_super_height muss größer als 5 Pixel sein, im Falle von deaktiviertem Flash werden hier keine 0 Pixel zurückgegeben
218     var sheight = (parseInt(inner_super_height) > 5 && inner_super_height < superheight) ? inner_super_height : superheight;
219     $(".superbanner").css('height', sheight);
220     $(".superbanner").css('margin-bottom', '-11px');
221
222     // console.log(lsky_left + " - " + rsky_left);
223     $('#' + sky_right).css('left',rsky_left);
224     $('#' + sky_left).css('left',lsky_left);
225
226     $('#' + sky_right).css('width',$("#right-skyscraper").width());
227     $('#' + sky_left).css('width',$("#left-skyscraper").width());
228
229     if(sky_fixed == true){
230      $('#' + sky_right).css('position','fixed');
231      $('#' + sky_left).css('position','fixed');
232     }
233   
234});
235
236$(document).on("singlebanner", function(event, banner_id, banner_width){
237  
238  var superbanner_id  = $("#superbanner > div > div").attr("id");
239  var rightsky_id     = $("#right-skyscraper > div > div").attr("id");
240  var leftsky_id      = $("#left-skyscraper  > div > div").attr("id");
241
242  if(rightsky_id == banner_id || leftsky_id == banner_id ){
243    var super_height = parseInt($("#superbanner").css("height"));
244        super_height = (super_height > 3) ? super_height : 0;
245    var sky_margin   = parseInt($("#"+banner_id).css("margin-top"));
246    // Ist im Template ein margin-top eingegeben, nimm dies
247    // Ansonsten berechne den Abstand anhand der Superbannerhöhe
248    var sky_pos      = (sky_margin != 0) ? sky_margin : super_height - 150;
249    $("#"+banner_id).css("margin-top",sky_pos);
250  }
251 
252  
253});
254
255/* ---- iPad-Events --- */
256$(window).on("orientationchange resize",function(){
257  if ( $("#superbanner .ad_superbanner").length) {
258    $(document).trigger("webskin");    
259  }
260});
261
262/* --------------- GA Event Zählung --------------- */
263var socialmedia_click = function(type, target) {
264    var fo_sm = {
265          'hitType': 'event',
266          'eventCategory': 'socialmedia-share_' + type,
267          'eventAction': 'Klick',
268          'eventLabel': target,
269          'page': window.location.pathname,
270          'location': window.location.href
271          };
272      dfv_ga_repl(fo_sm);
273};
274
275$("body").on("click", ".sticky-nav .nav-follow a", function(event){
276  if(event.currentTarget.getAttribute('data-te') !== undefined){
277    socialmedia_click("stickyheader", event.currentTarget.getAttribute('data-te'));
278  }
279});
280
281$("body").on("click", ".article-footer .share-bar a", function(event){
282  if(event.currentTarget.getAttribute('data-te') !== undefined){
283     socialmedia_click("content", event.currentTarget.getAttribute('data-te'));       
284  }
285});
286
287$("body").on("click", ".gallery-full .swiper-wrapper .nav-follow a", function(event){
288  if(event.currentTarget.getAttribute('data-te') !== undefined){
289    socialmedia_click("gallery", event.currentTarget.getAttribute('data-te'));
290  }
291});
292
293$(".PageArticle_body").on("submit", ".StageVoting_form",function(){
294  // Trigger Event bei Umfrage
295     var fo_mr = {
296      'hitType': 'event',
297      'eventCategory': 'Umfrage',
298      'eventAction': 'Klick',
299      'eventLabel': 'Detail',
300      'page': window.location.pathname,
301      'location': window.location.href
302      };
303  dfv_ga_repl(fo_mr);
304   
305});
306
307$(".StageVoting").on("submit", ".StageVoting_form",function(){
308  // Trigger Event bei Umfrage
309     var fo_mr = {
310      'hitType': 'event',
311      'eventCategory': 'Umfrage',
312      'eventAction': 'Klick',
313      'eventLabel': 'Arena',
314      'page': window.location.pathname,
315      'location': window.location.href
316      };
317  dfv_ga_repl(fo_mr);
318   
319});
320
321$(".related-content.news-stream").on("click", "a", function(){
322  // Trigger Event bei Aktuelle Nachrichten unter dem Artikel
323     var fo_mr = {
324      'hitType': 'event',
325      'eventCategory': 'Artikel des Tages',
326      'eventAction': 'Klick',
327      'page': window.location.pathname,
328      'location': window.location.href
329      };
330  dfv_ga_repl(fo_mr);
331   
332});
333
334$("#subscription-features .checkbox-large").on("click", function(event){
335  // Trigger Event bei Click auf Checkbox in Paywall
336  if(event.currentTarget.getAttribute('data-te') !== undefined){
337    var fo_pw = {
338            'hitType': 'event',
339            'eventCategory': event.currentTarget.getAttribute('data-te'),
340            'eventAction': 'Klick',
341            'eventLabel': event.currentTarget.getAttribute('data-price'),
342            'page': window.location.pathname,
343            'location': window.location.href
344            };
345        dfv_ga_repl(fo_pw);
346  }
347});
348
349$(".paywall .shop-link").on("click", function(event){
350  // Trigger Event bei Click auf Checkbox in Paywall
351  if(event.currentTarget.getAttribute('data-te') !== undefined){
352    var fo_pw = {
353            'hitType': 'event',
354            'eventCategory': event.currentTarget.getAttribute('data-te'),
355            'eventAction': 'Klick',
356            'eventLabel': '',
357            'page': window.location.pathname,
358            'location': window.location.href
359            };
360        dfv_ga_repl(fo_pw);
361  }
362});
363
364$(".stage-galleries .read-more").on("click", function(){
365  // Trigger Event bei Fotogaleriebühne Link Alle Fotogalerien
366     var fo_mr = {
367      'hitType': 'event',
368      'eventCategory': 'Alle Fotogalerien',
369      'eventAction': 'Klick',
370      'page': window.location.pathname,
371      'location': window.location.href
372      };
373  dfv_ga_repl(fo_mr);
374   
375});
376
377$(".stage-galleries").on("click", "a", function(event){
378  // Trigger Event bei Click auf Galerie Fotogaleriebühne
379  if(event.currentTarget.getAttribute('data-te') !== undefined){
380    var fo_pw = {
381            'hitType': 'event',
382            'eventCategory': 'Fotogalerie Bühne',
383            'eventAction': 'Klick',
384            'eventLabel': event.currentTarget.getAttribute('data-te'),
385            'page': window.location.pathname,
386            'location': window.location.href
387            };
388        dfv_ga_repl(fo_pw);
389  }
390});
391
392$(".stage-fashion .allfashion").on("click", function(){
393  // Trigger Event bei Fashionbühne Link Alle Fashion-Artikels
394     var fo_mr = {
395      'hitType': 'event',
396      'eventCategory': 'Alle Fashion-Artikel',
397      'eventAction': 'Klick',
398      'page': window.location.pathname,
399      'location': window.location.href
400      };
401  dfv_ga_repl(fo_mr);
402   
403});
404
405$(".stage-fashion").on("click", "a", function(event){
406  // Trigger Event bei Click auf News Fashionbühne
407  if(event.currentTarget.getAttribute('data-te') !== undefined){
408    var fo_pw = {
409            'hitType': 'event',
410            'eventCategory': 'Fashion Bühne',
411            'eventAction': 'Klick',
412            'eventLabel': event.currentTarget.getAttribute('data-te'),
413            'page': window.location.pathname,
414            'location': window.location.href
415            };
416        dfv_ga_repl(fo_pw);
417  }
418});
419
420$(".stage-szene .read-more").on("click", function(){
421  // Trigger Event bei Szenebühne Link Alle Szene-Galerien
422     var fo_mr = {
423      'hitType': 'event',
424      'eventCategory': ' Alle Szene-Galerien',
425      'eventAction': 'Klick',
426      'page': window.location.pathname,
427      'location': window.location.href
428      };
429  dfv_ga_repl(fo_mr);
430   
431});
432
433$(".stage-szene").on("click", "a", function(event){
434  // Trigger Event bei Click auf Galerie Szenebühne
435  if(event.currentTarget.getAttribute('data-te') !== undefined){
436    var fo_pw = {
437            'hitType': 'event',
438            'eventCategory': 'Szenegalerie Bühne',
439            'eventAction': 'Klick',
440            'eventLabel': event.currentTarget.getAttribute('data-te'),
441            'page': window.location.pathname,
442            'location': window.location.href
443            };
444        dfv_ga_repl(fo_pw);
445  }
446});
447
448$(".stage-print").on("click", "a, button", function(event){
449  // Trigger Event bei Click auf Verlagsbühne
450    var fo_pw = {
451            'hitType': 'event',
452            'eventCategory': 'Verlagsbühne',
453            'eventAction': 'Klick',
454            'eventLabel': $(".stage-print").find('img').attr('alt'),
455            'page': window.location.pathname,
456            'location': window.location.href
457            };
458        dfv_ga_repl(fo_pw);
459});
460
461$(".teaser-ranking").on("click", "a", function(event){
462  // Trigger Event bei Click auf Meist gelesen Blogroll
463  if(event.currentTarget.getAttribute('data-te') !== undefined){
464    var fo_pw = {
465            'hitType': 'event',
466            'eventCategory': 'Meist gelesen Blogroll',
467            'eventAction': 'Klick',
468            'eventLabel': event.currentTarget.getAttribute('data-te'),
469            'page': window.location.pathname,
470            'location': window.location.href
471            };
472        dfv_ga_repl(fo_pw);
473  }
474});
475
476$(".stage.opener #carousel-aside .most-read").on("click", "a", function(event){
477  // Trigger Event bei Click auf Meist gelesen Aufmacher
478  if(event.currentTarget.getAttribute('data-te') !== undefined){
479    var fo_pw = {
480            'hitType': 'event',
481            'eventCategory': 'Meist gelesen Aufmacher',
482            'eventAction': 'Klick',
483            'eventLabel': event.currentTarget.getAttribute('data-te'),
484            'page': window.location.pathname,
485            'location': window.location.href
486            };
487        dfv_ga_repl(fo_pw);
488  }
489});
490
491$(".stage.opener #carousel-aside .widget-ipad-app").on("click", "a", function(event){
492  // Trigger Event bei Click auf iPad-Teaser Aufmacher
493    var fo_pw = {
494            'hitType': 'event',
495            'eventCategory': 'iPad-Teaser Aufmacher',
496            'eventAction': 'Klick',
497            'eventLabel': '',
498            'page': window.location.pathname,
499            'location': window.location.href
500            };
501        dfv_ga_repl(fo_pw);
502});
503
504$("body").on("click", ".disable-lp", function(event) {
505  event.preventDefault();
506  var href = $(this).attr('href');
507  var fo_lp = {
508    'hitType': 'event',
509    'eventCategory': 'Jobs-Teaser',
510    'eventAction': 'Klick',
511    'eventLabel': '',
512    'page': window.location.pathname,
513    'location': window.location.href,
514    'nonInteraction': true
515  };
516  dfv_ga_repl(fo_lp);
517  window.open(href,'_blank');
518});
519
520$(".stage-instagram button").on("click", function(){
521  // Trigger Event bei Instagrambühne "Follo Us"
522     var fo_ib = {
523      'hitType': 'event',
524      'eventCategory': 'Instagram Bühne',
525      'eventAction': 'Klick',
526      'eventLabel': 'FollowUs',
527      'page': window.location.pathname,
528      'location': window.location.href
529      };
530  dfv_ga_repl(fo_ib);
531});
532
533$(".stage-instagram").on("click", "a.in-image", function(event){
534  // Trigger Event bei Click auf Bilder Instagrambühne
535    var fo_pw = {
536      'hitType': 'event',
537      'eventCategory': 'Instagram Image',
538      'eventAction': 'Klick',
539      'eventLabel': event.currentTarget.href
540      };
541  dfv_ga_repl(fo_pw);
542});
543
544var event_data = {
545                'hitType': 'event',
546                'eventCategory': 'default',
547                'eventAction': 'default',
548                'eventLabel': 'default',
549                'page': window.location.pathname,
550                'location': window.location.href
551              };
552
553
554/* --- Sponsoren Logos --- */
555$("a.Sponsor_item-link").on("click", function(){
556    event_data.eventCategory  = 'Dossiers';
557    event_data.eventAction    = 'click';
558    event_data.eventLabel     = event.currentTarget.href;
559    dfv_ga_repl(event_data);
560});
561
562
563
564$(document).on("ExitIntent", function(event, banner_id, target){
565    // Trigger Show Event
566    var show_val = target;
567    if(show_val != undefined){
568        event_data.hitType  = 'event';
569        event_data.eventCategory  = 'exit intent';
570        event_data.eventAction    = 'show'; 
571        event_data.eventLabel     = show_val; 
572        event_data.nonInteraction = true;
573        dfv_ga_repl(event_data);
574       }
575       
576    $("#popup_exit_button").on("click", function(){
577      // Trigger Event bei Click auf Exit-PopUp
578       var val = target;
579       if(val != undefined){
580        event_data.eventCategory  = 'exit intent';
581        event_data.eventAction    = 'subscribe '; 
582        event_data.eventLabel     = 'FOOD SERVICE am Morgen'; 
583        event_data.nonInteraction = false;
584        dfv_ga_repl(event_data);
585        }
586       else{
587         return false;
588       }
589    });
590  
591});
592
593
594/* --------------- Suche ---------- */
595
596$(function(){
597   var showSearch = function() {
598     
599    var l = $("a.navsearch").position().left;
600    console.log($("a.navsearch").position());
601     
602    $("#header-searchinput").show();
603        $("#header-searchinput").animate({
604           width: "250px",
605           right: "0"
606        }, 200 );
607  };
608
609  var hideSearch = function() {
610    $( "#header-searchinput" ).animate({
611            width: "0px",
612            right: "0"
613            }, 200, function() {
614            $("#header-searchinput").hide();
615          });
616  };
617  
618  var searchurl = $(location).attr('href');
619    
620  $(document).on("click touchstart",function(e) {
621
622    if($(e.target).attr('id') == "headersearch" && $("#header-searchinput").css("display") == "none") {
623      e.preventDefault();
624      showSearch();
625    }
626    else {
627      if ($(e.target).attr('id') == "header-searchfield" || $(e.target).attr('id') == "header-searchbutton") {
628          ;// Klick innerhalb des Suchfeldes
629      }
630      else {
631          hideSearch();
632      }
633    }
634  });
635  
636});
637
638/*!
639	Colorbox 1.6.3
640	license: MIT
641	http://www.jacklmoore.com/colorbox
642*/
vendor: 4,671 bytes, line 643
643(function(t,e,i){function n(i,n,o){var r=e.createElement(i);return n&&(r.id=Z+n),o&&(r.style.cssText=o),t(r)}function o(){return i.innerHeight?i.innerHeight:t(i).height()}function r(e,i){i!==Object(i)&&(i={}),this.cache={},this.el=e,this.value=function(e){var n;return void 0===this.cache[e]&&(n=t(this.el).attr("data-cbox-"+e),void 0!==n?this.cache[e]=n:void 0!==i[e]?this.cache[e]=i[e]:void 0!==X[e]&&(this.cache[e]=X[e])),this.cache[e]},this.get=function(e){var i=this.value(e);return t.isFunction(i)?i.call(this.el,this):i}}function h(t){var e=W.length,i=(A+t)%e;return 0>i?e+i:i}function a(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():o())/100:1)*parseInt(t,10))}function s(t,e){return t.get("photo")||t.get("photoRegex").test(e)}function l(t,e){return t.get("retinaUrl")&&i.devicePixelRatio>1?e.replace(t.get("photoRegex"),t.get("retinaSuffix")):e}function d(t){"contains"in x[0]&&!x[0].contains(t.target)&&t.target!==v[0]&&(t.stopPropagation(),x.focus())}function c(t){c.str!==t&&(x.add(v).removeClass(c.str).addClass(t),c.str=t)}function g(e){A=0,e&&e!==!1&&"nofollow"!==e?(W=t("."+te).filter(function(){var i=t.data(this,Y),n=new r(this,i);return n.get("rel")===e}),A=W.index(_.el),-1===A&&(W=W.add(_.el),A=W.length-1)):W=t(_.el)}function u(i){t(e).trigger(i),ae.triggerHandler(i)}function f(i){var o;if(!G){if(o=t(i).data(Y),_=new r(i,o),g(_.get("rel")),!$){$=q=!0,c(_.get("className")),x.css({visibility:"hidden",display:"block",opacity:""}),I=n(se,"LoadedContent","width:0; height:0; overflow:hidden; visibility:hidden"),b.css({width:"",height:""}).append(I),j=T.height()+k.height()+b.outerHeight(!0)-b.height(),D=C.width()+H.width()+b.outerWidth(!0)-b.width(),N=I.outerHeight(!0),z=I.outerWidth(!0);var h=a(_.get("initialWidth"),"x"),s=a(_.get("initialHeight"),"y"),l=_.get("maxWidth"),f=_.get("maxHeight");_.w=Math.max((l!==!1?Math.min(h,a(l,"x")):h)-z-D,0),_.h=Math.max((f!==!1?Math.min(s,a(f,"y")):s)-N-j,0),I.css({width:"",height:_.h}),J.position(),u(ee),_.get("onOpen"),O.add(F).hide(),x.focus(),_.get("trapFocus")&&e.addEventListener&&(e.addEventListener("focus",d,!0),ae.one(re,function(){e.removeEventListener("focus",d,!0)})),_.get("returnFocus")&&ae.one(re,function(){t(_.el).focus()})}var p=parseFloat(_.get("opacity"));v.css({opacity:p===p?p:"",cursor:_.get("overlayClose")?"pointer":"",visibility:"visible"}).show(),_.get("closeButton")?B.html(_.get("close")).appendTo(b):B.appendTo("<div/>"),w()}}function p(){x||(V=!1,E=t(i),x=n(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),v=n(se,"Overlay").hide(),L=t([n(se,"LoadingOverlay")[0],n(se,"LoadingGraphic")[0]]),y=n(se,"Wrapper"),b=n(se,"Content").append(F=n(se,"Title"),R=n(se,"Current"),P=t('<button type="button"/>').attr({id:Z+"Previous"}),K=t('<button type="button"/>').attr({id:Z+"Next"}),S=n("button","Slideshow"),L),B=t('<button type="button"/>').attr({id:Z+"Close"}),y.append(n(se).append(n(se,"TopLeft"),T=n(se,"TopCenter"),n(se,"TopRight")),n(se,!1,"clear:left").append(C=n(se,"MiddleLeft"),b,H=n(se,"MiddleRight")),n(se,!1,"clear:left").append(n(se,"BottomLeft"),k=n(se,"BottomCenter"),n(se,"BottomRight"))).find("div div").css({"float":"left"}),M=n(se,!1,"position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;"),O=K.add(P).add(R).add(S)),e.body&&!x.parent().length&&t(e.body).append(v,x.append(y,M))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),f(this))}return x?(V||(V=!0,K.click(function(){J.next()}),P.click(function(){J.prev()}),B.click(function(){J.close()}),v.click(function(){_.get("overlayClose")&&J.close()}),t(e).bind("keydown."+Z,function(t){var e=t.keyCode;$&&_.get("escKey")&&27===e&&(t.preventDefault(),J.close()),$&&_.get("arrowKey")&&W[1]&&!t.altKey&&(37===e?(t.preventDefault(),P.click()):39===e&&(t.preventDefault(),K.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+Z,"."+te,i):t("."+te).live("click."+Z,i)),!0):!1}function w(){var e,o,r,h=J.prep,d=++le;if(q=!0,U=!1,u(he),u(ie),_.get("onLoad"),_.h=_.get("height")?a(_.get("height"),"y")-N-j:_.get("innerHeight")&&a(_.get("innerHeight"),"y"),_.w=_.get("width")?a(_.get("width"),"x")-z-D:_.get("innerWidth")&&a(_.get("innerWidth"),"x"),_.mw=_.w,_.mh=_.h,_.get("maxWidth")&&(_.mw=a(_.get("maxWidth"),"x")-z-D,_.mw=_.w&&_.w<_.mw?_.w:_.mw),_.get("maxHeight")&&(_.mh=a(_.get("maxHeight"),"y")-N-j,_.mh=_.h&&_.h<_.mh?_.h:_.mh),e=_.get("href"),Q=setTimeout(function(){L.show()},100),_.get("inline")){var c=t(e);r=t("<div>").hide().insertBefore(c),ae.one(he,function(){r.replaceWith(c)}),h(c)}else _.get("iframe")?h(" "):_.get("html")?h(_.get("html")):s(_,e)?(e=l(_,e),U=_.get("
643createImg"),t(U).addClass(Z+"Photo").bind("error."+Z,function(){h(n(se,"Error").html(_.get("imgError")))}).one("load",function(){d===le&&setTimeout(function(){var e;_.get("retinaImage")&&i.devicePixelRatio>1&&(U.height=U.height/i.devicePixelRatio,U.width=U.width/i.devicePixelRatio),_.get("scalePhotos")&&(o=function(){U.height-=U.height*e,U.width-=U.width*e},_.mw&&U.width>_.mw&&(e=(U.width-_.mw)/U.width,o()),_.mh&&U.height>_.mh&&(e=(U.height-_.mh)/U.height,o())),_.h&&(U.style.marginTop=Math.max(_.mh-U.height,0)/2+"px"),W[1]&&(_.get("loop")||W[A+1])&&(U.style.cursor="pointer",t(U).bind("click."+Z,function(){J.next()})),U.style.width=U.width+"px",U.style.height=U.height+"px",h(U)},1)}),U.src=e):e&&M.load(e,_.get("data"),function(e,i){d===le&&h("error"===i?n(se,"Error").html(_.get("xhrError")):t(this).contents())})}var v,x,y,b,T,C,H,k,W,E,I,M,L,F,R,S,K,P,B,O,_,j,D,N,z,A,U,$,q,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp|jxr|svg)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,rel:function(){return this.rel},href:function(){return t(this).attr("href")},title:function(){return this.title},createImg:function(){var e=new Image,i=t(this).data("cbox-img-attrs");return"object"==typeof i&&t.each(i,function(t,i){e[t]=i}),e},createIframe:function(){var i=e.createElement("iframe"),n=t(this).data("cbox-iframe-attrs");return"object"==typeof n&&t.each(n,function(t,e){i[t]=e}),"frameBorder"in i&&(i.frameBorder=0),"allowTransparency"in i&&(i.allowTransparency="true"),i.name=(new Date).getTime(),i.allowFullscreen=!0,i}},Y="colorbox",Z="cbox",te=Z+"Element",ee=Z+"_open",ie=Z+"_load",ne=Z+"_complete",oe=Z+"_cleanup",re=Z+"_closed",he=Z+"_purge",ae=t("<a/>"),se="div",le=0,de={},ce=function(){function t(){clearTimeout(h)}function e(){(_.get("loop")||W[A+1])&&(t(),h=setTimeout(J.next,_.get("slideshowSpeed")))}function i(){S.html(_.get("slideshowStop")).unbind(s).one(s,n),ae.bind(ne,e).bind(ie,t),x.removeClass(a+"off").addClass(a+"on")}function n(){t(),ae.unbind(ne,e).unbind(ie,t),S.html(_.get("slideshowStart")).unbind(s).one(s,function(){J.next(),i()}),x.removeClass(a+"on").addClass(a+"off")}function o(){r=!1,S.hide(),t(),ae.unbind(ne,e).unbind(ie,t),x.removeClass(a+"off "+a+"on")}var r,h,a=Z+"Slideshow_",s="click."+Z;return function(){r?_.get("slideshow")||(ae.unbind(oe,o),o()):_.get("slideshow")&&W[1]&&(r=!0,ae.one(oe,o),_.get("slideshowAuto")?i():n(),S.show())}}();t[Y]||(t(p),J=t.fn[Y]=t[Y]=function(e,i){var n,o=this;return e=e||{},t.isFunction(o)&&(o=t("<a/>"),e.open=!0),o[0]?(p(),m()&&(i&&(e.onComplete=i),o.each(function(){var i=t.data(this,Y)||{};t.data(this,Y,t.extend(i,e))}).addClass(te),n=new r(o[0],e),n.get("open")&&f(o[0])),o):o},J.position=function(e,i){function n(){T[0].style.width=k[0].style.width=b[0].style.width=parseInt(x[0].style.width,10)-D+"px",b[0].style.height=C[0].style.height=H[0].style.height=parseInt(x[0].style.height,10)-j+"px"}var r,h,s,l=0,d=0,c=x.offset();if(E.unbind("resize."+Z),x.css({top:-9e4,left:-9e4}),h=E.scrollTop(),s=E.scrollLeft(),_.get("fixed")?(c.top-=h,c.left-=s,x.css({position:"fixed"})):(l=h,d=s,x.css({position:"absolute"})),d+=_.get("right")!==!1?Math.max(E.width()-_.w-z-D-a(_.get("right"),"x"),0):_.get("left")!==!1?a(_.get("left"),"x"):Math.round(Math.max(E.width()-_.w-z-D,0)/2),l+=_.get("bottom")!==!1?Math.max(o()-_.h-N-j-a(_.get("bottom"),"y"),0):_.get("top")!==!1?a(_.get("top"),"y"):Math.round(Math.max(o()-_.h-N-j,0)/2),x.css({top:c.top,left
643:c.left,visibility:"visible"}),y[0].style.width=y[0].style.height="9999px",r={width:_.w+z+D,height:_.h+N+j,top:l,left:d},e){var g=0;t.each(r,function(t){return r[t]!==de[t]?(g=e,void 0):void 0}),e=g}de=r,e||x.css(r),x.dequeue().animate(r,{duration:e||0,complete:function(){n(),q=!1,y[0].style.width=_.w+z+D+"px",y[0].style.height=_.h+N+j+"px",_.get("reposition")&&setTimeout(function(){E.bind("resize."+Z,J.position)},1),t.isFunction(i)&&i()},step:n})},J.resize=function(t){var e;$&&(t=t||{},t.width&&(_.w=a(t.width,"x")-z-D),t.innerWidth&&(_.w=a(t.innerWidth,"x")),I.css({width:_.w}),t.height&&(_.h=a(t.height,"y")-N-j),t.innerHeight&&(_.h=a(t.innerHeight,"y")),t.innerHeight||t.height||(e=I.scrollTop(),I.css({height:"auto"}),_.h=I.height()),I.css({height:_.h}),e&&I.scrollTop(e),J.position("none"===_.get("transition")?0:_.get("speed")))},J.prep=function(i){function o(){return _.w=_.w||I.width(),_.w=_.mw&&_.mw<_.w?_.mw:_.w,_.w}function a(){return _.h=_.h||I.height(),_.h=_.mh&&_.mh<_.h?_.mh:_.h,_.h}if($){var d,g="none"===_.get("transition")?0:_.get("speed");I.remove(),I=n(se,"LoadedContent").append(i),I.hide().appendTo(M.show()).css({width:o(),overflow:_.get("scrolling")?"auto":"hidden"}).css({height:a()}).prependTo(b),M.hide(),t(U).css({"float":"none"}),c(_.get("className")),d=function(){function i(){t.support.opacity===!1&&x[0].style.removeAttribute("filter")}var n,o,a=W.length;$&&(o=function(){clearTimeout(Q),L.hide(),u(ne),_.get("onComplete")},F.html(_.get("title")).show(),I.show(),a>1?("string"==typeof _.get("current")&&R.html(_.get("current").replace("{current}",A+1).replace("{total}",a)).show(),K[_.get("loop")||a-1>A?"show":"hide"]().html(_.get("next")),P[_.get("loop")||A?"show":"hide"]().html(_.get("previous")),ce(),_.get("preloading")&&t.each([h(-1),h(1)],function(){var i,n=W[this],o=new r(n,t.data(n,Y)),h=o.get("href");h&&s(o,h)&&(h=l(o,h),i=e.createElement("img"),i.src=h)})):O.hide(),_.get("iframe")?(n=_.get("createIframe"),_.get("scrolling")||(n.scrolling="no"),t(n).attr({src:_.get("href"),"class":Z+"Iframe"}).one("load",o).appendTo(I),ae.one(he,function(){n.src="//about:blank"}),_.get("fastIframe")&&t(n).trigger("load")):o(),"fade"===_.get("transition")?x.fadeTo(g,1,i):i())},"fade"===_.get("transition")?x.fadeTo(g,0,function(){J.position(0,d)}):J.position(g,d)}},J.next=function(){!q&&W[1]&&(_.get("loop")||W[A+1])&&(A=h(1),f(W[A]))},J.prev=function(){!q&&W[1]&&(_.get("loop")||A)&&(A=h(-1),f(W[A]))},J.close=function(){$&&!G&&(G=!0,$=!1,u(oe),_.get("onCleanup"),E.unbind("."+Z),v.fadeTo(_.get("fadeOut")||0,0),x.stop().fadeTo(_.get("fadeOut")||0,0,function(){x.hide(),v.hide(),u(he),I.remove(),setTimeout(function(){G=!1,u(re),_.get("onClosed")},1)}))},J.remove=function(){x&&(x.stop(),t[Y].close(),x.stop(!1,!0).remove(),v.remove(),G=!1,x=null,t("."+te).removeData(Y).removeClass(te),t(e).unbind("click."+Z).unbind("keydown."+Z))},J.element=function(){return t(_.el)},J.settings=X)})(jQuery,document,window);
644
645var md = new MobileDetect(window.navigator.userAgent);
646var oldScrollPosition;
647
648function initAsideNav() {
649  $('.aside-menu .toggle-menu').click(function(e) {
650    e.preventDefault();
651    $(this).closest('.aside-menu').toggleClass('open');
652    $(this).closest('.aside-menu').find('.collapse-area').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
653      if (e.originalEvent.propertyName === 'max-height') {
654        $(document.body).trigger("sticky_kit:recalc");
655      }
656    });
657  });
658}
659
660function initSearchToggle() {
661  $('.toggle-search').click(function() {
662    $('.SiteHeader .SiteHeader_searchform').toggleClass('open');
663    $(this).toggleClass('hidden');
664  });
665}
666
667function initMobileNav() {
668  $('.toggle-mobile-nav').click(function(e) {
669    $('body').toggleClass('mobile-nav-open');
670  });
671}
672
673function initNewsletterSelect() {
674  $('.newsletter-select').click(function(e) {
675    $(this).toggleClass('selected');
676  });
677}
678
679function initStickyColumn() {
680  var ButtonsSharing_margin_top = $('.PageArticle_content .PageArticle_sticky .ButtonsSharing').css('margin-top');
681
682  $('.PageArticle_content .PageArticle_sticky').stick_in_parent({
683    parent     : '.sticky-container',
684    offset_top: 75,
685    bottoming: true
686  }).on("sticky_kit:stick", function(e) {
687    $(this).addClass('is_sticky');
688    $('.PageArticle_content .PageArticle_sticky .ButtonsSharing').css('margin-top',0);
689  })
690  .on("sticky_kit:bottom", function(e) {
691    $(this).parent().css('position', 'static');
692  })  
693  .on("sticky_kit:unstick", function(e) {
694    $(this).removeClass('is_sticky'); 
695    $('.PageArticle_content .PageArticle_sticky .ButtonsSharing').css('margin-top',ButtonsSharing_margin_top);   
696  });
697  
698  $('a[href="#"]').click(function(e){
699    e.preventDefault();
700  });
701}
702
703function setStickyDescription (){
704  var sticky_text = "";
705  
706  if($('.PageArticle').length){
707    
708    if($('.ArticleHeader_subject .ArticleHeader_headline').text().length > 0){
709      var description_tagline  = $('.ArticleHeader_subject .ArticleHeader_tagline').length > 0 ? $('.ArticleHeader_subject .ArticleHeader_tagline').text() + ": " : "";
710      var description_headline = $('.ArticleHeader_subject .ArticleHeader_headline').text();
711      sticky_text = description_tagline + description_headline;
712    }
713    else if($(".article-body h1").text().length > 0){
714      sticky_text = $(".article-body > h1").first().text();
715    }
716    else{
717      // nothing
718    }
719  
720    if(sticky_text.length > 45){      
721      sticky_text = sticky_text.substr(0, 45) + "...";
722    }
723  
724    $( ".SiteHeaderSticky_description" ).append(sticky_text);
725  
726  }
727  
728}
729
730function initCards() {
731  $('.card-collapse').on('click',(function(e) {
732    var me = $(this);
733    $('.card-collapse.open').not(this).removeClass('open');
734    me.toggleClass('open');
735  }));
736  $('.card-collapse').on('click','a',(function(e) {
737    //e.stopImmediatePropagation();
738    $(this).trigger('click');
739  }));
740}
741
742
743
744// __________________________________________________
745//
746//
747//			!Check Idle Time Mobile
748
749var timeoutID;
750
751function goInactive() {
752    if($('body').scrollTop() > 0) {
753      $('body').addClass('idle');
754    }
755    
756    $('.modal').addClass('idle');
757}
758 
759function goActive() {
760    $('body.idle').removeClass('idle');
761    $('.modal.idle').removeClass('idle');
762    startTimer();
763}
764 
765function resetTimer(e) {
766    window.clearTimeout(timeoutID);
767    goActive();
768}
769 
770function startTimer() {
771    // wait 2 seconds before calling goInactive
772    timeoutID = window.setTimeout(goInactive, 2000);
773}
774
775
776function make_square(element) {
777//   var cw = $(element).width();
778//   $(element).css({'height':cw+'px'});
779}
780
781
782function createYoutubeApi() {
783    var tag = document.createElement('script');
784    tag.src = "https://www.youtube.com/iframe_api";
785    var firstScriptTag = document.getElementsByTagName('script')[0];
786    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
787}
788 
789 
790function setupIdle() {
791    this.addEventListener("mousemove", resetTimer);
792    this.addEventListener("mousedown", resetTimer);
793    this.addEventListener("keypress", resetTimer);
794    this.addEventListener("DOMMouseScroll", resetTimer);
795    this.addEventListener('mousewheel', resetTimer, {passive: true});
796    this.addEventListener("touchmove", resetTimer);
797    this.addEventListener("touchstart", resetTimer);
798    this.addEventListener("MSPointerMove", resetTimer);
799 
800    startTimer();
801}
802
803    
804$(document).ready(function(){
805
806  createYoutubeApi();
807  setStickyDescription();
808  initSearchToggle();
809  setupIdle();
810  initStickyColumn();  
811  initAsideNav();
812  initMobileNav();
813  initCards();
814  initNewsletterSelect();
815
816  $('.number-of-the-week .number').slabText();
817
818  // lazy image load
819   $("img.lazy").lazy({});
820   
821   
822  // mobile Navigation Flyout
823  $(".NavigationFlyout_toggleButton").on('click',function(e){
824    e.preventDefault();$('.NavigationFlyout').toggleClass('isActive');
825  });
826  
827  // mobile Navigation Flyout
828  $(".NavigationMobile_toggle").on('click',function(e){
829    e.preventDefault();$('.NavigationMobile').toggleClass('isActive');
830    $('body').toggleClass('isFixed');
831  });
832  
833  $('.paneltop').click( function() {
834    $(this).css({"background-position":"0px -21px"})
835    .siblings().animate({"height":"100px"}, 200)
836}, function() {
837$(this).css({"background-position":"0px 0px"})
838    .siblings().animate({"height":"0px"}, 200);
839
840})
841
842   // Bilder quadratisieren
843   $( '.to-be-squared .teaser-image' ).each(function( index ) {
844      make_square($(this));
845   });
846   
847
848    $(".RankingTable_responsive").each(function(count) {
849        if ( $(this).add('.RankingTable_table').width() > 310 ) {
850          $(this).add('.RankingTable_navigations').css('display','block');
851        }
852        
853    });
854 
855
856});
857
858// quadratische Bildergroessen beim Fenster-Verkleinern neu berechnen
859$( window ).resize(function() {
860   $( '.to-be-squared .teaser-image' ).each(function( index ) {
861      make_square($(this));
862   });
863});
864
865function manageCreditsLink(outerClassName) {
866  document.addEventListener('DOMContentLoaded', function() {
867
868    const imageList = document.getElementsByClassName(outerClassName);
869    for (let i = 0; i < imageList.length; i++) {
870
871      for (let j = 0; j < imageList[i].children.length; j++) {
872
873        if (imageList[i].children[j].classList[0] === 'MediaImage_credits') {
874          let creditsText = imageList[i].children[j];
875          let creditsTextTrimmed = creditsText.innerHTML.replace(/^\s+|\s+$/g, '');
876          if (creditsTextTrimmed === '') {
877            creditsText.remove(); //remove empty credits
878          } else {
879            //Open credits link in new tab
880            let creditsLinkContainer =
881              (creditsText.getElementsByClassName('MediaImage_credits-link')[0] !== undefined)
882                ? creditsText.getElementsByClassName('MediaImage_credits-link')[0]
883                : '';
884            let creditsLink =
885              (creditsLinkContainer !== '' && creditsLinkContainer.dataset.href !== undefined)
886                ? creditsLinkContainer.dataset.href
887                : '';
888            if (creditsLink) {
889              creditsLinkContainer.onclick = function(e) {
890                e.preventDefault();
891                let opener = window.open();
892                opener.opener = null;
893                opener.location = creditsLink;
894                opener.target = '_blank';
895              };
896            }
897          }
898        }
899
900      }
901
902    }
903
904  }, false);
905}
906manageCreditsLink('MediaImage');
907manageCreditsLink('MediaImageGallery');
908
909(()=>{var __webpack_modules__={768:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";__webpack_require__.d(__webpack_exports__,{Z:()=>Embed});var _module__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(631),_utils_sendRequest__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(58),_utils_adBlockCheck__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(173),_tracking_module__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(558);function _await(e,t,n){return n?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}function _empty(){}function _invokeIgnored(e){var t=e();if(t&&t.then)return t.then(_empty)}function _async(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function _awaitIgnored(e,t){if(!t)return e&&e.then?e.then(_empty):Promise.resolve()}function _invoke(e,t){var n=e();return n&&n.then?n.then(t):t(n)}function ownKeys(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function _objectSpread(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};
909t%2?ownKeys(Object(n),!0).forEach((function(t){_defineProperty(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ownKeys(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function _createClass(e,t,n){return t&&_defineProperties(e.prototype,t),n&&_defineProperties(e,n),e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var loadAutoplayList=_async((function(e,t,n,i){var o;return _invoke((function(){if(e.fallbackElementsPromise)return _awaitIgnored(e.fallbackElementsPromise)}),(function(){var a,r=null===(a=e.fallbackElements)||void 0===a?void 0:a.length;return _await(r?e.fallbackElements.map((function(e){return _objectSpread(_objectSpread({},e),{},{fallback_id:e.id})})):new Promise((function(n){(0,_utils_sendRequest__WEBPACK_IMPORTED_MODULE_1__.w)("https://api.embed.pinpoll.com/autoplay/nextEmbeds",{elementId:t,url:e.url,topic:e.topic},window.Pinpoll.storage).then((function(e){return e.json()})).then((function(t){var o;return n(null===(o=window.Pinpoll.embed)||void 0===o?void 0:o.sortPreferredAutoEmbeddedElements(t.elements,e,i))})).catch((function(e){console.log("Pinpoll: error during fetching autoplay polls",e),n([])}))})),(function(e){var t;return o=e,n&&(o=null===(t=o)||void 0===t?void 0:t.slice(0,n)),o}),r)}))})),Embed=function(){function Embed(e,t,n){var i=this;if(_classCallCheck(this,Embed),_defineProperty(this,"targetWindow",void 0),_defineProperty(this,"lazyLoading",void 0),_defineProperty(this,"type",void 0),_defineProperty(this,"id",void 0),_defineProperty(this,"iframe",void 0),_defineProperty(this,"element",void 0),_defineProperty(this,"mode",void 0),_defineProperty(this,"data",void 0),_defineProperty(this,"loaded",!1),_defineProperty(this,"instance",void 0),_defineProperty(this,"questionViewTriggered",!1),_defineProperty(this,"url",void 0),_defineProperty(this,"autoplay",null),_defineProperty(this,"nativeAd",null),_defineProperty(this,"pendings",{}),_defineProperty(this,"pendingPostMessages",[]),_defineProperty(this,"loadDataSet",!1),_defineProperty(this,"widgetIndex",void 0),_defineProperty(this,"stats",void 0),this.element=t,this.targetWindow=e.location,this.type=e.type,this.mode=e.mode,this.data=e,this.stats=n,this.id=generateId(e),this.widgetIndex=window.Pinpoll.embed.initedEmbeds,window.Pinpoll.embed.initedEmbeds+=1,this.lazyLoading="eager"!==e.loading&&"preload"!==e.loading,this.data.native)return this.loadNative(t,e).then((function(t){if(t){t.targetId=i.id,i.instance=t,i.instance.promises.preload?i.instance.promises.preload.then((function(){return i.stats.markLoad()})):i.stats.markLoad();var n=!1;i.instance.on("poll:initialized","global.js - statTracker",(function(){var e;n||(n=!0,i.stats.markRender(),i.stats.observeImpression((null===(e=i.instance)||void 0===e?void 0:e.container)||i.element))})),i.instance.on("poll:initialized","global.js",(function(){var n,o;t.elementId&&(e.id=+t.elementId,(0,_tracking_module__WEBPACK_IMPORTED_MODULE_2__.Z)(t.visitorStorage,{widgetIndex:"e"+(null!==(n=null===(o=window.Pinpoll.embed)||void 0===o?void 0:o.embeds.findIndex((function(e){return e===i})))&&void 0!==n?n:0),originPage:e.url,widgetLocation:buildUrl(e,t.targetId||"")}).start())}))}})).catch((function(e){console.error("Pinpoll: error during loading native embed",e)})),void this.registerEventListener();this.iframe=buildIframe(e,this.id),this.lazyLoading?(this.iframe.setAttribute("class","lazyload"),document.addEventListener("lazybeforeunveil",(function e(t){t.target===i.iframe&&((0,_module__WEBPACK_IMPORTED_MODULE_0__.oW)(i.data,i.element),i.url=buildUrl(i.data,i.id),i.iframe.setAttribute("data-src",
909i.url),i.stats.markLoad(),document.removeEventListener("lazybeforeunveil",e))})),document.addEventListener("lazyloaded",(function e(t){t.target===i.iframe&&(i.loaded=!0,i.stats.markRender(),i.stats.observeImpression(i.iframe),document.removeEventListener("lazyloaded",e))}))):(this.loaded=!0,this.stats.markLoad(),this.url=buildUrl(e,this.id),this.iframe.src=this.url),this.registerEventListener(),t.parentNode===document.getElementsByTagName("head")[0]?document.body.appendChild(this.iframe):t.parentElement?t.parentElement.insertBefore(this.iframe,t):document.body.appendChild(this.iframe),this.lazyLoading||(this.stats.markRender(),this.stats.observeImpression(this.iframe))}return _createClass(Embed,[{key:"loadNative",value:function(e,t){if(!window.Pinpoll.nativeLoader){var n=document.createElement("script");n.async=!0,n.type="module",n.innerHTML="window.Pinpoll.nativeLoader = async (embedElement, options) => {\n                const { createEmbed } = await import('".concat("https://tools.pinpoll.com/embed-v2/main.js?v=1790061720894","');\n                return createEmbed(embedElement, options);\n            }"),document.head.appendChild(n)}return new Promise((function(n){!function i(){if("function"==typeof window.Pinpoll.nativeLoader)return n(window.Pinpoll.nativeLoader(e,t));setTimeout(i,100)}()}))}},{key:"loadNextEmbed",value:function(){if(this.autoplay){var e;this.autoplay.currentIndex=this.autoplay.currentIndex||0;var t=null===(e=this.autoplay.nextAutoplayedElements)||void 0===e?void 0:e[this.autoplay.currentIndex++];t&&this.loadEmbedItem(t)}}},{key:"registerEventListener",value:function(){var e=this;window.addEventListener("message",(function(t){var n,i,o=t.data;try{if("string"==typeof o){if(!o.startsWith("{"))return!1;o=JSON.parse(o)}}catch(e){console.warn(e)}if(o&&"object"===_typeof(o)&&o.action)if("vote"===o.action||"unvote"===o.action)-1!==navigator.appName.indexOf("Internet Explorer")&&-1===navigator.appVersion.indexOf("MSIE 1")&&(o=JSON.stringify(o)),null!==(n=e.iframe)&&void 0!==n&&n.contentWindow||(e.iframe=document.getElementById(e.id)),null===(i=e.iframe.contentWindow)||void 0===i||i.postMessage(o,e.targetWindow);else if(o.target===e.id)switch(o.action){case"get:loaddata":e.setLoadData();break;case"set:height":e.data.height||e.setEmbedHeight(o.value);break;case"get:recaptcha":e.activateRecaptcha(o.top,o.sitekey);break;case"poll-view:finished":e.questionViewTriggered=!0;break;case"autoplay:check":var a;e.initAutoplay(),e.autoplay&&(null===(a=e.autoplay.loadPromise)||void 0===a||a.then((function(){var t,n,i,o;null!==(t=e.autoplay)&&void 0!==t&&null!==(n=t.nextAutoplayedElements)&&void 0!==n&&n.length&&e.autoplay.nextAutoplayedElements[e.autoplay.currentIndex||0]&&(null===(i=e.iframe)||void 0===i||null===(o=i.contentWindow)||void 0===o||o.postMessage({action:"autoplay:ready"},"*"))})));break;case"autoplay:fire":e.loadNextEmbed();break;case"update:visitor":window.Pinpoll.storage.visitor=o.visitor;break;case"native-ad:set":(0,_utils_adBlockCheck__WEBPACK_IMPORTED_MODULE_3__.I)().finally((function(){var t;if(window.Pinpoll.userHasAdblock&&1===(null===(t=o.adConfig)||void 0===t?void 0:t.type))return console.warn("Pinpoll Native Ad: AdBlock detected, no native ad will be shown");e.setNativeAd(o.adTag,o.adConfig),e.nativeAd&&e.pendings.nativeinterstitial&&(e.nativeAd.onInterstitialStart(""+e.pendings.nativeinterstitial),e.pendings.nativeinterstitial=null)}));break;case"interstitial-start":e.nativeAd?e.nativeAd.onInterstitialStart(o.ad.duration):e.pendings.nativeinterstitial=o.ad.duration}}))}}
909,{key:"setLoadData",value:function(){var e,t=this;if(null!==(e=this.iframe)&&void 0!==e&&e.contentWindow){var n,i,o={embed_url:this.url,visitor:window.Pinpoll.storage.visitor,trackingDone:null===(n=window.Pinpoll.tracking)||void 0===n?void 0:n.requestDone,cookieEnabled:navigator.cookieEnabled,originPage:this.data.url,path:window.location.pathname,fallback_id:this.data.fallback_id,autoplayedElementId:this.data.autoplayedElementId,cssClass:this.data.cssClass,parent_id:this.id,autoplayDelay:this.data.autoplayDelay};for(["consent","targetAds","customURL","ppId"].forEach((function(e){t.data[e]&&(o[e]=t.data[e])})),window.Pinpoll.appName&&(o.app=window.Pinpoll.appName),this.loadDataSet||void 0===this.widgetIndex||(o.widgetIndex="e"+this.widgetIndex),null===(i=this.iframe)||void 0===i||i.contentWindow.postMessage({action:"set:loaddata",data:o},"*"),this.loadDataSet=!0;this.pendingPostMessages.length;){var a=this.pendingPostMessages.shift();a&&this.postMessage(a)}}}},{key:"setNativeAd",value:function setNativeAd(adTag,adConfig){var _this4=this;if(adTag)if(this.nativeAd)this.nativeAd.handle("reinitialized",{adTag,adConfig})||this.nativeAd.show();else{var _ref,_this$instance2,container=document.createElement("div");container.setAttribute("style","position:relative;"),null===(_ref=this.iframe||(null===(_this$instance2=this.instance)||void 0===_this$instance2?void 0:_this$instance2.container))||void 0===_ref||_ref.after(container);var script=document.createElement("script");script.adData={config:adConfig,embed:this},script.innerText=adTag,container.append(script),this.nativeAd={script,container,handle:function handle(handlerName,params){return!!_this4.nativeAd&&!!_this4.nativeAd.script.adData.config[handlerName]&&(eval(String(_this4.nativeAd.script.adData.config[handlerName]))(params),!0)},hide:function(){_this4.nativeAd&&(_this4.nativeAd.handle("hide")||(_this4.nativeAd.container.style.visibility="hidden"),_this4.nativeAd.handle("hidden"))},show:function(){_this4.nativeAd&&(_this4.nativeAd.handle("show")||(_this4.nativeAd.container.style.visibility="visible"),_this4.nativeAd.handle("shown"))},onInterstitialStart:function(e){var t,n,i;null!==(t=_this4.nativeAd)&&void 0!==t&&t.handle("interstitialStart",{duration:e})||(null===(i=_this4.nativeAd)||void 0===i||i.hide(),setTimeout((function(){var e,t,n;(null===(e=_this4.nativeAd)||void 0===e?void 0:e.handle("interstitialStop"))||null===(t=_this4.nativeAd)||void 0===t||t.show(),null===(n=_this4.nativeAd)||void 0===n||n.handle("interstitialStopped")}),1e3*+e)),null===(n=_this4.nativeAd)||void 0===n||n.handle("interstitialStarted")}},this.nativeAd.handle("initialized",{adConfig})}}},{key:"loadEmbedItem",value:function(e){var t,n;this.iframe&&e&&(this.data.id=e.element_id,e.id&&(this.data.fallback_id=e.id),e.element_id&&(this.data.autoplayedElementId=e.element_id),e.custom_design_id&&(this.data.design=e.custom_design_id),null===(t=this.nativeAd)||void 0===t||t.hide(),this.id=generateId(this.data),this.url=buildUrl(this.data,this.id),null===(n=this.iframe)||void 0===n||n.setAttribute("id",this.id),this.iframe.src=this.url)}},{key:"setEmbedHeight",value:function(e){if(e&&parseFloat(e)){var t=document.getElementById(this.id);t&&(t.setAttribute("height",e),t.setAttribute("style","display:block;height:".concat(parseFloat(e),"px!important;")))}}},{key:"activateRecaptcha",value:function(e,t){var n=this,i=function(e){var i,o,a,r,l,s=document.createElement("div"),d=document.createElement("div");window.grecaptcha.render(d,{sitekey:t,callback:function(e){var t,i;null===(t=n.iframe)||void 0===t||null===(i=t.contentWindow)||void 0===i||i.postMessage({action:"recaptcha:success",response:e},n.targetWindow),s.style.opacity="0",s.style.transform="translateY(20px)",window.setTimeout((function(){var e;null==s||null===(e=s.parentNode)||void 0===e||e.removeChild(s)}),400)}}),s.appendChild(d),s.setAttribute("style","-webkit-transition:opacity .4s,-webkit-transform .4s;transition:opacity .4s,-webkit-transform .4s;transition:opacity .4s,transform .4s;transition:opacity .4s,transform .4s,-webkit-transform .4s;-webkit-transform:translateY(20px);transform:translateY(20px)"),s.style.position="absolute",s.style.width="".concat(null===(i=n.iframe)||void 0===i?void 0:i.offsetWidth,"px"),s.style.left="".concat(null===(o=n.iframe)||void 0===o?void 0:o.offsetLeft,"px"),s.style.top="".concat((null===(a=n.iframe)||void 0===a?void 0:a.offsetTop)||0+e,"px"),s.style["text-align"]="answer"!=n.type?"center":"left",d.style.display="inline-block",d.style.margin="answer"!=n.type?"0 0 0 12%":"0 0 0 8em",s.style.opacity="0",window.setTimeout((function(){s.style.opacity="1",s.setAttribute("style",s.getAttribute("style").replace("translateY(20px)","translateY(0)"))}),1),null===(r=n.iframe)||void 0===r||null===(l=r.parentNode)||void 0===l||l.insertBefore(s,n.iframe.nextSibling)};if(window.grecaptcha)i(e);
909else{var o="recaptcha_".concat(this.id),a=document.createElement("script");a.src="https://www.google.com/recaptcha/api.js?onload=".concat(o,"&render=explicit"),a.async=!0,a.defer=!0,window[o]=function(){i(e)},document.head.appendChild(a)}}},{key:"postMessage",value:function(e){var t,n;this.loadDataSet?null===(t=this.iframe)||void 0===t||null===(n=t.contentWindow)||void 0===n||n.postMessage(e,this.targetWindow):this.pendingPostMessages.push(e)}},{key:"initPreload",value:function(){(0,_module__WEBPACK_IMPORTED_MODULE_0__.oW)(this.data,this.element);var e=this.instance;if(e)e.dispatch("poll:initPreload",e);else{var t=_objectSpread(_objectSpread({},this.data),{},{fallbackElementsPromise:void 0});this.postMessage({action:"preload:init",data:t})}"preload"===this.data.loading&&(this.data.loading="eager")}},{key:"reload",value:function(){this.iframe&&(this.iframe.src=buildUrl(this.data,this.id))}},{key:"loadAutoplayedElements",value:function(e){var t=this;this.autoplay&&(this.autoplay.loadPromise=_async((function(){return _invokeIgnored((function(){if(t.autoplay)return _await(loadAutoplayList(t.data,t.autoplay.elementId,e||t.autoplay.limit,t.iframe),(function(e){t.autoplay.nextAutoplayedElements=e,t.data.id||t.loadNextEmbed()}))}))}))())}},{key:"initAutoplay",value:function(){this.autoplay||void 0===this.data.autoplay||(this.autoplay={nextAutoplayedElements:void 0,limit:this.data.autoplay,elementId:this.data.id},this.loadAutoplayedElements())}}]),Embed}();function generateId(e){return"pinpoll_".concat(e.type,"_").concat(e.id,"_").concat(e.mode)}function buildIframe(e,t){var n;switch(e.type){case"quiz":n=500;break;case"answer":n=50;break;default:n=0}var i=document.createElement("iframe");i.setAttribute("title","Pinpoll Widget"),i.setAttribute("frameborder","0"),i.setAttribute("scrolling","no"),i.setAttribute("width","100%"),i.setAttribute("id",t),i.setAttribute("name",window.location.toString()),i.setAttribute("style","display:block; height:"+e.height||0);var o=e.height||n;return o&&i.setAttribute("height",o.toString()),i}function buildUrl(e,t){var n,i=!1,o="";e.styles&&(o+=e.styles),e.height&&(o+="".concat(o.length>0?"&":"","height=").concat(e.height)),e.trackmode&&"preview"===e.trackmode&&(o+="".concat(o.length>0?"&":"","previewMode=1")),e.simulate&&"on"===e.simulate&&(o+="".concat(o.length>0?"&":"","simulate=1")),e.editmode&&"on"===e.editmode&&(o+="".concat(o.length>0?"&":"","editMode=1"),i=!0),e.randomQuestions&&(o+="".concat(o.length>0?"&":"","randomQuestions=1")),e.randomAnswers&&(o+="".concat(o.length>0?"&":"","randomAnswers=1")),"preload"===e.loading&&(o+="".concat(o.length>0?"&":"","preloadMode=1")),e.blockAds&&(o+="".concat(o.length>0?"&":"","blockAds=1")),e.info&&Object.keys(e.info).length&&(o+="".concat(o.length>0?"&":"","info=").concat(encodeURIComponent(JSON.stringify(e.info)))),t&&(o+="".concat(o.length>0?"&":"","parentID=").concat(encodeURIComponent(t)));var a="";if(e.version)return"".concat(e.location,"/embed/").concat(e.version,"?id=").concat(e.id).concat(o?"&".concat(o):"");switch(e.type){case"answer":n="".concat(e.location,"/embed/answer/").concat(e.id).concat(o?"?".concat(o):"");break;default:"result"===e.mode&&(a+="/result"),n="".concat(e.location||"","/").concat(i?"direct/":"","embed/").concat("aipoll"===e.mode?"inspire/":"").concat(e.id).concat(a),e.design&&(n+="/cd/"+e.design),n+=o?"?".concat(o):""}return n}},631:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>g,oW:()=>v});var i=n(768);function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var l=["served","loads","renders","impressions"],s=new Set(["url","ppid","class","consent","style","opointdata","rect_data","bis_style"]),d=["target-ads-","_","font-"],c=function(){function e(t,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:500;o(this,e),r(this,"endpoint",void 0),r(this,"flushDelayMs",void 0),r(this,"url",void 0),r(this,"embedcode",void 0),r(this,"stage",-1),r(this,"sentStage",-1),r(this,"flushTimer",null),r(this,"flushing",!1),r(this,"impressionObserver",void 0),this.endpoint=this.resolveEndpoint(),this.flushDelayMs=i,this.url=n,this.embedcode=this.buildEmbedcode(t),this.registerLifecycleFlush()}var t,n;return t=e,(n=[{key:"markServed",value:function(){this.mark("served")}},{key:"markLoad",value:function(){this.mark("loads")}},{key:"markRender",value:function(){this.mark("renders")}},{key:"markImpression",value:function(){var e=this.stage;this.mark("impressions",!1),this.stage>e&&(null!==this.flushTimer&&(window.clearTimeout(this.flushTimer),this.flushTimer=null),this.flush(!1))}},{key:"observeImpression",value:function(e){var t=this;this.stage>=l.indexOf("impressions")||("IntersectionObserver"in window?(this.impressionObserver||(this.impressionObserver=new IntersectionObserver((function(e){e.forEach((function(e){var n;e.isIntersecting&&e.intersectionRatio>=.5&&(t.markImpression(),null===(n=t.impressionObserver)||void 0===n||n.disconnect())}
909))}),{threshold:[.5]})),this.impressionObserver.observe(e)):this.markImpression())}},{key:"resolveEndpoint",value:function(){var e="https://api.embed.pinpoll.com";return"".concat(e.replace(/\/+$/,""),"/v3/widget")}},{key:"buildEmbedcode",value:function(e){var t=this,n={};Array.from(e.attributes).sort((function(e,t){return e.name.localeCompare(t.name)})).forEach((function(e){var i=t.normalizeAttrName(e.name);!i||s.has(i)||d.some((function(e){return i.startsWith(e)}))||void 0!==n[i]||(n[i]=e.value)}));var i={};return Object.keys(n).sort().forEach((function(e){i[e]=n[e]})),JSON.stringify(i)}},{key:"normalizeAttrName",value:function(e){return e.startsWith("data-pinpoll-")?e.substring(13):e.startsWith("data-")?e.substring(5):e}},{key:"advance",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=l.indexOf(e);if(!(n<=this.stage)){if(n>this.stage+1)for(var i=this.stage+1;i<n;i++){var o=l[i];console.warn('Pinpoll: automatically marked skipped stage "'.concat(o,'" for embed ').concat(this.embedcode))}this.stage=n,t&&this.scheduleFlush()}}},{key:"scheduleFlush",value:function(){var e=this;this.endpoint&&(null!==this.flushTimer&&window.clearTimeout(this.flushTimer),this.flushTimer=window.setTimeout((function(){e.flushTimer=null,e.flush(!1)}),this.flushDelayMs))}},{key:"hasPending",value:function(){return this.stage>this.sentStage}},{key:"buildPayloadRow",value:function(e,t){var n=function(n){var i=l.indexOf(n);return i>e&&i<=t?1:0};return{url:this.url,embedcode:this.embedcode,served:n("served"),loads:n("loads"),renders:n("renders"),impressions:n("impressions")}}},{key:"flush",value:function(e){var t=this;if(this.endpoint&&this.hasPending()&&!this.flushing){var n=this.stage,i=this.buildPayloadRow(this.sentStage,n);if(i.served+i.loads+i.renders+i.impressions!==0){var o=i;e&&navigator.sendBeacon?navigator.sendBeacon(this.endpoint,new Blob([JSON.stringify(o)],{type:"application/json"}))&&(this.sentStage=Math.max(this.sentStage,n)):(this.flushing=!0,fetch(this.endpoint,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},credentials:"include",keepalive:e,body:JSON.stringify(o)}).then((function(){t.sentStage=Math.max(t.sentStage,n)})).catch((function(){})).finally((function(){t.flushing=!1,t.hasPending()&&t.scheduleFlush()})))}}}},{key:"mark",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.advance(e,t)}},{key:"registerLifecycleFlush",value:function(){var e=this;window.addEventListener("pagehide",(function(){return e.flush(!0)})),document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e.flush(!0)}))}}])&&a(t.prototype,n),e}();function u(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=p(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var i=0,o=function(){};return{s:o,n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,r=!0,l=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){l=!0,a=e},f:function(){try{r||null==n.return||n.return()}finally{if(l)throw a}}}}function p(e,t){if(e){if("string"==typeof e)return f(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?f(e,t):void 0}}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}var m={1:"poll",2:"quiz",6:"personality_test"};function h(e){var t,n,i=e.getAttribute("data-pinpoll-location")||e.getAttribute("data-location")||"https://embed.pinpoll.com",o=e.getAttribute("data-design");return{type:e.getAttribute("data-pinpoll-type")||e.getAttribute("data-type")||"poll",aiPollMode:"aipoll"===e.getAttribute("data-mode"),version:e.getAttribute("data-version"),native:null!==e.getAttribute("data-native")||"v2"===e.getAttribute("data-version"),mode:e.getAttribute("data-pinpoll-mode")||e.getAttribute("data-mode")||"poll",location:i,trackmode:e.getAttribute("data-pinpoll-trackmode")||e.getAttribute("data-trackmode")||"default",editmode:e.getAttribute("data-pinpoll-editmode")||e.getAttribute("data-editmode")||"default",simulate:e.getAttribute("data-pinpoll-simulate")||e.getAttribute("data-simulate")||"default",id:parseInt(e.getAttribute("data-pinpoll-id")||e.getAttribute("data-id"),10)||0,height:parseInt(e.getAttribute("data-pinpoll-height")||e.getAttribute("data-height"),10)||0,label:e.getAttribute("data-pinpoll-label")||e.getAttribute("data-label")||"",bgcolor:e.getAttribute("data-pinpoll-bgcolor")||e.getAttribute("data-bgcolor")||"#2395a6",styles:function(){var t,n=/data(?:-pinpoll)?-style-(.+)/,i=[],o=u(e.attributes);try{for(o.s();!(t=o.n()).done;){var a=t.value,r=a.name.match(n);r&&i.push("".concat(encodeURIComponent(r[1]),"=").concat(encodeURIComponent(a.value)))}}catch(e){o.e(e)}finally{o.f()}return!!i.length&&i.join("&")}(),loading:e.getAttribute("data-loading")||!1,design:o?+o:null,randomQuestions:null!==e.getAttribute("random-questions"),randomAnswers:null!==e.getAttribute("random-answers"),forceLoad:null!==e.getAttribute("force-load"),cssClass:null===(t=e.getAttribute("data-css-class"))||void 0===t?void 0:t.trim(),customURL:null===(n=e.getAttribute("data-url"))||void 0===n?void 0:n.trim(),url:e.getAttribute("data-url")||(window.location.origin||"unknown_origin")+window.location.pathname,info:e.getAttributeNames().reduce((function(t,n){return n.startsWith("data-info-")&&(t[n.substring(10)]=e.getAttribute(n)),t}),{}),targetAds:e.getAttributeNames().reduce((function(t,n){return n.startsWith("data-target-a
909ds-")&&(t[n.substring(16)]=e.getAttribute(n)),t}),{}),autoplay:[null,"false"].includes(e.getAttribute("data-autoplay"))?void 0:+(e.getAttribute("data-autoplay")||0),autoplayDelay:[null,""].includes(e.getAttribute("data-autoplay-delay"))?void 0:+(e.getAttribute("data-autoplay-delay")||0),mqeDelay:[null,""].includes(e.getAttribute("data-mqe-delay"))?void 0:+(e.getAttribute("data-mqe-delay")||0),blockAds:![null,"false","0"].includes(e.getAttribute("data-block-ads")),topic:e.getAttribute("data-topic"),ppId:e.getAttribute("data-ppid"),consent:e.getAttribute("data-consent"),muteVoted:![null,"false","0"].includes(e.getAttribute("data-mute-voted"))}}function v(e,t){var n,i=h(t);Object.assign(e,i,{id:i.id||e.id,design:null!==(n=i.design)&&void 0!==n?n:e.design})}const g=function(){return{embeds:[],initedEmbeds:0,fallbackElementsPromise:{},isElementAlreadyEmbedded:function(e,t,n){var i=t?m[t]:null;try{var o=['[data-pinpoll-id="'.concat(e,'"]'),'script[data-location*="'.concat(n||"pinpoll.com",'"][data-id="').concat(e,'"]')],a=i?o.map((function(e){return"".concat(e,":not([data-type]), ").concat(e,'[data-type="').concat(i,'"]')})).join(", "):o.join(", ");return!!document.body.querySelector(a)||!!this.embeds.find((function(t){var n,i,o;return(null===(n=t.data)||void 0===n?void 0:n.id)===e&&("poll"===(null===(i=t.data)||void 0===i?void 0:i.type)||"aipoll"===(null===(o=t.data)||void 0===o?void 0:o.type))}))}catch(e){return!1}},isAnyElementEmbedded:function(){return!!this.embeds.find((function(e){return"aipoll"!==e.mode}))||!!document.body.querySelector('[data-pinpoll-id]:not([data-mode="aipoll"]), script[data-location*="'.concat("pinpoll.com",'"][data-id]'))},getElementVotedStatus:function(e){var t,n,i=e.questions,o=e.multiple_vote_interval,a=null===(t=window.Pinpoll)||void 0===t||null===(n=t.storage)||void 0===n?void 0:n.votes;if(i&&a){var r=a.filter((function(e){return i.includes(e.question_id)}));if(null!=r&&r.length)return!o||r.find((function(e){return e.voted_at+o>(new Date).getTime()}))?2:1}return 0},sortPreferredAutoEmbeddedElements:function(e,t,n){var i=this,o=t.location,a=t.muteVoted,r=t.height,l=[];if(e){var s,d;if(l=e.filter((function(e){return!i.isElementAlreadyEmbedded(e.element_id,e.type_id,o)})),null!==(s=window.Pinpoll)&&void 0!==s&&s.appName&&(l=l.filter((function(e){return 1===e.type_id&&2===e.max_answers}))),null!==(d=window.Pinpoll)&&void 0!==d&&d.heightFilterActive&&r){var c=n&&n.parentNode!==document.getElementsByTagName("head")[0]&&n.parentElement?n.clientWidth:document.body.clientWidth;l=l.filter((function(e){try{var t=JSON.parse(e.height),n=Math.max.apply(Math,function(e){if(Array.isArray(e))return f(e)}(i=Object.keys(t).map(Number).filter((function(e){return e<=c})))||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(i)||p(i)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());if(t[n])return parseInt(t[n])<=r}catch(e){return!1}var i}))}a?l=l.filter((function(e){return 2!==i.getElementVotedStatus(e)})):l.length&&void 0===l[0].sort&&(l=l.sort((function(e,t){var n=i.getElementVotedStatus(e),o=i.getElementVotedStatus(t);return n===o?0:n<o?-1:1})))}return l},getFallbackElements:function(e,t){var n=t+e;if(!this.fallbackElementsPromise[n]){var i={url:e};t&&(i.topic=t),this.fallbackElementsPromise[n]=fetch("https://api.embed.pinpoll.com/aipolls/search?"+new URLSearchParams(i),{method:"GET"}).then((function(e){return e.json()})).then((function(e){return e})).catch((function(e){console.log("Pinpoll: error during fetching aipolls",e)}))}return this.fallbackElementsPromise[n]},initEmbed:function(e){var t=this;if(!this.embeds.find((function(t){return t.element===e}))){var n=h(e),o=new c(e,n.url);e.classList.add("loaded"),o.markServed(),n.id&&!n.native?this.embeds.push(new i.Z(n,e,o)):new Promise((function(t){"eager"!==n.loading&&"preload"!==n.loading?(e.classList.add("lazyload"),new Promise((function(t){document.addEventListener("lazybeforeunveil",(function(n){n.target===e&&t()}))})).finally((function(){t()}))):t()})).then((function(){v(n,e),n.native?t.embeds.push(new i.Z(n,e,o)):n.aiPollMode||n.topic?n.forceLoad||!t.isAnyElementEmbedded()?new Promise((function(e){n.aiPollMode?(o.markLoad(),fetch("https://api.embed.pinpoll.com/aipolls/first?"+new URLSearchParams({url:n.url}),{method:"GET"}).then((function(e){return e.json()})).then((function(t){n.id=t.id,e()})).catch((function(t){console.log("Pinpoll: error during fetching aipoll",t),e()}))):e()})).finally((function(){n.id?t.embeds.push(new i.Z(n,e,o)):(n.aiPollMode&&!n.topic||!n.aiPollMode&&n.topic)&&(o.markLoad(),n.fallbackElementsPromise=t.getFallbackElements(n.url,n.topic).then((function(a){var r,l=a.elements;n.fallbackElements=t.sortPreferredAutoEmbeddedElements(l,n,e);var s=null===(r=n.fallbackElements)||void 0===r?void 0:r.shift();s?(n.id=s.element_id,!n.design&&s.custom_design_id&&(n.design=s.custom_design_id),n.fallback_id=s.id,t.embeds.push(new i.Z(n,e,o))):console.log("Pinpoll: no suitable element found for",e)})))})):console.log("Pinpoll: not embedding as another element is already embedded",e):console.log("Pinpoll: no id or data specified for element",e)}))}},start:function(){var e=this;window.MutationObserver=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;var t=function(){var t,n=u(document.querySelectorAll("div[data-pinpoll-id]:not(.loaded), div.pinpoll:not(.loaded)"));try{for(n.s();!(t=n.n()).done;){var i=t.value;e.initEmbed(i)}}catch(e){n.e(e)}finally{n.f()}};t();var n=window.setInterval((function(){t()}),500);window.MutationObserver&&(window.setTimeout((function(){window.clearInterval(n)}),1e4),new window.MutationObserver((function(t){t.forEach((function(t){var n,i=u(t.addedNodes);try{for(i.s();!(n=i.n()).done;){var o=n.value;o.matches&&o.matches("div[data-pinpoll-id]:not(.loaded), div.pinpoll:not(.loaded)")&&e.initEmbed(o)}}catch(e){i.e(e)}finally{i.f()}}))})).observe(document,{childList:!0,subtree:!0}))},broadcast:function(e){var t,n=u(this.embeds);try{for(n.s();!(t=n.n()).done;)t.value.postMessage(e)}catch(e){n.e(e)}finally{n.f()}}}}},726:()=>{function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function t(t){for(var i=1;i<arguments.length;i++){var o=null!=arguments[i]?arguments[i]:{};
909i%2?e(Object(o),!0).forEach((function(e){n(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):e(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e){var t=window.Pinpoll.storage.votes;t||(t=[]),-1===t.findIndex((function(t){return t.answer_id===e.answer_id&&t.voted_at===e.voted_at}))&&t.push(e),window.Pinpoll.storage.votes=t}window.addEventListener("message",(function(e){var n=e.data;try{if("string"==typeof n){if(!n.startsWith("{"))return!1;n=JSON.parse(n)}}catch(e){console.warn(e)}var a=function(t){e.source&&e.source.postMessage(t,e.origin)};if(n&&"object"===i(n)&&n.action)switch(n.action){case"get:visitor-votes":a({action:"return:visitor-votes",data:window.Pinpoll.storage.votes.map((function(e){return t(t({},e),{},{justVoted:!!window.Pinpoll.votelinkVotes.find((function(t){return t.answer_id===e.answer_id&&t.voted_at===e.voted_at}))})}))});break;case"add:visitor-vote":o(n.data);break;case"remove:visitor-vote":var r=window.Pinpoll.storage.votes,l=n.data,s=l.questionId,d=l.answerId;if(r){var c=r.filter((function(e){return(e.question_id||e.poll_id)!==s||e.answer_id!==d}));window.Pinpoll.storage.votes=c}break;case"remove:visitor-vote-element":var u=window.Pinpoll.storage.votes,p=n.data.questionIds;if(u){var f=u.filter((function(e){return!p.some((function(t){return t===e.question_id}))}));window.Pinpoll.storage.votes=f}break;case"add":var m=n.key;if(!m)break;var h=window.Pinpoll.storage[m];if(!h)break;if(!(h instanceof Array))break;h.push(n.value),window.Pinpoll.storage[m]=h;break;case"get":var v=n.key;if(!v)break;a({action:"return:"+v,data:{key:v,value:window.Pinpoll.storage[v]}})}return null})),function(){var e=new URL(window.location.href),t=e.searchParams.get("pinpoll_votes");if(t){var n;try{n=JSON.parse(t)}catch(e){console.warn("Pinpoll: Failed parsing pinpoll_votes GET parameter")}n&&n instanceof Array&&n.forEach((function(e){o(e),window.Pinpoll.votelinkVotes.push(e)}));try{e.searchParams.delete("pinpoll_votes"),window.history.pushState({},document.title,e.toString())}catch(e){}}}()},558:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var i=n(38),o=n(58),a=n(173);function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const d=function(e,t){var n=t||{},d=n.widgetIndex,c=n.originPage,u=n.widgetLocation,p={},f=(0,i.G)({BASE_DOMAIN:"pinpoll.com",CDN_ENDPOINT:"https://static.pinpoll.com",API_ENDPOINT:"https://pa.pinpoll.com/v1",cookiesEnabled:function(){if(navigator.cookieEnabled)return!0;document.cookie="cookietest=1";var e=-1!==document.cookie.indexOf("cookietest=");return document.cookie="cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT",e}(),thirdPartyCookiesEnabled:!1,tcfApi:{},requestSent:!1,requestDone:!1,start:function(e){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",m):m(),e&&(p=e)}});function m(){window.setTimeout((function(){Promise.all([(0,a.I)(),window.location.hostname.match(f.BASE_DOMAIN)?Promise.resolve():new Promise((function(e){try{var t=document.createElement("iframe");t.style.display="none",t.title="Pinpoll Third Party Cookie Test",t.src="".concat(f.CDN_ENDPOINT,"/static/start.html"),window.addEventListener("message",(function(t){"MM:3PCunsupported"===t.data?f.thirdPartyCookiesEnabled=!1:"MM:3PCsupported"===t.data&&(f.thirdPartyCookiesEnabled=!0),e()}),!1),document.body.appendChild(t),window.setTimeout((function(){t.remove(),e()}),5e3)}catch(t){f.log("Could not check ThirdPartyCookiesEnabled",t),e()}})),window.ppTcString?(f.tcfApi.tcString=window.ppTcString,f.tcfApi.available=!!window.__tcfapi,Promise.resolve()):window.__tcfapi?(f.tcfApi.available=!0,new Promise((function(e){var t=(new Date).getTime();window.__tcfapi("addEventListener",2,(function(n,i){f.tcfApi.responseTime=(new Date).getTime()-t,i?f.tcfApi.tcString=n.tcString:f.log("tcf api responded with error",n),f.tcfApi.timeout||(f.tcfApi.timeout=!1),f.tcfApi.checkFinished=!0,e()})),window.setTimeout((function(){f.tcfApi.checkFinished||(f.tcfApi.timeout=!0,e())}),1e3)}))):(f.tcfApi.available=!1,Promise.resolve())]).then((function(){var t,n;t=u?function(){try{return new URL(u)}catch(e){return f.log("Could not parse widget location",e),document.location}}():document.location,n=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};
909t%2?l(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({timezone:(new Date).getTimezoneOffset(),adblock:window.Pinpoll.userHasAdblock?1:0,dnt:window.navigator.doNotTrack,cookiesEnabled:f.cookiesEnabled?1:0,localStorageEnabled:v(),thirdPartyCookiesEnabled:f.thirdPartyCookiesEnabled?1:0,referrer:c||document.referrer,title:document.title,tcString:f.tcfApi.tcString,tcfApiAvailable:f.tcfApi.available,location:{hash:t.hash,hostname:t.hostname,pathname:t.pathname,protocol:t.protocol,search:t.search},screen:{width:window.screen.width,height:window.screen.height,colorDepth:window.screen.colorDepth,orientation:window.screen.orientation?window.screen.orientation.type:null},metaTags:h(),widgetIndex:d||""},p),(0,o.w)(f.API_ENDPOINT,n,e).then((function(t){var n,i,o=t.headers.get("PP-Visitor");o&&(e.visitor=o,null===(n=window.Pinpoll)||void 0===n||null===(i=n.embed)||void 0===i||i.broadcast({action:"global:trackingDone",visitor:o}))})).catch((function(e){var t,n;f.log("fetch request failed",e),null===(t=window.Pinpoll)||void 0===t||null===(n=t.embed)||void 0===n||n.broadcast({action:"global:trackingDone"})})).finally((function(){f.requestDone=!0}))}))}))}function h(){var e,t={},n=function(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var i=0,o=function(){};return{s:o,n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,l=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){s=!0,a=e},f:function(){try{l||null==n.return||n.return()}finally{if(s)throw a}}}}(document.getElementsByTagName("meta"));try{for(n.s();!(e=n.n()).done;){var i=e.value,o=i.getAttribute("name")||i.getAttribute("property"),a=i.getAttribute("content");if(o&&a&&o.replace(/\s/g,"").length>0){var l=o.trim().toLowerCase(),s=t[l];s?s instanceof Array?t[l].push(a):t[l]=[s,a]:t[l]=a}}}catch(e){n.e(e)}finally{n.f()}return t}function v(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}return f}},38:(e,t,n)=>{"use strict";function i(e){var t=e;return t.logs=[],t.log=function(){for(var e=arguments.length,n=new Array(e),i=0;i<e;i++)n[i]=arguments[i];t.logs.push([new Date,n])},t}n.d(t,{G:()=>i})},173:(e,t,n)=>{"use strict";function i(){var e;return void 0!==(null===(e=window.Pinpoll)||void 0===e?void 0:e.userHasAdblock)?Promise.resolve(window.Pinpoll.userHasAdblock):new Promise((function(e){var t=window.setTimeout((function(){var e;null!==(e=window.Pinpoll)&&void 0!==e&&e.userHasAdblock||n(!1)}),1e3),n=function(n){clearTimeout(t),window.Pinpoll=window.Pinpoll||{},window.Pinpoll.userHasAdblock=n,e(n)},i=document.createElement("div");i.innerHTML="&nbsp;",i.style.position="absolute",i.className="native-ad-container mobile-ad js-ad_iframe";try{document.body.appendChild(i)}catch(e){console.log("Could not check Adblock",e),n(!1)}window.setTimeout((function(){n(0===i.offsetHeight),i.remove()}),100)}))}n.d(t,{I:()=>i})},58:(e,t,n)=>{"use strict";function i(e,t,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"post",o={Accept:"application/json","Content-Type":"application/json"},a=n.visitor;return a&&(o["PP-Visitor"]=a),fetch(e,{method:i,headers:o,credentials:"include",body:JSON.stringify(t)})}n.d(t,{w:()=>i})},90:e=>{!function(t,n){var i=function(e,t,n){"use strict";var i,o;if(function(){var t,n={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};for(t in o=e.lazySizesConfig||e.lazysizesConfig||{},n)t in o||(o[t]=n[t])}(),!t||!t.getElementsByClassName)return{init:function(){},cfg:o,noSupport:!0};var a,r,l,s,d,c,u,p,f,m,h,v,g,b,w,y,_,k,P,A,E,O,S,I,C,T,x,M,N,D,j,z,L,q,R,W,B,U,G,F,V,J,H,K,$=t.documentElement,Z=e.HTMLPictureElement,Y="addEventListener",X=e.addEventListener.bind(e),Q=e.setTimeout,ee=e.requestAnimationFrame||Q,te=e.requestIdleCallback,ne=/^picture$/i,ie=["load","error","lazyincluded","_lazyloaded"],oe={},ae=Array.prototype.forEach,re=function(e,t){return oe[t]||(oe[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),oe[t].test(e.getAttribute("class")||"")&&oe[t]},le=function(e,t){re(e,t)||e.setAttribute("class",(e.getAttribute("class")||"").trim()+" "+t)},se=function(e,t){var n;(n=re(e,t))&&e.setAttribute("class",(e.getAttribute("class")||"").replace(n," "))},de=function(e,t,n){var i=n?Y:"removeEventListener";n&&de(e,t),ie.forEach((function(n){e[i](n,t)}))},ce=function(e,n,o,a,r){var l=t.createEvent("Event");return o||(o={}),o.instance=i,l.initEvent(n,!a,!r),l.detail=o,e.dispatchEvent(l),l},ue=function(t,n){var i;!Z&&(i=e.picturefill||o.pf)?(n&&n.src&&!t.getAttribute("srcset")&&t.setAttribute("srcset",n.src),i({reevaluate:!0,elements:[t]})):n&&n.src&&(t.src=n.src)},pe=function(e,t){return(getComputedStyle(e,null)||{})[t]},fe=function(e,t,n){for(n=n||e.offsetWidth;n<o.minSize&&t&&!e._lazysizesWidth;)n=t.offsetWidth,t=t.parentNode;return n},me=(V=[],J=F=[],(K=function(e,n){U&&!n?e.apply(this,arguments):(J.push(e),G||(G=!0,(t.hidden?Q:ee)(H)))})._lsFlush=H=function(){var e=J;for(J=F.length?V:F,U=!0,G=!1;e.length;)e.shift()();U=!1},K),he=function(e,t){return t?function(){me(e)}:function(){var t=this,n=arguments;me((function(){e.apply(t,n)}))}},ve=function(e){var t,i,o=function(){t=null,e()},a=function(){var e=n.now()-i;e<99?Q(a,99-e):(te||o)(o)};return function(){i=n.now(),t||(t=Q(a,99))}},ge=(_=/^img$/i,k=/^iframe$/i,P="onscroll"in e&&!/(gle|ing)bot/.test(navigator.userAgent),0,A=0,E=0,O=-1,S=function(e){E--,(!e||E<0||!e.target)&&(E=0)},I=function(e){return null==y&&(y="hidden"==pe(t.body,"visibility")),y||!("hidden"==pe(e.parentNode,"visibility")&&"hidden"==pe(e,"visibility"))},C=function(e,n){var i,o=e,a=I(e);for(v-=n,w+=n,g-=n,b+=n;a&&(o=o.offsetParent)&&o!=t.body&&o!=$;)(a=(pe(o,"opacity")||1)>0)&&"visible"!=pe(o,"overflow")&&(i=o.getBoundingClientRect(),a=b>i.left&&g<i.right&&w>i.top-1&&v<i.bottom+1);return a},x=function(e){var t,i=0,a=o.throttleDelay,r=o.ricTimeout,l=function(){t=!1,i=n.now(),e()},s=te&&r>49?function(){te(l,{timeout:r}),r!==o.ricTimeout&&(r=o.ricTimeout)}:he((function(){Q(l)}),!0);return function(e){var o;(e=!0===e)&&(r=33),t||(t=!0,(o=a-(n.now()-i))<0&&(o=0),e||o<9?s():Q(s,o))}}(T=function(){var e,n,a,r,l,s,u,f,_,k,S,T,x=i.elements;if((p=o.loadMode)&&E<8&&(e=x.length)){for(n=0,O++;n<e;n++)if(x[n]&&!x[n]._lazyRace)if(!P||i.prematureUnveil&&i.prematureUnveil(x[n]))q(x[n]);else if((f=x[n].getAttribute("data-expand"))&&(s=1*f)||(s=A),k||(k=!o.expand||o.expand<1?$.clientHeight>500&&$.clientWidth>500?500:370:o.expand,i._defEx=k,S=k*o.expFactor,T=o.hFac,y=null,A<S&&E<1&&O>2&&p>2&&!t.hidden?(A=S,O=0):A=p>1&&O>1&&E<6?k:0),_!==s&&(m=innerWidth+s*T,h=innerHeight+s,u=-1*s,_=s),a=x[n].getBoundingClientRect(),(w=a.bottom)>=u&&(v=a.top)<=h&&(b=a.right)>=u*T&&(g=a.left)<=m&&(w||b||g||v)&&(o.loadHidden||I(x[n]))&&(c&&E<3&&!f&&(p<3||O<4)||C(x[n],s))){if(q(x[n]),l=!0,E>9)break}else!l&&c&&!r&&E<4&&O<4&&p>
9092&&(d[0]||o.preloadAfterLoad)&&(d[0]||!f&&(w||b||g||v||"auto"!=x[n].getAttribute(o.sizesAttr)))&&(r=d[0]||x[n]);r&&!l&&q(r)}}),N=he(M=function(e){var t=e.target;t._lazyCache?delete t._lazyCache:(S(e),le(t,o.loadedClass),se(t,o.loadingClass),de(t,D),ce(t,"lazyloaded"))}),D=function(e){N({target:e.target})},j=function(e,t){var n=e.getAttribute("data-load-mode")||o.iframeLoadMode;0==n?e.contentWindow.location.replace(t):1==n&&(e.src=t)},z=function(e){var t,n=e.getAttribute(o.srcsetAttr);(t=o.customMedia[e.getAttribute("data-media")||e.getAttribute("media")])&&e.setAttribute("media",t),n&&e.setAttribute("srcset",n)},L=he((function(e,t,n,i,a){var r,l,s,d,c,p;(c=ce(e,"lazybeforeunveil",t)).defaultPrevented||(i&&(n?le(e,o.autosizesClass):e.setAttribute("sizes",i)),l=e.getAttribute(o.srcsetAttr),r=e.getAttribute(o.srcAttr),a&&(d=(s=e.parentNode)&&ne.test(s.nodeName||"")),p=t.firesLoad||"src"in e&&(l||r||d),c={target:e},le(e,o.loadingClass),p&&(clearTimeout(u),u=Q(S,2500),de(e,D,!0)),d&&ae.call(s.getElementsByTagName("source"),z),l?e.setAttribute("srcset",l):r&&!d&&(k.test(e.nodeName)?j(e,r):e.src=r),a&&(l||d)&&ue(e,{src:r})),e._lazyRace&&delete e._lazyRace,se(e,o.lazyClass),me((function(){var t=e.complete&&e.naturalWidth>1;p&&!t||(t&&le(e,o.fastLoadedClass),M(c),e._lazyCache=!0,Q((function(){"_lazyCache"in e&&delete e._lazyCache}),9)),"lazy"==e.loading&&E--}),!0)})),q=function(e){if(!e._lazyRace){var t,n=_.test(e.nodeName),i=n&&(e.getAttribute(o.sizesAttr)||e.getAttribute("sizes")),a="auto"==i;(!a&&c||!n||!e.getAttribute("src")&&!e.srcset||e.complete||re(e,o.errorClass)||!re(e,o.lazyClass))&&(t=ce(e,"lazyunveilread").detail,a&&be.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,E++,L(e,t,a,i,n))}},R=ve((function(){o.loadMode=3,x()})),B=function(){c||(n.now()-f<999?Q(B,999):(c=!0,o.loadMode=3,x(),X("scroll",W,!0)))},{_:function(){f=n.now(),i.elements=t.getElementsByClassName(o.lazyClass),d=t.getElementsByClassName(o.lazyClass+" "+o.preloadClass),X("scroll",x,!0),X("resize",x,!0),X("pageshow",(function(e){if(e.persisted){var n=t.querySelectorAll("."+o.loadingClass);n.length&&n.forEach&&ee((function(){n.forEach((function(e){e.complete&&q(e)}))}))}})),e.MutationObserver?new MutationObserver(x).observe($,{childList:!0,subtree:!0,attributes:!0}):($.addEventListener("DOMNodeInserted",x,!0),$.addEventListener("DOMAttrModified",x,!0),setInterval(x,999)),X("hashchange",x,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach((function(e){t.addEventListener(e,x,!0)})),/d$|^c/.test(t.readyState)?B():(X("load",B),t.addEventListener("DOMContentLoaded",x),Q(B,2e4)),i.elements.length?(T(),me._lsFlush()):x()},checkElems:x,unveil:q,_aLSL:W=function(){3==o.loadMode&&(o.loadMode=2),R()}}),be=(r=he((function(e,t,n,i){var o,a,r;if(e._lazysizesWidth=i,i+="px",e.setAttribute("sizes",i),ne.test(t.nodeName||""))for(a=0,r=(o=t.getElementsByTagName("source")).length;a<r;a++)o[a].setAttribute("sizes",i);n.detail.dataAttr||ue(e,n.detail)})),l=function(e,t,n){var i,o=e.parentNode;o&&(n=fe(e,o,n),(i=ce(e,"lazybeforesizes",{width:n,dataAttr:!!t})).defaultPrevented||(n=i.detail.width)&&n!==e._lazysizesWidth&&r(e,o,i,n))},{_:function(){a=t.getElementsByClassName(o.autosizesClass),X("resize",s)},checkElems:s=ve((function(){var e,t=a.length;if(t)for(e=0;e<t;e++)l(a[e])})),updateElem:l}),we=function(){!we.i&&t.getElementsByClassName&&(we.i=!0,be._(),ge._())};return Q((function(){o.init&&we()})),i={cfg:o,autoSizer:be,loader:ge,init:we,uP:ue,aC:le,rC:se,hC:re,fire:ce,gW:fe,rAF:me}}(t,t.document,Date);t.lazySizes=i,e.exports&&(e.exports=i)}("undefined"!=typeof window?window:{})}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var __webpack_exports__={};(()=>{"use strict";const e={embed:null,tracking:null,retargeting:null,remarketing:null,storage:function(){var e={};Object.defineProperty(e,"visitor",{set:function(e){if(window.Pinpoll.embed){var t;try{t=JSON.parse(localStorage.PP_visitor).value}catch(e){t=null}t!==e&&setTimeout((function(){window.Pinpoll.embed.broadcast({action:"set:visitor",visitor:e})}))}try{localStorage.PP_visitor=e&&"null"!==e?JSON.stringify({value:e,expires:(new Date).setDate((new Date).getDate()+30)}):JSON.stringify({value:e,expires:0})}catch(e){console.warn(e)}},get:function(){try{if(!localStorage.PP_visitor)return null;var e=JSON.parse(localStorage.PP_visitor);return e.expires&&e.expires<Date.now()?(delete localStorage.PP_visitor,null):(e.expires=(new Date).setDate((new Date).getDate()+30),localStorage.PP_visitor=JSON.stringify(e),e.value)}catch(e){return console.warn(e),null}}});for(var t=function(){var t=i[n];Object.defineProperty(e,t.id,{set:function(e){try{localStorage[t.key]=JSON.stringify(e)}catch(e){console.warn(e)}},get:function(){try{var e=localStorage[t.key];return e?JSON.parse(e):t.d}catch(e){return console.warn(e),t.d}}})},n=0,i=[{id:"votes",key:"PP_votes",d:[]},{id:"leadForms",key:"PP_forms",d:[]},{id:"lastTriggered",key:"PP_marketing",d:null}];n<i.length;n++)t();try{localStorage.pinpoll_allVisitorVotes&&(localStorage.PP_votes=localStorage.pinpoll_allVisitorVotes,delete localStorage.pinpoll_allVisitorVotes)}catch(e){}return e}(),heightFilterActive:!1,nativeLoader:void 0,votelinkVotes:[],init:function(){var e=document.querySelector("script[src*='pinpoll.com/global.js'][data-app]");e&&(this.appName=e.getAttribute("data-app"))}};window.Pinpoll&&Object.keys(window.Pinpoll).length>0||(window.Pinpoll=e,e.init())})(),(()=>{"use strict";var e=__webpack_require__(558);window.Pinpoll.tracking||(window.Pinpoll.tracking=(0,e.Z)(window.Pinpoll.storage,{widgetIndex:"global"}),window.Pinpoll.tracking.start(window.Pinpoll.appName?{app:window.Pinpoll.appName}:void 0))})(),(()=>{"use strict";var e=__webpack_require__(38),t=__webpack_require__(58);function n(){var e;if(null!==(e=window.Pinpoll)&&void 0!==e&&e.appName)return!0;var t=window.navigator,n=t.userAgent.toLowerCase();return/iphone|ipod|ipad/.test(n)&&!window.MSStream?!t.standalone&&!/safari/.test(n):n.includes("wv")}var i=eval;window.Pinpoll.retargeting||(window.Pinpoll.retargeting=function(o,a){var r,l,s=(0,e.G)({RETARGETING_ENDPOINT:"https://api2.dmp.pinpoll.com",pixelsLoaded:!1,pixels:[],isMobileDevice:(l=!1,r=navigator.userAgent||navigator.vendor||window.opera,(/(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(r)||/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 )|
909sy(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(r.substr(0,4)))&&(l=!0),l),isApp:n(),googleLoaded:!1,trackEmbedEvent:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(s.pixelsLoaded)d(e,n);else{var o=window.location!==window.parent.location?document.referrer:document.location.href;p({referrer:o,questionId:t,leadFormId:i}).then((function(t){s.pixelsLoaded=!0,t&&"success"===t.status&&t.data.length>0&&(s.pixels=t.data),d(e,n)})).catch((function(e){s.log("Retargeting Endpoint not reachable:",e)}))}},triggerPixels:function(e){c(e,!1)}});function d(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=s.pixels.filter((function(n){if(("vote"===e||"vote_click"===e)&&n.answer_id&&(!t.length||!t.includes(n.answer_id)))return!1;if("all"!==n.device_type){if(a&&n.device_type!==a)return!1;if(s.isApp&&"app"!==n.device_type)return!1;if(s.isMobileDevice&&"desktop"===n.device_type)return!1;if(!s.isMobileDevice&&"mobile"===n.device_type)return!1}return n.event===e}));(n=n.filter((function(e,t,n){return t===n.findIndex((function(t){return t.id===e.id}))}))).length&&c(n,!0)}function c(e,n){var a;e&&e.length>0&&(e.forEach((function(e){!function(e){switch(e.type){case"javascript":!function(e,t){e.externalcode?u({src:e.externalcode,async:!0},(function(){e.staticcode&&u({text:e.staticcode}),e.loaded=!0,t()})):e.staticcode?(u({text:e.staticcode}),e.loaded=!0,t()):t()}(e,(function(){e.trigger_code&&i(e.trigger_code)}));break;case"google":!function(e,t,n){if(window.google_trackConversion)window.google_trackConversion&&window.google_trackConversion({google_conversion_id:e,google_conversion_label:t,google_custom_value:n,google_custom_params:window.google_tag_params,google_remarketing_only:!0});else{var i=document.createElement("script");i.src="https://www.googleadservices.com/pagead/conversion_async.js",i.async=!0,i.addEventListener("load",(function(){s.googleLoaded=!0,window.google_trackConversion&&window.google_trackConversion({google_conversion_id:e,google_conversion_label:t,google_custom_value:n,google_custom_params:window.google_tag_params,google_remarketing_only:!0})}),!1),document.body.appendChild(i)}}(e.conversion_id,e.conversion_label,e.custom_value);break;case"facebook":e.event&&(e.group_title=e.event),function(e,t,n){if(function(e,t,n,i,o,a,r){e.fbq||(o=e.fbq=function(){o.callMethod?o.callMethod.apply(o,arguments):o.queue.push(arguments)},e._fbq||(e._fbq=o),o.push=o,o.loaded=!0,o.version="2.0",o.queue=[],(a=t.createElement(n)).async=!0,a.src="https://connect.facebook.net/en_US/fbevents.js",(r=t.getElementsByTagName(n)[0]).parentNode.insertBefore(a,r))}(window,document,"script"),window.fbq){window.fbq("init",e),window.fbq("track","PageView");var i="string"==typeof n&&n.length>0?{customValue:n}:{};window.fbq("trackCustom",t,i)}}(e.facebook_id,e.group_title,e.custom_value);break;case"image":t=e.source,(n=new Image).onload=function(){n.naturalHeight+n.naturalWidth!==0?document.body.appendChild(n):s.log("Error on loadImage: natural height and width === 0")},n.onerror=function(e){s.log(e)},t&&(n.src=t);break;default:s.log("Pixel execution error: no type specified!")}var t,n}(e)})),n&&(a={triggeredPixels:e.map((function(e){return{pixel_id:e.id,campaign_id:e.campaign_id}}))},(0,t.w)(s.RETARGETING_ENDPOINT+"/public/triggered",a,o).then((function(e){return e.json()})).then((function(e){"success"!==e.status&&s.log("Return type of triggered data did not success!",e.data)})).catch((function(e){s.log("Failed to send triggered data!",e)}))))}function u(e,t){var n=document.createElement("script");Object.keys(e).forEach((function(t){n[t]=e[t]})),t&&"function"==typeof t&&n.addEventListener("load",(function(e){t(null,e)}),!1),document.body.appendChild(n)}function p(e){return(0,t.w)(s.RETARGETING_ENDPOINT+"/public/tr",e,o).then((function(e){return e.json()}))}return s}(window.Pinpoll.storage),window.Pinpoll.remarketing=function(n,i){var o=(0,e.G)({RETARGETING_ENDPOINT:"https://api2.dmp.pinpoll.com",REMARKETING_MAX_TRIGGER_TIME:parseInt("MISSING_ENV_VAR".MIX_REMARKETING_MAX_TRIGGER_TIME||"",10)||36e5,start:function(){window.requestIdleCallback?window.requestIdleCallback((function(){a()}),{timeout:3e3}):window.setTimeout((function(){a()}),3e3)}});function a(){var e,a;!(a=i.lastTriggered)||Date.now()-a>o.REMARKETING_MAX_TRIGGER_TIME?(e={referrer:window.location.origin||window.location.hostname},(0,t.w)(o.RETARGETING_ENDPOINT+"/public/remarketing",e,i).then((function(e){return e.json()}))).then((function(e){i.lastTriggered=Date.now(),e.data.length&&n.triggerPixels(e.data)})).catch((function(e){o.log("Failed to send getRemarketingPixels",e)})):o.log("Checked Remarketing; last triggered happened within max trigger time, last triggered at:",i.lastTriggered)}return o.start(),o}(window.Pinpoll.retargeting,window.Pinpoll.storage))})(),(()=>{"use strict";var e=__webpack_require__(631);__webpack_require__(90),__webpack_require__(726),window.Pinpoll.embed||(window.Pinpoll.embed=(0,e.ZP)(),window.Pinpoll.embed.start())})()})();
910
911
912/* ----- DOCUMENT READY FUNCTION ------ */
913
914$(function() {
915  
916  if (!$("Body.BodyGallery").length ) {
917    // Sticky Header nicht in Galerie-Detailseiten
918
919      $(window).on('scroll resize touchmove',function(){
920        stickybegins = $(".SiteHeader").offset().top + $(".SiteHeader").height();
921
922        if($(this).scrollTop()>stickybegins && window.innerWidth>768){
923          $('.SiteHeaderSticky').fadeIn();
924        }else{
925          $('.SiteHeaderSticky').fadeOut();
926        }
927      });
928
929      $(window).on('scroll resize touchmove',function(){
930        if($(".RankingTable_table").length){
931        stickybegins = $(".RankingTable_table").offset().top;
932
933        if($(this).scrollTop()>stickybegins){
934          $('.table-button-right').css('position','sticky');
935          $('.table-button-left').css('position','sticky');
936        }else{
937          $('.table-button-right').css('position','relative');
938          $('.table-button-left').css('position','relative');
939        }
940        }
941      });
942
943  }
944
945  
946} );
947 
948
949
950!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,
vendor: 6,594 bytes, line 950
950sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.o
vendor: 3,442 bytes, line 950
950ptions.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.
950slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:
950parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"}
950,e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0}
vendor: 5,619 bytes, line 950
950,100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};
950!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}
950):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+
950o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")}
950,e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}});
951
vendor: 122,971 bytes, lines 952-4119
952/* Javascript plotting library for jQuery, version 0.8.3.
953
954Copyright (c) 2007-2014 IOLA and Ole Laursen.
955Licensed under the MIT license.
956
957*/
958
959// first an inline dependency, jquery.colorhelpers.js, we inline it here
960// for convenience
961
962/* Plugin for jQuery for working with colors.
963 *
964 * Version 1.1.
965 *
966 * Inspiration from jQuery color animation plugin by John Resig.
967 *
968 * Released under the MIT license by Ole Laursen, October 2009.
969 *
970 * Examples:
971 *
972 *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
973 *   var c = $.color.extract($("#mydiv"), 'background-color');
974 *   console.log(c.r, c.g, c.b, c.a);
975 *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
976 *
977 * Note that .scale() and .add() return the same modified object
978 * instead of making a new one.
979 *
980 * V. 1.1: Fix error handling so e.g. parsing an empty string does
981 * produce a color rather than just crashing.
982 */
983(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
984
985// the actual Flot code
986(function($) {
987
988	// Cache the prototype hasOwnProperty for faster access
989
990	var hasOwnProperty = Object.prototype.hasOwnProperty;
991
992    // A shim to provide 'detach' to jQuery versions prior to 1.4.  Using a DOM
993    // operation produces the same effect as detach, i.e. removing the element
994    // without touching its jQuery data.
995
996    // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
997
998    if (!$.fn.detach) {
999        $.fn.detach = function() {
1000            return this.each(function() {
1001                if (this.parentNode) {
1002                    this.parentNode.removeChild( this );
1003                }
1004            });
1005        };
1006    }
1007
1008	///////////////////////////////////////////////////////////////////////////
1009	// The Canvas object is a wrapper around an HTML5 <canvas> tag.
1010	//
1011	// @constructor
1012	// @param {string} cls List of classes to apply to the canvas.
1013	// @param {element} container Element onto which to append the canvas.
1014	//
1015	// Requiring a container is a little iffy, but unfortunately canvas
1016	// operations don't work unless the canvas is attached to the DOM.
1017
1018	function Canvas(cls, container) {
1019
1020		var element = container.children("." + cls)[0];
1021
1022		if (element == null) {
1023
1024			element = document.createElement("canvas");
1025			element.className = cls;
1026
1027			$(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
1028				.appendTo(container);
1029
1030			// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
1031
1032			if (!element.getContext) {
1033				if (window.G_vmlCanvasManager) {
1034					element = window.G_vmlCanvasManager.initElement(element);
1035				} else {
1036					throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
1037				}
1038			}
1039		}
1040
1041		this.element = element;
1042
1043		var context = this.context = element.getContext("2d");
1044
1045		// Determine the screen's ratio of physical to device-independent
1046		// pixels.  This is the ratio between the canvas width that the browser
1047		// advertises and the number of pixels actually present in that space.
1048
1049		// The iPhone 4, for example, has a device-independent width of 320px,
1050		// but its screen is actually 640px wide.  It therefore has a pixel
1051		// ratio of 2, while most normal devices have a ratio of 1.
1052
1053		var devicePixelRatio = window.devicePixelRatio || 1,
1054			backingStoreRatio =
1055				context.webkitBackingStorePixelRatio ||
1056				context.mozBackingStorePixelRatio ||
1057				context.msBackingStorePixelRatio ||
1058				context.oBackingStorePixelRatio ||
1059				context.backingStorePixelRatio || 1;
1060
1061		this.pixelRatio = devicePixelRatio / backingStoreRatio;
1062
1063		// Size the canvas to match the internal dimensions of its container
1064
1065		this.resize(container.width(), container.height());
1066
1067		// Collection of HTML div layers for text overlaid onto the canvas
1068
1069		this.textContainer = null;
1070		this.text = {};
1071
1072		// Cache of text fragments and metrics, so we can avoid expensively
1073		// re-calculating them when the plot is re-rendered in a loop.
1074
1075		this._textCache = {};
1076	}
1077
1078	// Resizes the canvas to the given dimensions.
1079	//
1080	// @param {number} width New width of the canvas, in pixels.
1081	// @param {number} width New height of the canvas, in pixels.
1082
1083	Canvas.prototype.resize = function(width, height) {
1084
1085		if (width <= 0 || height <= 0) {
1086			throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
1087		}
1088
1089		var element = this.element,
1090			context = this.context,
1091			pixelRatio = this.pixelRatio;
1092
1093		// Resize the canvas, increasing its density based on the display's
1094		// pixel ratio; basically giving it more pixels without increasing the
1095		// size of its element, to take advantage of the fact that retina
1096		// displays have that many more pixels in the same advertised space.
1097
1098		// Resizing should reset the state (excanvas seems to be buggy though)
1099
1100		if (this.width != width) {
1101			element.width = width * pixelRatio;
1102			element.style.width = width + "px";
1103			this.width = width;
1104		}
1105
1106		if (this.height != height) {
1107			element.height = height * pixelRatio;
1108			element.style.height = height + "px";
1109			this.height = height;
1110		}
1111
1112		// Save the context, so we can reset in case we get replotted.  The
1113		// restore ensure that we're really back at the initial state, and
1114		// should be safe even if we haven't saved the initial state yet.
1115
1116		context.restore();
1117		context.save();
1118
1119		// Scale the coordinate space to match the display density; so even though we
1120		// may have twice as many pixels, we still want lines and other drawing to
1121		// appear at the same size; the extra pixels will just make them crisper.
1122
1123		context.scale(pixelRatio, pixelRatio);
1124	};
1125
1126	// Clears the entire canvas area, not including any overlaid HTML text
1127
1128	Canvas.prototype.clear = function() {
1129		this.context.clearRect(0, 0, this.width, this.height);
1130	};
1131
1132	// Finishes rendering the canvas, including managing the text overlay.
1133
1134	Canvas.prototype.render = function() {
1135
1136		var cache = this._textCache;
1137
1138		// For each text layer, add elements marked as active that haven't
1139		// already been rendered, and remove those that are no longer active.
1140
1141		for (var layerKey in cache) {
1142			if (hasOwnProperty.call(cache, layerKey)) {
1143
1144				var layer = this.getTextLayer(layerKey),
1145					layerCache = cache[layerKey];
1146
1147				layer.hide();
1148
1149				for (var styleKey in layerCache) {
1150					if (hasOwnProperty.call(layerCache, styleKey)) {
1151						var styleCache = layerCache[styleKey];
1152						for (var key in styleCache) {
1153							if (hasOwnProperty.call(styleCache, key)) {
1154
1155								var positions = styleCache[key].positions;
1156
1157								for (var i = 0, position; position = positions[i]; i++) {
1158									if (position.active) {
1159										if (!position.rendered) {
1160											layer.append(position.element);
1161											position.rendered = true;
1162										}
1163									} else {
1164										positions.splice(i--, 1);
1165										if (position.rendered) {
1166											position.element.detach();
1167										}
1168									}
1169								}
1170
1171								if (positions.length == 0) {
1172									delete styleCache[key];
1173								}
1174							}
1175						}
1176					}
1177				}
1178
1179				layer.show();
1180			}
1181		}
1182	};
1183
1184	// Creates (if necessary) and returns the text overlay container.
1185	//
1186	// @param {string} classes String of space-separated CSS classes used to
1187	//     uniquely identify the text layer.
1188	// @return {object} The jQuery-wrapped text-layer div.
1189
1190	Canvas.prototype.getTextLayer = function(classes) {
1191
1192		var layer = this.text[classes];
1193
1194		// Create the text layer if it doesn't exist
1195
1196		if (layer == null) {
1197
1198			// Create the text layer container, if it doesn't exist
1199
1200			if (this.textContainer == null) {
1201				this.textContainer = $("<div class='flot-text'></div>")
1202					.css({
1203						position: "absolute",
1204						top: 0,
1205						left: 0,
1206						bottom: 0,
1207						right: 0,
1208						'font-size': "smaller",
1209						color: "#545454"
1210					})
1211					.insertAfter(this.element);
1212			}
1213
1214			layer = this.text[classes] = $("<div></div>")
1215				.addClass(classes)
1216				.css({
1217					position: "absolute",
1218					top: 0,
1219					left: 0,
1220					bottom: 0,
1221					right: 0
1222				})
1223				.appendTo(this.textContainer);
1224		}
1225
1226		return layer;
1227	};
1228
1229	// Creates (if necessary) and returns a text info object.
1230	//
1231	// The object looks like this:
1232	//
1233	// {
1234	//     width: Width of the text's wrapper div.
1235	//     height: Height of the text's wrapper div.
1236	//     element: The jQuery-wrapped HTML div containing the text.
1237	//     positions: Array of positions at which this text is drawn.
1238	// }
1239	//
1240	// The positions array contains objects that look like this:
1241	//
1242	// {
1243	//     active: Flag indicating whether the text should be visible.
1244	//     rendered: Flag indicating whether the text is currently visible.
1245	//     element: The jQuery-wrapped HTML div containing the text.
1246	//     x: X coordinate at which to draw the text.
1247	//     y: Y coordinate at which to draw the text.
1248	// }
1249	//
1250	// Each position after the first receives a clone of the original element.
1251	//
1252	// The idea is that that the width, height, and general 'identity' of the
1253	// text is constant no matter where it is placed; the placements are a
1254	// secondary property.
1255	//
1256	// Canvas maintains a cache of recently-used text info objects; getTextInfo
1257	// either returns the cached element or creates a new entry.
1258	//
1259	// @param {string} layer A string of space-separated CSS classes uniquely
1260	//     identifying the layer containing this text.
1261	// @param {string} text Text string to retrieve info for.
1262	// @param {(string|object)=} font Either a string of space-separated CSS
1263	//     classes or a font-spec object, defining the text's font and style.
1264	// @param {number=} angle Angle at which to rotate the text, in degrees.
1265	//     Angle is currently unused, it will be implemented in the future.
1266	// @param {number=} width Maximum width of the text before it wraps.
1267	// @return {object} a text info object.
1268
1269	Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
1270
1271		var textStyle, layerCache, styleCache, info;
1272
1273		// Cast the value to a string, in case we were given a number or such
1274
1275		text = "" + text;
1276
1277		// If the font is a font-spec object, generate a CSS font definition
1278
1279		if (typeof font === "object") {
1280			textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
1281		} else {
1282			textStyle = font;
1283		}
1284
1285		// Retrieve (or create) the cache for the text's layer and styles
1286
1287		layerCache = this._textCache[layer];
1288
1289		if (layerCache == null) {
1290			layerCache = this._textCache[layer] = {};
1291		}
1292
1293		styleCache = layerCache[textStyle];
1294
1295		if (styleCache == null) {
1296			styleCache = layerCache[textStyle] = {};
1297		}
1298
1299		info = styleCache[text];
1300
1301		// If we can't find a matching element in our cache, create a new one
1302
1303		if (info == null) {
1304
1305			var element = $("<div></div>").html(text)
1306				.css({
1307					position: "absolute",
1308					'max-width': width,
1309					top: -9999
1310				})
1311				.appendTo(this.getTextLayer(layer));
1312
1313			if (typeof font === "object") {
1314				element.css({
1315					font: textStyle,
1316					color: font.color
1317				});
1318			} else if (typeof font === "string") {
1319				element.addClass(font);
1320			}
1321
1322			info = styleCache[text] = {
1323				width: element.outerWidth(true),
1324				height: element.outerHeight(true),
1325				element: element,
1326				positions: []
1327			};
1328
1329			element.detach();
1330		}
1331
1332		return info;
1333	};
1334
1335	// Adds a text string to the canvas text overlay.
1336	//
1337	// The text isn't drawn immediately; it is marked as rendering, which will
1338	// result in its addition to the canvas on the next render pass.
1339	//
1340	// @param {string} layer A string of space-separated CSS classes uniquely
1341	//     identifying the layer containing this text.
1342	// @param {number} x X coordinate at which to draw the text.
1343	// @param {number} y Y coordinate at which to draw the text.
1344	// @param {string} text Text string to draw.
1345	// @param {(string|object)=} font Either a string of space-separated CSS
1346	//     classes or a font-spec object, defining the text's font and style.
1347	// @param {number=} angle Angle at which to rotate the text, in degrees.
1348	//     Angle is currently unused, it will be implemented in the future.
1349	// @param {number=} width Maximum width of the text before it wraps.
1350	// @param {string=} halign Horizontal alignment of the text; either "left",
1351	//     "center" or "right".
1352	// @param {string=} valign Vertical alignment of the text; either "top",
1353	//     "middle" or "bottom".
1354
1355	Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
1356
1357		var info = this.getTextInfo(layer, text, font, angle, width),
1358			positions = info.positions;
1359
1360		// Tweak the div's position to match the text's alignment
1361
1362		if (halign == "center") {
1363			x -= info.width / 2;
1364		} else if (halign == "right") {
1365			x -= info.width;
1366		}
1367
1368		if (valign == "middle") {
1369			y -= info.height / 2;
1370		} else if (valign == "bottom") {
1371			y -= info.height;
1372		}
1373
1374		// Determine whether this text already exists at this position.
1375		// If so, mark it for inclusion in the next render pass.
1376
1377		for (var i = 0, position; position = positions[i]; i++) {
1378			if (position.x == x && position.y == y) {
1379				position.active = true;
1380				return;
1381			}
1382		}
1383
1384		// If the text doesn't exist at this position, create a new entry
1385
1386		// For the very first position we'll re-use the original element,
1387		// while for subsequent ones we'll clone it.
1388
1389		position = {
1390			active: true,
1391			rendered: false,
1392			element: positions.length ? info.element.clone() : info.element,
1393			x: x,
1394			y: y
1395		};
1396
1397		positions.push(position);
1398
1399		// Move the element to its final position within the container
1400
1401		position.element.css({
1402			top: Math.round(y),
1403			left: Math.round(x),
1404			'text-align': halign	// In case the text wraps
1405		});
1406	};
1407
1408	// Removes one or more text strings from the canvas text overlay.
1409	//
1410	// If no parameters are given, all text within the layer is removed.
1411	//
1412	// Note that the text is not immediately removed; it is simply marked as
1413	// inactive, which will result in its removal on the next render pass.
1414	// This avoids the performance penalty for 'clear and redraw' behavior,
1415	// where we potentially get rid of all text on a layer, but will likely
1416	// add back most or all of it later, as when redrawing axes, for example.
1417	//
1418	// @param {string} layer A string of space-separated CSS classes uniquely
1419	//     identifying the layer containing this text.
1420	// @param {number=} x X coordinate of the text.
1421	// @param {number=} y Y coordinate of the text.
1422	// @param {string=} text Text string to remove.
1423	// @param {(string|object)=} font Either a string of space-separated CSS
1424	//     classes or a font-spec object, defining the text's font and style.
1425	// @param {number=} angle Angle at which the text is rotated, in degrees.
1426	//     Angle is currently unused, it will be implemented in the future.
1427
1428	Canvas.prototype.removeText = function(layer, x, y, text, font, angle) {
1429		if (text == null) {
1430			var layerCache = this._textCache[layer];
1431			if (layerCache != null) {
1432				for (var styleKey in layerCache) {
1433					if (hasOwnProperty.call(layerCache, styleKey)) {
1434						var styleCache = layerCache[styleKey];
1435						for (var key in styleCache) {
1436							if (hasOwnProperty.call(styleCache, key)) {
1437								var positions = styleCache[key].positions;
1438								for (var i = 0, position; position = positions[i]; i++) {
1439									position.active = false;
1440								}
1441							}
1442						}
1443					}
1444				}
1445			}
1446		} else {
1447			var positions = this.getTextInfo(layer, text, font, angle).positions;
1448			for (var i = 0, position; position = positions[i]; i++) {
1449				if (position.x == x && position.y == y) {
1450					position.active = false;
1451				}
1452			}
1453		}
1454	};
1455
1456	///////////////////////////////////////////////////////////////////////////
1457	// The top-level container for the entire plot.
1458
1459    function Plot(placeholder, data_, options_, plugins) {
1460        // data is on the form:
1461        //   [ series1, series2 ... ]
1462        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
1463        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
1464
1465        var series = [],
1466            options = {
1467                // the color theme used for graphs
1468                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
1469                legend: {
1470                    show: true,
1471                    noColumns: 1, // number of colums in legend table
1472                    labelFormatter: null, // fn: string -> string
1473                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
1474                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
1475                    position: "ne", // position of default legend container within plot
1476                    margin: 5, // distance from grid edge to default legend container within plot
1477                    backgroundColor: null, // null means auto-detect
1478                    backgroundOpacity: 0.85, // set to 0 to avoid background
1479                    sorted: null    // default to no legend sorting
1480                },
1481                xaxis: {
1482                    show: null, // null = auto-detect, true = always, false = never
1483                    position: "bottom", // or "top"
1484                    mode: null, // null or "time"
1485                    font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
1486                    color: null, // base color, labels, ticks
1487                    tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
1488                    transform: null, // null or f: number -> number to transform axis
1489                    inverseTransform: null, // if transform is set, this should be the inverse function
1490                    min: null, // min. value to show, null means set automatically
1491                    max: null, // max. value to show, null means set automatically
1492                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
1493                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
1494                    tickFormatter: null, // fn: number -> string
1495                    labelWidth: null, // size of tick labels in pixels
1496                    labelHeight: null,
1497                    reserveSpace: null, // whether to reserve space even if axis isn't shown
1498                    tickLength: null, // size in pixels of ticks, or "full" for whole line
1499                    alignTicksWithAxis: null, // axis number or null for no sync
1500                    tickDecimals: null, // no. of decimals, null means auto
1501                    tickSize: null, // number or [number, "unit"]
1502                    minTickSize: null // number or [number, "unit"]
1503                },
1504                yaxis: {
1505                    autoscaleMargin: 0.02,
1506                    position: "left" // or "right"
1507                },
1508                xaxes: [],
1509                yaxes: [],
1510                series: {
1511                    points: {
1512                        show: false,
1513                        radius: 3,
1514                        lineWidth: 2, // in pixels
1515                        fill: true,
1516                        fillColor: "#ffffff",
1517                        symbol: "circle" // or callback
1518                    },
1519                    lines: {
1520                        // we don't put in show: false so we can see
1521                        // whether lines were actively disabled
1522                        lineWidth: 2, // in pixels
1523                        fill: false,
1524                        fillColor: null,
1525                        steps: false
1526                        // Omit 'zero', so we can later default its value to
1527                        // match that of the 'fill' option.
1528                    },
1529                    bars: {
1530                        show: false,
1531                        lineWidth: 2, // in pixels
1532                        barWidth: 1, // in units of the x axis
1533                        fill: true,
1534                        fillColor: null,
1535                        align: "left", // "left", "right", or "center"
1536                        horizontal: false,
1537                        zero: true
1538                    },
1539                    shadowSize: 3,
1540                    highlightColor: null
1541                },
1542                grid: {
1543                    show: true,
1544                    aboveData: false,
1545                    color: "#545454", // primary color used for outline and labels
1546                    backgroundColor: null, // null for transparent, else color
1547                    borderColor: null, // set if different from the grid color
1548                    tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
1549                    margin: 0, // distance from the canvas edge to the grid
1550                    labelMargin: 5, // in pixels
1551                    axisMargin: 8, // in pixels
1552                    borderWidth: 2, // in pixels
1553                    minBorderMargin: null, // in pixels, null means taken from points radius
1554                    markings: null, // array of ranges or fn: axes -> array of ranges
1555                    markingsColor: "#f4f4f4",
1556                    markingsLineWidth: 2,
1557                    // interactive stuff
1558                    clickable: false,
1559                    hoverable: false,
1560                    autoHighlight: true, // highlight in case mouse is near
1561                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
1562                },
1563                interaction: {
1564                    redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow
1565                },
1566                hooks: {}
1567            },
1568        surface = null,     // the canvas for the plot itself
1569        overlay = null,     // canvas for interactive stuff on top of plot
1570        eventHolder = null, // jQuery object that events should be bound to
1571        ctx = null, octx = null,
1572        xaxes = [], yaxes = [],
1573        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
1574        plotWidth = 0, plotHeight = 0,
1575        hooks = {
1576            processOptions: [],
1577            processRawData: [],
1578            processDatapoints: [],
1579            processOffset: [],
1580            drawBackground: [],
1581            drawSeries: [],
1582            draw: [],
1583            bindEvents: [],
1584            drawOverlay: [],
1585            shutdown: []
1586        },
1587        plot = this;
1588
1589        // public functions
1590        plot.setData = setData;
1591        plot.setupGrid = setupGrid;
1592        plot.draw = draw;
1593        plot.getPlaceholder = function() { return placeholder; };
1594        plot.getCanvas = function() { return surface.element; };
1595        plot.getPlotOffset = function() { return plotOffset; };
1596        plot.width = function () { return plotWidth; };
1597        plot.height = function () { return plotHeight; };
1598        plot.offset = function () {
1599            var o = eventHolder.offset();
1600            o.left += plotOffset.left;
1601            o.top += plotOffset.top;
1602            return o;
1603        };
1604        plot.getData = function () { return series; };
1605        plot.getAxes = function () {
1606            var res = {}, i;
1607            $.each(xaxes.concat(yaxes), function (_, axis) {
1608                if (axis)
1609                    res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
1610            });
1611            return res;
1612        };
1613        plot.getXAxes = function () { return xaxes; };
1614        plot.getYAxes = function () { return yaxes; };
1615        plot.c2p = canvasToAxisCoords;
1616        plot.p2c = axisToCanvasCoords;
1617        plot.getOptions = function () { return options; };
1618        plot.highlight = highlight;
1619        plot.unhighlight = unhighlight;
1620        plot.triggerRedrawOverlay = triggerRedrawOverlay;
1621        plot.pointOffset = function(point) {
1622            return {
1623                left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
1624                top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
1625            };
1626        };
1627        plot.shutdown = shutdown;
1628        plot.destroy = function () {
1629            shutdown();
1630            placeholder.removeData("plot").empty();
1631
1632            series = [];
1633            options = null;
1634            surface = null;
1635            overlay = null;
1636            eventHolder = null;
1637            ctx = null;
1638            octx = null;
1639            xaxes = [];
1640            yaxes = [];
1641            hooks = null;
1642            highlights = [];
1643            plot = null;
1644        };
1645        plot.resize = function () {
1646        	var width = placeholder.width(),
1647        		height = placeholder.height();
1648            surface.resize(width, height);
1649            overlay.resize(width, height);
1650        };
1651
1652        // public attributes
1653        plot.hooks = hooks;
1654
1655        // initialize
1656        initPlugins(plot);
1657        parseOptions(options_);
1658        setupCanvases();
1659        setData(data_);
1660        setupGrid();
1661        draw();
1662        bindEvents();
1663
1664
1665        function executeHooks(hook, args) {
1666            args = [plot].concat(args);
1667            for (var i = 0; i < hook.length; ++i)
1668                hook[i].apply(this, args);
1669        }
1670
1671        function initPlugins() {
1672
1673            // References to key classes, allowing plugins to modify them
1674
1675            var classes = {
1676                Canvas: Canvas
1677            };
1678
1679            for (var i = 0; i < plugins.length; ++i) {
1680                var p = plugins[i];
1681                p.init(plot, classes);
1682                if (p.options)
1683                    $.extend(true, options, p.options);
1684            }
1685        }
1686
1687        function parseOptions(opts) {
1688
1689            $.extend(true, options, opts);
1690
1691            // $.extend merges arrays, rather than replacing them.  When less
1692            // colors are provided than the size of the default palette, we
1693            // end up with those colors plus the remaining defaults, which is
1694            // not expected behavior; avoid it by replacing them here.
1695
1696            if (opts && opts.colors) {
1697            	options.colors = opts.colors;
1698            }
1699
1700            if (options.xaxis.color == null)
1701                options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
1702            if (options.yaxis.color == null)
1703                options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
1704
1705            if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
1706                options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
1707            if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
1708                options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
1709
1710            if (options.grid.borderColor == null)
1711                options.grid.borderColor = options.grid.color;
1712            if (options.grid.tickColor == null)
1713                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
1714
1715            // Fill in defaults for axis options, including any unspecified
1716            // font-spec fields, if a font-spec was provided.
1717
1718            // If no x/y axis options were provided, create one of each anyway,
1719            // since the rest of the code assumes that they exist.
1720
1721            var i, axisOptions, axisCount,
1722                fontSize = placeholder.css("font-size"),
1723                fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
1724                fontDefaults = {
1725                    style: placeholder.css("font-style"),
1726                    size: Math.round(0.8 * fontSizeDefault),
1727                    variant: placeholder.css("font-variant"),
1728                    weight: placeholder.css("font-weight"),
1729                    family: placeholder.css("font-family")
1730                };
1731
1732            axisCount = options.xaxes.length || 1;
1733            for (i = 0; i < axisCount; ++i) {
1734
1735                axisOptions = options.xaxes[i];
1736                if (axisOptions && !axisOptions.tickColor) {
1737                    axisOptions.tickColor = axisOptions.color;
1738                }
1739
1740                axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
1741                options.xaxes[i] = axisOptions;
1742
1743                if (axisOptions.font) {
1744                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
1745                    if (!axisOptions.font.color) {
1746                        axisOptions.font.color = axisOptions.color;
1747                    }
1748                    if (!axisOptions.font.lineHeight) {
1749                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
1750                    }
1751                }
1752            }
1753
1754            axisCount = options.yaxes.length || 1;
1755            for (i = 0; i < axisCount; ++i) {
1756
1757                axisOptions = options.yaxes[i];
1758                if (axisOptions && !axisOptions.tickColor) {
1759                    axisOptions.tickColor = axisOptions.color;
1760                }
1761
1762                axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
1763                options.yaxes[i] = axisOptions;
1764
1765                if (axisOptions.font) {
1766                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
1767                    if (!axisOptions.font.color) {
1768                        axisOptions.font.color = axisOptions.color;
1769                    }
1770                    if (!axisOptions.font.lineHeight) {
1771                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
1772                    }
1773                }
1774            }
1775
1776            // backwards compatibility, to be removed in future
1777            if (options.xaxis.noTicks && options.xaxis.ticks == null)
1778                options.xaxis.ticks = options.xaxis.noTicks;
1779            if (options.yaxis.noTicks && options.yaxis.ticks == null)
1780                options.yaxis.ticks = options.yaxis.noTicks;
1781            if (options.x2axis) {
1782                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
1783                options.xaxes[1].position = "top";
1784                // Override the inherit to allow the axis to auto-scale
1785                if (options.x2axis.min == null) {
1786                    options.xaxes[1].min = null;
1787                }
1788                if (options.x2axis.max == null) {
1789                    options.xaxes[1].max = null;
1790                }
1791            }
1792            if (options.y2axis) {
1793                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
1794                options.yaxes[1].position = "right";
1795                // Override the inherit to allow the axis to auto-scale
1796                if (options.y2axis.min == null) {
1797                    options.yaxes[1].min = null;
1798                }
1799                if (options.y2axis.max == null) {
1800                    options.yaxes[1].max = null;
1801                }
1802            }
1803            if (options.grid.coloredAreas)
1804                options.grid.markings = options.grid.coloredAreas;
1805            if (options.grid.coloredAreasColor)
1806                options.grid.markingsColor = options.grid.coloredAreasColor;
1807            if (options.lines)
1808                $.extend(true, options.series.lines, options.lines);
1809            if (options.points)
1810                $.extend(true, options.series.points, options.points);
1811            if (options.bars)
1812                $.extend(true, options.series.bars, options.bars);
1813            if (options.shadowSize != null)
1814                options.series.shadowSize = options.shadowSize;
1815            if (options.highlightColor != null)
1816                options.series.highlightColor = options.highlightColor;
1817
1818            // save options on axes for future reference
1819            for (i = 0; i < options.xaxes.length; ++i)
1820                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
1821            for (i = 0; i < options.yaxes.length; ++i)
1822                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
1823
1824            // add hooks from options
1825            for (var n in hooks)
1826                if (options.hooks[n] && options.hooks[n].length)
1827                    hooks[n] = hooks[n].concat(options.hooks[n]);
1828
1829            executeHooks(hooks.processOptions, [options]);
1830        }
1831
1832        function setData(d) {
1833            series = parseData(d);
1834            fillInSeriesOptions();
1835            processData();
1836        }
1837
1838        function parseData(d) {
1839            var res = [];
1840            for (var i = 0; i < d.length; ++i) {
1841                var s = $.extend(true, {}, options.series);
1842
1843                if (d[i].data != null) {
1844                    s.data = d[i].data; // move the data instead of deep-copy
1845                    delete d[i].data;
1846
1847                    $.extend(true, s, d[i]);
1848
1849                    d[i].data = s.data;
1850                }
1851                else
1852                    s.data = d[i];
1853                res.push(s);
1854            }
1855
1856            return res;
1857        }
1858
1859        function axisNumber(obj, coord) {
1860            var a = obj[coord + "axis"];
1861            if (typeof a == "object") // if we got a real axis, extract number
1862                a = a.n;
1863            if (typeof a != "number")
1864                a = 1; // default to first axis
1865            return a;
1866        }
1867
1868        function allAxes() {
1869            // return flat array without annoying null entries
1870            return $.grep(xaxes.concat(yaxes), function (a) { return a; });
1871        }
1872
1873        function canvasToAxisCoords(pos) {
1874            // return an object with x/y corresponding to all used axes
1875            var res = {}, i, axis;
1876            for (i = 0; i < xaxes.length; ++i) {
1877                axis = xaxes[i];
1878                if (axis && axis.used)
1879                    res["x" + axis.n] = axis.c2p(pos.left);
1880            }
1881
1882            for (i = 0; i < yaxes.length; ++i) {
1883                axis = yaxes[i];
1884                if (axis && axis.used)
1885                    res["y" + axis.n] = axis.c2p(pos.top);
1886            }
1887
1888            if (res.x1 !== undefined)
1889                res.x = res.x1;
1890            if (res.y1 !== undefined)
1891                res.y = res.y1;
1892
1893            return res;
1894        }
1895
1896        function axisToCanvasCoords(pos) {
1897            // get canvas coords from the first pair of x/y found in pos
1898            var res = {}, i, axis, key;
1899
1900            for (i = 0; i < xaxes.length; ++i) {
1901                axis = xaxes[i];
1902                if (axis && axis.used) {
1903                    key = "x" + axis.n;
1904                    if (pos[key] == null && axis.n == 1)
1905                        key = "x";
1906
1907                    if (pos[key] != null) {
1908                        res.left = axis.p2c(pos[key]);
1909                        break;
1910                    }
1911                }
1912            }
1913
1914            for (i = 0; i < yaxes.length; ++i) {
1915                axis = yaxes[i];
1916                if (axis && axis.used) {
1917                    key = "y" + axis.n;
1918                    if (pos[key] == null && axis.n == 1)
1919                        key = "y";
1920
1921                    if (pos[key] != null) {
1922                        res.top = axis.p2c(pos[key]);
1923                        break;
1924                    }
1925                }
1926            }
1927
1928            return res;
1929        }
1930
1931        function getOrCreateAxis(axes, number) {
1932            if (!axes[number - 1])
1933                axes[number - 1] = {
1934                    n: number, // save the number for future reference
1935                    direction: axes == xaxes ? "x" : "y",
1936                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
1937                };
1938
1939            return axes[number - 1];
1940        }
1941
1942        function fillInSeriesOptions() {
1943
1944            var neededColors = series.length, maxIndex = -1, i;
1945
1946            // Subtract the number of series that already have fixed colors or
1947            // color indexes from the number that we still need to generate.
1948
1949            for (i = 0; i < series.length; ++i) {
1950                var sc = series[i].color;
1951                if (sc != null) {
1952                    neededColors--;
1953                    if (typeof sc == "number" && sc > maxIndex) {
1954                        maxIndex = sc;
1955                    }
1956                }
1957            }
1958
1959            // If any of the series have fixed color indexes, then we need to
1960            // generate at least as many colors as the highest index.
1961
1962            if (neededColors <= maxIndex) {
1963                neededColors = maxIndex + 1;
1964            }
1965
1966            // Generate all the colors, using first the option colors and then
1967            // variations on those colors once they're exhausted.
1968
1969            var c, colors = [], colorPool = options.colors,
1970                colorPoolSize = colorPool.length, variation = 0;
1971
1972            for (i = 0; i < neededColors; i++) {
1973
1974                c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
1975
1976                // Each time we exhaust the colors in the pool we adjust
1977                // a scaling factor used to produce more variations on
1978                // those colors. The factor alternates negative/positive
1979                // to produce lighter/darker colors.
1980
1981                // Reset the variation after every few cycles, or else
1982                // it will end up producing only white or black colors.
1983
1984                if (i % colorPoolSize == 0 && i) {
1985                    if (variation >= 0) {
1986                        if (variation < 0.5) {
1987                            variation = -variation - 0.2;
1988                        } else variation = 0;
1989                    } else variation = -variation;
1990                }
1991
1992                colors[i] = c.scale('rgb', 1 + variation);
1993            }
1994
1995            // Finalize the series options, filling in their colors
1996
1997            var colori = 0, s;
1998            for (i = 0; i < series.length; ++i) {
1999                s = series[i];
2000
2001                // assign colors
2002                if (s.color == null) {
2003                    s.color = colors[colori].toString();
2004                    ++colori;
2005                }
2006                else if (typeof s.color == "number")
2007                    s.color = colors[s.color].toString();
2008
2009                // turn on lines automatically in case nothing is set
2010                if (s.lines.show == null) {
2011                    var v, show = true;
2012                    for (v in s)
2013                        if (s[v] && s[v].show) {
2014                            show = false;
2015                            break;
2016                        }
2017                    if (show)
2018                        s.lines.show = true;
2019                }
2020
2021                // If nothing was provided for lines.zero, default it to match
2022                // lines.fill, since areas by default should extend to zero.
2023
2024                if (s.lines.zero == null) {
2025                    s.lines.zero = !!s.lines.fill;
2026                }
2027
2028                // setup axes
2029                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
2030                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
2031            }
2032        }
2033
2034        function processData() {
2035            var topSentry = Number.POSITIVE_INFINITY,
2036                bottomSentry = Number.NEGATIVE_INFINITY,
2037                fakeInfinity = Number.MAX_VALUE,
2038                i, j, k, m, length,
2039                s, points, ps, x, y, axis, val, f, p,
2040                data, format;
2041
2042            function updateAxis(axis, min, max) {
2043                if (min < axis.datamin && min != -fakeInfinity)
2044                    axis.datamin = min;
2045                if (max > axis.datamax && max != fakeInfinity)
2046                    axis.datamax = max;
2047            }
2048
2049            $.each(allAxes(), function (_, axis) {
2050                // init axis
2051                axis.datamin = topSentry;
2052                axis.datamax = bottomSentry;
2053                axis.used = false;
2054            });
2055
2056            for (i = 0; i < series.length; ++i) {
2057                s = series[i];
2058                s.datapoints = { points: [] };
2059
2060                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
2061            }
2062
2063            // first pass: clean and copy data
2064            for (i = 0; i < series.length; ++i) {
2065                s = series[i];
2066
2067                data = s.data;
2068                format = s.datapoints.format;
2069
2070                if (!format) {
2071                    format = [];
2072                    // find out how to copy
2073                    format.push({ x: true, number: true, required: true });
2074                    format.push({ y: true, number: true, required: true });
2075
2076                    if (s.bars.show || (s.lines.show && s.lines.fill)) {
2077                        var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
2078                        format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
2079                        if (s.bars.horizontal) {
2080                            delete format[format.length - 1].y;
2081                            format[format.length - 1].x = true;
2082                        }
2083                    }
2084
2085                    s.datapoints.format = format;
2086                }
2087
2088                if (s.datapoints.pointsize != null)
2089                    continue; // already filled in
2090
2091                s.datapoints.pointsize = format.length;
2092
2093                ps = s.datapoints.pointsize;
2094                points = s.datapoints.points;
2095
2096                var insertSteps = s.lines.show && s.lines.steps;
2097                s.xaxis.used = s.yaxis.used = true;
2098
2099                for (j = k = 0; j < data.length; ++j, k += ps) {
2100                    p = data[j];
2101
2102                    var nullify = p == null;
2103                    if (!nullify) {
2104                        for (m = 0; m < ps; ++m) {
2105                            val = p[m];
2106                            f = format[m];
2107
2108                            if (f) {
2109                                if (f.number && val != null) {
2110                                    val = +val; // convert to number
2111                                    if (isNaN(val))
2112                                        val = null;
2113                                    else if (val == Infinity)
2114                                        val = fakeInfinity;
2115                                    else if (val == -Infinity)
2116                                        val = -fakeInfinity;
2117                                }
2118
2119                                if (val == null) {
2120                                    if (f.required)
2121                                        nullify = true;
2122
2123                                    if (f.defaultValue != null)
2124                                        val = f.defaultValue;
2125                                }
2126                            }
2127
2128                            points[k + m] = val;
2129                        }
2130                    }
2131
2132                    if (nullify) {
2133                        for (m = 0; m < ps; ++m) {
2134                            val = points[k + m];
2135                            if (val != null) {
2136                                f = format[m];
2137                                // extract min/max info
2138                                if (f.autoscale !== false) {
2139                                    if (f.x) {
2140                                        updateAxis(s.xaxis, val, val);
2141                                    }
2142                                    if (f.y) {
2143                                        updateAxis(s.yaxis, val, val);
2144                                    }
2145                                }
2146                            }
2147                            points[k + m] = null;
2148                        }
2149                    }
2150                    else {
2151                        // a little bit of line specific stuff that
2152                        // perhaps shouldn't be here, but lacking
2153                        // better means...
2154                        if (insertSteps && k > 0
2155                            && points[k - ps] != null
2156                            && points[k - ps] != points[k]
2157                            && points[k - ps + 1] != points[k + 1]) {
2158                            // copy the point to make room for a middle point
2159                            for (m = 0; m < ps; ++m)
2160                                points[k + ps + m] = points[k + m];
2161
2162                            // middle point has same y
2163                            points[k + 1] = points[k - ps + 1];
2164
2165                            // we've added a point, better reflect that
2166                            k += ps;
2167                        }
2168                    }
2169                }
2170            }
2171
2172            // give the hooks a chance to run
2173            for (i = 0; i < series.length; ++i) {
2174                s = series[i];
2175
2176                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
2177            }
2178
2179            // second pass: find datamax/datamin for auto-scaling
2180            for (i = 0; i < series.length; ++i) {
2181                s = series[i];
2182                points = s.datapoints.points;
2183                ps = s.datapoints.pointsize;
2184                format = s.datapoints.format;
2185
2186                var xmin = topSentry, ymin = topSentry,
2187                    xmax = bottomSentry, ymax = bottomSentry;
2188
2189                for (j = 0; j < points.length; j += ps) {
2190                    if (points[j] == null)
2191                        continue;
2192
2193                    for (m = 0; m < ps; ++m) {
2194                        val = points[j + m];
2195                        f = format[m];
2196                        if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
2197                            continue;
2198
2199                        if (f.x) {
2200                            if (val < xmin)
2201                                xmin = val;
2202                            if (val > xmax)
2203                                xmax = val;
2204                        }
2205                        if (f.y) {
2206                            if (val < ymin)
2207                                ymin = val;
2208                            if (val > ymax)
2209                                ymax = val;
2210                        }
2211                    }
2212                }
2213
2214                if (s.bars.show) {
2215                    // make sure we got room for the bar on the dancing floor
2216                    var delta;
2217
2218                    switch (s.bars.align) {
2219                        case "left":
2220                            delta = 0;
2221                            break;
2222                        case "right":
2223                            delta = -s.bars.barWidth;
2224                            break;
2225                        default:
2226                            delta = -s.bars.barWidth / 2;
2227                    }
2228
2229                    if (s.bars.horizontal) {
2230                        ymin += delta;
2231                        ymax += delta + s.bars.barWidth;
2232                    }
2233                    else {
2234                        xmin += delta;
2235                        xmax += delta + s.bars.barWidth;
2236                    }
2237                }
2238
2239                updateAxis(s.xaxis, xmin, xmax);
2240                updateAxis(s.yaxis, ymin, ymax);
2241            }
2242
2243            $.each(allAxes(), function (_, axis) {
2244                if (axis.datamin == topSentry)
2245                    axis.datamin = null;
2246                if (axis.datamax == bottomSentry)
2247                    axis.datamax = null;
2248            });
2249        }
2250
2251        function setupCanvases() {
2252
2253            // Make sure the placeholder is clear of everything except canvases
2254            // from a previous plot in this container that we'll try to re-use.
2255
2256            placeholder.css("padding", 0) // padding messes up the positioning
2257                .children().filter(function(){
2258                    return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
2259                }).remove();
2260
2261            if (placeholder.css("position") == 'static')
2262                placeholder.css("position", "relative"); // for positioning labels and overlay
2263
2264            surface = new Canvas("flot-base", placeholder);
2265            overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
2266
2267            ctx = surface.context;
2268            octx = overlay.context;
2269
2270            // define which element we're listening for events on
2271            eventHolder = $(overlay.element).unbind();
2272
2273            // If we're re-using a plot object, shut down the old one
2274
2275            var existing = placeholder.data("plot");
2276
2277            if (existing) {
2278                existing.shutdown();
2279                overlay.clear();
2280            }
2281
2282            // save in case we get replotted
2283            placeholder.data("plot", plot);
2284        }
2285
2286        function bindEvents() {
2287            // bind events
2288            if (options.grid.hoverable) {
2289                eventHolder.mousemove(onMouseMove);
2290
2291                // Use bind, rather than .mouseleave, because we officially
2292                // still support jQuery 1.2.6, which doesn't define a shortcut
2293                // for mouseenter or mouseleave.  This was a bug/oversight that
2294                // was fixed somewhere around 1.3.x.  We can return to using
2295                // .mouseleave when we drop support for 1.2.6.
2296
2297                eventHolder.bind("mouseleave", onMouseLeave);
2298            }
2299
2300            if (options.grid.clickable)
2301                eventHolder.click(onClick);
2302
2303            executeHooks(hooks.bindEvents, [eventHolder]);
2304        }
2305
2306        function shutdown() {
2307            if (redrawTimeout)
2308                clearTimeout(redrawTimeout);
2309
2310            eventHolder.unbind("mousemove", onMouseMove);
2311            eventHolder.unbind("mouseleave", onMouseLeave);
2312            eventHolder.unbind("click", onClick);
2313
2314            executeHooks(hooks.shutdown, [eventHolder]);
2315        }
2316
2317        function setTransformationHelpers(axis) {
2318            // set helper functions on the axis, assumes plot area
2319            // has been computed already
2320
2321            function identity(x) { return x; }
2322
2323            var s, m, t = axis.options.transform || identity,
2324                it = axis.options.inverseTransform;
2325
2326            // precompute how much the axis is scaling a point
2327            // in canvas space
2328            if (axis.direction == "x") {
2329                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
2330                m = Math.min(t(axis.max), t(axis.min));
2331            }
2332            else {
2333                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
2334                s = -s;
2335                m = Math.max(t(axis.max), t(axis.min));
2336            }
2337
2338            // data point to canvas coordinate
2339            if (t == identity) // slight optimization
2340                axis.p2c = function (p) { return (p - m) * s; };
2341            else
2342                axis.p2c = function (p) { return (t(p) - m) * s; };
2343            // canvas coordinate to data point
2344            if (!it)
2345                axis.c2p = function (c) { return m + c / s; };
2346            else
2347                axis.c2p = function (c) { return it(m + c / s); };
2348        }
2349
2350        function measureTickLabels(axis) {
2351
2352            var opts = axis.options,
2353                ticks = axis.ticks || [],
2354                labelWidth = opts.labelWidth || 0,
2355                labelHeight = opts.labelHeight || 0,
2356                maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
2357                legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
2358                layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
2359                font = opts.font || "flot-tick-label tickLabel";
2360
2361            for (var i = 0; i < ticks.length; ++i) {
2362
2363                var t = ticks[i];
2364
2365                if (!t.label)
2366                    continue;
2367
2368                var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
2369
2370                labelWidth = Math.max(labelWidth, info.width);
2371                labelHeight = Math.max(labelHeight, info.height);
2372            }
2373
2374            axis.labelWidth = opts.labelWidth || labelWidth;
2375            axis.labelHeight = opts.labelHeight || labelHeight;
2376        }
2377
2378        function allocateAxisBoxFirstPhase(axis) {
2379            // find the bounding box of the axis by looking at label
2380            // widths/heights and ticks, make room by diminishing the
2381            // plotOffset; this first phase only looks at one
2382            // dimension per axis, the other dimension depends on the
2383            // other axes so will have to wait
2384
2385            var lw = axis.labelWidth,
2386                lh = axis.labelHeight,
2387                pos = axis.options.position,
2388                isXAxis = axis.direction === "x",
2389                tickLength = axis.options.tickLength,
2390                axisMargin = options.grid.axisMargin,
2391                padding = options.grid.labelMargin,
2392                innermost = true,
2393                outermost = true,
2394                first = true,
2395                found = false;
2396
2397            // Determine the axis's position in its direction and on its side
2398
2399            $.each(isXAxis ? xaxes : yaxes, function(i, a) {
2400                if (a && (a.show || a.reserveSpace)) {
2401                    if (a === axis) {
2402                        found = true;
2403                    } else if (a.options.position === pos) {
2404                        if (found) {
2405                            outermost = false;
2406                        } else {
2407                            innermost = false;
2408                        }
2409                    }
2410                    if (!found) {
2411                        first = false;
2412                    }
2413                }
2414            });
2415
2416            // The outermost axis on each side has no margin
2417
2418            if (outermost) {
2419                axisMargin = 0;
2420            }
2421
2422            // The ticks for the first axis in each direction stretch across
2423
2424            if (tickLength == null) {
2425                tickLength = first ? "full" : 5;
2426            }
2427
2428            if (!isNaN(+tickLength))
2429                padding += +tickLength;
2430
2431            if (isXAxis) {
2432                lh += padding;
2433
2434                if (pos == "bottom") {
2435                    plotOffset.bottom += lh + axisMargin;
2436                    axis.box = { top: surface.height - plotOffset.bottom, height: lh };
2437                }
2438                else {
2439                    axis.box = { top: plotOffset.top + axisMargin, height: lh };
2440                    plotOffset.top += lh + axisMargin;
2441                }
2442            }
2443            else {
2444                lw += padding;
2445
2446                if (pos == "left") {
2447                    axis.box = { left: plotOffset.left + axisMargin, width: lw };
2448                    plotOffset.left += lw + axisMargin;
2449                }
2450                else {
2451                    plotOffset.right += lw + axisMargin;
2452                    axis.box = { left: surface.width - plotOffset.right, width: lw };
2453                }
2454            }
2455
2456             // save for future reference
2457            axis.position = pos;
2458            axis.tickLength = tickLength;
2459            axis.box.padding = padding;
2460            axis.innermost = innermost;
2461        }
2462
2463        function allocateAxisBoxSecondPhase(axis) {
2464            // now that all axis boxes have been placed in one
2465            // dimension, we can set the remaining dimension coordinates
2466            if (axis.direction == "x") {
2467                axis.box.left = plotOffset.left - axis.labelWidth / 2;
2468                axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
2469            }
2470            else {
2471                axis.box.top = plotOffset.top - axis.labelHeight / 2;
2472                axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
2473            }
2474        }
2475
2476        function adjustLayoutForThingsStickingOut() {
2477            // possibly adjust plot offset to ensure everything stays
2478            // inside the canvas and isn't clipped off
2479
2480            var minMargin = options.grid.minBorderMargin,
2481                axis, i;
2482
2483            // check stuff from the plot (FIXME: this should just read
2484            // a value from the series, otherwise it's impossible to
2485            // customize)
2486            if (minMargin == null) {
2487                minMargin = 0;
2488                for (i = 0; i < series.length; ++i)
2489                    minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
2490            }
2491
2492            var margins = {
2493                left: minMargin,
2494                right: minMargin,
2495                top: minMargin,
2496                bottom: minMargin
2497            };
2498
2499            // check axis labels, note we don't check the actual
2500            // labels but instead use the overall width/height to not
2501            // jump as much around with replots
2502            $.each(allAxes(), function (_, axis) {
2503                if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
2504                    if (axis.direction === "x") {
2505                        margins.left = Math.max(margins.left, axis.labelWidth / 2);
2506                        margins.right = Math.max(margins.right, axis.labelWidth / 2);
2507                    } else {
2508                        margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
2509                        margins.top = Math.max(margins.top, axis.labelHeight / 2);
2510                    }
2511                }
2512            });
2513
2514            plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
2515            plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
2516            plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
2517            plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
2518        }
2519
2520        function setupGrid() {
2521            var i, axes = allAxes(), showGrid = options.grid.show;
2522
2523            // Initialize the plot's offset from the edge of the canvas
2524
2525            for (var a in plotOffset) {
2526                var margin = options.grid.margin || 0;
2527                plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
2528            }
2529
2530            executeHooks(hooks.processOffset, [plotOffset]);
2531
2532            // If the grid is visible, add its border width to the offset
2533
2534            for (var a in plotOffset) {
2535                if(typeof(options.grid.borderWidth) == "object") {
2536                    plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
2537                }
2538                else {
2539                    plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
2540                }
2541            }
2542
2543            $.each(axes, function (_, axis) {
2544                var axisOpts = axis.options;
2545                axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
2546                axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
2547                setRange(axis);
2548            });
2549
2550            if (showGrid) {
2551
2552                var allocatedAxes = $.grep(axes, function (axis) {
2553                    return axis.show || axis.reserveSpace;
2554                });
2555
2556                $.each(allocatedAxes, function (_, axis) {
2557                    // make the ticks
2558                    setupTickGeneration(axis);
2559                    setTicks(axis);
2560                    snapRangeToTicks(axis, axis.ticks);
2561                    // find labelWidth/Height for axis
2562                    measureTickLabels(axis);
2563                });
2564
2565                // with all dimensions calculated, we can compute the
2566                // axis bounding boxes, start from the outside
2567                // (reverse order)
2568                for (i = allocatedAxes.length - 1; i >= 0; --i)
2569                    allocateAxisBoxFirstPhase(allocatedAxes[i]);
2570
2571                // make sure we've got enough space for things that
2572                // might stick out
2573                adjustLayoutForThingsStickingOut();
2574
2575                $.each(allocatedAxes, function (_, axis) {
2576                    allocateAxisBoxSecondPhase(axis);
2577                });
2578            }
2579
2580            plotWidth = surface.width - plotOffset.left - plotOffset.right;
2581            plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
2582
2583            // now we got the proper plot dimensions, we can compute the scaling
2584            $.each(axes, function (_, axis) {
2585                setTransformationHelpers(axis);
2586            });
2587
2588            if (showGrid) {
2589                drawAxisLabels();
2590            }
2591
2592            insertLegend();
2593        }
2594
2595        function setRange(axis) {
2596            var opts = axis.options,
2597                min = +(opts.min != null ? opts.min : axis.datamin),
2598                max = +(opts.max != null ? opts.max : axis.datamax),
2599                delta = max - min;
2600
2601            if (delta == 0.0) {
2602                // degenerate case
2603                var widen = max == 0 ? 1 : 0.01;
2604
2605                if (opts.min == null)
2606                    min -= widen;
2607                // always widen max if we couldn't widen min to ensure we
2608                // don't fall into min == max which doesn't work
2609                if (opts.max == null || opts.min != null)
2610                    max += widen;
2611            }
2612            else {
2613                // consider autoscaling
2614                var margin = opts.autoscaleMargin;
2615                if (margin != null) {
2616                    if (opts.min == null) {
2617                        min -= delta * margin;
2618                        // make sure we don't go below zero if all values
2619                        // are positive
2620                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
2621                            min = 0;
2622                    }
2623                    if (opts.max == null) {
2624                        max += delta * margin;
2625                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
2626                            max = 0;
2627                    }
2628                }
2629            }
2630            axis.min = min;
2631            axis.max = max;
2632        }
2633
2634        function setupTickGeneration(axis) {
2635            var opts = axis.options;
2636
2637            // estimate number of ticks
2638            var noTicks;
2639            if (typeof opts.ticks == "number" && opts.ticks > 0)
2640                noTicks = opts.ticks;
2641            else
2642                // heuristic based on the model a*sqrt(x) fitted to
2643                // some data points that seemed reasonable
2644                noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
2645
2646            var delta = (axis.max - axis.min) / noTicks,
2647                dec = -Math.floor(Math.log(delta) / Math.LN10),
2648                maxDec = opts.tickDecimals;
2649
2650            if (maxDec != null && dec > maxDec) {
2651                dec = maxDec;
2652            }
2653
2654            var magn = Math.pow(10, -dec),
2655                norm = delta / magn, // norm is between 1.0 and 10.0
2656                size;
2657
2658            if (norm < 1.5) {
2659                size = 1;
2660            } else if (norm < 3) {
2661                size = 2;
2662                // special case for 2.5, requires an extra decimal
2663                if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
2664                    size = 2.5;
2665                    ++dec;
2666                }
2667            } else if (norm < 7.5) {
2668                size = 5;
2669            } else {
2670                size = 10;
2671            }
2672
2673            size *= magn;
2674
2675            if (opts.minTickSize != null && size < opts.minTickSize) {
2676                size = opts.minTickSize;
2677            }
2678
2679            axis.delta = delta;
2680            axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
2681            axis.tickSize = opts.tickSize || size;
2682
2683            // Time mode was moved to a plug-in in 0.8, and since so many people use it
2684            // we'll add an especially friendly reminder to make sure they included it.
2685
2686            if (opts.mode == "time" && !axis.tickGenerator) {
2687                throw new Error("Time mode requires the flot.time plugin.");
2688            }
2689
2690            // Flot supports base-10 axes; any other mode else is handled by a plug-in,
2691            // like flot.time.js.
2692
2693            if (!axis.tickGenerator) {
2694
2695                axis.tickGenerator = function (axis) {
2696
2697                    var ticks = [],
2698                        start = floorInBase(axis.min, axis.tickSize),
2699                        i = 0,
2700                        v = Number.NaN,
2701                        prev;
2702
2703                    do {
2704                        prev = v;
2705                        v = start + i * axis.tickSize;
2706                        ticks.push(v);
2707                        ++i;
2708                    } while (v < axis.max && v != prev);
2709                    return ticks;
2710                };
2711
2712				axis.tickFormatter = function (value, axis) {
2713
2714					var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
2715					var formatted = "" + Math.round(value * factor) / factor;
2716
2717					// If tickDecimals was specified, ensure that we have exactly that
2718					// much precision; otherwise default to the value's own precision.
2719
2720					if (axis.tickDecimals != null) {
2721						var decimal = formatted.indexOf(".");
2722						var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
2723						if (precision < axis.tickDecimals) {
2724							return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
2725						}
2726					}
2727
2728                    return formatted;
2729                };
2730            }
2731
2732            if ($.isFunction(opts.tickFormatter))
2733                axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
2734
2735            if (opts.alignTicksWithAxis != null) {
2736                var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
2737                if (otherAxis && otherAxis.used && otherAxis != axis) {
2738                    // consider snapping min/max to outermost nice ticks
2739                    var niceTicks = axis.tickGenerator(axis);
2740                    if (niceTicks.length > 0) {
2741                        if (opts.min == null)
2742                            axis.min = Math.min(axis.min, niceTicks[0]);
2743                        if (opts.max == null && niceTicks.length > 1)
2744                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
2745                    }
2746
2747                    axis.tickGenerator = function (axis) {
2748                        // copy ticks, scaled to this axis
2749                        var ticks = [], v, i;
2750                        for (i = 0; i < otherAxis.ticks.length; ++i) {
2751                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
2752                            v = axis.min + v * (axis.max - axis.min);
2753                            ticks.push(v);
2754                        }
2755                        return ticks;
2756                    };
2757
2758                    // we might need an extra decimal since forced
2759                    // ticks don't necessarily fit naturally
2760                    if (!axis.mode && opts.tickDecimals == null) {
2761                        var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
2762                            ts = axis.tickGenerator(axis);
2763
2764                        // only proceed if the tick interval rounded
2765                        // with an extra decimal doesn't give us a
2766                        // zero at end
2767                        if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
2768                            axis.tickDecimals = extraDec;
2769                    }
2770                }
2771            }
2772        }
2773
2774        function setTicks(axis) {
2775            var oticks = axis.options.ticks, ticks = [];
2776            if (oticks == null || (typeof oticks == "number" && oticks > 0))
2777                ticks = axis.tickGenerator(axis);
2778            else if (oticks) {
2779                if ($.isFunction(oticks))
2780                    // generate the ticks
2781                    ticks = oticks(axis);
2782                else
2783                    ticks = oticks;
2784            }
2785
2786            // clean up/labelify the supplied ticks, copy them over
2787            var i, v;
2788            axis.ticks = [];
2789            for (i = 0; i < ticks.length; ++i) {
2790                var label = null;
2791                var t = ticks[i];
2792                if (typeof t == "object") {
2793                    v = +t[0];
2794                    if (t.length > 1)
2795                        label = t[1];
2796                }
2797                else
2798                    v = +t;
2799                if (label == null)
2800                    label = axis.tickFormatter(v, axis);
2801                if (!isNaN(v))
2802                    axis.ticks.push({ v: v, label: label });
2803            }
2804        }
2805
2806        function snapRangeToTicks(axis, ticks) {
2807            if (axis.options.autoscaleMargin && ticks.length > 0) {
2808                // snap to ticks
2809                if (axis.options.min == null)
2810                    axis.min = Math.min(axis.min, ticks[0].v);
2811                if (axis.options.max == null && ticks.length > 1)
2812                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
2813            }
2814        }
2815
2816        function draw() {
2817
2818            surface.clear();
2819
2820            executeHooks(hooks.drawBackground, [ctx]);
2821
2822            var grid = options.grid;
2823
2824            // draw background, if any
2825            if (grid.show && grid.backgroundColor)
2826                drawBackground();
2827
2828            if (grid.show && !grid.aboveData) {
2829                drawGrid();
2830            }
2831
2832            for (var i = 0; i < series.length; ++i) {
2833                executeHooks(hooks.drawSeries, [ctx, series[i]]);
2834                drawSeries(series[i]);
2835            }
2836
2837            executeHooks(hooks.draw, [ctx]);
2838
2839            if (grid.show && grid.aboveData) {
2840                drawGrid();
2841            }
2842
2843            surface.render();
2844
2845            // A draw implies that either the axes or data have changed, so we
2846            // should probably update the overlay highlights as well.
2847
2848            triggerRedrawOverlay();
2849        }
2850
2851        function extractRange(ranges, coord) {
2852            var axis, from, to, key, axes = allAxes();
2853
2854            for (var i = 0; i < axes.length; ++i) {
2855                axis = axes[i];
2856                if (axis.direction == coord) {
2857                    key = coord + axis.n + "axis";
2858                    if (!ranges[key] && axis.n == 1)
2859                        key = coord + "axis"; // support x1axis as xaxis
2860                    if (ranges[key]) {
2861                        from = ranges[key].from;
2862                        to = ranges[key].to;
2863                        break;
2864                    }
2865                }
2866            }
2867
2868            // backwards-compat stuff - to be removed in future
2869            if (!ranges[key]) {
2870                axis = coord == "x" ? xaxes[0] : yaxes[0];
2871                from = ranges[coord + "1"];
2872                to = ranges[coord + "2"];
2873            }
2874
2875            // auto-reverse as an added bonus
2876            if (from != null && to != null && from > to) {
2877                var tmp = from;
2878                from = to;
2879                to = tmp;
2880            }
2881
2882            return { from: from, to: to, axis: axis };
2883        }
2884
2885        function drawBackground() {
2886            ctx.save();
2887            ctx.translate(plotOffset.left, plotOffset.top);
2888
2889            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
2890            ctx.fillRect(0, 0, plotWidth, plotHeight);
2891            ctx.restore();
2892        }
2893
2894        function drawGrid() {
2895            var i, axes, bw, bc;
2896
2897            ctx.save();
2898            ctx.translate(plotOffset.left, plotOffset.top);
2899
2900            // draw markings
2901            var markings = options.grid.markings;
2902            if (markings) {
2903                if ($.isFunction(markings)) {
2904                    axes = plot.getAxes();
2905                    // xmin etc. is backwards compatibility, to be
2906                    // removed in the future
2907                    axes.xmin = axes.xaxis.min;
2908                    axes.xmax = axes.xaxis.max;
2909                    axes.ymin = axes.yaxis.min;
2910                    axes.ymax = axes.yaxis.max;
2911
2912                    markings = markings(axes);
2913                }
2914
2915                for (i = 0; i < markings.length; ++i) {
2916                    var m = markings[i],
2917                        xrange = extractRange(m, "x"),
2918                        yrange = extractRange(m, "y");
2919
2920                    // fill in missing
2921                    if (xrange.from == null)
2922                        xrange.from = xrange.axis.min;
2923                    if (xrange.to == null)
2924                        xrange.to = xrange.axis.max;
2925                    if (yrange.from == null)
2926                        yrange.from = yrange.axis.min;
2927                    if (yrange.to == null)
2928                        yrange.to = yrange.axis.max;
2929
2930                    // clip
2931                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
2932                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
2933                        continue;
2934
2935                    xrange.from = Math.max(xrange.from, xrange.axis.min);
2936                    xrange.to = Math.min(xrange.to, xrange.axis.max);
2937                    yrange.from = Math.max(yrange.from, yrange.axis.min);
2938                    yrange.to = Math.min(yrange.to, yrange.axis.max);
2939
2940                    var xequal = xrange.from === xrange.to,
2941                        yequal = yrange.from === yrange.to;
2942
2943                    if (xequal && yequal) {
2944                        continue;
2945                    }
2946
2947                    // then draw
2948                    xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
2949                    xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
2950                    yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
2951                    yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
2952
2953                    if (xequal || yequal) {
2954                        var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
2955                            subPixel = lineWidth % 2 ? 0.5 : 0;
2956                        ctx.beginPath();
2957                        ctx.strokeStyle = m.color || options.grid.markingsColor;
2958                        ctx.lineWidth = lineWidth;
2959                        if (xequal) {
2960                            ctx.moveTo(xrange.to + subPixel, yrange.from);
2961                            ctx.lineTo(xrange.to + subPixel, yrange.to);
2962                        } else {
2963                            ctx.moveTo(xrange.from, yrange.to + subPixel);
2964                            ctx.lineTo(xrange.to, yrange.to + subPixel);                            
2965                        }
2966                        ctx.stroke();
2967                    } else {
2968                        ctx.fillStyle = m.color || options.grid.markingsColor;
2969                        ctx.fillRect(xrange.from, yrange.to,
2970                                     xrange.to - xrange.from,
2971                                     yrange.from - yrange.to);
2972                    }
2973                }
2974            }
2975
2976            // draw the ticks
2977            axes = allAxes();
2978            bw = options.grid.borderWidth;
2979
2980            for (var j = 0; j < axes.length; ++j) {
2981                var axis = axes[j], box = axis.box,
2982                    t = axis.tickLength, x, y, xoff, yoff;
2983                if (!axis.show || axis.ticks.length == 0)
2984                    continue;
2985
2986                ctx.lineWidth = 1;
2987
2988                // find the edges
2989                if (axis.direction == "x") {
2990                    x = 0;
2991                    if (t == "full")
2992                        y = (axis.position == "top" ? 0 : plotHeight);
2993                    else
2994                        y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
2995                }
2996                else {
2997                    y = 0;
2998                    if (t == "full")
2999                        x = (axis.position == "left" ? 0 : plotWidth);
3000                    else
3001                        x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
3002                }
3003
3004                // draw tick bar
3005                if (!axis.innermost) {
3006                    ctx.strokeStyle = axis.options.color;
3007                    ctx.beginPath();
3008                    xoff = yoff = 0;
3009                    if (axis.direction == "x")
3010                        xoff = plotWidth + 1;
3011                    else
3012                        yoff = plotHeight + 1;
3013
3014                    if (ctx.lineWidth == 1) {
3015                        if (axis.direction == "x") {
3016                            y = Math.floor(y) + 0.5;
3017                        } else {
3018                            x = Math.floor(x) + 0.5;
3019                        }
3020                    }
3021
3022                    ctx.moveTo(x, y);
3023                    ctx.lineTo(x + xoff, y + yoff);
3024                    ctx.stroke();
3025                }
3026
3027                // draw ticks
3028
3029                ctx.strokeStyle = axis.options.tickColor;
3030
3031                ctx.beginPath();
3032                for (i = 0; i < axis.ticks.length; ++i) {
3033                    var v = axis.ticks[i].v;
3034
3035                    xoff = yoff = 0;
3036
3037                    if (isNaN(v) || v < axis.min || v > axis.max
3038                        // skip those lying on the axes if we got a border
3039                        || (t == "full"
3040                            && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
3041                            && (v == axis.min || v == axis.max)))
3042                        continue;
3043
3044                    if (axis.direction == "x") {
3045                        x = axis.p2c(v);
3046                        yoff = t == "full" ? -plotHeight : t;
3047
3048                        if (axis.position == "top")
3049                            yoff = -yoff;
3050                    }
3051                    else {
3052                        y = axis.p2c(v);
3053                        xoff = t == "full" ? -plotWidth : t;
3054
3055                        if (axis.position == "left")
3056                            xoff = -xoff;
3057                    }
3058
3059                    if (ctx.lineWidth == 1) {
3060                        if (axis.direction == "x")
3061                            x = Math.floor(x) + 0.5;
3062                        else
3063                            y = Math.floor(y) + 0.5;
3064                    }
3065
3066                    ctx.moveTo(x, y);
3067                    ctx.lineTo(x + xoff, y + yoff);
3068                }
3069
3070                ctx.stroke();
3071            }
3072
3073
3074            // draw border
3075            if (bw) {
3076                // If either borderWidth or borderColor is an object, then draw the border
3077                // line by line instead of as one rectangle
3078                bc = options.grid.borderColor;
3079                if(typeof bw == "object" || typeof bc == "object") {
3080                    if (typeof bw !== "object") {
3081                        bw = {top: bw, right: bw, bottom: bw, left: bw};
3082                    }
3083                    if (typeof bc !== "object") {
3084                        bc = {top: bc, right: bc, bottom: bc, left: bc};
3085                    }
3086
3087                    if (bw.top > 0) {
3088                        ctx.strokeStyle = bc.top;
3089                        ctx.lineWidth = bw.top;
3090                        ctx.beginPath();
3091                        ctx.moveTo(0 - bw.left, 0 - bw.top/2);
3092                        ctx.lineTo(plotWidth, 0 - bw.top/2);
3093                        ctx.stroke();
3094                    }
3095
3096                    if (bw.right > 0) {
3097                        ctx.strokeStyle = bc.right;
3098                        ctx.lineWidth = bw.right;
3099                        ctx.beginPath();
3100                        ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
3101                        ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
3102                        ctx.stroke();
3103                    }
3104
3105                    if (bw.bottom > 0) {
3106                        ctx.strokeStyle = bc.bottom;
3107                        ctx.lineWidth = bw.bottom;
3108                        ctx.beginPath();
3109                        ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
3110                        ctx.lineTo(0, plotHeight + bw.bottom / 2);
3111                        ctx.stroke();
3112                    }
3113
3114                    if (bw.left > 0) {
3115                        ctx.strokeStyle = bc.left;
3116                        ctx.lineWidth = bw.left;
3117                        ctx.beginPath();
3118                        ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);
3119                        ctx.lineTo(0- bw.left/2, 0);
3120                        ctx.stroke();
3121                    }
3122                }
3123                else {
3124                    ctx.lineWidth = bw;
3125                    ctx.strokeStyle = options.grid.borderColor;
3126                    ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
3127                }
3128            }
3129
3130            ctx.restore();
3131        }
3132
3133        function drawAxisLabels() {
3134
3135            $.each(allAxes(), function (_, axis) {
3136                var box = axis.box,
3137                    legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
3138                    layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
3139                    font = axis.options.font || "flot-tick-label tickLabel",
3140                    tick, x, y, halign, valign;
3141
3142                // Remove text before checking for axis.show and ticks.length;
3143                // otherwise plugins, like flot-tickrotor, that draw their own
3144                // tick labels will end up with both theirs and the defaults.
3145
3146                surface.removeText(layer);
3147
3148                if (!axis.show || axis.ticks.length == 0)
3149                    return;
3150
3151                for (var i = 0; i < axis.ticks.length; ++i) {
3152
3153                    tick = axis.ticks[i];
3154                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
3155                        continue;
3156
3157                    if (axis.direction == "x") {
3158                        halign = "center";
3159                        x = plotOffset.left + axis.p2c(tick.v);
3160                        if (axis.position == "bottom") {
3161                            y = box.top + box.padding;
3162                        } else {
3163                            y = box.top + box.height - box.padding;
3164                            valign = "bottom";
3165                        }
3166                    } else {
3167                        valign = "middle";
3168                        y = plotOffset.top + axis.p2c(tick.v);
3169                        if (axis.position == "left") {
3170                            x = box.left + box.width - box.padding;
3171                            halign = "right";
3172                        } else {
3173                            x = box.left + box.padding;
3174                        }
3175                    }
3176
3177                    surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
3178                }
3179            });
3180        }
3181
3182        function drawSeries(series) {
3183            if (series.lines.show)
3184                drawSeriesLines(series);
3185            if (series.bars.show)
3186                drawSeriesBars(series);
3187            if (series.points.show)
3188                drawSeriesPoints(series);
3189        }
3190
3191        function drawSeriesLines(series) {
3192            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
3193                var points = datapoints.points,
3194                    ps = datapoints.pointsize,
3195                    prevx = null, prevy = null;
3196
3197                ctx.beginPath();
3198                for (var i = ps; i < points.length; i += ps) {
3199                    var x1 = points[i - ps], y1 = points[i - ps + 1],
3200                        x2 = points[i], y2 = points[i + 1];
3201
3202                    if (x1 == null || x2 == null)
3203                        continue;
3204
3205                    // clip with ymin
3206                    if (y1 <= y2 && y1 < axisy.min) {
3207                        if (y2 < axisy.min)
3208                            continue;   // line segment is outside
3209                        // compute new intersection point
3210                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
3211                        y1 = axisy.min;
3212                    }
3213                    else if (y2 <= y1 && y2 < axisy.min) {
3214                        if (y1 < axisy.min)
3215                            continue;
3216                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
3217                        y2 = axisy.min;
3218                    }
3219
3220                    // clip with ymax
3221                    if (y1 >= y2 && y1 > axisy.max) {
3222                        if (y2 > axisy.max)
3223                            continue;
3224                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
3225                        y1 = axisy.max;
3226                    }
3227                    else if (y2 >= y1 && y2 > axisy.max) {
3228                        if (y1 > axisy.max)
3229                            continue;
3230                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
3231                        y2 = axisy.max;
3232                    }
3233
3234                    // clip with xmin
3235                    if (x1 <= x2 && x1 < axisx.min) {
3236                        if (x2 < axisx.min)
3237                            continue;
3238                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
3239                        x1 = axisx.min;
3240                    }
3241                    else if (x2 <= x1 && x2 < axisx.min) {
3242                        if (x1 < axisx.min)
3243                            continue;
3244                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
3245                        x2 = axisx.min;
3246                    }
3247
3248                    // clip with xmax
3249                    if (x1 >= x2 && x1 > axisx.max) {
3250                        if (x2 > axisx.max)
3251                            continue;
3252                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
3253                        x1 = axisx.max;
3254                    }
3255                    else if (x2 >= x1 && x2 > axisx.max) {
3256                        if (x1 > axisx.max)
3257                            continue;
3258                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
3259                        x2 = axisx.max;
3260                    }
3261
3262                    if (x1 != prevx || y1 != prevy)
3263                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
3264
3265                    prevx = x2;
3266                    prevy = y2;
3267                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
3268                }
3269                ctx.stroke();
3270            }
3271
3272            function plotLineArea(datapoints, axisx, axisy) {
3273                var points = datapoints.points,
3274                    ps = datapoints.pointsize,
3275                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
3276                    i = 0, top, areaOpen = false,
3277                    ypos = 1, segmentStart = 0, segmentEnd = 0;
3278
3279                // we process each segment in two turns, first forward
3280                // direction to sketch out top, then once we hit the
3281                // end we go backwards to sketch the bottom
3282                while (true) {
3283                    if (ps > 0 && i > points.length + ps)
3284                        break;
3285
3286                    i += ps; // ps is negative if going backwards
3287
3288                    var x1 = points[i - ps],
3289                        y1 = points[i - ps + ypos],
3290                        x2 = points[i], y2 = points[i + ypos];
3291
3292                    if (areaOpen) {
3293                        if (ps > 0 && x1 != null && x2 == null) {
3294                            // at turning point
3295                            segmentEnd = i;
3296                            ps = -ps;
3297                            ypos = 2;
3298                            continue;
3299                        }
3300
3301                        if (ps < 0 && i == segmentStart + ps) {
3302                            // done with the reverse sweep
3303                            ctx.fill();
3304                            areaOpen = false;
3305                            ps = -ps;
3306                            ypos = 1;
3307                            i = segmentStart = segmentEnd + ps;
3308                            continue;
3309                        }
3310                    }
3311
3312                    if (x1 == null || x2 == null)
3313                        continue;
3314
3315                    // clip x values
3316
3317                    // clip with xmin
3318                    if (x1 <= x2 && x1 < axisx.min) {
3319                        if (x2 < axisx.min)
3320                            continue;
3321                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
3322                        x1 = axisx.min;
3323                    }
3324                    else if (x2 <= x1 && x2 < axisx.min) {
3325                        if (x1 < axisx.min)
3326                            continue;
3327                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
3328                        x2 = axisx.min;
3329                    }
3330
3331                    // clip with xmax
3332                    if (x1 >= x2 && x1 > axisx.max) {
3333                        if (x2 > axisx.max)
3334                            continue;
3335                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
3336                        x1 = axisx.max;
3337                    }
3338                    else if (x2 >= x1 && x2 > axisx.max) {
3339                        if (x1 > axisx.max)
3340                            continue;
3341                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
3342                        x2 = axisx.max;
3343                    }
3344
3345                    if (!areaOpen) {
3346                        // open area
3347                        ctx.beginPath();
3348                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
3349                        areaOpen = true;
3350                    }
3351
3352                    // now first check the case where both is outside
3353                    if (y1 >= axisy.max && y2 >= axisy.max) {
3354                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
3355                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
3356                        continue;
3357                    }
3358                    else if (y1 <= axisy.min && y2 <= axisy.min) {
3359                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
3360                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
3361                        continue;
3362                    }
3363
3364                    // else it's a bit more complicated, there might
3365                    // be a flat maxed out rectangle first, then a
3366                    // triangular cutout or reverse; to find these
3367                    // keep track of the current x values
3368                    var x1old = x1, x2old = x2;
3369
3370                    // clip the y values, without shortcutting, we
3371                    // go through all cases in turn
3372
3373                    // clip with ymin
3374                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
3375                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
3376                        y1 = axisy.min;
3377                    }
3378                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
3379                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
3380                        y2 = axisy.min;
3381                    }
3382
3383                    // clip with ymax
3384                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
3385                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
3386                        y1 = axisy.max;
3387                    }
3388                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
3389                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
3390                        y2 = axisy.max;
3391                    }
3392
3393                    // if the x value was changed we got a rectangle
3394                    // to fill
3395                    if (x1 != x1old) {
3396                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
3397                        // it goes to (x1, y1), but we fill that below
3398                    }
3399
3400                    // fill triangular section, this sometimes result
3401                    // in redundant points if (x1, y1) hasn't changed
3402                    // from previous line to, but we just ignore that
3403                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
3404                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
3405
3406                    // fill the other rectangle if it's there
3407                    if (x2 != x2old) {
3408                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
3409                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
3410                    }
3411                }
3412            }
3413
3414            ctx.save();
3415            ctx.translate(plotOffset.left, plotOffset.top);
3416            ctx.lineJoin = "round";
3417
3418            var lw = series.lines.lineWidth,
3419                sw = series.shadowSize;
3420            // FIXME: consider another form of shadow when filling is turned on
3421            if (lw > 0 && sw > 0) {
3422                // draw shadow as a thick and thin line with transparency
3423                ctx.lineWidth = sw;
3424                ctx.strokeStyle = "rgba(0,0,0,0.1)";
3425                // position shadow at angle from the mid of line
3426                var angle = Math.PI/18;
3427                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
3428                ctx.lineWidth = sw/2;
3429                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
3430            }
3431
3432            ctx.lineWidth = lw;
3433            ctx.strokeStyle = series.color;
3434            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
3435            if (fillStyle) {
3436                ctx.fillStyle = fillStyle;
3437                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
3438            }
3439
3440            if (lw > 0)
3441                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
3442            ctx.restore();
3443        }
3444
3445        function drawSeriesPoints(series) {
3446            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
3447                var points = datapoints.points, ps = datapoints.pointsize;
3448
3449                for (var i = 0; i < points.length; i += ps) {
3450                    var x = points[i], y = points[i + 1];
3451                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
3452                        continue;
3453
3454                    ctx.beginPath();
3455                    x = axisx.p2c(x);
3456                    y = axisy.p2c(y) + offset;
3457                    if (symbol == "circle")
3458                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
3459                    else
3460                        symbol(ctx, x, y, radius, shadow);
3461                    ctx.closePath();
3462
3463                    if (fillStyle) {
3464                        ctx.fillStyle = fillStyle;
3465                        ctx.fill();
3466                    }
3467                    ctx.stroke();
3468                }
3469            }
3470
3471            ctx.save();
3472            ctx.translate(plotOffset.left, plotOffset.top);
3473
3474            var lw = series.points.lineWidth,
3475                sw = series.shadowSize,
3476                radius = series.points.radius,
3477                symbol = series.points.symbol;
3478
3479            // If the user sets the line width to 0, we change it to a very 
3480            // small value. A line width of 0 seems to force the default of 1.
3481            // Doing the conditional here allows the shadow setting to still be 
3482            // optional even with a lineWidth of 0.
3483
3484            if( lw == 0 )
3485                lw = 0.0001;
3486
3487            if (lw > 0 && sw > 0) {
3488                // draw shadow in two steps
3489                var w = sw / 2;
3490                ctx.lineWidth = w;
3491                ctx.strokeStyle = "rgba(0,0,0,0.1)";
3492                plotPoints(series.datapoints, radius, null, w + w/2, true,
3493                           series.xaxis, series.yaxis, symbol);
3494
3495                ctx.strokeStyle = "rgba(0,0,0,0.2)";
3496                plotPoints(series.datapoints, radius, null, w/2, true,
3497                           series.xaxis, series.yaxis, symbol);
3498            }
3499
3500            ctx.lineWidth = lw;
3501            ctx.strokeStyle = series.color;
3502            plotPoints(series.datapoints, radius,
3503                       getFillStyle(series.points, series.color), 0, false,
3504                       series.xaxis, series.yaxis, symbol);
3505            ctx.restore();
3506        }
3507
3508        function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
3509            var left, right, bottom, top,
3510                drawLeft, drawRight, drawTop, drawBottom,
3511                tmp;
3512
3513            // in horizontal mode, we start the bar from the left
3514            // instead of from the bottom so it appears to be
3515            // horizontal rather than vertical
3516            if (horizontal) {
3517                drawBottom = drawRight = drawTop = true;
3518                drawLeft = false;
3519                left = b;
3520                right = x;
3521                top = y + barLeft;
3522                bottom = y + barRight;
3523
3524                // account for negative bars
3525                if (right < left) {
3526                    tmp = right;
3527                    right = left;
3528                    left = tmp;
3529                    drawLeft = true;
3530                    drawRight = false;
3531                }
3532            }
3533            else {
3534                drawLeft = drawRight = drawTop = true;
3535                drawBottom = false;
3536                left = x + barLeft;
3537                right = x + barRight;
3538                bottom = b;
3539                top = y;
3540
3541                // account for negative bars
3542                if (top < bottom) {
3543                    tmp = top;
3544                    top = bottom;
3545                    bottom = tmp;
3546                    drawBottom = true;
3547                    drawTop = false;
3548                }
3549            }
3550
3551            // clip
3552            if (right < axisx.min || left > axisx.max ||
3553                top < axisy.min || bottom > axisy.max)
3554                return;
3555
3556            if (left < axisx.min) {
3557                left = axisx.min;
3558                drawLeft = false;
3559            }
3560
3561            if (right > axisx.max) {
3562                right = axisx.max;
3563                drawRight = false;
3564            }
3565
3566            if (bottom < axisy.min) {
3567                bottom = axisy.min;
3568                drawBottom = false;
3569            }
3570
3571            if (top > axisy.max) {
3572                top = axisy.max;
3573                drawTop = false;
3574            }
3575
3576            left = axisx.p2c(left);
3577            bottom = axisy.p2c(bottom);
3578            right = axisx.p2c(right);
3579            top = axisy.p2c(top);
3580
3581            // fill the bar
3582            if (fillStyleCallback) {
3583                c.fillStyle = fillStyleCallback(bottom, top);
3584                c.fillRect(left, top, right - left, bottom - top)
3585            }
3586
3587            // draw outline
3588            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
3589                c.beginPath();
3590
3591                // FIXME: inline moveTo is buggy with excanvas
3592                c.moveTo(left, bottom);
3593                if (drawLeft)
3594                    c.lineTo(left, top);
3595                else
3596                    c.moveTo(left, top);
3597                if (drawTop)
3598                    c.lineTo(right, top);
3599                else
3600                    c.moveTo(right, top);
3601                if (drawRight)
3602                    c.lineTo(right, bottom);
3603                else
3604                    c.moveTo(right, bottom);
3605                if (drawBottom)
3606                    c.lineTo(left, bottom);
3607                else
3608                    c.moveTo(left, bottom);
3609                c.stroke();
3610            }
3611        }
3612
3613        function drawSeriesBars(series) {
3614            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
3615                var points = datapoints.points, ps = datapoints.pointsize;
3616
3617                for (var i = 0; i < points.length; i += ps) {
3618                    if (points[i] == null)
3619                        continue;
3620                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
3621                }
3622            }
3623
3624            ctx.save();
3625            ctx.translate(plotOffset.left, plotOffset.top);
3626
3627            // FIXME: figure out a way to add shadows (for instance along the right edge)
3628            ctx.lineWidth = series.bars.lineWidth;
3629            ctx.strokeStyle = series.color;
3630
3631            var barLeft;
3632
3633            switch (series.bars.align) {
3634                case "left":
3635                    barLeft = 0;
3636                    break;
3637                case "right":
3638                    barLeft = -series.bars.barWidth;
3639                    break;
3640                default:
3641                    barLeft = -series.bars.barWidth / 2;
3642            }
3643
3644            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
3645            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
3646            ctx.restore();
3647        }
3648
3649        function getFillStyle(filloptions, seriesColor, bottom, top) {
3650            var fill = filloptions.fill;
3651            if (!fill)
3652                return null;
3653
3654            if (filloptions.fillColor)
3655                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
3656
3657            var c = $.color.parse(seriesColor);
3658            c.a = typeof fill == "number" ? fill : 0.4;
3659            c.normalize();
3660            return c.toString();
3661        }
3662
3663        function insertLegend() {
3664
3665            if (options.legend.container != null) {
3666                $(options.legend.container).html("");
3667            } else {
3668                placeholder.find(".legend").remove();
3669            }
3670
3671            if (!options.legend.show) {
3672                return;
3673            }
3674
3675            var fragments = [], entries = [], rowStarted = false,
3676                lf = options.legend.labelFormatter, s, label;
3677
3678            // Build a list of legend entries, with each having a label and a color
3679
3680            for (var i = 0; i < series.length; ++i) {
3681                s = series[i];
3682                if (s.label) {
3683                    label = lf ? lf(s.label, s) : s.label;
3684                    if (label) {
3685                        entries.push({
3686                            label: label,
3687                            color: s.color
3688                        });
3689                    }
3690                }
3691            }
3692
3693            // Sort the legend using either the default or a custom comparator
3694
3695            if (options.legend.sorted) {
3696                if ($.isFunction(options.legend.sorted)) {
3697                    entries.sort(options.legend.sorted);
3698                } else if (options.legend.sorted == "reverse") {
3699                	entries.reverse();
3700                } else {
3701                    var ascending = options.legend.sorted != "descending";
3702                    entries.sort(function(a, b) {
3703                        return a.label == b.label ? 0 : (
3704                            (a.label < b.label) != ascending ? 1 : -1   // Logical XOR
3705                        );
3706                    });
3707                }
3708            }
3709
3710            // Generate markup for the list of entries, in their final order
3711
3712            for (var i = 0; i < entries.length; ++i) {
3713
3714                var entry = entries[i];
3715
3716                if (i % options.legend.noColumns == 0) {
3717                    if (rowStarted)
3718                        fragments.push('</tr>');
3719                    fragments.push('<tr>');
3720                    rowStarted = true;
3721                }
3722
3723                fragments.push(
3724                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' +
3725                    '<td class="legendLabel">' + entry.label + '</td>'
3726                );
3727            }
3728
3729            if (rowStarted)
3730                fragments.push('</tr>');
3731
3732            if (fragments.length == 0)
3733                return;
3734
3735            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
3736            if (options.legend.container != null)
3737                $(options.legend.container).html(table);
3738            else {
3739                var pos = "",
3740                    p = options.legend.position,
3741                    m = options.legend.margin;
3742                if (m[0] == null)
3743                    m = [m, m];
3744                if (p.charAt(0) == "n")
3745                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
3746                else if (p.charAt(0) == "s")
3747                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
3748                if (p.charAt(1) == "e")
3749                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
3750                else if (p.charAt(1) == "w")
3751                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
3752                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
3753                if (options.legend.backgroundOpacity != 0.0) {
3754                    // put in the transparent background
3755                    // separately to avoid blended labels and
3756                    // label boxes
3757                    var c = options.legend.backgroundColor;
3758                    if (c == null) {
3759                        c = options.grid.backgroundColor;
3760                        if (c && typeof c == "string")
3761                            c = $.color.parse(c);
3762                        else
3763                            c = $.color.extract(legend, 'background-color');
3764                        c.a = 1;
3765                        c = c.toString();
3766                    }
3767                    var div = legend.children();
3768                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
3769                }
3770            }
3771        }
3772
3773
3774        // interactive features
3775
3776        var highlights = [],
3777            redrawTimeout = null;
3778
3779        // returns the data item the mouse is over, or null if none is found
3780        function findNearbyItem(mouseX, mouseY, seriesFilter) {
3781            var maxDistance = options.grid.mouseActiveRadius,
3782                smallestDistance = maxDistance * maxDistance + 1,
3783                item = null, foundPoint = false, i, j, ps;
3784
3785            for (i = series.length - 1; i >= 0; --i) {
3786                if (!seriesFilter(series[i]))
3787                    continue;
3788
3789                var s = series[i],
3790                    axisx = s.xaxis,
3791                    axisy = s.yaxis,
3792                    points = s.datapoints.points,
3793                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
3794                    my = axisy.c2p(mouseY),
3795                    maxx = maxDistance / axisx.scale,
3796                    maxy = maxDistance / axisy.scale;
3797
3798                ps = s.datapoints.pointsize;
3799                // with inverse transforms, we can't use the maxx/maxy
3800                // optimization, sadly
3801                if (axisx.options.inverseTransform)
3802                    maxx = Number.MAX_VALUE;
3803                if (axisy.options.inverseTransform)
3804                    maxy = Number.MAX_VALUE;
3805
3806                if (s.lines.show || s.points.show) {
3807                    for (j = 0; j < points.length; j += ps) {
3808                        var x = points[j], y = points[j + 1];
3809                        if (x == null)
3810                            continue;
3811
3812                        // For points and lines, the cursor must be within a
3813                        // certain distance to the data point
3814                        if (x - mx > maxx || x - mx < -maxx ||
3815                            y - my > maxy || y - my < -maxy)
3816                            continue;
3817
3818                        // We have to calculate distances in pixels, not in
3819                        // data units, because the scales of the axes may be different
3820                        var dx = Math.abs(axisx.p2c(x) - mouseX),
3821                            dy = Math.abs(axisy.p2c(y) - mouseY),
3822                            dist = dx * dx + dy * dy; // we save the sqrt
3823
3824                        // use <= to ensure last point takes precedence
3825                        // (last generally means on top of)
3826                        if (dist < smallestDistance) {
3827                            smallestDistance = dist;
3828                            item = [i, j / ps];
3829                        }
3830                    }
3831                }
3832
3833                if (s.bars.show && !item) { // no other point can be nearby
3834
3835                    var barLeft, barRight;
3836
3837                    switch (s.bars.align) {
3838                        case "left":
3839                            barLeft = 0;
3840                            break;
3841                        case "right":
3842                            barLeft = -s.bars.barWidth;
3843                            break;
3844                        default:
3845                            barLeft = -s.bars.barWidth / 2;
3846                    }
3847
3848                    barRight = barLeft + s.bars.barWidth;
3849
3850                    for (j = 0; j < points.length; j += ps) {
3851                        var x = points[j], y = points[j + 1], b = points[j + 2];
3852                        if (x == null)
3853                            continue;
3854
3855                        // for a bar graph, the cursor must be inside the bar
3856                        if (series[i].bars.horizontal ?
3857                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
3858                             my >= y + barLeft && my <= y + barRight) :
3859                            (mx >= x + barLeft && mx <= x + barRight &&
3860                             my >= Math.min(b, y) && my <= Math.max(b, y)))
3861                                item = [i, j / ps];
3862                    }
3863                }
3864            }
3865
3866            if (item) {
3867                i = item[0];
3868                j = item[1];
3869                ps = series[i].datapoints.pointsize;
3870
3871                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
3872                         dataIndex: j,
3873                         series: series[i],
3874                         seriesIndex: i };
3875            }
3876
3877            return null;
3878        }
3879
3880        function onMouseMove(e) {
3881            if (options.grid.hoverable)
3882                triggerClickHoverEvent("plothover", e,
3883                                       function (s) { return s["hoverable"] != false; });
3884        }
3885
3886        function onMouseLeave(e) {
3887            if (options.grid.hoverable)
3888                triggerClickHoverEvent("plothover", e,
3889                                       function (s) { return false; });
3890        }
3891
3892        function onClick(e) {
3893            triggerClickHoverEvent("plotclick", e,
3894                                   function (s) { return s["clickable"] != false; });
3895        }
3896
3897        // trigger click or hover event (they send the same parameters
3898        // so we share their code)
3899        function triggerClickHoverEvent(eventname, event, seriesFilter) {
3900            var offset = eventHolder.offset(),
3901                canvasX = event.pageX - offset.left - plotOffset.left,
3902                canvasY = event.pageY - offset.top - plotOffset.top,
3903            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
3904
3905            pos.pageX = event.pageX;
3906            pos.pageY = event.pageY;
3907
3908            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
3909
3910            if (item) {
3911                // fill in mouse pos for any listeners out there
3912                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
3913                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
3914            }
3915
3916            if (options.grid.autoHighlight) {
3917                // clear auto-highlights
3918                for (var i = 0; i < highlights.length; ++i) {
3919                    var h = highlights[i];
3920                    if (h.auto == eventname &&
3921                        !(item && h.series == item.series &&
3922                          h.point[0] == item.datapoint[0] &&
3923                          h.point[1] == item.datapoint[1]))
3924                        unhighlight(h.series, h.point);
3925                }
3926
3927                if (item)
3928                    highlight(item.series, item.datapoint, eventname);
3929            }
3930
3931            placeholder.trigger(eventname, [ pos, item ]);
3932        }
3933
3934        function triggerRedrawOverlay() {
3935            var t = options.interaction.redrawOverlayInterval;
3936            if (t == -1) {      // skip event queue
3937                drawOverlay();
3938                return;
3939            }
3940
3941            if (!redrawTimeout)
3942                redrawTimeout = setTimeout(drawOverlay, t);
3943        }
3944
3945        function drawOverlay() {
3946            redrawTimeout = null;
3947
3948            // draw highlights
3949            octx.save();
3950            overlay.clear();
3951            octx.translate(plotOffset.left, plotOffset.top);
3952
3953            var i, hi;
3954            for (i = 0; i < highlights.length; ++i) {
3955                hi = highlights[i];
3956
3957                if (hi.series.bars.show)
3958                    drawBarHighlight(hi.series, hi.point);
3959                else
3960                    drawPointHighlight(hi.series, hi.point);
3961            }
3962            octx.restore();
3963
3964            executeHooks(hooks.drawOverlay, [octx]);
3965        }
3966
3967        function highlight(s, point, auto) {
3968            if (typeof s == "number")
3969                s = series[s];
3970
3971            if (typeof point == "number") {
3972                var ps = s.datapoints.pointsize;
3973                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
3974            }
3975
3976            var i = indexOfHighlight(s, point);
3977            if (i == -1) {
3978                highlights.push({ series: s, point: point, auto: auto });
3979
3980                triggerRedrawOverlay();
3981            }
3982            else if (!auto)
3983                highlights[i].auto = false;
3984        }
3985
3986        function unhighlight(s, point) {
3987            if (s == null && point == null) {
3988                highlights = [];
3989                triggerRedrawOverlay();
3990                return;
3991            }
3992
3993            if (typeof s == "number")
3994                s = series[s];
3995
3996            if (typeof point == "number") {
3997                var ps = s.datapoints.pointsize;
3998                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
3999            }
4000
4001            var i = indexOfHighlight(s, point);
4002            if (i != -1) {
4003                highlights.splice(i, 1);
4004
4005                triggerRedrawOverlay();
4006            }
4007        }
4008
4009        function indexOfHighlight(s, p) {
4010            for (var i = 0; i < highlights.length; ++i) {
4011                var h = highlights[i];
4012                if (h.series == s && h.point[0] == p[0]
4013                    && h.point[1] == p[1])
4014                    return i;
4015            }
4016            return -1;
4017        }
4018
4019        function drawPointHighlight(series, point) {
4020            var x = point[0], y = point[1],
4021                axisx = series.xaxis, axisy = series.yaxis,
4022                highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
4023
4024            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
4025                return;
4026
4027            var pointRadius = series.points.radius + series.points.lineWidth / 2;
4028            octx.lineWidth = pointRadius;
4029            octx.strokeStyle = highlightColor;
4030            var radius = 1.5 * pointRadius;
4031            x = axisx.p2c(x);
4032            y = axisy.p2c(y);
4033
4034            octx.beginPath();
4035            if (series.points.symbol == "circle")
4036                octx.arc(x, y, radius, 0, 2 * Math.PI, false);
4037            else
4038                series.points.symbol(octx, x, y, radius, false);
4039            octx.closePath();
4040            octx.stroke();
4041        }
4042
4043        function drawBarHighlight(series, point) {
4044            var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
4045                fillStyle = highlightColor,
4046                barLeft;
4047
4048            switch (series.bars.align) {
4049                case "left":
4050                    barLeft = 0;
4051                    break;
4052                case "right":
4053                    barLeft = -series.bars.barWidth;
4054                    break;
4055                default:
4056                    barLeft = -series.bars.barWidth / 2;
4057            }
4058
4059            octx.lineWidth = series.bars.lineWidth;
4060            octx.strokeStyle = highlightColor;
4061
4062            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
4063                    function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
4064        }
4065
4066        function getColorOrGradient(spec, bottom, top, defaultColor) {
4067            if (typeof spec == "string")
4068                return spec;
4069            else {
4070                // assume this is a gradient spec; IE currently only
4071                // supports a simple vertical gradient properly, so that's
4072                // what we support too
4073                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
4074
4075                for (var i = 0, l = spec.colors.length; i < l; ++i) {
4076                    var c = spec.colors[i];
4077                    if (typeof c != "string") {
4078                        var co = $.color.parse(defaultColor);
4079                        if (c.brightness != null)
4080                            co = co.scale('rgb', c.brightness);
4081                        if (c.opacity != null)
4082                            co.a *= c.opacity;
4083                        c = co.toString();
4084                    }
4085                    gradient.addColorStop(i / (l - 1), c);
4086                }
4087
4088                return gradient;
4089            }
4090        }
4091    }
4092
4093    // Add the plot function to the top level of the jQuery object
4094
4095    $.plot = function(placeholder, data, options) {
4096        //var t0 = new Date();
4097        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
4098        //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
4099        return plot;
4100    };
4101
4102    $.plot.version = "0.8.3";
4103
4104    $.plot.plugins = [];
4105
4106    // Also add the plot function as a chainable property
4107
4108    $.fn.plot = function(data, options) {
4109        return this.each(function() {
4110            $.plot(this, data, options);
4111        });
4112    };
4113
4114    // round to nearby lower multiple of base
4115    function floorInBase(n, base) {
4116        return base * Math.floor(n / base);
4117    }
4118
4119})(jQuery);
4120
4121/* Flot plugin for plotting textual data or categories.
4122
4123Copyright (c) 2007-2014 IOLA and Ole Laursen.
4124Licensed under the MIT license.
4125
4126Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
4127allows you to plot such a dataset directly.
4128
4129To enable it, you must specify mode: "categories" on the axis with the textual
4130labels, e.g.
4131
4132	$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
4133
4134By default, the labels are ordered as they are met in the data series. If you
4135need a different ordering, you can specify "categories" on the axis options
4136and list the categories there:
4137
4138	xaxis: {
4139		mode: "categories",
4140		categories: ["February", "March", "April"]
4141	}
4142
4143If you need to customize the distances between the categories, you can specify
4144"categories" as an object mapping labels to values
4145
4146	xaxis: {
4147		mode: "categories",
4148		categories: { "February": 1, "March": 3, "April": 4 }
4149	}
4150
4151If you don't specify all categories, the remaining categories will be numbered
4152from the max value plus 1 (with a spacing of 1 between each).
4153
4154Internally, the plugin works by transforming the input data through an auto-
4155generated mapping where the first category becomes 0, the second 1, etc.
4156Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
4157is visible in hover and click events that return numbers rather than the
4158category labels). The plugin also overrides the tick generator to spit out the
4159categories as ticks instead of the values.
4160
4161If you need to map a value back to its label, the mapping is always accessible
4162as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
4163
4164*/
4165
4166(function ($) {
4167    var options = {
4168        xaxis: {
4169            categories: null
4170        },
4171        yaxis: {
4172            categories: null
4173        }
4174    };
4175    
4176    function processRawData(plot, series, data, datapoints) {
4177        // if categories are enabled, we need to disable
4178        // auto-transformation to numbers so the strings are intact
4179        // for later processing
4180
4181        var xCategories = series.xaxis.options.mode == "categories",
4182            yCategories = series.yaxis.options.mode == "categories";
4183        
4184        if (!(xCategories || yCategories))
4185            return;
4186
4187        var format = datapoints.format;
4188
4189        if (!format) {
4190            // FIXME: auto-detection should really not be defined here
4191            var s = series;
4192            format = [];
4193            format.push({ x: true, number: true, required: true });
4194            format.push({ y: true, number: true, required: true });
4195
4196            if (s.bars.show || (s.lines.show && s.lines.fill)) {
4197                var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
4198                format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
4199                if (s.bars.horizontal) {
4200                    delete format[format.length - 1].y;
4201                    format[format.length - 1].x = true;
4202                }
4203            }
4204            
4205            datapoints.format = format;
4206        }
4207
4208        for (var m = 0; m < format.length; ++m) {
4209            if (format[m].x && xCategories)
4210                format[m].number = false;
4211            
4212            if (format[m].y && yCategories)
4213                format[m].number = false;
4214        }
4215    }
4216
4217    function getNextIndex(categories) {
4218        var index = -1;
4219        
4220        for (var v in categories)
4221            if (categories[v] > index)
4222                index = categories[v];
4223
4224        return index + 1;
4225    }
4226
4227    function categoriesTickGenerator(axis) {
4228        var res = [];
4229        for (var label in axis.categories) {
4230            var v = axis.categories[label];
4231            if (v >= axis.min && v <= axis.max)
4232                res.push([v, label]);
4233        }
4234
4235        res.sort(function (a, b) { return a[0] - b[0]; });
4236
4237        return res;
4238    }
4239    
4240    function setupCategoriesForAxis(series, axis, datapoints) {
4241        if (series[axis].options.mode != "categories")
4242            return;
4243        
4244        if (!series[axis].categories) {
4245            // parse options
4246            var c = {}, o = series[axis].options.categories || {};
4247            if ($.isArray(o)) {
4248                for (var i = 0; i < o.length; ++i)
4249                    c[o[i]] = i;
4250            }
4251            else {
4252                for (var v in o)
4253                    c[v] = o[v];
4254            }
4255            
4256            series[axis].categories = c;
4257        }
4258
4259        // fix ticks
4260        if (!series[axis].options.ticks)
4261            series[axis].options.ticks = categoriesTickGenerator;
4262
4263        transformPointsOnAxis(datapoints, axis, series[axis].categories);
4264    }
4265    
4266    function transformPointsOnAxis(datapoints, axis, categories) {
4267        // go through the points, transforming them
4268        var points = datapoints.points,
4269            ps = datapoints.pointsize,
4270            format = datapoints.format,
4271            formatColumn = axis.charAt(0),
4272            index = getNextIndex(categories);
4273
4274        for (var i = 0; i < points.length; i += ps) {
4275            if (points[i] == null)
4276                continue;
4277            
4278            for (var m = 0; m < ps; ++m) {
4279                var val = points[i + m];
4280
4281                if (val == null || !format[m][formatColumn])
4282                    continue;
4283
4284                if (!(val in categories)) {
4285                    categories[val] = index;
4286                    ++index;
4287                }
4288                
4289                points[i + m] = categories[val];
4290            }
4291        }
4292    }
4293
4294    function processDatapoints(plot, series, datapoints) {
4295        setupCategoriesForAxis(series, "xaxis", datapoints);
4296        setupCategoriesForAxis(series, "yaxis", datapoints);
4297    }
4298
4299    function init(plot) {
4300        plot.hooks.processRawData.push(processRawData);
4301        plot.hooks.processDatapoints.push(processDatapoints);
4302    }
4303    
4304    $.plot.plugins.push({
4305        init: init,
4306        options: options,
4307        name: 'categories',
4308        version: '1.0'
4309    });
4310})(jQuery);
4311
vendor: 23,809 bytes, lines 4312-5131
4312/* Flot plugin for rendering pie charts.
4313
4314Copyright (c) 2007-2014 IOLA and Ole Laursen.
4315Licensed under the MIT license.
4316
4317The plugin assumes that each series has a single data value, and that each
4318value is a positive integer or zero.  Negative numbers don't make sense for a
4319pie chart, and have unpredictable results.  The values do NOT need to be
4320passed in as percentages; the plugin will calculate the total and per-slice
4321percentages internally.
4322
4323* Created by Brian Medendorp
4324
4325* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
4326
4327The plugin supports these options:
4328
4329	series: {
4330		pie: {
4331			show: true/false
4332			radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
4333			innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
4334			startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
4335			tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
4336			offset: {
4337				top: integer value to move the pie up or down
4338				left: integer value to move the pie left or right, or 'auto'
4339			},
4340			stroke: {
4341				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
4342				width: integer pixel width of the stroke
4343			},
4344			label: {
4345				show: true/false, or 'auto'
4346				formatter:  a user-defined function that modifies the text/style of the label text
4347				radius: 0-1 for percentage of fullsize, or a specified pixel length
4348				background: {
4349					color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
4350					opacity: 0-1
4351				},
4352				threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
4353			},
4354			combine: {
4355				threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
4356				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
4357				label: any text value of what the combined slice should be labeled
4358			}
4359			highlight: {
4360				opacity: 0-1
4361			}
4362		}
4363	}
4364
4365More detail and specific examples can be found in the included HTML file.
4366
4367*/
4368
4369(function($) {
4370
4371	// Maximum redraw attempts when fitting labels within the plot
4372
4373	var REDRAW_ATTEMPTS = 10;
4374
4375	// Factor by which to shrink the pie when fitting labels within the plot
4376
4377	var REDRAW_SHRINK = 0.95;
4378
4379	function init(plot) {
4380
4381		var canvas = null,
4382			target = null,
4383			options = null,
4384			maxRadius = null,
4385			centerLeft = null,
4386			centerTop = null,
4387			processed = false,
4388			ctx = null;
4389
4390		// interactive variables
4391
4392		var highlights = [];
4393
4394		// add hook to determine if pie plugin in enabled, and then perform necessary operations
4395
4396		plot.hooks.processOptions.push(function(plot, options) {
4397			if (options.series.pie.show) {
4398
4399				options.grid.show = false;
4400
4401				// set labels.show
4402
4403				if (options.series.pie.label.show == "auto") {
4404					if (options.legend.show) {
4405						options.series.pie.label.show = false;
4406					} else {
4407						options.series.pie.label.show = true;
4408					}
4409				}
4410
4411				// set radius
4412
4413				if (options.series.pie.radius == "auto") {
4414					if (options.series.pie.label.show) {
4415						options.series.pie.radius = 3/4;
4416					} else {
4417						options.series.pie.radius = 1;
4418					}
4419				}
4420
4421				// ensure sane tilt
4422
4423				if (options.series.pie.tilt > 1) {
4424					options.series.pie.tilt = 1;
4425				} else if (options.series.pie.tilt < 0) {
4426					options.series.pie.tilt = 0;
4427				}
4428			}
4429		});
4430
4431		plot.hooks.bindEvents.push(function(plot, eventHolder) {
4432			var options = plot.getOptions();
4433			if (options.series.pie.show) {
4434				if (options.grid.hoverable) {
4435					eventHolder.unbind("mousemove").mousemove(onMouseMove);
4436				}
4437				if (options.grid.clickable) {
4438					eventHolder.unbind("click").click(onClick);
4439				}
4440			}
4441		});
4442
4443		plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
4444			var options = plot.getOptions();
4445			if (options.series.pie.show) {
4446				processDatapoints(plot, series, data, datapoints);
4447			}
4448		});
4449
4450		plot.hooks.drawOverlay.push(function(plot, octx) {
4451			var options = plot.getOptions();
4452			if (options.series.pie.show) {
4453				drawOverlay(plot, octx);
4454			}
4455		});
4456
4457		plot.hooks.draw.push(function(plot, newCtx) {
4458			var options = plot.getOptions();
4459			if (options.series.pie.show) {
4460				draw(plot, newCtx);
4461			}
4462		});
4463
4464		function processDatapoints(plot, series, datapoints) {
4465			if (!processed)	{
4466				processed = true;
4467				canvas = plot.getCanvas();
4468				target = $(canvas).parent();
4469				options = plot.getOptions();
4470				plot.setData(combine(plot.getData()));
4471			}
4472		}
4473
4474		function combine(data) {
4475
4476			var total = 0,
4477				combined = 0,
4478				numCombined = 0,
4479				color = options.series.pie.combine.color,
4480				newdata = [];
4481
4482			// Fix up the raw data from Flot, ensuring the data is numeric
4483
4484			for (var i = 0; i < data.length; ++i) {
4485
4486				var value = data[i].data;
4487
4488				// If the data is an array, we'll assume that it's a standard
4489				// Flot x-y pair, and are concerned only with the second value.
4490
4491				// Note how we use the original array, rather than creating a
4492				// new one; this is more efficient and preserves any extra data
4493				// that the user may have stored in higher indexes.
4494
4495				if ($.isArray(value) && value.length == 1) {
4496    				value = value[0];
4497				}
4498
4499				if ($.isArray(value)) {
4500					// Equivalent to $.isNumeric() but compatible with jQuery < 1.7
4501					if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
4502						value[1] = +value[1];
4503					} else {
4504						value[1] = 0;
4505					}
4506				} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
4507					value = [1, +value];
4508				} else {
4509					value = [1, 0];
4510				}
4511
4512				data[i].data = [value];
4513			}
4514
4515			// Sum up all the slices, so we can calculate percentages for each
4516
4517			for (var i = 0; i < data.length; ++i) {
4518				total += data[i].data[0][1];
4519			}
4520
4521			// Count the number of slices with percentages below the combine
4522			// threshold; if it turns out to be just one, we won't combine.
4523
4524			for (var i = 0; i < data.length; ++i) {
4525				var value = data[i].data[0][1];
4526				if (value / total <= options.series.pie.combine.threshold) {
4527					combined += value;
4528					numCombined++;
4529					if (!color) {
4530						color = data[i].color;
4531					}
4532				}
4533			}
4534
4535			for (var i = 0; i < data.length; ++i) {
4536				var value = data[i].data[0][1];
4537				if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
4538					newdata.push(
4539						$.extend(data[i], {     /* extend to allow keeping all other original data values
4540						                           and using them e.g. in labelFormatter. */
4541							data: [[1, value]],
4542							color: data[i].color,
4543							label: data[i].label,
4544							angle: value * Math.PI * 2 / total,
4545							percent: value / (total / 100)
4546						})
4547					);
4548				}
4549			}
4550
4551			if (numCombined > 1) {
4552				newdata.push({
4553					data: [[1, combined]],
4554					color: color,
4555					label: options.series.pie.combine.label,
4556					angle: combined * Math.PI * 2 / total,
4557					percent: combined / (total / 100)
4558				});
4559			}
4560
4561			return newdata;
4562		}
4563
4564		function draw(plot, newCtx) {
4565
4566			if (!target) {
4567				return; // if no series were passed
4568			}
4569
4570			var canvasWidth = plot.getPlaceholder().width(),
4571				canvasHeight = plot.getPlaceholder().height(),
4572				legendWidth = target.children().filter(".legend").children().width() || 0;
4573
4574			ctx = newCtx;
4575
4576			// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
4577
4578			// When combining smaller slices into an 'other' slice, we need to
4579			// add a new series.  Since Flot gives plugins no way to modify the
4580			// list of series, the pie plugin uses a hack where the first call
4581			// to processDatapoints results in a call to setData with the new
4582			// list of series, then subsequent processDatapoints do nothing.
4583
4584			// The plugin-global 'processed' flag is used to control this hack;
4585			// it starts out false, and is set to true after the first call to
4586			// processDatapoints.
4587
4588			// Unfortunately this turns future setData calls into no-ops; they
4589			// call processDatapoints, the flag is true, and nothing happens.
4590
4591			// To fix this we'll set the flag back to false here in draw, when
4592			// all series have been processed, so the next sequence of calls to
4593			// processDatapoints once again starts out with a slice-combine.
4594			// This is really a hack; in 0.9 we need to give plugins a proper
4595			// way to modify series before any processing begins.
4596
4597			processed = false;
4598
4599			// calculate maximum radius and center point
4600
4601			maxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
4602			centerTop = canvasHeight / 2 + options.series.pie.offset.top;
4603			centerLeft = canvasWidth / 2;
4604
4605			if (options.series.pie.offset.left == "auto") {
4606				if (options.legend.position.match("w")) {
4607					centerLeft += legendWidth / 2;
4608				} else {
4609					centerLeft -= legendWidth / 2;
4610				}
4611				if (centerLeft < maxRadius) {
4612					centerLeft = maxRadius;
4613				} else if (centerLeft > canvasWidth - maxRadius) {
4614					centerLeft = canvasWidth - maxRadius;
4615				}
4616			} else {
4617				centerLeft += options.series.pie.offset.left;
4618			}
4619
4620			var slices = plot.getData(),
4621				attempts = 0;
4622
4623			// Keep shrinking the pie's radius until drawPie returns true,
4624			// indicating that all the labels fit, or we try too many times.
4625
4626			do {
4627				if (attempts > 0) {
4628					maxRadius *= REDRAW_SHRINK;
4629				}
4630				attempts += 1;
4631				clear();
4632				if (options.series.pie.tilt <= 0.8) {
4633					drawShadow();
4634				}
4635			} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
4636
4637			if (attempts >= REDRAW_ATTEMPTS) {
4638				clear();
4639				target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
4640			}
4641
4642			if (plot.setSeries && plot.insertLegend) {
4643				plot.setSeries(slices);
4644				plot.insertLegend();
4645			}
4646
4647			// we're actually done at this point, just defining internal functions at this point
4648
4649			function clear() {
4650				ctx.clearRect(0, 0, canvasWidth, canvasHeight);
4651				target.children().filter(".pieLabel, .pieLabelBackground").remove();
4652			}
4653
4654			function drawShadow() {
4655
4656				var shadowLeft = options.series.pie.shadow.left;
4657				var shadowTop = options.series.pie.shadow.top;
4658				var edge = 10;
4659				var alpha = options.series.pie.shadow.alpha;
4660				var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
4661
4662				if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
4663					return;	// shadow would be outside canvas, so don't draw it
4664				}
4665
4666				ctx.save();
4667				ctx.translate(shadowLeft,shadowTop);
4668				ctx.globalAlpha = alpha;
4669				ctx.fillStyle = "#000";
4670
4671				// center and rotate to starting position
4672
4673				ctx.translate(centerLeft,centerTop);
4674				ctx.scale(1, options.series.pie.tilt);
4675
4676				//radius -= edge;
4677
4678				for (var i = 1; i <= edge; i++) {
4679					ctx.beginPath();
4680					ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
4681					ctx.fill();
4682					radius -= i;
4683				}
4684
4685				ctx.restore();
4686			}
4687
4688			function drawPie() {
4689
4690				var startAngle = Math.PI * options.series.pie.startAngle;
4691				var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
4692
4693				// center and rotate to starting position
4694
4695				ctx.save();
4696				ctx.translate(centerLeft,centerTop);
4697				ctx.scale(1, options.series.pie.tilt);
4698				//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
4699
4700				// draw slices
4701
4702				ctx.save();
4703				var currentAngle = startAngle;
4704				for (var i = 0; i < slices.length; ++i) {
4705					slices[i].startAngle = currentAngle;
4706					drawSlice(slices[i].angle, slices[i].color, true);
4707				}
4708				ctx.restore();
4709
4710				// draw slice outlines
4711
4712				if (options.series.pie.stroke.width > 0) {
4713					ctx.save();
4714					ctx.lineWidth = options.series.pie.stroke.width;
4715					currentAngle = startAngle;
4716					for (var i = 0; i < slices.length; ++i) {
4717						drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
4718					}
4719					ctx.restore();
4720				}
4721
4722				// draw donut hole
4723
4724				drawDonutHole(ctx);
4725
4726				ctx.restore();
4727
4728				// Draw the labels, returning true if they fit within the plot
4729
4730				if (options.series.pie.label.show) {
4731					return drawLabels();
4732				} else return true;
4733
4734				function drawSlice(angle, color, fill) {
4735
4736					if (angle <= 0 || isNaN(angle)) {
4737						return;
4738					}
4739
4740					if (fill) {
4741						ctx.fillStyle = color;
4742					} else {
4743						ctx.strokeStyle = color;
4744						ctx.lineJoin = "round";
4745					}
4746
4747					ctx.beginPath();
4748					if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
4749						ctx.moveTo(0, 0); // Center of the pie
4750					}
4751
4752					//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
4753					ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
4754					ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
4755					ctx.closePath();
4756					//ctx.rotate(angle); // This doesn't work properly in Opera
4757					currentAngle += angle;
4758
4759					if (fill) {
4760						ctx.fill();
4761					} else {
4762						ctx.stroke();
4763					}
4764				}
4765
4766				function drawLabels() {
4767
4768					var currentAngle = startAngle;
4769					var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
4770
4771					for (var i = 0; i < slices.length; ++i) {
4772						if (slices[i].percent >= options.series.pie.label.threshold * 100) {
4773							if (!drawLabel(slices[i], currentAngle, i)) {
4774								return false;
4775							}
4776						}
4777						currentAngle += slices[i].angle;
4778					}
4779
4780					return true;
4781
4782					function drawLabel(slice, startAngle, index) {
4783
4784						if (slice.data[0][1] == 0) {
4785							return true;
4786						}
4787
4788						// format label text
4789
4790						var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
4791
4792						if (lf) {
4793							text = lf(slice.label, slice);
4794						} else {
4795							text = slice.label;
4796						}
4797
4798						if (plf) {
4799							text = plf(text, slice);
4800						}
4801
4802						var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
4803						var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
4804						var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
4805
4806						var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>";
4807						target.append(html);
4808
4809						var label = target.children("#pieLabel" + index);
4810						var labelTop = (y - label.height() / 2);
4811						var labelLeft = (x - label.width() / 2);
4812
4813						label.css("top", labelTop);
4814						label.css("left", labelLeft);
4815
4816						// check to make sure that the label is not outside the canvas
4817
4818						if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
4819							return false;
4820						}
4821
4822						if (options.series.pie.label.background.opacity != 0) {
4823
4824							// put in the transparent background separately to avoid blended labels and label boxes
4825
4826							var c = options.series.pie.label.background.color;
4827
4828							if (c == null) {
4829								c = slice.color;
4830							}
4831
4832							var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
4833							$("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>")
4834								.css("opacity", options.series.pie.label.background.opacity)
4835								.insertBefore(label);
4836						}
4837
4838						return true;
4839					} // end individual label function
4840				} // end drawLabels function
4841			} // end drawPie function
4842		} // end draw function
4843
4844		// Placed here because it needs to be accessed from multiple locations
4845
4846		function drawDonutHole(layer) {
4847			if (options.series.pie.innerRadius > 0) {
4848
4849				// subtract the center
4850
4851				layer.save();
4852				var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
4853				layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
4854				layer.beginPath();
4855				layer.fillStyle = options.series.pie.stroke.color;
4856				layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
4857				layer.fill();
4858				layer.closePath();
4859				layer.restore();
4860
4861				// add inner stroke
4862
4863				layer.save();
4864				layer.beginPath();
4865				layer.strokeStyle = options.series.pie.stroke.color;
4866				layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
4867				layer.stroke();
4868				layer.closePath();
4869				layer.restore();
4870
4871				// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
4872			}
4873		}
4874
4875		//-- Additional Interactive related functions --
4876
4877		function isPointInPoly(poly, pt) {
4878			for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
4879				((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
4880				&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
4881				&& (c = !c);
4882			return c;
4883		}
4884
4885		function findNearbySlice(mouseX, mouseY) {
4886
4887			var slices = plot.getData(),
4888				options = plot.getOptions(),
4889				radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
4890				x, y;
4891
4892			for (var i = 0; i < slices.length; ++i) {
4893
4894				var s = slices[i];
4895
4896				if (s.pie.show) {
4897
4898					ctx.save();
4899					ctx.beginPath();
4900					ctx.moveTo(0, 0); // Center of the pie
4901					//ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.
4902					ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
4903					ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
4904					ctx.closePath();
4905					x = mouseX - centerLeft;
4906					y = mouseY - centerTop;
4907
4908					if (ctx.isPointInPath) {
4909						if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
4910							ctx.restore();
4911							return {
4912								datapoint: [s.percent, s.data],
4913								dataIndex: 0,
4914								series: s,
4915								seriesIndex: i
4916							};
4917						}
4918					} else {
4919
4920						// excanvas for IE doesn;t support isPointInPath, this is a workaround.
4921
4922						var p1X = radius * Math.cos(s.startAngle),
4923							p1Y = radius * Math.sin(s.startAngle),
4924							p2X = radius * Math.cos(s.startAngle + s.angle / 4),
4925							p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
4926							p3X = radius * Math.cos(s.startAngle + s.angle / 2),
4927							p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
4928							p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
4929							p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
4930							p5X = radius * Math.cos(s.startAngle + s.angle),
4931							p5Y = radius * Math.sin(s.startAngle + s.angle),
4932							arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
4933							arrPoint = [x, y];
4934
4935						// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
4936
4937						if (isPointInPoly(arrPoly, arrPoint)) {
4938							ctx.restore();
4939							return {
4940								datapoint: [s.percent, s.data],
4941								dataIndex: 0,
4942								series: s,
4943								seriesIndex: i
4944							};
4945						}
4946					}
4947
4948					ctx.restore();
4949				}
4950			}
4951
4952			return null;
4953		}
4954
4955		function onMouseMove(e) {
4956			triggerClickHoverEvent("plothover", e);
4957		}
4958
4959		function onClick(e) {
4960			triggerClickHoverEvent("plotclick", e);
4961		}
4962
4963		// trigger click or hover event (they send the same parameters so we share their code)
4964
4965		function triggerClickHoverEvent(eventname, e) {
4966
4967			var offset = plot.offset();
4968			var canvasX = parseInt(e.pageX - offset.left);
4969			var canvasY =  parseInt(e.pageY - offset.top);
4970			var item = findNearbySlice(canvasX, canvasY);
4971
4972			if (options.grid.autoHighlight) {
4973
4974				// clear auto-highlights
4975
4976				for (var i = 0; i < highlights.length; ++i) {
4977					var h = highlights[i];
4978					if (h.auto == eventname && !(item && h.series == item.series)) {
4979						unhighlight(h.series);
4980					}
4981				}
4982			}
4983
4984			// highlight the slice
4985
4986			if (item) {
4987				highlight(item.series, eventname);
4988			}
4989
4990			// trigger any hover bind events
4991
4992			var pos = { pageX: e.pageX, pageY: e.pageY };
4993			target.trigger(eventname, [pos, item]);
4994		}
4995
4996		function highlight(s, auto) {
4997			//if (typeof s == "number") {
4998			//	s = series[s];
4999			//}
5000
5001			var i = indexOfHighlight(s);
5002
5003			if (i == -1) {
5004				highlights.push({ series: s, auto: auto });
5005				plot.triggerRedrawOverlay();
5006			} else if (!auto) {
5007				highlights[i].auto = false;
5008			}
5009		}
5010
5011		function unhighlight(s) {
5012			if (s == null) {
5013				highlights = [];
5014				plot.triggerRedrawOverlay();
5015			}
5016
5017			//if (typeof s == "number") {
5018			//	s = series[s];
5019			//}
5020
5021			var i = indexOfHighlight(s);
5022
5023			if (i != -1) {
5024				highlights.splice(i, 1);
5025				plot.triggerRedrawOverlay();
5026			}
5027		}
5028
5029		function indexOfHighlight(s) {
5030			for (var i = 0; i < highlights.length; ++i) {
5031				var h = highlights[i];
5032				if (h.series == s)
5033					return i;
5034			}
5035			return -1;
5036		}
5037
5038		function drawOverlay(plot, octx) {
5039
5040			var options = plot.getOptions();
5041
5042			var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
5043
5044			octx.save();
5045			octx.translate(centerLeft, centerTop);
5046			octx.scale(1, options.series.pie.tilt);
5047
5048			for (var i = 0; i < highlights.length; ++i) {
5049				drawHighlight(highlights[i].series);
5050			}
5051
5052			drawDonutHole(octx);
5053
5054			octx.restore();
5055
5056			function drawHighlight(series) {
5057
5058				if (series.angle <= 0 || isNaN(series.angle)) {
5059					return;
5060				}
5061
5062				//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
5063				octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
5064				octx.beginPath();
5065				if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
5066					octx.moveTo(0, 0); // Center of the pie
5067				}
5068				octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
5069				octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
5070				octx.closePath();
5071				octx.fill();
5072			}
5073		}
5074	} // end init (plugin body)
5075
5076	// define pie specific options and their default values
5077
5078	var options = {
5079		series: {
5080			pie: {
5081				show: false,
5082				radius: "auto",	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
5083				innerRadius: 0, /* for donut */
5084				startAngle: 3/2,
5085				tilt: 1,
5086				shadow: {
5087					left: 5,	// shadow left offset
5088					top: 15,	// shadow top offset
5089					alpha: 0.02	// shadow alpha
5090				},
5091				offset: {
5092					top: 0,
5093					left: "auto"
5094				},
5095				stroke: {
5096					color: "#fff",
5097					width: 1
5098				},
5099				label: {
5100					show: "auto",
5101					formatter: function(label, slice) {
5102						return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>";
5103					},	// formatter function
5104					radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
5105					background: {
5106						color: null,
5107						opacity: 0
5108					},
5109					threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)
5110				},
5111				combine: {
5112					threshold: -1,	// percentage at which to combine little slices into one larger slice
5113					color: null,	// color to give the new slice (auto-generated if null)
5114					label: "Other"	// label to give the new slice
5115				},
5116				highlight: {
5117					//color: "#fff",		// will add this functionality once parseColor is available
5118					opacity: 0.5
5119				}
5120			}
5121		}
5122	};
5123
5124	$.plot.plugins.push({
5125		init: init,
5126		options: options,
5127		name: "pie",
5128		version: "1.1"
5129	});
5130
5131})(jQuery);
5132
5133(function() {
5134
5135  if (typeof window.googletag === 'undefined') {
5136    window.googletag = { cmd: [] };
5137  }
5138
5139  /* Event-Listener Adition iframe */
5140  window.addEventListener('message',function(event) {
5141    const origin = window.location.origin;
5142    if(event.origin !== origin) return;
5143
5144    switch(event.data) {
5145      case 'bta':
5146        $(document).trigger('btaTeasering');
5147        break;
5148
5149      default:
5150        return;
5151    }
5152
5153  },false);
5154
5155
5156
5157  'use strict';
5158
5159  function insertAdvTag2(AdvTxt) {
5160    const taglines = document.querySelectorAll('.bta1Tagline, .bta2Tagline, .BTA-Artikeldetail-aSide-1 .Tagline, .BTA-Artikeldetail-aSide-2 .Tagline, .BTA-Artikeldetail-Stage-1 .Tagline, .BTA-Artikeldetail-Stage-2 .Tagline, .BTA-Artikeldetail-Stage-3 .Tagline');
5161
5162    taglines.forEach(tagline => {
5163      const btaAdvTag = document.createElement('div');
5164      btaAdvTag.className = 'AdvertNote';
5165      btaAdvTag.textContent = AdvTxt;
5166
5167      /* btaAdvTag als erstes Kind des aktuellen Tagline-Elements einfügen */
5168      tagline.insertBefore(btaAdvTag, tagline.firstChild);
5169    });
5170  }
5171
5172  function insertAdvTag(AdvTxt, tagline) {
5173
5174      const btaAdvTag = document.createElement('div');
5175      btaAdvTag.className = 'AdvertNote';
5176      btaAdvTag.textContent = AdvTxt;
5177
5178      /* btaAdvTag als erstes Kind des aktuellen Tagline-Elements einfügen */
5179      tagline.insertBefore(btaAdvTag, tagline.firstChild);
5180
5181  }
5182
5183  let btaAsideExists = false;
5184  let btaStageExists = false;
5185
5186  function setBtaStageMargin() {
5187
5188
5189    if (btaAsideExists) {
5190      const pageArticleContent = document.querySelector('.PageArticle_content');
5191      if (!pageArticleContent) return;
5192
5193      const elAfterContent = pageArticleContent.nextElementSibling;
5194      if (elAfterContent) {
5195        const btaAsideDiv = document.querySelector('.btaAsideContainer');
5196
5197        if (btaAsideDiv) {
5198          const computedStyle = getComputedStyle(btaAsideDiv);
5199          const btaAsideHeight = btaAsideDiv.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
5200          elAfterContent.style.marginTop = `${btaAsideHeight + 20}px`;
5201        }
5202      }
5203    }
5204
5205  }
5206
5207/* BTA-Aside */
5208
5209  let isAsideListenerActive = false;
5210
5211  function positionAsideBta() {
5212    const leadEl = document.querySelector('.PageArticle_sticky');
5213    const targetEl = document.querySelector('.btaAsideContainer');
5214
5215    if (leadEl && targetEl) {
5216      /* hat leadEl "position: fixed" */
5217      const leadComputedStyle = window.getComputedStyle(leadEl);
5218      const isLeadFixed = leadComputedStyle.position === 'fixed';
5219
5220      let newTop;
5221
5222      if (isLeadFixed) {
5223        // wenn leadEl "fixed", dann positioniere targetEl relativ zum Viewport
5224        const leadRect = leadEl.getBoundingClientRect();
5225        targetEl.style.position = 'fixed';
5226        newTop = leadRect.bottom + 5;
5227      } else {
5228        // wenn leadEl nicht "fixed", dann positioniere targetEl relativ zum Dokument
5229        const leadOffsetTop = leadEl.offsetTop + leadEl.offsetHeight;
5230        targetEl.style.position = 'absolute';
5231        newTop = leadOffsetTop + 5;
5232      }
5233
5234      targetEl.style.top = `${newTop}px`;
5235
5236      /* debugging */
5237      /*
5238      console.log({
5239                    leadPosition: leadComputedStyle.position,
5240                    leadBottom: leadEl.getBoundingClientRect().bottom,
5241                    leadOffsetTop: leadEl.offsetTop,
5242                    targetTop: targetEl.style.top,
5243                  });
5244      */
5245    }
5246  }
5247
5248  function addAsideEventListeners() {
5249    if (!isAsideListenerActive) {
5250      window.addEventListener('resize', positionAsideBta);
5251      window.addEventListener('scroll', positionAsideBta);
5252      isAsideListenerActive = true;
5253    }
5254  }
5255
5256  $(document).on("btaTeasering", function(event){
5257    // alle Elementen mit der Klasse "btaFrame" und dem Data-Attribut "ad_position" gleich "0"
5258    const bta1Els = document.querySelectorAll('.btaFrame[data-ad_position="bta1"]');
5259    const bta2Els = document.querySelectorAll('.btaFrame[data-ad_position="bta2"]');
5260    const bta3Els = document.querySelectorAll('.btaFrame[data-ad_position="bta3"]');
5261    const bta4Els = document.querySelectorAll('.btaFrame[data-ad_position="bta4"]');
5262    const bta5Els = document.querySelectorAll('.btaFrame[data-ad_position="bta5"]');
5263    const bta6Els = document.querySelectorAll('.btaFrame[data-ad_position="bta6"]');
5264    const bta7Els = document.querySelectorAll('.btaFrame[data-ad_position="bta7"]');
5265
5266    if (bta1Els.length > 0) {
5267      const bta1Tagline = document.querySelector('.bta1Tagline');
5268      const bta1Headline = document.querySelector('.bta1Headline');
5269      const bta1href = document.querySelector('.bta1Url');
5270      const bta1Text = document.querySelector('.BTA-Homepage-Aufmacher .ArticleTeaser_abstract');
5271
5272      bta1Els.forEach(bta1El => {
5273        const bta_kicker = bta1El.getAttribute('data-kicker');
5274        if (bta1Tagline && bta_kicker) {
5275          bta1Tagline.textContent = bta_kicker;
5276        }
5277        const bta_titel = bta1El.getAttribute('data-titel');
5278        if (bta1Headline && bta_titel) {
5279          bta1Headline.textContent = bta_titel;
5280        }
5281        const bta_url = bta1El.getAttribute('data-targeturl');
5282        if (bta1href && bta_url) {
5283          bta1href.href = bta_url;
5284          bta1href.setAttribute('target', '_blank');
5285        }
5286        const bta_text = bta1El.getAttribute('data-text_content');
5287        if (bta1Text) {
5288          bta1Text.textContent = bta_text;
5289        }
5290        insertAdvTag('Anzeige', bta1Tagline);
5291      });
5292
5293    }
5294
5295    if (bta2Els.length > 0) {
5296      const bta2Tagline = document.querySelector('.bta2Tagline');
5297      const bta2Headline = document.querySelector('.bta2Headline');
5298      const bta2href = document.querySelector('.bta2Url');
5299
5300      bta2Els.forEach(bta2El => {
5301        const bta_kicker = bta2El.getAttribute('data-kicker');
5302        if (bta2Tagline && bta_kicker) {
5303          bta2Tagline.textContent = bta_kicker;
5304        }
5305        const bta_titel = bta2El.getAttribute('data-titel');
5306        if (bta2Headline && bta_titel) {
5307          bta2Headline.textContent = bta_titel;
5308        }
5309        const bta_url = bta2El.getAttribute('data-targeturl');
5310        if (bta2href && bta_url) {
5311          bta2href.href = bta_url;
5312        }
5313      });
5314      insertAdvTag('Anzeige', bta2Tagline);
5315    }
5316
5317
5318    if (bta3Els.length > 0) {
5319      const bta3Tagline = document.querySelector('.BTA-Artikeldetail-aSide-1 .Tagline');
5320      const bta3Headline = document.querySelector('.BTA-Artikeldetail-aSide-1 .Headline');
5321      const bta3href = document.querySelector('.BTA-Artikeldetail-aSide-1 .btaAside1Link');
5322
5323      bta3Els.forEach(bta3El => {
5324        const bta_kicker = bta3El.getAttribute('data-kicker');
5325        if (bta3Tagline && bta_kicker) {
5326          bta3Tagline.textContent = bta_kicker;
5327        }
5328        const bta_titel = bta3El.getAttribute('data-titel');
5329        if (bta3Headline && bta_titel) {
5330          bta3Headline.textContent = bta_titel;
5331        }
5332        const bta_url = bta3El.getAttribute('data-targeturl');
5333        if (bta3href && bta_url) {
5334          bta3href.href = bta_url;
5335        }
5336
5337        /* Position bei Änderungen aktualisieren */
5338        addAsideEventListeners();
5339
5340        /* Initiale Positionierung */
5341        document.addEventListener('DOMContentLoaded', positionAsideBta);
5342        btaAsideExists = true;
5343        insertAdvTag('Anzeige', bta3Tagline);
5344
5345      });
5346    } else {
5347      const btaAsideContainer = document.querySelector('.btaAsideContainer');
5348      if (btaAsideContainer && (bta4Els.length < 1) ) {
5349        btaAsideContainer.style.display = 'none';
5350      }
5351    }
5352
5353    if (bta4Els.length > 0) {
5354      const bta4Tagline = document.querySelector('.BTA-Artikeldetail-aSide-2 .Tagline');
5355      const bta4Headline = document.querySelector('.BTA-Artikeldetail-aSide-2 .Headline');
5356      const bta4href = document.querySelector('.BTA-Artikeldetail-aSide-2 .btaAside2Link');
5357
5358      bta4Els.forEach(bta4El => {
5359        const bta_kicker = bta4El.getAttribute('data-kicker');
5360        if (bta4Tagline && bta_kicker) {
5361          bta4Tagline.textContent = bta_kicker;
5362        }
5363        const bta_titel = bta4El.getAttribute('data-titel');
5364        if (bta4Headline && bta_titel) {
5365          bta4Headline.textContent = bta_titel;
5366        }
5367        const bta_url = bta4El.getAttribute('data-targeturl');
5368        if (bta4href && bta_url) {
5369          bta4href.href = bta_url;
5370        }
5371
5372        addAsideEventListeners();
5373
5374        /* Initiale Positionierung */
5375        document.addEventListener('DOMContentLoaded', positionAsideBta);
5376        btaAsideExists = true;
5377        insertAdvTag('Anzeige', bta4Tagline);
5378      });
5379    } else {
5380      const btaAsideContainer = document.querySelector('.btaAsideContainer');
5381      if (btaAsideContainer && (bta3Els.length < 1)) {
5382        btaAsideContainer.style.display = 'none';
5383      }
5384    }
5385
5386    if (bta5Els.length > 0) {
5387      btaStageExists = true;
5388      const bta5Tagline = document.querySelector('.BTA-Artikeldetail-Stage-1 .Tagline');
5389      const bta5Headline = document.querySelector('.BTA-Artikeldetail-Stage-1 .Headline');
5390      const bta5hrefs = document.querySelectorAll('.BTA-Artikeldetail-Stage-1 a.ArticleTeaser_link');
5391      const bta5Text = document.querySelector('.BTA-Artikeldetail-Stage-1 .ArticleTeaser_abstract a.ArticleTeaser_link');
5392
5393      bta5Els.forEach(bta5El => {
5394        const bta_kicker = bta5El.getAttribute('data-kicker');
5395        if (bta5Tagline && bta_kicker) {
5396          bta5Tagline.textContent = bta_kicker;
5397        }
5398        const bta_titel = bta5El.getAttribute('data-titel');
5399        if (bta5Headline && bta_titel) {
5400          bta5Headline.textContent = bta_titel;
5401        }
5402        bta5hrefs.forEach(bta5href => {
5403          const bta_url = bta5El.getAttribute('data-targeturl');
5404          if (bta_url) {
5405            bta5href.href = bta_url;
5406            bta5href.setAttribute('target', '_blank');
5407          }
5408        });
5409        const bta_text = bta5El.getAttribute('data-text_content');
5410        if (bta5Text) {
5411          bta5Text.textContent = bta_text;
5412        }
5413        setBtaFrameHeight(bta5El);
5414        insertAdvTag('Anzeige', bta5Tagline);
5415      });
5416
5417    }
5418
5419    if (bta6Els.length > 0) {
5420      btaStageExists = true;
5421      const bta6Tagline = document.querySelector('.BTA-Artikeldetail-Stage-2 .Tagline');
5422      const bta6Headline = document.querySelector('.BTA-Artikeldetail-Stage-2 .Headline');
5423      const bta6hrefs = document.querySelectorAll('.BTA-Artikeldetail-Stage-2 a.ArticleTeaser_link');
5424      const bta6Text = document.querySelector('.BTA-Artikeldetail-Stage-2 .ArticleTeaser_abstract a.ArticleTeaser_link');
5425
5426      bta6Els.forEach(bta6El => {
5427        const bta_kicker = bta6El.getAttribute('data-kicker');
5428        if (bta6Tagline && bta_kicker) {
5429          bta6Tagline.textContent = bta_kicker;
5430        }
5431        const bta_titel = bta6El.getAttribute('data-titel');
5432        if (bta6Headline && bta_titel) {
5433          bta6Headline.textContent = bta_titel;
5434        }
5435        bta6hrefs.forEach(bta6href => {
5436          const bta_url = bta6El.getAttribute('data-targeturl');
5437          if (bta_url) {
5438            bta6href.href = bta_url;
5439            bta6href.setAttribute('target', '_blank');
5440          }
5441        });
5442        const bta_text = bta6El.getAttribute('data-text_content');
5443        if (bta6Text) {
5444          bta6Text.textContent = bta_text;
5445        }
5446        setBtaFrameHeight(bta6El);
5447        insertAdvTag('Anzeige', bta6Tagline);
5448      });
5449    }
5450
5451    if (bta7Els.length > 0) {
5452      btaStageExists = true;
5453      const bta7Tagline = document.querySelector('.BTA-Artikeldetail-Stage-3 .Tagline');
5454      const bta7Headline = document.querySelector('.BTA-Artikeldetail-Stage-3 .Headline');
5455      const bta7hrefs = document.querySelectorAll('.BTA-Artikeldetail-Stage-3 a.ArticleTeaser_link');
5456      const bta7Text = document.querySelector('.BTA-Artikeldetail-Stage-3 .ArticleTeaser_abstract a.ArticleTeaser_link');
5457
5458      bta7Els.forEach(bta7El => {
5459        const bta_kicker = bta7El.getAttribute('data-kicker');
5460        if (bta7Tagline && bta_kicker) {
5461          bta7Tagline.textContent = bta_kicker;
5462        }
5463        const bta_titel = bta7El.getAttribute('data-titel');
5464        if (bta7Headline && bta_titel) {
5465          bta7Headline.textContent = bta_titel;
5466        }
5467        bta7hrefs.forEach(bta7href => {
5468          const bta_url = bta7El.getAttribute('data-targeturl');
5469          if (bta_url) {
5470            bta7href.href = bta_url;
5471            bta7href.setAttribute('target', '_blank');
5472          }
5473        });
5474        const bta_text = bta7El.getAttribute('data-text_content');
5475        if (bta7Text) {
5476          bta7Text.textContent = bta_text;
5477        }
5478        setBtaFrameHeight(bta7El);
5479        insertAdvTag('Anzeige', bta7Tagline);
5480      });
5481    }
5482
5483    setBtaStageMargin();
5484    eraseEmptyStageArticles();
5485
5486
5487
5488  }); /* end btaTeasering */
5489
5490
5491  function isStageSlotFilled(slotElement) {
5492    if (!slotElement) return false;
5493
5494    // Echte Anzeige vorhanden
5495    const adIframe = slotElement.querySelector('iframe');
5496    if (adIframe) {
5497      return adIframe.offsetHeight > 0 || adIframe.dataset.loadComplete === 'true';
5498    }
5499
5500    // GAM-Container ohne iframe -> nur als gefuellt werten, wenn sichtbar > 0
5501    const gamContainer = slotElement.querySelector('div[id$="__container__"]');
5502    if (gamContainer) {
5503      return gamContainer.offsetHeight > 0;
5504    }
5505
5506    return false;
5507  }
5508
5509
5510  function eraseEmptyStageArticles() {
5511    const btaStageSection = document.querySelector('.StageAdvertNativeTextAds');
5512
5513    if (btaStageSection) {
5514      const stageElements = btaStageSection.querySelectorAll('[id^="renderSlot_BTA-Artikeldetail-Stage-"]');
5515      let hiddenArticles = 0;
5516      stageElements.forEach((element) => {
5517        const isFilled = isStageSlotFilled(element);
5518        if (!isFilled) {
5519          const articleElement = element.closest('article');
5520          if (articleElement) {
5521            articleElement.style.display = 'none';
5522            articleElement.classList.add('noDisplay');
5523            hiddenArticles++;
5524
5525          } else {
5526
5527          }
5528        }
5529      });
5530
5531      if (hiddenArticles === 2) {
5532        layoutSingleArticle();
5533      }
5534
5535    }
5536  }
5537
5538  function layoutSingleArticle() {
5539    window.onload = () => {
5540      console.log('Seite vollständig geladen');
5541
5542      setTimeout(() => {
5543        const singleArticleEl = Array.from(document.querySelectorAll('[class*="BTA-Artikeldetail-Stage-"]')).find(element => {
5544          const style = window.getComputedStyle(element);
5545          return (style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0') &&
5546            !element.classList.contains('noDisplay');
5547        });
5548
5549        if (singleArticleEl) {
5550          const anchorTag = singleArticleEl.querySelector('a.ArticleTeaser_imgWrapper');
5551          if (anchorTag) {
5552            anchorTag.style.float = 'left';
5553            anchorTag.style.marginRight = '1em';
5554          }
5555        } else {
5556          console.log('Kein sichtbares Element gefunden.');
5557        }
5558      }, 150);
5559    };
5560
5561
5562  }
5563
5564  /* in BTA-Bühne Höhe des iFrames an img anpassen */
5565  function setBtaFrameHeight(btaFrame) {
5566    if (btaFrame) {
5567      btaFrame.onload = function() {
5568        const btaFrameDocument = btaFrame.contentDocument || btaFrame.contentWindow.document;
5569        const bannerImage = btaFrameDocument.getElementById('banner_image');
5570        if (bannerImage) {
5571          const bannerHeight = bannerImage.offsetHeight;
5572
5573          requestAnimationFrame(() => {
5574            btaFrame.style.height = bannerHeight + 'px';
5575          });
5576        } else {
5577          console.error('Das <img>-Element mit der ID "banner_image" wurde im btaFrame nicht gefunden.');
5578        }
5579      };
5580    }
5581  }
5582
5583  /*
5584  START
5585  check ob bta-Bühne leer ist, dann nicht anzeigen
5586  */
5587  function waitForLoad() {
5588    return new Promise((resolve) => {
5589      window.onload = resolve;
5590    });
5591  }
5592
5593  function waitForAdditionalTime(ms) {
5594    return new Promise((resolve) => setTimeout(resolve, ms));
5595  }
5596
5597  waitForLoad().then(() => {
5598    return waitForAdditionalTime(1000);
5599  }).then(() => {
5600    const bta5Els = document.querySelector('.btaFrame[data-ad_position="bta5"]');
5601    const bta6Els = document.querySelector('.btaFrame[data-ad_position="bta6"]');
5602    const bta7Els = document.querySelector('.btaFrame[data-ad_position="bta7"]');
5603
5604    if (!bta5Els && !bta6Els && !bta7Els) {
5605      const btaStageSection = document.querySelector('.StageAdvertNativeTextAds');
5606      if (btaStageSection) {
5607        btaStageSection.style.display = 'none';
5608      }
5609    }
5610  });
5611  /*
5612   END
5613   check ob bta-Bühne leer ist, dann nicht anzeigen
5614   */
5615
5616
5617
5618})();
5619
5620
5621/* Event-Listener Adition iframe */
5622if (typeof window.googletag === 'undefined') {
5623  window.googletag = { cmd: [] };
5624}
5625
5626window.addEventListener('message',function(event) {
5627  const origin = window.location.origin;
5628  if(event.origin !== origin) return;
5629
5630  let currentUrl = window.location.href;
5631
5632  let be_domainsInsertAdvTextDiv = [
5633    'iz.de',
5634    'handelextra.pl',
5635    'how-green-works.de',
5636    'foodservice24.pl',
5637    'horizont.net',
5638    'mmponline.pl',
5639    'lebensmittelzeitung.net',
5640    'tw-media.com',
5641    'pebbles.dfv-is.de',
5642    'fibers-in-process.de',
5643    'umweltwirtschaft.com',
5644    'wwt-online.de',
5645    'changement-magazin.de',
5646    'zoe-online.org'
5647  ];
5648
5649  let be_domainsAddSliderControl = ['ahgz.at', 'lebensmittelzeitung.net'];
5650
5651  let be_domainsContainerClass = {
5652    'default': 'PageFrame',
5653    'the-spin-off.com' : 'container',
5654    'horizont.net' : 'SiteHeader',
5655    'dfv-is.de' : 'SiteHeader',
5656    'fibers-in-process.de' : 'SiteHeader',
5657    'umweltwirtschaft.com' : 'SiteHeader',
5658    'wwt-online.de' : 'SiteHeader',
5659    'changement-magazin.de' : 'SiteHeader',
5660    'zoe-online.org' : 'SiteHeader'
5661  };
5662
5663  let be_domainsWideLayout = [
5664    'horizont.net',
5665    'mmponline.pl',
5666    'dfv-is.de',
5667    'fibers-in-process.de',
5668    'umweltwirtschaft.com',
5669    'wwt-online.de',
5670    'changement-magazin.de',
5671    'zoe-online.org'
5672  ];
5673
5674  function be_isDomainInUrl(domainsArray, currentUrl) {
5675    return domainsArray.some(domain => currentUrl.includes(domain));
5676  }
5677
5678  let wideLayout = false;
5679  if (be_isDomainInUrl(be_domainsWideLayout, currentUrl)) {
5680    wideLayout = true;
5681  }
5682
5683  let be_containerClass;
5684  const matchingKey = Object.keys(be_domainsContainerClass).find(key => currentUrl.includes(key));
5685
5686  if (matchingKey) {
5687    be_containerClass = be_domainsContainerClass[matchingKey];
5688  } else {
5689    be_containerClass = be_domainsContainerClass['default'];
5690  }
5691
5692  switch(event.data) {
5693
5694    case 'textAd': $(document).trigger('textAd');
5695      break;
5696    /*
5697     case 'teadsResize':
5698     $(document).trigger('teadsResize');
5699     break;
5700
5701     */
5702    case 'parallax':
5703      if (be_isDomainInUrl(be_domainsInsertAdvTextDiv, currentUrl)) {
5704        $(document).trigger('insertAdvTextDiv');
5705      }
5706      $(document).trigger('parallax');
5707      break;
5708    case 'bannerinit':
5709      //$(document).trigger('resizeIframe');
5710      $(document).trigger('advertOnImage');
5711      $(document).trigger('clsAlignSuperbanner');
5712      $(document).trigger('clsAlignBillboard');
5713      $(document).trigger('BillboardHeight');
5714
5715
5716      if (be_isDomainInUrl(be_domainsAddSliderControl,currentUrl)) {
5717        $(document).trigger('adSliderControl');
5718      }
5719      if (be_isDomainInUrl(be_domainsInsertAdvTextDiv, currentUrl)) {
5720        $(document).trigger('insertAdvTextDiv');
5721      }
5722      break;
5723    case 'singlebanner':
5724      $(document).trigger('clsAlignSuperbanner');
5725      $(document).trigger('clsAlignBillboard');
5726      break;
5727    case 'halfpage':
5728      $(document).trigger('halfpage', [be_containerClass]);
5729      break;
5730    case 'floorAd':
5731      $(document).trigger('floorAd');
5732      //$(document).trigger('resizeIframe');
5733      break;
5734    /*
5735     case 'html5floorAd':
5736     $(document).trigger('html5floorAd');
5737     break;
5738     case 'HTML5sitebar':
5739     $(document).trigger('html5sitebar');
5740     break;
5741     */
5742    case 'layerAd':
5743      $(document).trigger('layerAd');
5744      break;
5745
5746    case 'bridgeAd':
5747      $(document).trigger('alignSkyscraperLeft');
5748      $(document).trigger('alignSkyscraperRight');
5749      $(document).trigger('bridgeAd');
5750      break;
5751    case 'bridgeAdSticky':
5752      $(document).trigger('alignSkyscraperLeft');
5753      $(document).trigger('alignSkyscraperRight');
5754      $(document).trigger('bridgeAdSticky');
5755      $(document).trigger('billboardSticky');
5756      break;
5757
5758    case 'bridgeAdComp':
5759      $(document).trigger('bridgeAdComp');
5760      break;
5761
5762    case 'fullWidthBillboard':
5763      $(document).trigger('fullWidthBillboard');
5764      break;
5765
5766    case 'valueAd':
5767      $(document).trigger('valueAd');
5768      break;
5769    /*
5770     case 'exitintent':
5771     $(document).trigger('exitintent');
5772     break;
5773     case 'background':
5774     $(document).trigger('changeBackgroundColor');
5775     break;
5776     case 'backgroundclick':
5777     $(document).trigger('isBackgroundClick');
5778     break;
5779     case 'counterAd':
5780     $(document).trigger('counterAd');
5781     break;
5782     case 'centerFrame': $(document).trigger('centerIframe');
5783     break;
5784     case 'blockadvertisement':
5785     $(document).trigger('blockadvertisement');
5786     break;
5787     case 'wallpapercolor':
5788     $(document).trigger('wallpapercolor');
5789     break;
5790     */
5791    case 'sitebar':
5792    case 'sitebarHTML5':
5793      $(document).trigger('sitebar', [wideLayout]);
5794      break;
5795    case 'sitebar-switch':
5796      $(document).trigger('sitebar-switch', [be_domainsContainerClass, wideLayout]);
5797      break;
5798    case 'sitebarLeft':
5799      $(document).trigger('sitebarLeft', [wideLayout]);
5800      break;
5801    case 'pushdown':
5802    case 'pushdown2':
5803    case 'pushdown3':
5804    case 'pushdown4':
5805    case 'pushdown5':
5806    case 'pushdown6':
5807    case 'pushdown7':
5808      const elementclass = event.data;
5809      $(document).trigger('pushdown', [elementclass]);
5810      break;
5811    case 'parallax_outstream':
5812      $(document).trigger('parallax_outstream');
5813      break;
5814    case 'dynamic_sitebar':
5815      $(document).trigger('dynamic_sitebar');
5816      break;
5817    case 'billboardSticky':
5818      $(document).trigger('billboardSticky');
5819      break;
5820    case 'dfvSolutionAd':
5821      $(document).trigger('dfvSolutionAd');
5822      break;
5823    case 'welcomeVideo':
5824      $(document).trigger('welcomeAdVideo');  break;
5825    case 'welcomeVideoMobil':
5826      $(document).trigger('welcomeAdVideoMobil');  break;
5827    case 'welcomeImage':
5828      $(document).trigger('welcomeAdImage');  break;
5829    case 'welcomeImageMobil':
5830      $(document).trigger('welcomeAdImageMobil');  break;
5831    case 'understitial':
5832      $(document).trigger('understitial');
5833      break;
5834    case 'bbreminder':
5835      $(document).trigger('bbReminder');
5836      break;
5837    case 'fadeoutadvertisement':
5838      $(document).trigger('fadeoutadvertisement');
5839      break;
5840    default:
5841      return;
5842  }
5843
5844},false);
5845
5846/**
5847 *  billboardHeight
5848 *  billboard pushdown - margin bottom / overflow hidden
5849 */
5850$(document).one('billboardHeight', function() {
5851  const slots = document.querySelectorAll('#renderSlot_Billboard, #renderSlot_Mobil-Billboard');
5852
5853  slots.forEach(slot => {
5854    let banner_div = slot.querySelector('div');
5855    if (banner_div) {
5856      const checkStyleInterval = setInterval(() => {
5857        if (banner_div.getAttribute('style')) {
5858          banner_div.style.marginBottom = '20px';
5859          if (slot.offsetHeight < 290) { /* CLS */
5860            slot.style.marginBottom = '20px';
5861          }
5862          slot.style.overflow = 'hidden';
5863          clearInterval(checkStyleInterval);
5864        }
5865      }, 100);
5866    } else {
5867      const observer = new MutationObserver((mutationsList, observer) => {
5868        mutationsList.forEach(mutation => {
5869          if (mutation.type === 'childList') {
5870            banner_div = slot.querySelector('div');
5871            if (banner_div) {
5872              const checkStyleInterval = setInterval(() => {
5873                if (banner_div.getAttribute('style')) {
5874                  banner_div.style.marginBottom = '20px';
5875                  if (slot.offsetHeight < 290) { /* CLS */
5876                    slot.style.marginBottom = '20px';
5877                  }
5878                  slot.style.overflow = 'hidden';
5879                  clearInterval(checkStyleInterval);
5880                }
5881              }, 100);
5882              observer.disconnect();
5883            }
5884          }
5885        });
5886      });
5887      observer.observe(slot, { childList: true, subtree: true });
5888    }
5889  });
5890});
5891
5892/**
5893 *  billboardSticky
5894 */
5895$(document).on('billboardSticky', function() {
5896  const slot = document.querySelector('#renderSlot_Billboard, #renderSlot_Mobil-Billboard');
5897  if (!slot) return;
5898
5899  const billboardIframe = document.querySelector('.billboardSticky');
5900  const stickyHeader = document.querySelector('.SiteHeaderSticky');
5901
5902  const stickyHeaderHeight = stickyHeader ? stickyHeader.offsetHeight : 0;
5903  const billboardPositionTop = slot.getBoundingClientRect().top + window.scrollY;
5904
5905  const parentMarginTop = billboardIframe ? parseFloat(getComputedStyle(billboardIframe.parentNode).marginTop) : 0;
5906  let billboardStickyOffsetTop = stickyHeaderHeight + 5;
5907  billboardStickyOffsetTop += (Math.sign(parentMarginTop) === -1) ? Math.abs(parentMarginTop) : -Math.abs(parentMarginTop);
5908
5909  // Banner-ID aus iframe.id erzeugen (zwischen erstem und zweitem "/")
5910  const idParts = billboardIframe.id.split('/');
5911  let bId = idParts[1] || 'default';
5912  const lsKey = 'stickyBillboard_' + bId;
5913  let sTimer = null;
5914  let ticking = false;
5915  let animationFrameId = null;
5916
5917  const scrollDuration = 300;
5918
5919  // LocalStorage prüfen
5920  const lsValue = localStorage.getItem(lsKey);
5921  if (lsValue) {
5922    const expireDate = JSON.parse(lsValue).expireAt;
5923    if (expireDate >= Date.now()) return;
5924    else localStorage.removeItem(lsKey);
5925  }
5926
5927  function animateSlot(from, to, duration) {
5928    let startTime = null;
5929    function animate(time) {
5930      if (!startTime) startTime = time;
5931      const progress = Math.min((time - startTime) / duration, 1);
5932      slot.style.top = from + (to - from) * progress + 'px';
5933      if (progress < 1) animationFrameId = requestAnimationFrame(animate);
5934      else animationFrameId = null;
5935    }
5936    animationFrameId = requestAnimationFrame(animate);
5937  }
5938
5939  function handleScroll() {
5940    const scrollTop = window.scrollY;
5941
5942    if (scrollTop > billboardPositionTop) {
5943      if (!slot.classList.contains('isStickyBillboard') && !sTimer && !localStorage.getItem(lsKey)) {
5944        slot.classList.add('isStickyBillboard');
5945        slot.style.position = 'fixed';
5946        slot.style.top = billboardStickyOffsetTop + 'px';
5947        slot.style.zIndex = 999;
5948
5949        sTimer = setTimeout(() => {
5950          animateSlot(billboardStickyOffsetTop, -600, 3000);
5951          sTimer = null;
5952          const expireAt = Date.now() + 60000 * 1440;
5953          localStorage.setItem(lsKey, JSON.stringify({ expireAt }));
5954        }, 2000);
5955      }
5956    } else {
5957      if (sTimer) {
5958        clearTimeout(sTimer);
5959        sTimer = null;
5960      }
5961      if (animationFrameId) {
5962        cancelAnimationFrame(animationFrameId);
5963        animationFrameId = null;
5964      }
5965      const currentTop = parseFloat(getComputedStyle(slot).top) || 0;
5966      animateSlot(currentTop, 0, scrollDuration);
5967      slot.classList.remove('isStickyBillboard');
5968      slot.style.position = '';
5969    }
5970
5971    ticking = false;
5972  }
5973
5974  window.addEventListener('scroll', function() {
5975    if (!ticking) {
5976      window.requestAnimationFrame(handleScroll);
5977      ticking = true;
5978    }
5979  });
5980});
5981
5982
5983
5984/**
5985 *  parallax
5986 */
5987$(document).on("parallax", function(event){
5988  'use strict';
5989  const htmlTag = document.getElementsByTagName('html')[0];
5990  const peephole = $(".parallax").parent().parent();
5991  const parallax_div = $(".parallax").parent();
5992  const parallax_iframe = $(".parallax");
5993
5994  const peephole_width = peephole.width();
5995  const peephole_height = peephole.height();
5996
5997  const bgcolor = parallax_iframe.data("bgcolor");
5998  const parallax_ratio = parallax_iframe.data("height") / parallax_iframe.data("width");
5999
6000  htmlTag.classList.add('Ad_setZindex'); /* Workaround für Safari < v15 */
6001
6002  let viewportHeight = window.innerHeight - $(".SiteHeaderSticky").outerHeight(true);
6003  if (window.innerWidth < 768) {
6004    viewportHeight = window.innerHeight;
6005  }
6006  if (parallax_iframe.data("width") >= parallax_div.width()){
6007    parallax_iframe.height( parallax_div.width() * parallax_ratio);
6008  }
6009
6010  let ad_top = parseInt(viewportHeight - parallax_iframe.height()) / 2;
6011  const parallax_height_diff = Math.abs(viewportHeight - parallax_iframe.height()) * parallax_ratio;
6012  const parallax_width_diff = Math.floor(parallax_height_diff);
6013
6014  if ((parallax_iframe.data("height") >= viewportHeight) || (ad_top < parseInt($(".SiteHeaderSticky").outerHeight(true)))) {
6015    ad_top = $(".SiteHeaderSticky").outerHeight(true) +"px";
6016  }
6017
6018  peephole.height(viewportHeight);
6019  peephole.css("position","relative");
6020  peephole.prepend('<span class=\"Ad_parallax-borderTop\" style=\"width: ' + peephole_width + 'px;\"></span>'); /*Chrome-Render-Fix*/
6021
6022  parallax_div.css('width', peephole_width + 'px');
6023  parallax_div.css("height",viewportHeight);
6024  if (bgcolor) {
6025    parallax_div.css("background-color", bgcolor);
6026  }
6027  parallax_div.addClass('Ad_parallax-innerWrapper');
6028  parallax_div.css('margin', '0 auto');
6029  parallax_iframe.height(viewportHeight);
6030  const parallax_width = parallax_div.height() / parallax_ratio;
6031
6032  if ((peephole_height > viewportHeight) && (window.innerWidth < 768)) {
6033    parallax_iframe.width(parallax_width-parallax_width_diff);
6034  } else {
6035    parallax_iframe.width(parallax_width);
6036  }
6037
6038  if (parallax_width > peephole_width) {
6039    parallax_iframe.width(peephole_width);
6040  }
6041
6042  if (parallax_div.width() - parallax_iframe.width() > 48 ){
6043    parallax_iframe.css("margin-left", ((parallax_div.width() - parallax_iframe.width()) / 2) + "px");
6044  } else {
6045    parallax_iframe.css("margin-left", "0px");
6046  }
6047  parallax_iframe.css("position","fixed");
6048  parallax_iframe.css("bottom",ad_top);
6049  parallax_iframe.css("top",ad_top);
6050
6051});
6052
6053/**
6054 *  textAd
6055 */
6056$(document).one("textAd", function() {
6057  $("iframe.textAd").each(function() {
6058
6059    const $iframe = $(this);
6060
6061    $.each(this.attributes, function() {
6062      if(this.name.startsWith('data-')) {
6063        /* console.log(this.name + ': ' + $iframe.attr(this.name)); */
6064      }
6065    });
6066
6067    // Füge ein leeres DIV direkt unter das nächste Elternelement mit id^="renderSlot_"
6068    const $container = $iframe.closest('[id^="renderSlot_"]');
6069    if ($container.length) {
6070      $('<div class="AnzHelper"></div>').insertBefore($container.children().first());
6071    }
6072
6073    const headline = $iframe.attr("data-headline") || "";
6074    const text = $iframe.attr("data-text") || "";
6075    const imgPos = ($iframe.attr("data-img-pos") || "top").toLowerCase();
6076    const moreButton = $iframe.attr("data-more_button") === "ja";
6077    const buttonText = $iframe.attr("data-button_text") || "Mehr";
6078    const clickUrl = $iframe.attr("data-clickurl") || "#";
6079    const centerAd = $iframe.attr("data-center_ad") === "1";
6080    const marginTop = parseInt($iframe.attr("data-margin-top") || "0", 10);
6081
6082    const $textWrapper = $("<div class=\"ArticleTeaser_content\"><div class='textAd-text-wrapper ArticleTeaser_content'></div></div>")
6083      .css({
6084        "line-height": "1.4em",
6085        "white-space": "normal",
6086        "font-family": "inherit",
6087        "font-size": "16px",
6088        "text-align": centerAd ? "center" : "left",
6089        "margin-top": `${marginTop}px`
6090      })
6091      .html(`
6092        <h2 class="Headline ArticleTeaser_headline TextAdHeadLine">${headline}</h2>
6093        <div class="ArticleTeaser_abstract TextAdContent">${text}</div>
6094      `);
6095
6096    if (moreButton) {
6097      const btn = document.createElement("a");
6098      btn.href = clickUrl;
6099      btn.target = "_blank";
6100      btn.innerHTML  = buttonText;
6101      btn.className = "ReadMore ArticleTeaser_readMore";
6102      btn.setAttribute("data-pw-ev", "arena-more");
6103
6104      //$textWrapper[0].appendChild(btn);
6105      $textWrapper.append(btn);
6106    }
6107
6108    if (imgPos === "left") {
6109      const $parent = $iframe.parent();
6110      $parent.css({
6111        display: "flex",
6112        "align-items": "flex-start",
6113        "gap": "16px"
6114      });
6115
6116      // Responsive Mobile: auf kleinen Bildschirmen Block-Layout
6117      if (window.innerWidth <= 480) {
6118        $parent.css({ display: "block" });
6119      }
6120
6121      $iframe.after($textWrapper);
6122    } else if (imgPos === "right") {
6123      const $parent = $iframe.parent();
6124      $parent.css({
6125        display: "flex",
6126        "align-items": "flex-start",
6127        "gap": "16px"
6128      });
6129      $iframe.before($textWrapper);
6130    } else if (imgPos === "top") {
6131      $iframe.after($textWrapper);
6132    } else if (imgPos === "bottom") {
6133      $iframe.before($textWrapper);
6134    }
6135  });
6136});
6137
6138/**
6139 *  resizeIframe
6140 */
6141
6142const be_onGptSlotRenderEnded = function(event) {
6143  const $slot = $('#' + event.slot.getSlotElementId());
6144  const $iframe = $slot.find('iframe');
6145  if (event.isEmpty || $iframe.length === 0) return;
6146
6147  /** --- Check, wenn iFrame mit data-is-safeframe-Attribut, dann Parent-Element margin-bottom setzen (mit Retry) --- **/
6148  function setSafeFrameMargin($slot, retries = 3, delay = 300) {
6149    const $safeFrame = $slot.find('iframe[data-is-safeframe]');
6150    if ($safeFrame.length > 0) {
6151      $safeFrame.parent().css('margin-bottom', '1rem');
6152    } else if (retries > 0) {
6153      setTimeout(function() {
6154        setSafeFrameMargin($slot, retries - 1, delay);
6155      }, delay);
6156    }
6157  }
6158  setSafeFrameMargin($slot);
6159
6160  /**  --- NEU: FLUID CHECK ---// Prüfen, ob die Größe "fluid" ist. Falls ja, nichts am Iframe schrauben. */
6161  if (event.size === 'fluid' || (Array.isArray(event.size) && event.size[0] === 0)) {     return; }
6162
6163  const w = event.size[0], h = event.size[1], ratio = h / w;
6164  const isFloorAd = $slot.hasClass('Ad-FloorAd') || $slot.closest('.Ad-FloorAd').length > 0;
6165
6166  const adjustAdSize = function () {
6167    const containerWidth = $slot.parent().width() || 0;
6168    const viewportWidth = $(window).width() - 15;
6169    const adPosition = String($iframe.data('ad_position') || '').toLowerCase();
6170    const isBtaStageSlot = ['bta5', 'bta6', 'bta7'].includes(adPosition);
6171
6172    // Nicht-FloorAds nur am Viewport begrenzen, da Parent-Container oft schmaler sind.
6173    const availableSpace = isFloorAd ? Math.min(containerWidth, viewportWidth) : viewportWidth;
6174
6175    if (!isBtaStageSlot) {
6176      const targetWidth = w > availableSpace ? availableSpace : w;
6177      const targetHeight = w > availableSpace ? (availableSpace * ratio) : h;
6178
6179      $iframe.css({
6180        'width': targetWidth + 'px',
6181        'max-width': 'none',
6182        'height': targetHeight + 'px',
6183        'display': 'block'
6184      });
6185    }
6186
6187    // Zentrierung für Bühne (nicht FloorAd)
6188    if (!isFloorAd) {
6189      $iframe.css({'margin-left': 'auto', 'margin-right': 'auto'});
6190    }
6191
6192    function isValidPxValue(val) {
6193      return val && !["0", "NULL", ""].includes(val);
6194    }
6195
6196    const pxLeftValue = $iframe.data('pxleft');
6197    if (isValidPxValue(pxLeftValue)) {
6198      $iframe.css('margin-left', pxLeftValue + 'px');
6199    }
6200
6201    const pxRightValue = $iframe.data('pxright');
6202    if (isValidPxValue(pxRightValue)) {
6203      $iframe.css('margin-right', pxRightValue + 'px');
6204    }
6205
6206  };
6207
6208  const injectStyles = function() {
6209    try {
6210      const doc = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
6211      if (doc && !doc.getElementById('ad-res-style')) {
6212        const style = doc.createElement('style');
6213        style.id = 'ad-res-style';
6214        style.innerHTML = 'img, canvas { max-width: 100% !important; height: auto !important; display: block; margin: 0 auto; } body { margin: 0; padding: 0; }';
6215        doc.head.appendChild(style);
6216      }
6217    } catch (e) {}
6218  };
6219
6220  adjustAdSize();
6221  injectStyles();
6222  $iframe.on('load', injectStyles);
6223  $(window).off('resize.' + event.slot.getSlotElementId()).on('resize.' + event.slot.getSlotElementId(), adjustAdSize);
6224
6225  // Fallback: Auf manchen Seiten wird insertAdvTextDiv zu frueh getriggert.
6226  // Wenn der Billboard-Slot jetzt da ist, aber noch kein Ad_text hat, erneut triggern.
6227  if ($slot.is('#renderSlot_Billboard, #renderSlot_Mobil-Billboard') && $slot.find('.Ad_text').length === 0) {
6228    setTimeout(function() {
6229      $(document).trigger('insertAdvTextDiv');
6230    }, 0);
6231  }
6232
6233  if ($slot.closest('.slick-track').length) { $('.SliderBannerArticleDetail_dots').show(); }
6234};
6235
6236if (window.googletag && typeof window.googletag.pubads === 'function' &&
6237    typeof window.googletag.pubads().addEventListener === 'function') {
6238  window.googletag.pubads().addEventListener('slotRenderEnded', be_onGptSlotRenderEnded);
6239} else if (window.googletag && Array.isArray(window.googletag.cmd)) {
6240  window.googletag.cmd.push(function() {
6241    if (window.googletag && typeof window.googletag.pubads === 'function' &&
6242        typeof window.googletag.pubads().addEventListener === 'function') {
6243      window.googletag.pubads().addEventListener('slotRenderEnded', be_onGptSlotRenderEnded);
6244    }
6245  });
6246}
6247
6248/**
6249 * adSliderControl
6250 */
6251$(document).one("adSliderControl", function(event) {
6252  /**
6253   *  Nur geschaltete Banner in Banner-Slider auf Artikelseite zeigen.
6254   *  Wenn es nur einen geschalteten Banner gibt, dann wird Auto-Slide deaktiviert
6255   *  und zum Slide mit dem Banner gesprungen. Sind beide Banner vorhanden,
6256   *  wird der Auto-Slide des Sliders wieder aktiviert.
6257   *
6258   *  Eine Umsetzung mit sowohl "unslick" als auch "slickRemove" funktionierte nicht,
6259   *  da dann alle Werbemittel nicht mehr sichtbar waren. Auch vornherein den Slider nur
6260   *  anzuwenden, wenn es mehr als einen Banner gibt, hatte nicht funktioniert, da das Banner-JS bereits
6261   *  verarbeitet war.
6262   */
6263  'use strict';
6264  const bannerSlider = '.SliderBannerArticleDetail';
6265  const bannerSliderDots = bannerSlider + '_dots';
6266  const slideSelectors = ['slick-slide00', 'slick-slide01'];
6267  const slideState = [];
6268
6269  $(bannerSliderDots).css('display', 'none');
6270  $(bannerSlider).slick('slickPause');
6271  $(bannerSlider).slick('slickGoTo', 0); /* Slider refreshen, damit Slides aufrufbar sind */
6272
6273  const waitForEl = function (slideSelectors, callback) {
6274    const startTimeInMs = Date.now();
6275
6276    for (let i = 0; i < slideSelectors.length; i++) {
6277      const selectorObj = document.getElementById(slideSelectors[i]);
6278      if (selectorObj && selectorObj.children.length && selectorObj.children[0].tagName === 'DIV') {
6279        slideState[i] = 1;
6280      } else {
6281        slideState[i] = 0;
6282      }
6283    }
6284
6285    if (slideState[0] === 1 && slideState[1] === 0) {
6286      $(bannerSlider).slick('slickGoTo', 0);
6287      callback();
6288      return;
6289    } else if (slideState[0] === 0 && slideState[1] === 1) {
6290      $(bannerSlider).slick('slickGoTo', 1);
6291      callback();
6292      return;
6293    } else if (slideState[0] === 1 && slideState[1] === 1) {
6294      $(bannerSlider).slick('slickPlay');
6295      $(bannerSliderDots + ' li').css('padding-left', '0');
6296      $(bannerSliderDots).css('display', 'block');
6297      callback();
6298      return;
6299    } else {
6300      setTimeout(function () {
6301        if (Date.now() - startTimeInMs > 10000) {
6302          /*Callback spätestens nach 10 Sekunden abbrechen */
6303          return;
6304        }
6305        waitForEl(slideSelectors, callback);
6306      }, 10);
6307    }
6308  };
6309
6310  waitForEl(slideSelectors, function() {});
6311
6312});
6313
6314/**
6315 * halfpage
6316 */
6317$(document).on("halfpage", function(event, be_containerClass){
6318
6319  /*
6320   const $iframes = $("iframe.halfpage");
6321
6322   $iframes.each(function(){
6323   const slot = $(this).parent().parent();
6324   slot.css("width","300px");
6325   });
6326   */
6327
6328  function halfpageResize() {
6329    /* Class-Name für sitebarContainer und .page-footer entsprechend einsetzen */
6330    const halfpageContainer = '.Ad-skyscraper-right';
6331
6332    const stageWidth = $("." + be_containerClass).width();
6333    let halfpageSpace = ($(this).width() - stageWidth) / 2;
6334    halfpageSpace = Math.floor(halfpageSpace) -15;
6335
6336    if ($(halfpageContainer + ' iframe.responsiveFrame').data("width") > halfpageSpace ) {
6337      $(halfpageContainer + ' iframe.responsiveFrame').width(halfpageSpace);
6338    }
6339
6340    const halfpageAd = $('.halfpage').parent().parent();
6341    const halfpage = $('.halfpage');
6342    const halfpage_width = halfpage.data('width');
6343
6344    if (halfpage_width > halfpageSpace ) {
6345      halfpage.width(halfpageSpace);
6346      halfpageAd.css("width",halfpageSpace+"px");
6347      halfpage.css("width",halfpageSpace+"px");
6348
6349      $(document).ready(function(){
6350        const halfpageDOM = halfpage.contents();
6351        halfpageDOM.find("iframe").css("width", halfpageSpace+"px");
6352        const currWinHeight = $(window).height();
6353        halfpageDOM.find("iframe").css("max-height", currWinHeight+"px");
6354      });
6355    }
6356  }
6357
6358  const halfpageAd = $('.halfpage').parent().parent();
6359  const halfpage    = $('.halfpage');
6360
6361  const halfpage_width = halfpage.data('width');
6362  halfpageAd.css("width",halfpage_width+'px');
6363  halfpageAd.css("max-width",halfpage_width+'px');
6364
6365  const halfpage_fixed = halfpage.data('fixed');
6366  if (halfpage_fixed != 'false') {
6367    halfpageAd.css("position","fixed");
6368  }
6369
6370  /* Resize halfpage when the window is resized */
6371  $( window ).resize( function() {
6372    halfpageResize();
6373    /* Resize to fix halfpage on page load. */
6374  }).resize();
6375
6376}
6376);
6377
6378
6379/**
6380 * floorAd
6381 */
6382$(document).on('floorAd', function(event) {
6383  //console.log('[DEBUG] floorAd Event ausgelöst:', event);
6384
6385  const floorAd = $('.floorAd').parent().parent();
6386  const floorAdIframe = $('.floorAd');
6387  const floorAdIframeContent = $('.floorAd').contents();
6388  const scroll_pos = floorAdIframe.data('display-at-pixel');
6389  const display_on_scroll = floorAdIframe.data('display-on-scroll');
6390  let isHidden = false;
6391
6392  /*
6393   console.log('[DEBUG] floorAd Variablen:', {
6394   floorAd,
6395   floorAdIframe,
6396   floorAdIframeContent,
6397   scroll_pos,
6398   display_on_scroll,
6399   center_ad,
6400   });
6401   */
6402
6403  floorAd.css('z-index', floorAdIframe.data('zindex'));
6404  if (display_on_scroll === "1" || display_on_scroll === 1 || display_on_scroll === true) {
6405    //console.log('[DEBUG] floorAd wird nur beim Scrollen angezeigt.');
6406    floorAd.css('display', 'none');
6407  }
6408
6409  floorAd.css('position', 'fixed');
6410  floorAd.css('bottom', '0');
6411  //floorAd.css('min-height', '90px'); // Fallback-Mindesthöhe
6412
6413  // Dynamische Höhe anhand des Bildes im iFrame setzen
6414  function setFloorAdHeightFromImage() {
6415    try {
6416      var iframe = floorAdIframe.get(0);
6417      if (!iframe || !iframe.contentWindow || !iframe.contentDocument) return;
6418      var doc = iframe.contentDocument || iframe.contentWindow.document;
6419      var img = doc.querySelector('img');
6420      if (img && img.complete) {
6421        var imgHeight = img.naturalHeight || img.height;
6422        if (imgHeight > 0) {
6423          floorAd.height(imgHeight);
6424          floorAdIframe.height(imgHeight);
6425        }
6426      } else if (img) {
6427        img.addEventListener('load', function() {
6428          var imgHeight = img.naturalHeight || img.height;
6429          if (imgHeight > 0) {
6430            floorAd.height(imgHeight);
6431            floorAdIframe.height(imgHeight);
6432          }
6433        });
6434      }
6435    } catch (e) {
6436      // Cross-Origin: keine Aktion möglich
6437    }
6438  }
6439
6440  // Nach dem Laden des iFrames prüfen
6441  floorAdIframe.on('load', function() {
6442    setFloorAdHeightFromImage();
6443  });
6444  // Falls das iFrame schon geladen ist
6445  setFloorAdHeightFromImage();
6446
6447  $(window).on('resize', function() {
6448    $('#renderSlot_Layer-Ad, #renderSlot_Layer-Ad > div, #renderSlot_Layer-Ad iframe').css({
6449      width: '100%',
6450      minWidth: 0,
6451      maxWidth: '100vw',
6452      boxSizing: 'border-box'
6453    });
6454  }).trigger('resize');
6455
6456  if (display_on_scroll == 1 || display_on_scroll === true) {
6457    window.onscroll = function() {
6458      if (window && !isHidden) {
6459        var currentScroll = window.pageYOffset !== undefined ? window.pageYOffset : document.documentElement.scrollTop;
6460        if (currentScroll > scroll_pos) {
6461          $(floorAd).fadeIn("slow");
6462        } else if (currentScroll < scroll_pos) {
6463          $(floorAd).fadeOut("slow");
6464        }
6465      }
6466    };
6467  }
6468
6469  floorAdIframeContent.find('.CloseAd').click(function() {
6470    $(floorAd).fadeOut('slow');
6471    isHidden = true;
6472  });
6473
6474});
6475
6476
6477/**
6478 * layerAd
6479 */
6480$(document).on('layerAd', function(event) {
6481  const layerAd = $('.layerAd').parent().parent();
6482  const layerAdWrapper = $('.layerAd').parent();
6483  const layerAdIframe = $('.layerAd');
6484  const ad_close_time = layerAdIframe.data('ad-close-time');
6485
6486  const bg_color = layerAdIframe.data('bgcolor');
6487  const bg_opacity = layerAdIframe.data('bgopacity');
6488
6489  const align_banner = layerAdIframe.data('align');
6490  const vertical_px_offset = layerAdIframe.data('vertical-px-offset');
6491  const vertical_pos = layerAdIframe.data('vertical-pos');
6492  const horizontal_px_offset = layerAdIframe.data('horizontal-px-offset');
6493  const horizontal_pos = layerAdIframe.data('horizontal-pos');
6494
6495  function convertHex(hex,opacity){
6496    hex = hex.replace('#','');
6497    r = parseInt(hex.substring(0,2), 16);
6498    g = parseInt(hex.substring(2,4), 16);
6499    b = parseInt(hex.substring(4,6), 16);
6500
6501    return 'rgba(' + r + ',' + g + ',' + b + ',' + opacity / 100 + ')';
6502  }
6503
6504  const bgColor_rgb = convertHex(bg_color, bg_opacity);
6505
6506  layerAd.css('width', '100%');
6507  layerAd.css('height', '100%');
6508  layerAd.css('background', bgColor_rgb);
6509  layerAd.css('position', 'fixed');
6510  layerAd.css('top', '0');
6511  layerAd.css('left', '0');
6512  layerAd.css('z-index', '12000');
6513
6514  layerAd.css('display', 'flex');
6515  layerAd.css('display', '-webkit-box');
6516  layerAd.css('display', '-webkit-flex');
6517  layerAd.css('display', '-ms-flexbox');
6518
6519  layerAd.css('-webkit-box-align', 'center');
6520  layerAd.css('-webkit-align-items', 'center');
6521  layerAd.css('-ms-flex-align', 'center');
6522  layerAd.css('align-items', 'center');
6523
6524  layerAd.css('-webkit-box-pack', 'center');
6525  layerAd.css('-webkit-justify-content', 'center');
6526  layerAd.css('-ms-flex-pack', 'center');
6527  layerAd.css('justify-content', 'center');
6528
6529
6530  layerAd.css('z-index', '12000');
6531
6532  layerAdWrapper.css('position', 'absolute');
6533  layerAdWrapper.prepend("<div class='layer_close' style='z-index: 13000; position:absolute; color: #ffffff; top:0; right:0;'><i title =\"schließen\" class=\"fa fa-close fa-2x\"></i></div>");
6534
6535  layerAdWrapper.css('margin', 'auto');
6536
6537  if (align_banner == 1) {
6538    if (vertical_pos == 'bottom') {
6539      layerAdWrapper.css('margin-bottom', vertical_px_offset+'px');
6540    } else {
6541      layerAdWrapper.css('margin-top', vertical_px_offset+'px');
6542    }
6543    if (horizontal_pos == 'left') {
6544      layerAdWrapper.css('margin-left', horizontal_px_offset+'px');
6545    } else {
6546      layerAdWrapper.css('margin-right', horizontal_px_offset+'px');
6547    }
6548  }
6549
6550  function showLayerAd() {
6551    layerAd.show();
6552  }
6553
6554  function closeLayerAd() {
6555    layerAd.hide();
6556  }
6557
6558  if (ad_close_time > 0){
6559    setTimeout(function(){closeLayerAd();}, ad_close_time*1000);
6560  }
6561
6562  $( ".layer_close" ).click(function() {
6563    layerAd.hide();
6564  });
6565});
6566
6567/**
6568 * exitintent
6569 */
6570$(document).one("exitintent", function(event){
6571  $( "html" ).one( "mouseleave", function() {
6572    $("#LayerModal").addClass("show");
6573  });
6574});
6575
6576/**
6577 * changeBackgroundColor
6578 */
6579$(document).on('changeBackgroundColor',function(event){
6580  const iframe = $('.fireplace'),
6581    bg_color = iframe.data('bgcolor');
6582  $(".Body").css('background-color', bg_color);
6583});
6584
6585/**
6586 * isBackgroundClick
6587 * On Background click go to clickurl
6588 */
6589$(document).on('isBackgroundClick',function(event){
6590
6591  $("#usercentrics-root").click(function(event ) {
6592    event.stopPropagation();
6593  });
6594
6595  $(".PageFrame").click(function(event ) {
6596    event.stopPropagation();
6597  });
6598
6599  $("#uc-center-container").click(function(event ) {
6600    event.stopPropagation();
6601  });
6602
6603  $(".Body").click(function() {
6604    const iframe = $('.bgclickplace');
6605    const clickurl = iframe.data('clickurl');
6606    window.open(clickurl, '_blank');
6607  });
6608});
6609
6610/**
6611 * counterAd
6612 */
6613$(document).one('counterAd', function(event) {
6614  const counterAd = $('.counterAd').parent().parent();
6615  const counterAdIframe = $('.counterAd');
6616
6617  const pl_id = counterAdIframe.data('contentunit');
6618  const clickurl = counterAdIframe.data('clickurl');
6619  const enddatum = counterAdIframe.data('enddatum');
6620  const counterimage = counterAdIframe.data('counterimage');
6621  const layout = counterAdIframe.data('layout');
6622
6623  let countertext = '';
6624
6625  countertext = countertext + '<div id=\"'+pl_id+'\" class="noanzeige" width=\"300\" height=\"300\">\n';
6626  countertext = countertext + '	<div>\n' ;
6627  countertext = countertext + '		<a target=\"_blank\" href=\"'+clickurl+'\">\n';
6628  if(typeof layout !== 'undefined' && layout === 'image') {
6629    countertext = countertext + '			<img src=\"' + counterimage + '\" title=\"\" alt=\"\" border=\"0\" width=\"300\" height=\"150\"/>\n';
6630  }
6631  countertext = countertext + '		</a>\n';
6632  countertext = countertext + '		<div class=\"banner_counter\" border=\"0\" width=\"300\" height=\"150\" style=\"max-width: 300px !important;\"> 	\n';
6633  countertext = countertext + '			<span id=\"clockline\"></span>\n';
6634  countertext = countertext + '				<div id=\"banner_counter\"></div>\n';
6635  countertext = countertext + '			<div  id=\"name_time_block\">\n';
6636  countertext = countertext + '				<span class=\"name_time\">Tage</span>\n';
6637  countertext = countertext + '				<span class=\"name_time\">Stunden</span>\n';
6638  countertext = countertext + '				<span class=\"name_time\">Minuten</span>\n';
6639  countertext = countertext + '			</div>\n';
6640  countertext = countertext + '		</div>	  \n';
6641  countertext = countertext + '	 \n';
6642  countertext = countertext + '	</div>\n';
6643  countertext = countertext + '\n';
6644  countertext = countertext + '</div>\n';
6645  counterAd.append(countertext);
6646  if(typeof layout !== 'undefined' && layout === 'image'){
6647    counterAdIframe.css("display","none");
6648  }
6649  counterAd.css('margin-top', '10px');
6650  $('.noanzeige').not(':first').remove();
6651  if(typeof jQuery == "function"){
6652    $(function() {
6653      $(document).trigger( "counter", enddatum);
6654    });
6655  }
6656
6657  $( counterAd ).closest('div').next().find('.line').removeClass("line");
6658});
6659
6660/**
6661 * counter
6662 */
6663$(document).on("counter", function(event, endtime){
6664
6665  /* Datum mit Punkt */
6666  let iso_end_date;
6667  if (endtime.match(/\./) ) {
6668    let iso_end_dateArr = endtime.split(".");
6669
6670    /* Umwandlung in Iso-Format */
6671    if (iso_end_dateArr[2] < 100) iso_end_dateArr[2] = "20" + iso_end_dateArr[2];
6672    iso_end_date = iso_end_dateArr[2] + "-" + iso_end_dateArr[0] + "-" +iso_end_dateArr[1];
6673
6674    /* Datum im Iso-Format, z.B. 2020-11-09 */
6675  } else {
6676    iso_end_date = endtime;
6677  }
6678
6679  const end = new Date(iso_end_date);
6680
6681  const _second = 1000;
6682  const _minute = _second * 60;
6683  const _hour = _minute * 60;
6684  const _day = _hour * 24;
6685  let timer;
6686
6687  function showRemaining() {
6688    const now = new Date();
6689    now.setHours(now.getHours() +1);
6690
6691    const distance = end - now;
6692    if (distance < 0) {
6693
6694      clearInterval(timer);
6695      document.getElementById('banner_counter').innerHTML = '<span class="time">0</span> ';
6696      document.getElementById('banner_counter').innerHTML += '<span class="time">0</span> ';
6697      document.getElementById('banner_counter').innerHTML += '<span class="time">0</span> ';
6698      return;
6699    }
6700    const days = Math.floor(distance / _day);
6701    const hours = Math.floor((distance % _day) / _hour);
6702    const minutes = Math.floor((distance % _hour) / _minute);
6703
6704    document.getElementById('banner_counter').innerHTML = '<span class="time">' + days + '</span> ';
6705    document.getElementById('banner_counter').innerHTML += '<span class="time">' + hours + '</span> ';
6706    document.getElementById('banner_counter').innerHTML += '<span class="time">' + minutes + '</span> ';
6707
6708  }
6709  timer = setInterval(showRemaining, 1000);
6710
6711});
6712
6713/**
6714 * centerIframe
6715 */
6716$(document).on('centerIframe', function(event){
6717  const iframe = $('.centeredFrame'),
6718    container = iframe.parent();
6719
6720  container.css('display', 'flex');
6721  container.css('flex-flow','column');
6722  iframe.css('align-self','center');
6723});
6724
6725/**
6726 * blockadvertisement
6727 */
6728$(document).on("blockadvertisement", function(event){
6729
6730  const iframe = $('.blockadvertisement');
6731  let container = iframe.parent();
6732  container.css("display","none");
6733});
6734
6735/**
6736 * wallpapercolor
6737 * Einfärben des body für Wallpaper
6738 */
6739$(document).on("wallpapercolor", function(event){
6740
6741  const iframe = $('.wallpaper_banner');
6742  const wallpapercolor = iframe.data("wallpapercolor");
6743  $('body').css("background-color",wallpapercolor);
6744
6745});
6746
6747/**
6748 * advertOnImage
6749 */
6750$(document).one("advertOnImage", function(event){
6751  const slot = $('[id^="renderSlot_Rectangle-Online-Specials"]');
6752  if (slot.hasClass("Ad-mediumRectangleStageTeaserAdvert")) {
6753    if (slot.children('div').length > 0) {
6754      slot.parent().css('padding', '5px');
6755      slot.parent().css('background-color', '#fff');
6756    }
6757
6758  }
6759
6760});
6761
6762/**
6763 * be_sitebarResize
6764 */
6765function be_sitebarResize(wideLayout, sitebarBid) {
6766  const browser_scrollbar_width = 0;
6767  let offsetLeft = 460;
6768  let outerWidth = 980;
6769  const sitebarContainer = '.Ad-skyscraper-right';
6770  if (($('.SiteFooter').length) && (!wideLayout)) {
6771    offsetLeft = $('.SiteFooter').offset().left + browser_scrollbar_width;
6772    outerWidth = $('.SiteFooter').outerWidth();
6773  } else if (($('.PageGallery').length) && (!wideLayout)) {
6774    offsetLeft = $('.PageGallery').offset().left + browser_scrollbar_width;
6775    outerWidth = $('.PageGallery').outerWidth();
6776  }
6777  if (wideLayout === true) {
6778    let siteHeader = document.querySelector('.SiteHeader') || document.querySelector('.SiteHeaderSticky_firstLine-inner');
6779    if (siteHeader) {
6780      let rect = siteHeader.getBoundingClientRect();
6781      offsetLeft = rect.left + browser_scrollbar_width;
6782
6783      let siteHeaderStyles = window.getComputedStyle(siteHeader);
6784      outerWidth = parseFloat(siteHeaderStyles.getPropertyValue('width'));
6785    }
6786  }
6787
6788  let rightOffset = $(this).width() - (offsetLeft + outerWidth);
6789  rightOffset = Math.floor(rightOffset);
6790
6791  if ($(sitebarContainer + ' iframe.responsiveFrame').data("width") > rightOffset ) {
6792    $(sitebarContainer + ' iframe.responsiveFrame').width(rightOffset);
6793  }
6794
6795  const iframeEl = document.querySelector('iframe.sitebar');
6796  let iFrameElDocument = iframeEl.contentDocument || iframeEl.contentWindow.document;
6797  let imgSitebar = iFrameElDocument.getElementById("sitebar"+sitebarBid);
6798  let imgSky = iFrameElDocument.getElementById("sky"+sitebarBid);
6799  const offsetLowLmt = 135;
6800  const offsetUpLmt = 215;
6801
6802  if (imgSky && imgSitebar) {
6803    if ((offsetLeft >= offsetLowLmt) && (offsetLeft < offsetUpLmt)) {
6804      imgSitebar.style.display = "none";
6805      imgSky.style.display = "inline";
6806    } else if (offsetLeft >= offsetUpLmt) {
6807      imgSitebar.style.display = "inline";
6808      imgSky.style.display = "none";
6809    }
6810    else if (offsetLeft < offsetLowLmt) {
6811      imgSitebar.style.display = "none";
6812      imgSky.style.display = "none";
6813    }
6814  }
6815
6816
6817  const sitebarAd = $('.sitebar').parent().parent();
6818  const sitebar = $('.sitebar');
6819  const sitebar_width = sitebar.data('width');
6820
6821
6822  if (sitebar_width > rightOffset ) {
6823    sitebar.width(rightOffset);
6824    sitebarAd.css("width",rightOffset+"px");
6825    sitebar.css("width",rightOffset+"px");
6826
6827    $(document).ready(function(){
6828      const sitebarDOM = sitebar.contents();
6829      sitebarDOM.find("iframe").css("width", rightOffset+"px");
6830      const currWinHeight = $(window).height();
6831      sitebarDOM.find("iframe").css("max-height", currWinHeight+"px");
6832    });
6833  }
6834}
6835
6836/**
6837 * sitebar
6838 */
6839$(document).on('sitebar',function(event, wideLayout) {
6840  const sitebarAd = $('.sitebar').parent().parent();
6841  const sitebar = $('.sitebar');
6842  const sitebarBid = sitebar[0].getAttribute("data-bid");
6843  const sbAdMarginTop = sitebar[0].getAttribute("data-margintop");
6844  if (sbAdMarginTop !== "0" && sbAdMarginTop !== "NULL") {
6845    sitebarAd.css("margin-top",sbAdMarginTop+'px');
6846  }
6847
6848  if ( sitebar.data('bgcolor') ) {
6849    const bg_color = sitebar.data('bgcolor');
6850    if (bg_color.startsWith("#")) {
6851      document.getElementsByTagName('body')[0].style.backgroundColor = bg_color;
6852    }
6853  }
6854
6855  const sitebar_width = sitebar.data('width');
6856  sitebarAd.css("width",sitebar_width+'px');
6857  sitebarAd.css("max-width",sitebar_width+'px');
6858  sitebar.css("max-height",'100vh');
6859
6860  const sitebar_fixed = sitebar.data('fixed');
6861  if (sitebar_fixed != 'false') {
6862    sitebarAd.css("position","fixed");
6863  }
6864
6865  /* Resize sitebar when the window is resized */
6866  $( window ).resize( function() {
6867    be_sitebarResize(wideLayout, sitebarBid);
6868    /* Resize to fix sitebar on page load. */
6869  }).resize();
6870
6871}
6871);
6872
6873/**
6874 * be_sitebarLeftResize
6875 */
6876function be_sitebarLeftResize(wideLayout, sitebarBid) {
6877  const browser_scrollbar_width = 15;
6878  let offsetLeft = 460;
6879  let outerWidth = 980;
6880  const sitebarLeftContainer = '.Ad-skyscraper-left';
6881  if (($('.SiteFooter').length) && (!wideLayout)) {
6882    offsetLeft = $('.SiteFooter').offset().left + browser_scrollbar_width;
6883    outerWidth = $('.SiteFooter').outerWidth();
6884  } else if (($('.PageGallery').length) && (!wideLayout)) {
6885    offsetLeft = $('.PageGallery').offset().left + browser_scrollbar_width;
6886    outerWidth = $('.PageGallery').outerWidth();
6887  }
6888  if (wideLayout === true) {
6889    let siteHeader = document.querySelector('.SiteHeader') || document.querySelector('.SiteHeaderSticky_firstLine-inner');
6890    if (siteHeader) {
6891      let rect = siteHeader.getBoundingClientRect();
6892      offsetLeft = rect.left + browser_scrollbar_width;
6893
6894      let siteHeaderStyles = window.getComputedStyle(siteHeader);
6895      outerWidth = parseFloat(siteHeaderStyles.getPropertyValue('width'));
6896    }
6897  }
6898
6899  let leftOffset = offsetLeft;
6900  leftOffset = Math.round(leftOffset);
6901
6902  if ($(sitebarLeftContainer + ' iframe.responsiveFrame').data("width") > leftOffset ) {
6903    $(sitebarLeftContainer + ' iframe.responsiveFrame').width(leftOffset);
6904  }
6905
6906  const iframeElLeft = document.querySelector('iframe.sitebarLeft');
6907  let iFrameElLeftDocument = iframeElLeft.contentDocument || iframeElLeft.contentWindow.document;
6908  let imgSitebar = iFrameElLeftDocument.getElementById("sitebar"+sitebarBid);
6909  let imgSky = iFrameElLeftDocument.getElementById("sky"+sitebarBid);
6910  const offsetLowLmt = 140;
6911  const offsetUpLmt = 320;
6912
6913  if (imgSky && imgSitebar) {
6914    if ((offsetLeft >= offsetLowLmt) && (offsetLeft < offsetUpLmt)) {
6915      imgSitebar.style.display = "none";
6916      imgSky.style.display = "inline";
6917    } else if (offsetLeft >= offsetUpLmt) {
6918      imgSitebar.style.display = "inline";
6919      imgSky.style.display = "none";
6920    }
6921    else if (offsetLeft < offsetLowLmt) {
6922      imgSitebar.style.display = "none";
6923      imgSky.style.display = "none";
6924    }
6925  }
6926
6927
6928  const sitebarAd = $('.sitebarLeft').parent().parent();
6929  const sitebar = $('.sitebarLeft');
6930  const sitebar_width = sitebar.data('width');
6931  const hideWidth = (sitebar.data('hidewidth') !== undefined ? sitebar.data('hidewidth') : 0) + 15;
6932
6933  if (leftOffset <= hideWidth) {
6934    sitebarAd.css('display', 'none');
6935    return;
6936  } else {
6937    sitebarAd.css('display', 'block');
6938  }
6939
6940
6941  let sidebarLeftMargin = Math.round(leftOffset);
6942  sitebarAd.css("margin-left","0px");
6943  let currSitebar_width = sitebarAd[0].offsetWidth;
6944
6945  if (sitebar_width >= leftOffset ) {
6946    leftOffset = leftOffset-browser_scrollbar_width;
6947
6948    sitebar.width(leftOffset);
6949    sitebarAd.css("width",leftOffset+"px");
6950    sitebar.css("width",leftOffset+"px");
6951
6952    $(document).ready(function(){
6953      const sitebarDOM = sitebar.contents();
6954      sitebarDOM.find("iframe").css("width", leftOffset+"px");
6955      const currWinHeight = $(window).height();
6956      sitebarDOM.find("iframe").css("max-height", currWinHeight+"px");
6957    });
6958  } else if (sitebar_width < leftOffset) {
6959    let sbMarginLeft = leftOffset - browser_scrollbar_width - sitebar_width;
6960
6961    sitebarAd.css("width",sitebar_width+"px");
6962    sitebar.css("width",sitebar_width+"px");
6963    sitebarAd.css("margin-left",sbMarginLeft+"px");
6964  }
6965}
6966
6967/**
6968 * sitebarLeft
6969 */
6970$(document).on('sitebarLeft',function(event, wideLayout) {
6971  const sitebarLeftAd = $('.sitebarLeft').parent().parent();
6972  const sitebarLeft = $('.sitebarLeft');
6973  const sitebarLeftBid = sitebarLeft[0].getAttribute("data-bid");
6974  const leftSitebarSlot = document.getElementById("renderSlot_Skyscraper-links");
6975  leftSitebarSlot.classList.add("leftSitebarSlot");
6976
6977  const sitebarLeft_width = sitebarLeft.data('width');
6978  sitebarLeftAd.css("width",sitebarLeft_width+'px');
6979  sitebarLeftAd.css("max-width",sitebarLeft_width+'px');
6980
6981  const sitebarLeft_fixed = sitebarLeft.data('fixed');
6982  if (sitebarLeft_fixed != 'false') {
6983    sitebarLeftAd.css("position","fixed");
6984  }
6985
6986  const sbAdLeftMarginTop = sitebarLeft[0].getAttribute("data-margintop");
6987  if (sbAdLeftMarginTop !== "0" && sbAdLeftMarginTop !== "NULL") {
6988    sitebarLeftAd.css("margin-top",sbAdLeftMarginTop+'px');
6989  }
6990
6991  /* Resize sitebarLeft when the window is resized */
6992  $( window ).resize( function() {
6993    be_sitebarLeftResize(wideLayout, sitebarLeftBid);
6994    /* Resize to fix sitebar on page load. */
6995  }).resize();
6996
6997  window.addEventListener('load', function() {
6998    be_sitebarLeftResize(wideLayout, sitebarLeftBid);
6999  });
7000
7001  window.onload = function() {
7002    be_sitebarLeftResize(wideLayout, sitebarLeftBid);
7003  };
7004
7005
7006});
7007
7008/**
7009 * teadsResize
7010 * teads Videos
7011 */
7012$(document).on('teadsResize',function(event){
7013  const iframe = $('.video_ad'),
7014    aspect_ratio = 1.7,
7015    wrapper = iframe.parent();
7016
7017  iframe.height(iframe.width()/aspect_ratio);
7018
7019  wrapper.css('display', 'flex');
7020  wrapper.css('flex-flow','column');
7021  iframe.css('align-self','center');
7022});
7023
7024/**
7025 * pushdown
7026 */
7027$(document).on("pushdown", function(event, elementclass){
7028
7029  const pushdown_iframe = $("." + elementclass);
7030  const pushdown_container = pushdown_iframe.parent();
7031
7032  const ad_height = pushdown_iframe.data("height");
7033  const ad_width = pushdown_iframe.data("width");
7034  const ad_margin_bottom = parseInt(pushdown_container.css("height")) - ad_height;
7035  const pushdownheight = pushdown_iframe.data("pushdownheight") + ad_margin_bottom;
7036  const pushdowntime = pushdown_iframe.data("pushdowntime"); /* Dauer der Animation */
7037  const closingtime = pushdown_iframe.data("closingtime") * 1000;   /* Initiales Einfahren */
7038  const pushdown_center_ad = pushdown_iframe.data("center_ad");
7039  const pushdown_func = pushdown_iframe.data("pushdown-func") ? 1 : 0;
7040  const no_initialpushdown = pushdown_iframe.data("no_initialpushdown") ? 1 : 0;
7041
7042  /* Werbemittel zentrieren */
7043  if(pushdown_center_ad == 1){
7044    pushdown_container.css("text-align","center");
7045  }
7046
7047  if(pushdown_func == 0){
7048
7049    /* prevent too large iFrame-height on smaller stage */
7050    let pushdown_iframeWidth = pushdown_iframe[0].clientWidth;
7051    let pushdownRatio = ad_height / ad_width;
7052    let pushdownHeight = Math.ceil(pushdown_iframeWidth * pushdownRatio);
7053    pushdown_iframe.css("height",pushdownHeight + "px");
7054
7055    return;
7056  }
7057
7058  /* Nutzer-Handling */
7059  pushdown_iframe.on("mouseover", function(event){
7060    clearTimeout(waiting_for_closing);
7061    $(document).trigger('pushdown-animation', [pushdown_container, pushdown_iframe, '1', pushdownheight]);
7062
7063    pushdown_iframe.one("mouseout", function(event){
7064      $(document).trigger('pushdown-animation', [pushdown_container, pushdown_iframe, '1', ad_height]);
7065    });
7066  });
7067
7068  /* Initiales Ausfahren */
7069  if(no_initialpushdown != 1) {
7070    $(document).trigger('pushdown-animation', [pushdown_container, pushdown_iframe, pushdowntime, pushdownheight]);
7071  }
7072
7073  /* Einfahren nach initialem Ausfahren */
7074  let waiting_for_closing = window.setTimeout(function(){
7075    $(document).trigger('pushdown-animation', [pushdown_container, pushdown_iframe, pushdowntime, ad_height]);
7076  }, closingtime);
7077
7078});
7079
7080/**
7081 * pushdown-animation
7082 */
7083$(document).on("pushdown-animation", function(event, pushdown_container, pushdown_iframe, movingtime, newheight){
7084
7085  pushdown_container.css({
7086    height           : newheight,
7087    WebkitTransition : 'height ' + movingtime + 's ease-in-out',
7088    MozTransition    : 'height ' + movingtime + 's ease-in-out',
7089    MsTransition     : 'height ' + movingtime + 's ease-in-out',
7090    OTransition      : 'height ' + movingtime + 's ease-in-out',
7091    transition       : 'height ' + movingtime + 's ease-in-out'
7092  });
7093  pushdown_iframe.css({
7094    height           : newheight,
7095    WebkitTransition : 'height ' + movingtime + 's ease-in-out',
7096    MozTransition    : 'height ' + movingtime + 's ease-in-out',
7097    MsTransition     : 'height ' + movingtime + 's ease-in-out',
7098    OTransition      : 'height ' + movingtime + 's ease-in-out',
7099    transition       : 'height ' + movingtime + 's ease-in-out'
7100  });
7101});
7102
7103/**
7104 * parallax_outstream
7105 */
7106$(document).on("parallax_outstream", function(event){
7107  const iframe = $('.parallax_outstream');
7108  const container = iframe.parent();
7109  container.attr("id","parallax_outstream");
7110  iframe.css("height","0px");
7111  iframe.css("width","0px");
7112});
7113
7114/**
7115 * dynamic_sitebar
7116 */
7117$(document).on("dynamic_sitebar", function(event){
7118  const iframe = $('.dynamic_sitebar');
7119  const container = iframe.parent();
7120  const dynamic_space = ($('.PageFrame').outerWidth(true) - $('.PageFrame').outerWidth()) / 2;
7121  container.css("width", dynamic_space +"px");
7122  container.css("position","fixed");
7123});
7124
7125/**
7126 * insertAdvTextDiv
7127 *
7128 * "Anzeige"-Position und Border an Werbemittelgroesse positionieren/anpassen
7129 */
7130$(document).on("insertAdvTextDiv", function(event) {
7131  const $iframes = $('[id^="renderSlot_"] iframe');
7132  let el = $('<div class="Ad_text"></div>');
7133
7134  $iframes.each(function () {
7135    if ($(this).data("width") == '1') {
7136      $(this).parent('div').css('height', '0');
7137      return;
7138    }
7139
7140    const slot = $(this).parent().parent();
7141    if ($(this).parent().parent().length) {
7142      if (slot.attr('id').match(/renderSlot_(Super*|Sky*|Rectangle-Gal|Mobil-Rectangle-Gal)/)) {
7143        return;
7144      }
7145    } else {
7146      return;
7147    }
7148    if (slot.parent().length && slot.parent().hasClass() ){
7149      if(slot.parent().attr('class').match(/slick-track/)){
7150        /* SliderBannerArticleDetail_dots nur einblenden, wenn auch was geschaltet ist */
7151        $('.SliderBannerArticleDetail_dots').css('display', 'block');
7152      }
7153    }
7154
7155    let ad_text_div = $(this).parent().find('.Ad_text');
7156    let ad_text_parallax_div = $(this).parent().parent().find('.Ad_text');
7157
7158    ad_text_div.css('margin', '');
7159    if ($(this).hasClass('parallax')) {
7160
7161      if(!ad_text_parallax_div.length > 0){
7162        $(this).parent().parent('div').prepend(el);
7163        ad_text_parallax_div = $(this).parent().parent().find('.Ad_text');
7164      }
7165      ad_text_parallax_div.css("margin", "0 auto");
7166      ad_text_parallax_div.css("width", '100%');
7167      if ($(this).data("ad_text_bgc")) {
7168        ad_text_parallax_div.css("background-color", $(this).data("ad_text_bgc"));
7169      }
7170      if ($(this).data("ad_text_margintop")) {
7171        ad_text_parallax_div.css("margin-top", $(this).data("ad_text_margintop"));
7172      }
7173      if ($(this).data("ad_text_maxheight")) {
7174        ad_text_parallax_div.css("max-height", $(this).data("ad_text_maxheight"));
7175      }
7176      if ($(this).data("ad_text_noborder")) {
7177        ad_text_parallax_div.addClass('html5BannerBefore');
7178      }
7179      ad_text_parallax_div.css("z-index", '10');
7180    } else {
7181      if (!ad_text_div.length > 0) {
7182        $(this).parent('div').prepend(el);
7183        ad_text_div = $(this).parent().find('.Ad_text');
7184      }
7185      if (slot.attr('id').match(/renderSlot_(Rectangle-Aufmacher)/)) {
7186        ad_text_div.css("width", '100%');
7187      } else {
7188        const dataWidthRaw = $(this).data('width');
7189        const dataWidth = (dataWidthRaw !== undefined && dataWidthRaw !== null) ? String(dataWidthRaw).trim() : '';
7190        const widthAttr = parseInt($(this).attr('width'), 10) || 0;
7191        const cssWidth = parseInt($(this).css('width'), 10) || 0;
7192        const effectiveWidth = (dataWidth && dataWidth !== 'NULL' && dataWidth !== '0') ? dataWidth : (widthAttr || cssWidth || 0);
7193
7194        ad_text_div.css('width', /^\d+$/.test(String(effectiveWidth)) ? (effectiveWidth + 'px') : effectiveWidth);
7195        ad_text_div.css("margin", "0 auto");
7196      }
7197
7198    }
7199
7200    if (/[^-]?width\s?:\s?100%/.test($(this).attr('style'))) {
7201      ad_text_div.css("margin", "0 auto");
7202    }
7203    el = el.clone();
7204  });
7205});
7206
7207/**
7208 * fadeoutadvertisement
7209 * Hierüber kann eine Platzierung animiert ausgeblendet werden
7210 */
7211$(document).on("fadeoutadvertisement", function(event){
7212
7213  const iframe = $('.fadeoutadvertisement');
7214  let container = iframe.parent();
7215  container.animate({
7216    height: "0px"
7217  }, 2000, function() {
7218    container.css("display","none");
7219  });
7220
7221});
7222
7223/**
7224 * be_reduceBackgroundOpacity
7225 * @param element
7226 * @param opacity
7227 */
7228function be_reduceBackgroundOpacity(element, opacity) {
7229  let backgroundColor = element.style.backgroundColor;
7230  if (backgroundColor.substring(0, 4) === "rgba") {
7231    /* if rgba format is already used, just update the alpha value */
7232    backgroundColor = backgroundColor.replace(/[^,]+(?=\))/, opacity);
7233  } else {
7234    /* convert hexadecimal or RGB format to rgba format and add alpha value */
7235    let r = 0, g = 0, b = 0;
7236    if (backgroundColor.substring(0, 1) === "#") {
7237      /* convert hexadecimal to RGB */
7238      const hex = backgroundColor.substring(1);
7239      r = parseInt(hex.substring(0, 2), 16);
7240      g = parseInt(hex.substring(2, 4), 16);
7241      b = parseInt(hex.substring(4, 6), 16);
7242    } else if (backgroundColor.substring(0, 3) === "rgb") {
7243      /* extract RGB values from comma-separated string */
7244      const values = backgroundColor.match(/\d+/g);
7245      r = parseInt(values[0]);
7246      g = parseInt(values[1]);
7247      b = parseInt(values[2]);
7248    }
7249    /* convert RGB to rgba */
7250    backgroundColor = "rgba(" + r + ", " + g + ", " + b + ", " + opacity + ")";
7251  }
7252  element.style.backgroundColor = backgroundColor;
7253}
7254
7255/**
7256 * be_changeBGColor
7257 * @param element
7258 * @param color1
7259 * @param color2
7260 * @param mixVal
7261 */
7262function be_changeBGColor(element, color1, color2, mixVal) {
7263  const hexToRgb = function (hex) {
7264    const r = parseInt(hex.slice(1, 3), 16);
7265    const g = parseInt(hex.slice(3, 5), 16);
7266    const b = parseInt(hex.slice(5, 7), 16);
7267
7268    return [r, g, b];
7269  };
7270
7271  const rgbToHex = function (rgb) {
7272    const componentToHex = function (component) {
7273      const hex = component.toString();
7274      return hex.length == 1 ? "0" + hex : hex;
7275    };
7276
7277    const r = componentToHex(rgb[0]);
7278    const g = componentToHex(rgb[1]);
7279    const b = componentToHex(rgb[2]);
7280
7281    return "#" + r + g + b;
7282  };
7283
7284  const color1Rgb = hexToRgb(color1);
7285  const color2Rgb = hexToRgb(color2);
7286
7287  const r = Math.round((1 - mixVal) * color1Rgb[0] + mixVal * color2Rgb[0]);
7288  const g = Math.round((1 - mixVal) * color1Rgb[1] + mixVal * color2Rgb[1]);
7289  const b = Math.round((1 - mixVal) * color1Rgb[2] + mixVal * color2Rgb[2]);
7290
7291  element.style.backgroundColor = rgbToHex([r, g, b]);
7292}
7293
7294/**
7295 * be_rgbToHex
7296 * @param rgb
7297 * @returns {string}
7298 */
7299function be_rgbToHex(rgb) {
7300  /* Liefert nur die Ziffern 0-9 und a-f */
7301  function hex(x) {
7302    return ("0" + parseInt(x).toString(16)).slice(-2);
7303  }
7304
7305  /* Konvertiere den RGB-String in eine Array */
7306  const rgbArray = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
7307  /* Wandle die RGB-Werte in Hexadezimalwerte um */
7308  return "#" + hex(rgbArray[1]) + hex(rgbArray[2]) + hex(rgbArray[3]);
7309}
7310
7311/**
7312 * welcomeAdVideo
7313 * WelcomeAd mit Video-URL, wird beim Scrollen ausgeblendet, hat Close-Button
7314 */
7315$(document).on('welcomeAdVideo', function(event) {
7316
7317  let welcomeAdIframe = $('.welcomeFrame');
7318  let wcVideoSrc = welcomeAdIframe.data('videosrc');
7319  let wcVideoCodecs = welcomeAdIframe.data('videocodecs');
7320  let wcBgColor = welcomeAdIframe.data('bgcolor');
7321  let wcClickUrl = welcomeAdIframe.data('clickurl');
7322  let wcStageMarginTop = welcomeAdIframe.data('stagemargintop');
7323  let wcMuteButton = welcomeAdIframe.data('mutebutton');
7324  let bodyEl = document.getElementsByTagName("BODY")[0];
7325  let superbannerAd = document.getElementById('renderSlot_Superbanner');
7326  let defaultBgColor = window.getComputedStyle(document.body).getPropertyValue('background-color');
7327  defaultBgColor = be_rgbToHex(defaultBgColor);
7328  if(wcBgColor != 'default') {
7329    bodyEl.style.backgroundColor = wcBgColor;
7330  }
7331  let bgEl = document.createElement("div");
7332  const stageEl = document.querySelector('.PageFrame');
7333  bgEl.classList.add("wcVideo");
7334  let videoEl = document.createElement("video");
7335  videoEl.setAttribute("preload", "auto");
7336  videoEl.setAttribute("loop", "");
7337  //videoEl.setAttribute("autoplay", "");
7338  videoEl.setAttribute("muted", "");
7339  videoEl.classList.add("wcVideoTag");
7340
7341  let wcCloseButton = document.createElement("button");
7342  let closeBtnTxt = welcomeAdIframe.data('closebtntxt');
7343  let wcCloseButtonText = closeBtnTxt != 'default' ? closeBtnTxt : 'schließen';
7344  wcCloseButton.classList.add("wcCloseButton");
7345  wcCloseButton.prepend(wcCloseButtonText);
7346
7347  let playBtnTxt = welcomeAdIframe.data('playbtntxt');
7348  let pauseBtnTxt = welcomeAdIframe.data('pausebtntxt');
7349
7350  bgEl.prepend(videoEl);
7351  bodyEl.prepend(wcCloseButton);
7352
7353  if (playBtnTxt != 'default') {
7354    let wcPlayButton = document.createElement("button");
7355    let wcPlayButtonText = welcomeAdIframe.data('playbtntxt');
7356    let wcPauseButtonText = welcomeAdIframe.data('pausebtntxt');
7357    wcPlayButton.classList.add("wcPlayButton");
7358    wcPlayButton.prepend(wcPlayButtonText);
7359    bodyEl.prepend(wcPlayButton);
7360  }
7361
7362  if (wcMuteButton) {
7363    let wcMuteButtonEl = document.createElement("button");
7364    wcMuteButtonEl.classList.add("wcMuteButton");
7365    let wcMuteButtonElText = "<i class='fa fa-volume-off fa-2x'> </i>";
7366    wcMuteButtonEl.innerHTML = wcMuteButtonElText;
7367    bodyEl.prepend(wcMuteButtonEl);
7368
7369  }
7370
7371  let sourceEl = document.createElement("source");
7372  sourceEl.setAttribute("src", wcVideoSrc);
7373  sourceEl.setAttribute("type", "video/mp4");
7374  sourceEl.setAttribute("codecs", wcVideoCodecs);
7375
7376  videoEl.prepend(sourceEl);
7377  bodyEl.prepend(bgEl);
7378
7379  function playWcVideo() {
7380    videoEl.play();
7381  }
7382
7383  function pauseWcVideo() {
7384    videoEl.pause();
7385  }
7386
7387  function toggleWcVideo() {
7388    if(wcVideo.paused){
7389      wcVideo.play();
7390      if (wcPlayButton) {
7391        wcPlayButton.className = "wcPauseButton";
7392        if (playBtnTxt != 'default') {
7393          let wcPauseButtonText = welcomeAdIframe.data('pausebtntxt');
7394          wcPlayButton.innerText = wcPauseButtonText;
7395        }
7396
7397      }
7398    }else{
7399      wcVideo.pause();
7400      if (wcPlayButton) {
7401        wcPlayButton.className = "wcPlayButton";
7402        if (playBtnTxt != 'default') {
7403          let wcPlayButtonText = welcomeAdIframe.data('playbtntxt');
7404          wcPlayButton.innerText = wcPlayButtonText;
7405        }
7406      }
7407    }
7408
7409    /*
7410     if(wcVideo.muted){
7411     wcVideo.muted = false;
7412     }else{
7413     wcVideo.muted = true;
7414     }
7415     */
7416  }
7417
7418  function toggleMuteButton() {
7419    if (wcVideo.muted) {
7420      wcVideo.muted = false;
7421      wcMuteButtonEl.classList.add("wcMuteOn");
7422      wcMuteButtonEl.classList.remove("wcMuteOff");
7423      wcMuteButtonEl.innerHTML = "<i class='fa fa-volume-up fa-2x'> </i>";
7424    } else {
7425      wcVideo.muted = true;
7426      wcMuteButtonEl.classList.add("wcMuteOff");
7427      wcMuteButtonEl.classList.remove("wcMuteOn");
7428      wcMuteButtonEl.innerHTML = "<i class='fa fa-volume-off fa-2x'> </i>";
7429    }
7430  }
7431
7432  let wcVideo = document.getElementsByClassName("wcVideoTag")[0];
7433  wcVideo.addEventListener("click", toggleWcVideo);
7434  wcVideo.muted = true;
7435  wcVideo.autoplay = true;
7436
7437
7438  let wcPlayButton = document.querySelector(".wcPlayButton");
7439  wcPlayButton.innerText = pauseBtnTxt;
7440
7441  if (wcPlayButton) {
7442    wcPlayButton.addEventListener("click", toggleWcVideo);
7443  }
7444
7445  let wcPauseButton = document.querySelector(".wcPauseButton");
7446  if (wcPauseButton) {
7447    wcPauseButton.addEventListener("click", toggleWcVideo);
7448  }
7449
7450  let wcMuteButtonEl = document.querySelector(".wcMuteButton");
7451  if (wcMuteButtonEl) {
7452    wcMuteButtonEl.addEventListener("click", toggleMuteButton);
7453  }
7454
7455  /* clickable background -> */
7456  const wcMouseOverHandler = function (event) {
7457    if (event.target === document.body) {
7458      document.body.style.cursor = 'pointer';
7459    }
7460  };
7461  document.addEventListener('mouseover', wcMouseOverHandler);
7462
7463  const wcMouseOutHandler = function (event) {
7464    if (event.target === document.body) {
7465      document.body.style.cursor = 'auto';
7466    }
7467  };
7468  document.addEventListener('mouseout', wcMouseOutHandler);
7469
7470  const clickHandler = function (event) {
7471    if (event.target === document.body) {
7472      window.open(wcClickUrl, '_blank');
7473    }
7474  };
7475  document.addEventListener('click', clickHandler);
7476  /* <- clickable background */
7477
7478  function fadeOutOnScroll(element, stageEl) {
7479    if (!element || !stageEl) {
7480      return;
7481    }
7482
7483    let distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
7484    const elementHeight = element.offsetHeight;
7485    const scrollTop = document.documentElement.scrollTop;
7486
7487    let opacity = 1;
7488    distanceToTop = 0;
7489    element.style.position = 'fixed';
7490
7491    if (scrollTop > distanceToTop) {
7492      opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
7493      opacity = (opacity < 0) ? 0 : opacity;
7494      opacity = (opacity > 0.95) ? 1 : opacity;
7495    }
7496
7497    if (opacity >= 0) {
7498      element.style.opacity = opacity;
7499      /* be_reduceBackgroundOpacity(superbannerAd, opacity); */
7500      if(wcBgColor != 'default') {
7501        be_changeBGColor(bodyEl, defaultBgColor, wcBgColor, opacity);
7502      }
7503    }
7504  }
7505
7506  function scrollHandler() {
7507    fadeOutOnScroll(wcVideo, bgEl);
7508  }
7509
7510  window.addEventListener('scroll', scrollHandler, {passive: true});
7511
7512  /**
7513   * Close Button
7514   */
7515  function closeWcVideo() {
7516    wcVideo.remove();
7517    bodyEl.style.backgroundColor = defaultBgColor;
7518    superbannerAd.firstElementChild.remove();
7519    wcCloseButton.remove();
7520    if (wcPlayButton) {
7521      wcPlayButton.remove();
7522    }
7523    if (wcMuteButtonEl) {
7524      wcMuteButtonEl.remove();
7525    }
7526    window.removeEventListener('scroll', scrollHandler, {passive: true});
7527    document.removeEventListener('click', clickHandler);
7528    document.removeEventListener('mouseover', wcMouseOverHandler);
7529    document.removeEventListener('mouseout', wcMouseOutHandler);
7530    stageEl.style.transition = 'margin 1s';
7531    stageEl.style.marginTop = '0px';
7532  }
7533
7534  wcCloseButton.addEventListener("click", closeWcVideo);
7535
7536  /* wait until bg-video is available */
7537  let wcInterval = setInterval(function() {
7538    document.getElementById("renderSlot_Superbanner").style.height = "0";
7539    if (videoEl) {
7540      clearInterval(wcInterval);
7541      let OriginalStageMarginTop = wcStageMarginTop;
7542      let videoElStyle = getComputedStyle(videoEl);
7543      let videoElHeight = parseInt(videoElStyle.height);
7544      let videoElOrigHeight = videoEl.naturalHeight;
7545      videoElOrigHeight = videoElOrigHeight || welcomeAdIframe.data('height');
7546      if (videoElHeight > videoElOrigHeight) {
7547
7548        videoElHeight = videoElOrigHeight;
7549      }
7550
7551      let videoElRatio = (videoElHeight / videoElOrigHeight).toFixed(2);
7552      let StageMarginTop = Math.round(OriginalStageMarginTop * videoElRatio);
7553
7554      stageEl.style.marginTop = StageMarginTop+'px';
7555    }
7556    clearInterval(wcInterval);
7557  }, 200);
7558
7559});
7560
7561/**
7562 * welcomeAdImage
7563 * WelcomeAd mit Hintergrund-Image, wird beim Scrollen ausgeblendet, hat Close-Button
7564 */
7565$(document).on('welcomeAdImage', function(event) {
7566
7567  let welcomeAd = $('.welcomeFrame').parent().parent();
7568  let welcomeAdIframe = $('.welcomeFrame');
7569  let wcBgColor = welcomeAdIframe.data('bgcolor');
7570  let wcClickUrl = welcomeAdIframe.data('clickurl');
7571  let bodyEl = document.getElementsByTagName("BODY")[0];
7572  let superbannerAd = document.getElementById('renderSlot_Superbanner');
7573  let defaultBgColor = window.getComputedStyle(document.body).getPropertyValue('background-color');
7574  defaultBgColor = be_rgbToHex(defaultBgColor);
7575
7576  if(wcBgColor != 'default') {
7577    bodyEl.style.backgroundColor = wcBgColor;
7578  }
7579  let bgEl = document.createElement("div");
7580  const stageEl = document.querySelector('.PageFrame');
7581
7582  bgEl.classList.add("wcBgImage");
7583  let imgEl = document.createElement("img");
7584  imgEl.classList.add("wcBgImageTag");
7585
7586  let wcCloseButton = document.createElement("button");
7587  let closeBtnTxt = welcomeAdIframe.data('closebtntxt');
7588  let wcCloseButtonText = closeBtnTxt != 'default' ? closeBtnTxt : 'schließen';
7589
7590  wcCloseButton.classList.add("wcCloseButton");
7591  wcCloseButton.prepend(wcCloseButtonText);
7592
7593  bgEl.prepend(imgEl);
7594  bodyEl.prepend(wcCloseButton);
7595
7596  let bgImgSource = welcomeAdIframe.data('bgimagesrc');
7597
7598  imgEl.setAttribute('src',bgImgSource);
7599  bodyEl.prepend(bgEl);
7600
7601  /* clickable background -> */
7602  const wcMouseOverHandler = function (event) {
7603    if (event.target === document.body) {
7604      document.body.style.cursor = 'pointer';
7605    }
7606  };
7607  document.addEventListener('mouseover', wcMouseOverHandler);
7608
7609  const wcMouseOutHandler = function (event) {
7610    if (event.target === document.body) {
7611      document.body.style.cursor = 'auto';
7612    }
7613  };
7614  document.addEventListener('mouseout', wcMouseOutHandler);
7615
7616  const clickHandler = function (event) {
7617    if (event.target === document.body) {
7618      window.open(wcClickUrl, '_blank');
7619    }
7620  };
7621  document.addEventListener('click', clickHandler);
7622  /* <- clickable background */
7623
7624  /* Superbanner in Hintergrund und sticky -> */
7625  superbannerAd.classList.add("wcfixedSuperbanner");
7626  const stageElStyles = window.getComputedStyle(stageEl);
7627  const stageElMarginTop = stageElStyles.getPropertyValue('margin-top');
7628  stageEl.style.marginTop = superbannerAd.offsetHeight+'px';
7629  /*
7630   * Calculation of the distance from the stage to the top of the screen
7631   * in a fixed ratio of 1080 (width of background image) to 520 (original distance from stage to top of screen)
7632   */
7633  let wcInterval2 = setInterval(function() {
7634
7635    if (imgEl) {
7636      clearInterval(wcInterval2);
7637
7638      let imgElStyle = getComputedStyle(imgEl);
7639      let imgElCurrHeight = parseInt(imgElStyle.height);
7640
7641      let imgHeight = 520;
7642      let imgElOrigHeight = 1080;
7643      let imgElRatio = (imgHeight / imgElOrigHeight).toFixed(2);
7644      let StageMarginTop = Math.round(imgElCurrHeight * imgElRatio);
7645
7646      stageEl.style.marginTop = StageMarginTop+'px';
7647    }
7648    clearInterval(wcInterval2);
7649  }, 200);
7650
7651
7652  /* <- Superbanner in Hintergrund und sticky */
7653
7654  /* clickable superbanner -> */
7655
7656  superbannerAd.addEventListener('mouseover', function() {
7657    superbannerAd.style.cursor = 'pointer';
7658  });
7659
7660  superbannerAd.addEventListener('mouseout', function() {
7661    superbannerAd.style.cursor = 'auto';
7662  });
7663
7664  superbannerAd.addEventListener('click', function() {
7665    window.open(wcClickUrl, '_blank');
7666  });
7667  /* <- clickable superbanner */
7668
7669  function fadeOutOnScroll(element, stageEl) {
7670    if (!element || !stageEl) {
7671      return;
7672    }
7673
7674    let distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
7675    const elementHeight = element.offsetHeight;
7676    const scrollTop = document.documentElement.scrollTop;
7677
7678    let opacity = 1;
7679    distanceToTop = 0;
7680    element.style.position = 'fixed';
7681
7682    if (scrollTop > distanceToTop) {
7683      opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
7684      opacity = (opacity < 0) ? 0 : opacity;
7685      opacity = (opacity > 0.95) ? 1 : opacity;
7686    }
7687
7688    if (opacity >= 0) {
7689      element.style.opacity = opacity;
7690      /* be_reduceBackgroundOpacity(superbannerAd, opacity); */
7691      if(wcBgColor != 'default') {
7692        be_changeBGColor(bodyEl, defaultBgColor, wcBgColor, opacity);
7693      }
7694    }
7695  }
7696
7697  function scrollHandler() {
7698    fadeOutOnScroll(bgEl, stageEl);
7699  }
7700
7701  window.addEventListener('scroll', scrollHandler, {passive: true});
7702
7703  /*
7704   * Close Button
7705   */
7706  function closewcBgImage() {
7707    bgEl.remove();
7708    bodyEl.style.backgroundColor = defaultBgColor;
7709    superbannerAd.firstElementChild.remove();
7710    wcCloseButton.remove();
7711    window.removeEventListener('scroll', scrollHandler, {passive: true});
7712    document.removeEventListener('click', clickHandler);
7713    document.removeEventListener('mouseover', wcMouseOverHandler);
7714    document.removeEventListener('mouseout', wcMouseOutHandler);
7715    stageEl.style.transition = "margin-top 0.5s ease";
7716    stageEl.style.marginTop = stageElMarginTop;
7717  }
7718
7719  wcCloseButton.addEventListener("click", closewcBgImage);
7720
7721});
7722
7723/**
7724 * welcomeAdVideoMobil
7725 * WelcomeAd mit Video-URL für Mobil, hat Close-Button
7726 */
7727$(document).on('welcomeAdVideoMobil', function(event) {
7728
7729  let welcomeAdIframe = document.getElementById('welcomeFrameMobil');
7730
7731  let bodyEl = document.getElementsByTagName("BODY")[0];
7732  let superbannerAd = document.getElementById('renderSlot_Mobil-Superbanner');
7733
7734  let wcCloseButton = document.createElement("button");
7735  let closeBtnTxt = welcomeAdIframe.getAttribute('data-closebtntxt');
7736  let wcCloseButtonText = closeBtnTxt != 'default' ? closeBtnTxt : 'schließen';
7737  wcCloseButton.classList.add("wcCloseButtonMobil");
7738  wcCloseButton.prepend(wcCloseButtonText);
7739
7740  bodyEl.prepend(wcCloseButton);
7741
7742  let adHeight = superbannerAd.clientHeight;
7743
7744  welcomeAdIframe.style.position = "fixed";
7745  welcomeAdIframe.style.zIndex = "-1";
7746  superbannerAd.style.height = adHeight+"px";
7747
7748  wcCloseButton.style.top = adHeight-35+"px";
7749
7750
7751  /*
7752   * Create Video Tag
7753   */
7754  let bgEl = document.createElement("div");
7755  bgEl.classList.add("wcVideo");
7756  bgEl.classList.add("wcMobil");
7757
7758  let videoEl = document.createElement("video");
7759  videoEl.setAttribute("preload", "auto");
7760  videoEl.setAttribute("loop", "");
7761  videoEl.setAttribute("muted", "");
7762  videoEl.setAttribute("id", "wcVideoTag");
7763  videoEl.classList.add("wcVideoTag");
7764
7765  let wcVideoSrc = welcomeAdIframe.getAttribute('data-videosrc');
7766  let wcVideoCodecs = welcomeAdIframe.getAttribute('data-videocodecs');
7767  let sourceEl = document.createElement("source");
7768  sourceEl.setAttribute("src", wcVideoSrc);
7769  sourceEl.setAttribute("type", "video/mp4");
7770  sourceEl.setAttribute("codecs", wcVideoCodecs);
7771
7772  videoEl.prepend(sourceEl);
7773  bgEl.prepend(videoEl);
7774  bodyEl.prepend(bgEl);
7775
7776
7777
7778  /*
7779   * Close Button
7780   */
7781  function closeWcVideo() {
7782    superbannerAd.remove();
7783    wcCloseButton.remove();
7784    wcPlayButton.remove();
7785  }
7786
7787  wcCloseButton.addEventListener("click", closeWcVideo);
7788
7789
7790  /*
7791   * Play/Stop Button
7792   */
7793  let wcPlayBtnTxt = welcomeAdIframe.getAttribute('data-playbtntxt');
7794  let wcPauseBtnTxt = welcomeAdIframe.getAttribute('data-pausebtntxt');
7795
7796  let wcPlayButton = document.createElement("button");
7797  wcPlayButton.classList.add("wcPlayButtonMobil");
7798  wcPlayButton.prepend(wcPlayBtnTxt);
7799  bodyEl.prepend(wcPlayButton);
7800
7801  wcPlayButton.style.top = adHeight-35+"px";
7802
7803  wcPlayButton.addEventListener("click", toggleWcVideo);
7804
7805  let wcVideo = document.getElementById('wcVideo');
7806  wcVideo = videoEl;
7807
7808  function toggleWcVideo() {
7809    if(wcVideo.paused){
7810      wcVideo.play();
7811      if (wcPlayButton) {
7812        wcPlayButton.className = "wcPauseButtonMobil";
7813        if (wcPlayBtnTxt != 'default') {
7814          wcPlayButton.innerText = wcPauseBtnTxt;
7815        }
7816
7817      }
7818    }else{
7819      wcVideo.pause();
7820      if (wcPlayButton) {
7821        wcPlayButton.className = "wcPlayButtonMobil";
7822        if (wcPlayBtnTxt != 'default') {
7823          wcPlayButton.innerText = wcPlayBtnTxt;
7824        }
7825      }
7826    }
7827
7828    /*
7829     if(wcVideo.muted){
7830     wcVideo.muted = false;
7831     }else{
7832     wcVideo.muted = true;
7833     }
7834     */
7835  }
7836
7837});
7838
7839
7840/**
7841 * alignSkyscraperLeft
7842 */
7843$(document).one("alignSkyscraperLeft", function(event){
7844  if ($("#renderSlot_Skyscraper-links > div > iframe").length){
7845    let leftSkyEl = document.getElementById("renderSlot_Skyscraper-links");
7846
7847
7848    if($("#renderSlot_Skyscraper-links > div > iframe").length){
7849
7850      let elementSkyLeft = document.querySelector('.Ad-skyscraper-left');
7851      if(!elementSkyLeft) return;
7852      let style             = window.getComputedStyle(elementSkyLeft);
7853      let marginLeftSkyLeft = parseFloat(style.getPropertyValue('margin-left'));
7854
7855      const bannerFrame     = $("#renderSlot_Skyscraper-links > div > iframe");
7856      let bannerFrameWidth  = bannerFrame.data("width");
7857      let bannerFrameHeight = bannerFrame.data('height');
7858      let bannerFrameZIndex = bannerFrame.data('z-index');
7859
7860      if(bannerFrameWidth){
7861        let offset = bannerFrameWidth - Math.abs(marginLeftSkyLeft);
7862        offset     = Math.abs(offset);
7863        if(offset <= 20){ /* wenn versucht wurde durch css Abstand zur Bühne herzustellen */
7864          bannerFrameWidth = bannerFrameWidth + offset;
7865        }
7866        $("#renderSlot_Skyscraper-links").css("margin-left", "-" + bannerFrameWidth + "px");
7867        $("#renderSlot_Skyscraper-links").css("width", bannerFrameWidth + "px");
7868        $("#renderSlot_Skyscraper-links > div > iframe").css("height", bannerFrameHeight + "px");
7869      }
7870      if(bannerFrameZIndex){
7871        $('#renderSlot_Skyscraper-links').css('z-index', bannerFrameZIndex);
7872      }
7873    }
7874  }
7875
7876});
7877
7878/**
7879 * alignSkyscraperRight
7880 * Positioniert den rechten Skyscraper so, dass sein linker Rand am rechten Rand der Bühne (.PageFrame) anliegt.
7881 * Sitebar wird ausgeschlossen
7882 */
7883$(document).one("alignSkyscraperRight", function(event){
7884  var selector = "#renderSlot_Skyscraper-rechts iframe";
7885  var maxTries = 10;
7886  var tryCount = 0;
7887  function tryAlign() {
7888    var bannerFrame = $(selector);
7889    //console.log('[DEBUG] Versuch', tryCount+1, 'Gefundene iFrames:', bannerFrame.length, bannerFrame);
7890    if (bannerFrame.length) {
7891
7892      var bannerFrameWidth = bannerFrame.data("width");
7893      var marginTop = bannerFrame.data("margin-top");
7894      var marginBottom = bannerFrame.data("margin-bottom");
7895      var marginLeft = bannerFrame.data("margin-left");
7896      var marginRight = bannerFrame.data("margin-right");
7897      //console.log('[DEBUG] data-width:', bannerFrameWidth, 'marginTop:', marginTop, 'marginBottom:', marginBottom, 'marginLeft:', marginLeft, 'marginRight:', marginRight);
7898      var $pageFrame = $('.PageFrame');
7899      if (bannerFrameWidth && $pageFrame.length) {
7900        var pageFrameRight = $pageFrame.offset().left + $pageFrame.outerWidth();
7901        var $skyContainer = $("#renderSlot_Skyscraper-rechts");
7902        // Position berechnen: linker Rand des Skyscrapers = rechter Rand der Bühne
7903        var newLeft = pageFrameRight;
7904        var cssProps = {
7905          position: 'absolute',
7906          left: newLeft + 'px',
7907          width: bannerFrameWidth + 'px',
7908          'margin-left': 0
7909        };
7910        // Margin-Attribute aus dem Template
7911        if (typeof marginTop !== 'undefined' && marginTop !== null && marginTop !== '' && marginTop !== '0') {
7912          cssProps['margin-top'] = marginTop + 'px';
7913        }
7914        if (typeof marginBottom !== 'undefined' && marginBottom !== null && marginBottom !== '' && marginBottom !== '0') {
7915          cssProps['margin-bottom'] = marginBottom + 'px';
7916        }
7917        if (typeof marginLeft !== 'undefined' && marginLeft !== null && marginLeft !== '' && marginLeft !== '0') {
7918          cssProps['margin-left'] = marginLeft + 'px';
7919        }
7920        if (typeof marginRight !== 'undefined' && marginRight !== null && marginRight !== '' && marginRight !== '0') {
7921          cssProps['margin-right'] = marginRight + 'px';
7922        }
7923        $skyContainer.css(cssProps);
7924        console.log('[DEBUG] Skyscraper rechts positioniert:', cssProps);
7925      } else {
7926        //console.warn('[DEBUG] Kein data-width oder keine .PageFrame gefunden!');
7927      }
7928    } else if (++tryCount < maxTries) {
7929      setTimeout(tryAlign, 100);
7930    } else {
7931      //console.warn('[DEBUG] Kein iFrame gefunden für Selector nach', maxTries, 'Versuchen:', selector);
7932    }
7933  }
7934  tryAlign();
7935});
7936
7937/**
7938 * bridgeAd
7939 */
7940$(document).on("bridgeAd", function(event){
7941  const bA_iframe = document.querySelector('.bridgeAdFrame');
7942  const bA_renderSlot = document.querySelector('.Ad-billboard');
7943  bA_renderSlot.classList.add('bridgeAdSlot');
7944});
7945
7946/**
7947 * bridgeAdSticky
7948 */
7949$(document).on("bridgeAdSticky", function(event){
7950  const bA_iframe = document.querySelector('.bridgeAdFrame');
7951  const bA_renderSlot = document.querySelector('.Ad-billboard');
7952  bA_renderSlot.classList.add('bridgeAdSlot');
7953  bA_iframe.classList.add('billboardSticky');
7954});
7955
7956/**
7957 * Rechts-Ausrichtung
7958 * wird inbridgeAdComp aufgerufen, nachdem Skyscraper iFrame mit Grafik gefüllt wurde
7959 */
7960$(document).on("alignSkyscraperRightBridgeAd", function(event) {
7961  var selector = ".Ad-skyscraper-right iframe.CompFrame";
7962  var maxTries = 15;
7963  var tryCount = 0;
7964
7965  function tryAlign() {
7966    var $bannerFrame = $(selector).first();
7967    var $billboard = $('#renderSlot_Billboard');
7968
7969    if ($bannerFrame.length && $billboard.length) {
7970      var bannerFrameWidth = parseFloat($bannerFrame.attr("data-width"));
7971      if (!bannerFrameWidth) {
7972        if (++tryCount < maxTries) setTimeout(tryAlign, 100);
7973        return;
7974      }
7975
7976      var $skyContainer = $bannerFrame.closest('.Ad-skyscraper-right');
7977      var billboardRect = $billboard[0].getBoundingClientRect();
7978      var finalLeft = billboardRect.right;
7979
7980      var cssProps = {
7981        'position': 'fixed',
7982        // 'top': billboardRect.top + 'px', // Bei Bedarf aktivieren für vertikale Billboard-Bindung
7983        'left': finalLeft + 'px',
7984        'right': 'auto',
7985        'width': bannerFrameWidth + 'px',
7986        'margin': '0',
7987        'transform': 'none',
7988        'z-index': '100'
7989      };
7990
7991      // Optionaler Margin-Top aus dem iFrame
7992      var mTop = parseFloat($bannerFrame.attr("data-margin-top"));
7993      if (mTop) cssProps['top'] = (billboardRect.top + mTop) + 'px';
7994
7995      $skyContainer.css(cssProps);
7996    } else if (++tryCount < maxTries) {
7997      setTimeout(tryAlign, 100);
7998    }
7999  }
8000  tryAlign();
8001});
8002
8003/**
8004 * Links-Ausrichtung
8005 * wird in bridgeAdComp aufgerufen, nachdem Skyscraper iFrame mit Grafik gefüllt wurde
8006 */
8007$(document).on("alignSkyscraperLeftBridgeAd", function(event) {
8008  var selector = ".Ad-skyscraper-left iframe.CompFrame";
8009  var maxTries = 15;
8010  var tryCount = 0;
8011
8012  function tryAlign() {
8013    var $bannerFrame = $(selector).first();
8014    var $billboard = $('#renderSlot_Billboard');
8015
8016    if ($bannerFrame.length && $billboard.length) {
8017      var bannerFrameWidth = parseFloat($bannerFrame.attr("data-width"));
8018      if (!bannerFrameWidth) {
8019        if (++tryCount < maxTries) setTimeout(tryAlign, 100);
8020        return;
8021      }
8022
8023      var $skyContainer = $bannerFrame.closest('.Ad-skyscraper-left');
8024      var billboardRect = $billboard[0].getBoundingClientRect();
8025      var finalLeft = billboardRect.left - bannerFrameWidth;
8026
8027      var cssProps = {
8028        'position': 'fixed',
8029        // 'top': billboardRect.top + 'px', // Bei Bedarf aktivieren für vertikale Billboard-Bindung
8030        'left': finalLeft + 'px',
8031        'right': 'auto',
8032        'width': bannerFrameWidth + 'px',
8033        'margin': '0',
8034        'transform': 'none',
8035        'z-index': '100'
8036      };
8037
8038      var mTop = parseFloat($bannerFrame.attr("data-margin-top"));
8039      if (mTop) cssProps['top'] = (billboardRect.top + mTop) + 'px';
8040
8041      $skyContainer.css(cssProps);
8042    } else if (++tryCount < maxTries) {
8043      setTimeout(tryAlign, 100);
8044    }
8045  }
8046  tryAlign();
8047});
8048
8049$(document).on('valueAd', function() {
8050  const valueAdFrame = document.querySelector('#renderSlot_Billboard iframe.valueAdFrame, #renderSlot_Mobil-Billboard iframe.valueAdFrame, iframe.valueAdFrame');
8051  if (!valueAdFrame) return;
8052
8053  const bgImage = valueAdFrame.getAttribute('data-bgimage') || '';
8054  const bgColor = valueAdFrame.getAttribute('data-bgcolor') || '';
8055  if (bgImage && bgImage.indexOf('[%') === -1) {
8056    document.body.style.backgroundImage = 'url("' + bgImage + '")';
8057    document.body.style.backgroundRepeat = 'no-repeat';
8058    document.body.style.backgroundPosition = 'center top';
8059  }
8060  if (bgColor && bgColor.indexOf('[%') === -1) {
8061    document.body.style.backgroundColor = bgColor;
8062  }
8063
8064  const billboardSlot = valueAdFrame.closest('#renderSlot_Billboard, #renderSlot_Mobil-Billboard');
8065  if (billboardSlot) {
8066    // Bei ValueAd darf seitlich kein Padding bleiben, damit Sky direkt am Billboard anliegt.
8067    billboardSlot.style.paddingLeft = '0px';
8068    billboardSlot.style.paddingRight = '0px';
8069  }
8070
8071  if (valueAdFrame.parentElement) {
8072    valueAdFrame.parentElement.style.paddingLeft = '0px';
8073    valueAdFrame.parentElement.style.paddingRight = '0px';
8074  }
8075
8076  // Vorhandene BridgeAd-Logik wiederverwenden: ValueAd-iframe als Quelle markieren.
8077  valueAdFrame.classList.add('bridgeAdFrame');
8078
8079  const imgLeft = valueAdFrame.getAttribute('data-img_left') || '';
8080  const imgRight = valueAdFrame.getAttribute('data-img_right') || '';
8081  if (!imgLeft && !imgRight) return;
8082  if (imgLeft.indexOf('[%') !== -1 && imgRight.indexOf('[%') !== -1) return;
8083
8084  $(document).trigger('bridgeAdComp');
8085});
8086
8087
8088/**
8089 * bridgeAdComp
8090 * Hauptfunktion: Bridge-Ad Kompatibilität
8091 */
8092$(document).on("bridgeAdComp", function(event) {
8093  const bA_iframe = document.querySelector('.bridgeAdFrame');
8094  if (!bA_iframe) return;
8095
8096  const skyRight_Slot = document.querySelector('.Ad-skyscraper-right');
8097  const skyLeft_Slot = document.querySelector('.Ad-skyscraper-left');
8098  const commonClickUrl = bA_iframe.dataset.click_url;
8099
8100  const setupSkyscraper = (slot, imgUrl, linkUrl, eventName) => {
8101    if (!slot || !imgUrl) return;
8102
8103    const googleDiv = Array.from(slot.querySelectorAll('div'))
8104      .find(div => div.id && div.id.startsWith('google_ads_iframe_'));
8105
8106    if (googleDiv) {
8107      const imgLoader = new Image();
8108      imgLoader.src = imgUrl;
8109
8110      imgLoader.onload = function() {
8111        const realWidth = imgLoader.naturalWidth;
8112        const realHeight = imgLoader.naturalHeight;
8113
8114        googleDiv.innerHTML = '';
8115        let customFrame = document.createElement('iframe');
8116        customFrame.classList.add('responsiveFrame', 'CompFrame');
8117        customFrame.dataset.width = realWidth;
8118        customFrame.dataset.height = realHeight;
8119
8120        Object.assign(customFrame.style, {
8121          width: '100%',
8122          maxWidth: `${realWidth}px`,
8123          height: 'auto',
8124          aspectRatio: `${realWidth} / ${realHeight}`,
8125          border: 'none',
8126          display: 'block'
8127        });
8128
8129        customFrame.src = 'about:blank';
8130        googleDiv.appendChild(customFrame);
8131
8132        const finalizeFrame = () => {
8133          try {
8134            const doc = customFrame.contentDocument || customFrame.contentWindow.document;
8135            if (doc) {
8136              doc.open();
8137              // Einbau des Links um das Bild herum
8138              doc.write(`
8139                <!DOCTYPE html>
8140                <html>
8141                  <body style="margin:0;padding:0;overflow:hidden;">
8142                    <a href="${linkUrl || '#'}" target="_blank" style="display:block;text-decoration:none;outline:none;">
8143                      <img src="${imgUrl}" style="width:100%;display:block;border:none;-webkit-user-drag:none;" />
8144                    </a>
8145                  </body>
8146                </html>
8147              `);
8148              doc.close();
8149
8150              setTimeout(() => {
8151                $(document).trigger(eventName);
8152                console.log(`[DEBUG] ${eventName} mit Link ausgeführt`);
8153              }, 10);
8154            }
8155          } catch (e) {
8156            console.error("Fehler beim Finalisieren des iFrames:", e);
8157          }
8158        };
8159
8160        if (customFrame.contentDocument && customFrame.contentDocument.readyState === 'complete') {
8161          finalizeFrame();
8162        } else {
8163          customFrame.onload = finalizeFrame;
8164        }
8165      };
8166    }
8167  };
8168
8169  setupSkyscraper(
8170    skyRight_Slot,
8171    bA_iframe.dataset.img_right,
8172    // bA_iframe.dataset.click_right,
8173    commonClickUrl,
8174    "alignSkyscraperRightBridgeAd"
8175  );
8176
8177  setupSkyscraper(
8178    skyLeft_Slot,
8179    bA_iframe.dataset.img_left,
8180    // bA_iframe.dataset.click_left,
8181    commonClickUrl,
8182    "alignSkyscraperLeftBridgeAd"
8183  );
8184});
8185
8186/**
8187 * Magnet-Effekt bei Resize
8188 */
8189$(window).on('resize', function() {
8190  if ($('.Ad-skyscraper-right iframe.CompFrame').length) $(document).trigger("alignSkyscraperRightBridgeAd");
8191  if ($('.Ad-skyscraper-left iframe.CompFrame').length) $(document).trigger("alignSkyscraperLeftBridgeAd");
8192});
8193
8194/**
8195 * fullWidthBillboard
8196 */
8197$(document).on("fullWidthBillboard", function(event){
8198  const fw_renderSlot = document.querySelector('#renderSlot_Billboard');
8199  fw_renderSlot.classList.add('fullWidthBillboard');
8200});
8201
8202/**
8203 *  billboardSticky
8204 */
8205$(document).on('billboardSticky', function(){
8206  const slot = $('#renderSlot_Billboard, #renderSlot_Mobil-Billboard');
8207  const billboardAdIframe = $('.billboardSticky');
8208  const stickyHeaderHeight = $('.SiteHeaderSticky').height();
8209
8210  const billboardPositionTop = slot.offset().top;
8211  const billboardMarginTop = parseFloat(billboardAdIframe.parent().css('margin-top'));
8212  let billboardStickyOffsetTop = stickyHeaderHeight + 5;
8213  let sTimer = 0;
8214  if (Math.sign(billboardMarginTop) === -1) {
8215    billboardStickyOffsetTop = billboardStickyOffsetTop + Math.abs(billboardMarginTop);
8216  } else {
8217    billboardStickyOffsetTop = billboardStickyOffsetTop - Math.abs(billboardMarginTop);
8218  }
8219
8220  const bId = String(billboardAdIframe.data('bannerid'));
8221  const lsKey = 'stickyBillboard_' + bId;
8222  const lsValue = localStorage.getItem(lsKey);
8223
8224  if (lsValue !== null) {
8225    const expireDate = JSON.parse(lsValue).expireAt;
8226    if (expireDate < new Date().getTime()) {
8227      localStorage.removeItem(lsKey);
8228    } else {
8229      return false;
8230    }
8231  }
8232
8233  if ($('.PageFrame').height() > 2000) {
8234    $(window).scroll(function () {
8235      if ($(window).scrollTop() > billboardPositionTop) {
8236        if (localStorage.getItem(lsKey) === null && !sTimer && !slot.hasClass('isStickyBillboard')) {
8237          slot.css({top: billboardStickyOffsetTop + 'px'});
8238          slot.addClass('isStickyBillboard');
8239
8240          sTimer = setTimeout(function () {
8241            slot.css({'zIndex': 998});
8242            slot.animate({'top': -600}, 3000, function () {
8243            });
8244            sTimer = 0;
8245            const expireAt = new Date(new Date().getTime() + (60000 * 1440)).getTime();
8246            localStorage.setItem(lsKey, JSON.stringify({expireAt: expireAt}));
8247          }, 2000);
8248        }
8249      } else {
8250        if (sTimer) {
8251          clearTimeout(sTimer);
8252          sTimer = 0;
8253        }
8254        slot.css({top: '0px'});
8255        slot.removeClass('isStickyBillboard');
8256      }
8257    });
8258  }
8259});
8260
8261
8262window.googletag = window.googletag || { cmd: [] };
8263
8264
8265
8266// Scrollposition abspeichern
8267$(".PageFrame section a").on("click", function(){
8268	// cookie setzen
8269	document.cookie = "oldpos=" + $(document).scrollTop();
8270	document.cookie = "oldpospath=" + window.location.pathname;
8271});
8272
8273
8274// Scrollposition auslesen, scrollen und cookie löschen
8275$(document).ready(function() {
8276    if (localStorage.getItem('click')  == 'Logo') {
8277        localStorage.setItem('click', '');
8278        return;
8279    }
8280
8281	var cookie2_eq = "oldpospath=";
8282	var cookie2_val = null;
8283	var ca2 = document.cookie.split(';');
8284	for(var i=0;i< ca2.length;i++) {
8285        var c2 = ca2[i];
8286        while (c2.charAt(0)===' ') {
8287          c2 = c2.substring(1,c2.length);
8288        }
8289        if (c2.indexOf(cookie2_eq) === 0) {
8290            cookie2_val = c2.substring(cookie2_eq.length,c2.length);
8291        }
8292    }
8293    //
8294    if (window.location.pathname == cookie2_val) {
8295        //alert(window.location.pathname); alert(cookie2_val);
8296        var cookie_eq = "oldpos=";
8297        var cookie_val = null;
8298        var ca = document.cookie.split(';');
8299        for(var i=0;i< ca.length;i++) {
8300            var c = ca[i];
8301            while (c.charAt(0)===' ') {
8302                c = c.substring(1,c.length);
8303            }
8304            if (c.indexOf(cookie_eq) === 0) {
8305                cookie_val = c.substring(cookie_eq.length,c.length);
8306            }
8307        }
8308	}
8309    if (cookie_val !== null) {
8310        $(document).scrollTop(cookie_val);
8311        document.cookie = "oldpos=; expires=Thu, 01-Jan-70 00:00:01 GMT;" ;
8312    }
8313    document.cookie = "oldpospath=; expires=Thu, 01-Jan-70 00:00:01 GMT;" ;
8314});
8315
8316
8317
8318
8319/**
8320 * Swiper 12.0.3
8321 * Most modern mobile touch slider and framework with hardware accelerated transitions
8322 * https://swiperjs.com
8323 *
8324 * Copyright 2014-2025 Vladimir Kharlampidi
8325 *
8326 * Released under the MIT License
8327 *
8328 * Released on: October 21, 2025
8329 */
8330
8331var Swiper = (function () {
8332  'use strict';
8333
8334  /**
8335   * SSR Window 5.0.1
8336   * Better handling for window object in SSR environment
8337   * https://github.com/nolimits4web/ssr-window
8338   *
8339   * Copyright 2025, Vladimir Kharlampidi
8340   *
8341   * Licensed under MIT
8342   *
8343   * Released on: June 27, 2025
8344   */
8345  /* eslint-disable no-param-reassign */
8346  function isObject$1(obj) {
8347    return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
8348  }
8349  function extend$1(target = {}, src = {}) {
8350    const noExtend = ['__proto__', 'constructor', 'prototype'];
vendor: 5,054 bytes, lines 8351-8549
8351    Object.keys(src).filter(key => noExtend.indexOf(key) < 0).forEach(key => {
8352      if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) {
8353        extend$1(target[key], src[key]);
8354      }
8355    });
8356  }
8357  const ssrDocument = {
8358    body: {},
8359    addEventListener() {},
8360    removeEventListener() {},
8361    activeElement: {
8362      blur() {},
8363      nodeName: ''
8364    },
8365    querySelector() {
8366      return null;
8367    },
8368    querySelectorAll() {
8369      return [];
8370    },
8371    getElementById() {
8372      return null;
8373    },
8374    createEvent() {
8375      return {
8376        initEvent() {}
8377      };
8378    },
8379    createElement() {
8380      return {
8381        children: [],
8382        childNodes: [],
8383        style: {},
8384        setAttribute() {},
8385        getElementsByTagName() {
8386          return [];
8387        }
8388      };
8389    },
8390    createElementNS() {
8391      return {};
8392    },
8393    importNode() {
8394      return null;
8395    },
8396    location: {
8397      hash: '',
8398      host: '',
8399      hostname: '',
8400      href: '',
8401      origin: '',
8402      pathname: '',
8403      protocol: '',
8404      search: ''
8405    }
8406  };
8407  function getDocument() {
8408    const doc = typeof document !== 'undefined' ? document : {};
8409    extend$1(doc, ssrDocument);
8410    return doc;
8411  }
8412  const ssrWindow = {
8413    document: ssrDocument,
8414    navigator: {
8415      userAgent: ''
8416    },
8417    location: {
8418      hash: '',
8419      host: '',
8420      hostname: '',
8421      href: '',
8422      origin: '',
8423      pathname: '',
8424      protocol: '',
8425      search: ''
8426    },
8427    history: {
8428      replaceState() {},
8429      pushState() {},
8430      go() {},
8431      back() {}
8432    },
8433    CustomEvent: function CustomEvent() {
8434      return this;
8435    },
8436    addEventListener() {},
8437    removeEventListener() {},
8438    getComputedStyle() {
8439      return {
8440        getPropertyValue() {
8441          return '';
8442        }
8443      };
8444    },
8445    Image() {},
8446    Date() {},
8447    screen: {},
8448    setTimeout() {},
8449    clearTimeout() {},
8450    matchMedia() {
8451      return {};
8452    },
8453    requestAnimationFrame(callback) {
8454      if (typeof setTimeout === 'undefined') {
8455        callback();
8456        return null;
8457      }
8458      return setTimeout(callback, 0);
8459    },
8460    cancelAnimationFrame(id) {
8461      if (typeof setTimeout === 'undefined') {
8462        return;
8463      }
8464      clearTimeout(id);
8465    }
8466  };
8467  function getWindow() {
8468    const win = typeof window !== 'undefined' ? window : {};
8469    extend$1(win, ssrWindow);
8470    return win;
8471  }
8472
8473  function classesToTokens(classes = '') {
8474    return classes.trim().split(' ').filter(c => !!c.trim());
8475  }
8476
8477  function deleteProps(obj) {
8478    const object = obj;
8479    Object.keys(object).forEach(key => {
8480      try {
8481        object[key] = null;
8482      } catch (e) {
8483        // no getter for object
8484      }
8485      try {
8486        delete object[key];
8487      } catch (e) {
8488        // something got wrong
8489      }
8490    });
8491  }
8492  function nextTick(callback, delay = 0) {
8493    return setTimeout(callback, delay);
8494  }
8495  function now() {
8496    return Date.now();
8497  }
8498  function getComputedStyle$1(el) {
8499    const window = getWindow();
8500    let style;
8501    if (window.getComputedStyle) {
8502      style = window.getComputedStyle(el, null);
8503    }
8504    if (!style && el.currentStyle) {
8505      style = el.currentStyle;
8506    }
8507    if (!style) {
8508      style = el.style;
8509    }
8510    return style;
8511  }
8512  function getTranslate(el, axis = 'x') {
8513    const window = getWindow();
8514    let matrix;
8515    let curTransform;
8516    let transformMatrix;
8517    const curStyle = getComputedStyle$1(el);
8518    if (window.WebKitCSSMatrix) {
8519      curTransform = curStyle.transform || curStyle.webkitTransform;
8520      if (curTransform.split(',').length > 6) {
8521        curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
8522      }
8523      // Some old versions of Webkit choke when 'none' is passed; pass
8524      // empty string instead in this case
8525      transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
8526    } else {
8527      transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
8528      matrix = transformMatrix.toString().split(',');
8529    }
8530    if (axis === 'x') {
8531      // Latest Chrome and webkits Fix
8532      if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
8533      // Crazy IE10 Matrix
8534      else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
8535      // Normal Browsers
8536      else curTransform = parseFloat(matrix[4]);
8537    }
8538    if (axis === 'y') {
8539      // Latest Chrome and webkits Fix
8540      if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
8541      // Crazy IE10 Matrix
8542      else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
8543      // Normal Browsers
8544      else curTransform = parseFloat(matrix[5]);
8545    }
8546    return curTransform || 0;
8547  }
8548  function isObject(o) {
8549    return typeof o === 'object' && o !== null && o.constructor && Ob
vendor: 9,136 bytes, lines 8549-8813
8549ject.prototype.toString.call(o).slice(8, -1) === 'Object';
8550  }
8551  function isNode(node) {
8552    // eslint-disable-next-line
8553    if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
8554      return node instanceof HTMLElement;
8555    }
8556    return node && (node.nodeType === 1 || node.nodeType === 11);
8557  }
8558  function extend(...args) {
8559    const to = Object(args[0]);
8560    const noExtend = ['__proto__', 'constructor', 'prototype'];
8561    for (let i = 1; i < args.length; i += 1) {
8562      const nextSource = args[i];
8563      if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
8564        const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
8565        for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
8566          const nextKey = keysArray[nextIndex];
8567          const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
8568          if (desc !== undefined && desc.enumerable) {
8569            if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
8570              if (nextSource[nextKey].__swiper__) {
8571                to[nextKey] = nextSource[nextKey];
8572              } else {
8573                extend(to[nextKey], nextSource[nextKey]);
8574              }
8575            } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
8576              to[nextKey] = {};
8577              if (nextSource[nextKey].__swiper__) {
8578                to[nextKey] = nextSource[nextKey];
8579              } else {
8580                extend(to[nextKey], nextSource[nextKey]);
8581              }
8582            } else {
8583              to[nextKey] = nextSource[nextKey];
8584            }
8585          }
8586        }
8587      }
8588    }
8589    return to;
8590  }
8591  function setCSSProperty(el, varName, varValue) {
8592    el.style.setProperty(varName, varValue);
8593  }
8594  function animateCSSModeScroll({
8595    swiper,
8596    targetPosition,
8597    side
8598  }) {
8599    const window = getWindow();
8600    const startPosition = -swiper.translate;
8601    let startTime = null;
8602    let time;
8603    const duration = swiper.params.speed;
8604    swiper.wrapperEl.style.scrollSnapType = 'none';
8605    window.cancelAnimationFrame(swiper.cssModeFrameID);
8606    const dir = targetPosition > startPosition ? 'next' : 'prev';
8607    const isOutOfBound = (current, target) => {
8608      return dir === 'next' && current >= target || dir === 'prev' && current <= target;
8609    };
8610    const animate = () => {
8611      time = new Date().getTime();
8612      if (startTime === null) {
8613        startTime = time;
8614      }
8615      const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
8616      const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
8617      let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
8618      if (isOutOfBound(currentPosition, targetPosition)) {
8619        currentPosition = targetPosition;
8620      }
8621      swiper.wrapperEl.scrollTo({
8622        [side]: currentPosition
8623      });
8624      if (isOutOfBound(currentPosition, targetPosition)) {
8625        swiper.wrapperEl.style.overflow = 'hidden';
8626        swiper.wrapperEl.style.scrollSnapType = '';
8627        setTimeout(() => {
8628          swiper.wrapperEl.style.overflow = '';
8629          swiper.wrapperEl.scrollTo({
8630            [side]: currentPosition
8631          });
8632        });
8633        window.cancelAnimationFrame(swiper.cssModeFrameID);
8634        return;
8635      }
8636      swiper.cssModeFrameID = window.requestAnimationFrame(animate);
8637    };
8638    animate();
8639  }
8640  function getSlideTransformEl(slideEl) {
8641    return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl;
8642  }
8643  function elementChildren(element, selector = '') {
8644    const window = getWindow();
8645    const children = [...element.children];
8646    if (window.HTMLSlotElement && element instanceof HTMLSlotElement) {
8647      children.push(...element.assignedElements());
8648    }
8649    if (!selector) {
8650      return children;
8651    }
8652    return children.filter(el => el.matches(selector));
8653  }
8654  function elementIsChildOfSlot(el, slot) {
8655    // Breadth-first search through all parent's children and assigned elements
8656    const elementsQueue = [slot];
8657    while (elementsQueue.length > 0) {
8658      const elementToCheck = elementsQueue.shift();
8659      if (el === elementToCheck) {
8660        return true;
8661      }
8662      elementsQueue.push(...elementToCheck.children, ...(elementToCheck.shadowRoot ? elementToCheck.shadowRoot.children : []), ...(elementToCheck.assignedElements ? elementToCheck.assignedElements() : []));
8663    }
8664  }
8665  function elementIsChildOf(el, parent) {
8666    const window = getWindow();
8667    let isChild = parent.contains(el);
8668    if (!isChild && window.HTMLSlotElement && parent instanceof HTMLSlotElement) {
8669      const children = [...parent.assignedElements()];
8670      isChild = children.includes(el);
8671      if (!isChild) {
8672        isChild = elementIsChildOfSlot(el, parent);
8673      }
8674    }
8675    return isChild;
8676  }
8677  function showWarning(text) {
8678    try {
8679      console.warn(text);
8680      return;
8681    } catch (err) {
8682      // err
8683    }
8684  }
8685  function createElement(tag, classes = []) {
8686    const el = document.createElement(tag);
8687    el.classList.add(...(Array.isArray(classes) ? classes : classesToTokens(classes)));
8688    return el;
8689  }
8690  function elementOffset(el) {
8691    const window = getWindow();
8692    const document = getDocument();
8693    const box = el.getBoundingClientRect();
8694    const body = document.body;
8695    const clientTop = el.clientTop || body.clientTop || 0;
8696    const clientLeft = el.clientLeft || body.clientLeft || 0;
8697    const scrollTop = el === window ? window.scrollY : el.scrollTop;
8698    const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
8699    return {
8700      top: box.top + scrollTop - clientTop,
8701      left: box.left + scrollLeft - clientLeft
8702    };
8703  }
8704  function elementPrevAll(el, selector) {
8705    const prevEls = [];
8706    while (el.previousElementSibling) {
8707      const prev = el.previousElementSibling; // eslint-disable-line
8708      if (selector) {
8709        if (prev.matches(selector)) prevEls.push(prev);
8710      } else prevEls.push(prev);
8711      el = prev;
8712    }
8713    return prevEls;
8714  }
8715  function elementNextAll(el, selector) {
8716    const nextEls = [];
8717    while (el.nextElementSibling) {
8718      const next = el.nextElementSibling; // eslint-disable-line
8719      if (selector) {
8720        if (next.matches(selector)) nextEls.push(next);
8721      } else nextEls.push(next);
8722      el = next;
8723    }
8724    return nextEls;
8725  }
8726  function elementStyle(el, prop) {
8727    const window = getWindow();
8728    return window.getComputedStyle(el, null).getPropertyValue(prop);
8729  }
8730  function elementIndex(el) {
8731    let child = el;
8732    let i;
8733    if (child) {
8734      i = 0;
8735      // eslint-disable-next-line
8736      while ((child = child.previousSibling) !== null) {
8737        if (child.nodeType === 1) i += 1;
8738      }
8739      return i;
8740    }
8741    return undefined;
8742  }
8743  function elementParents(el, selector) {
8744    const parents = []; // eslint-disable-line
8745    let parent = el.parentElement; // eslint-disable-line
8746    while (parent) {
8747      if (selector) {
8748        if (parent.matches(selector)) parents.push(parent);
8749      } else {
8750        parents.push(parent);
8751      }
8752      parent = parent.parentElement;
8753    }
8754    return parents;
8755  }
8756  function elementTransitionEnd(el, callback) {
8757    function fireCallBack(e) {
8758      if (e.target !== el) return;
8759      callback.call(el, e);
8760      el.removeEventListener('transitionend', fireCallBack);
8761    }
8762    if (callback) {
8763      el.addEventListener('transitionend', fireCallBack);
8764    }
8765  }
8766  function elementOuterSize(el, size, includeMargins) {
8767    const window = getWindow();
8768    if (includeMargins) {
8769      return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
8770    }
8771    return el.offsetWidth;
8772  }
8773  function makeElementsArray(el) {
8774    return (Array.isArray(el) ? el : [el]).filter(e => !!e);
8775  }
8776  function getRotateFix(swiper) {
8777    return v => {
8778      if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) {
8779        return v + 0.001;
8780      }
8781      return v;
8782    };
8783  }
8784  function setInnerHTML(el, html = '') {
8785    if (typeof trustedTypes !== 'undefined') {
8786      el.innerHTML = trustedTypes.createPolicy('html', {
8787        createHTML: s => s
8788      }).createHTML(html);
8789    } else {
8790      el.innerHTML = html;
8791    }
8792  }
8793
8794  let support;
8795  function calcSupport() {
8796    const window = getWindow();
8797    const document = getDocument();
8798    return {
8799      smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
8800      touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
8801    };
8802  }
8803  function getSupport() {
8804    if (!support) {
8805      support = calcSupport();
8806    }
8807    return support;
8808  }
8809
8810  let deviceCached;
8811  function calcDevice({
8812    userAgent
8813  } = {}) {
vendor: 13,243 bytes, lines 8814-9201
8814    const support = getSupport();
8815    const window = getWindow();
8816    const platform = window.navigator.platform;
8817    const ua = userAgent || window.navigator.userAgent;
8818    const device = {
8819      ios: false,
8820      android: false
8821    };
8822    const screenWidth = window.screen.width;
8823    const screenHeight = window.screen.height;
8824    const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
8825    let ipad = ua.match(/(iPad)(?!\1).*OS\s([\d_]+)/);
8826    const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
8827    const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
8828    const windows = platform === 'Win32';
8829    let macos = platform === 'MacIntel';
8830
8831    // iPadOs 13 fix
8832    const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
8833    if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
8834      ipad = ua.match(/(Version)\/([\d.]+)/);
8835      if (!ipad) ipad = [0, 1, '13_0_0'];
8836      macos = false;
8837    }
8838
8839    // Android
8840    if (android && !windows) {
8841      device.os = 'android';
8842      device.android = true;
8843    }
8844    if (ipad || iphone || ipod) {
8845      device.os = 'ios';
8846      device.ios = true;
8847    }
8848
8849    // Export object
8850    return device;
8851  }
8852  function getDevice(overrides = {}) {
8853    if (!deviceCached) {
8854      deviceCached = calcDevice(overrides);
8855    }
8856    return deviceCached;
8857  }
8858
8859  let browser;
8860  function calcBrowser() {
8861    const window = getWindow();
8862    const device = getDevice();
8863    let needPerspectiveFix = false;
8864    function isSafari() {
8865      const ua = window.navigator.userAgent.toLowerCase();
8866      return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
8867    }
8868    if (isSafari()) {
8869      const ua = String(window.navigator.userAgent);
8870      if (ua.includes('Version/')) {
8871        const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
8872        needPerspectiveFix = major < 16 || major === 16 && minor < 2;
8873      }
8874    }
8875    const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
8876    const isSafariBrowser = isSafari();
8877    const need3dFix = isSafariBrowser || isWebView && device.ios;
8878    return {
8879      isSafari: needPerspectiveFix || isSafariBrowser,
8880      needPerspectiveFix,
8881      need3dFix,
8882      isWebView
8883    };
8884  }
8885  function getBrowser() {
8886    if (!browser) {
8887      browser = calcBrowser();
8888    }
8889    return browser;
8890  }
8891
8892  function Resize({
8893    swiper,
8894    on,
8895    emit
8896  }) {
8897    const window = getWindow();
8898    let observer = null;
8899    let animationFrame = null;
8900    const resizeHandler = () => {
8901      if (!swiper || swiper.destroyed || !swiper.initialized) return;
8902      emit('beforeResize');
8903      emit('resize');
8904    };
8905    const createObserver = () => {
8906      if (!swiper || swiper.destroyed || !swiper.initialized) return;
8907      observer = new ResizeObserver(entries => {
8908        animationFrame = window.requestAnimationFrame(() => {
8909          const {
8910            width,
8911            height
8912          } = swiper;
8913          let newWidth = width;
8914          let newHeight = height;
8915          entries.forEach(({
8916            contentBoxSize,
8917            contentRect,
8918            target
8919          }) => {
8920            if (target && target !== swiper.el) return;
8921            newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
8922            newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
8923          });
8924          if (newWidth !== width || newHeight !== height) {
8925            resizeHandler();
8926          }
8927        });
8928      });
8929      observer.observe(swiper.el);
8930    };
8931    const removeObserver = () => {
8932      if (animationFrame) {
8933        window.cancelAnimationFrame(animationFrame);
8934      }
8935      if (observer && observer.unobserve && swiper.el) {
8936        observer.unobserve(swiper.el);
8937        observer = null;
8938      }
8939    };
8940    const orientationChangeHandler = () => {
8941      if (!swiper || swiper.destroyed || !swiper.initialized) return;
8942      emit('orientationchange');
8943    };
8944    on('init', () => {
8945      if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
8946        createObserver();
8947        return;
8948      }
8949      window.addEventListener('resize', resizeHandler);
8950      window.addEventListener('orientationchange', orientationChangeHandler);
8951    });
8952    on('destroy', () => {
8953      removeObserver();
8954      window.removeEventListener('resize', resizeHandler);
8955      window.removeEventListener('orientationchange', orientationChangeHandler);
8956    });
8957  }
8958
8959  function Observer({
8960    swiper,
8961    extendParams,
8962    on,
8963    emit
8964  }) {
8965    const observers = [];
8966    const window = getWindow();
8967    const attach = (target, options = {}) => {
8968      const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
8969      const observer = new ObserverFunc(mutations => {
8970        // The observerUpdate event should only be triggered
8971        // once despite the number of mutations.  Additional
8972        // triggers are redundant and are very costly
8973        if (swiper.__preventObserver__) return;
8974        if (mutations.length === 1) {
8975          emit('observerUpdate', mutations[0]);
8976          return;
8977        }
8978        const observerUpdate = function observerUpdate() {
8979          emit('observerUpdate', mutations[0]);
8980        };
8981        if (window.requestAnimationFrame) {
8982          window.requestAnimationFrame(observerUpdate);
8983        } else {
8984          window.setTimeout(observerUpdate, 0);
8985        }
8986      });
8987      observer.observe(target, {
8988        attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
8989        childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList,
8990        characterData: typeof options.characterData === 'undefined' ? true : options.characterData
8991      });
8992      observers.push(observer);
8993    };
8994    const init = () => {
8995      if (!swiper.params.observer) return;
8996      if (swiper.params.observeParents) {
8997        const containerParents = elementParents(swiper.hostEl);
8998        for (let i = 0; i < containerParents.length; i += 1) {
8999          attach(containerParents[i]);
9000        }
9001      }
9002      // Observe container
9003      attach(swiper.hostEl, {
9004        childList: swiper.params.observeSlideChildren
9005      });
9006
9007      // Observe wrapper
9008      attach(swiper.wrapperEl, {
9009        attributes: false
9010      });
9011    };
9012    const destroy = () => {
9013      observers.forEach(observer => {
9014        observer.disconnect();
9015      });
9016      observers.splice(0, observers.length);
9017    };
9018    extendParams({
9019      observer: false,
9020      observeParents: false,
9021      observeSlideChildren: false
9022    });
9023    on('init', init);
9024    on('destroy', destroy);
9025  }
9026
9027  /* eslint-disable no-underscore-dangle */
9028
9029  var eventsEmitter = {
9030    on(events, handler, priority) {
9031      const self = this;
9032      if (!self.eventsListeners || self.destroyed) return self;
9033      if (typeof handler !== 'function') return self;
9034      const method = priority ? 'unshift' : 'push';
9035      events.split(' ').forEach(event => {
9036        if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
9037        self.eventsListeners[event][method](handler);
9038      });
9039      return self;
9040    },
9041    once(events, handler, priority) {
9042      const self = this;
9043      if (!self.eventsListeners || self.destroyed) return self;
9044      if (typeof handler !== 'function') return self;
9045      function onceHandler(...args) {
9046        self.off(events, onceHandler);
9047        if (onceHandler.__emitterProxy) {
9048          delete onceHandler.__emitterProxy;
9049        }
9050        handler.apply(self, args);
9051      }
9052      onceHandler.__emitterProxy = handler;
9053      return self.on(events, onceHandler, priority);
9054    },
9055    onAny(handler, priority) {
9056      const self = this;
9057      if (!self.eventsListeners || self.destroyed) return self;
9058      if (typeof handler !== 'function') return self;
9059      const method = priority ? 'unshift' : 'push';
9060      if (self.eventsAnyListeners.indexOf(handler) < 0) {
9061        self.eventsAnyListeners[method](handler);
9062      }
9063      return self;
9064    },
9065    offAny(handler) {
9066      const self = this;
9067      if (!self.eventsListeners || self.destroyed) return self;
9068      if (!self.eventsAnyListeners) return self;
9069      const index = self.eventsAnyListeners.indexOf(handler);
9070      if (index >= 0) {
9071        self.eventsAnyListeners.splice(index, 1);
9072      }
9073      return self;
9074    },
9075    off(events, handler) {
9076      const self = this;
9077      if (!self.eventsListeners || self.destroyed) return self;
9078      if (!self.eventsListeners) return self;
9079      events.split(' ').forEach(event => {
9080        if (typeof handler === 'undefined') {
9081          self.eventsListeners[event] = [];
9082        } else if (self.eventsListeners[event]) {
9083          self.eventsListeners[event].forEach((eventHandler, index) => {
9084            if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
9085              self.eventsListeners[event].splice(index, 1);
9086            }
9087          });
9088        }
9089      });
9090      return self;
9091    },
9092    emit(...args) {
9093      const self = this;
9094      if (!self.eventsListeners || self.destroyed) return self;
9095      if (!self.eventsListeners) return self;
9096      let events;
9097      let data;
9098      let context;
9099      if (typeof args[0] === 'string' || Array.isArray(args[0])) {
9100        events = args[0];
9101        data = args.slice(1, args.length);
9102        context = self;
9103      } else {
9104        events = args[0].events;
9105        data = args[0].data;
9106        context = args[0].context || self;
9107      }
9108      data.unshift(context);
9109      const eventsArray = Array.isArray(events) ? events : events.split(' ');
9110      eventsArray.forEach(event => {
9111        if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
9112          self.eventsAnyListeners.forEach(eventHandler => {
9113            eventHandler.apply(context, [event, ...data]);
9114          });
9115        }
9116        if (self.eventsListeners && self.eventsListeners[event]) {
9117          self.eventsListeners[event].forEach(eventHandler => {
9118            eventHandler.apply(context, data);
9119          });
9120        }
9121      });
9122      return self;
9123    }
9124  };
9125
9126  function updateSize() {
9127    const swiper = this;
9128    let width;
9129    let height;
9130    const el = swiper.el;
9131    if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
9132      width = swiper.params.width;
9133    } else {
9134      width = el.clientWidth;
9135    }
9136    if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
9137      height = swiper.params.height;
9138    } else {
9139      height = el.clientHeight;
9140    }
9141    if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
9142      return;
9143    }
9144
9145    // Subtract paddings
9146    width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
9147    height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
9148    if (Number.isNaN(width)) width = 0;
9149    if (Number.isNaN(height)) height = 0;
9150    Object.assign(swiper, {
9151      width,
9152      height,
9153      size: swiper.isHorizontal() ? width : height
9154    });
9155  }
9156
9157  function updateSlides() {
9158    const swiper = this;
9159    function getDirectionPropertyValue(node, label) {
9160      return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
9161    }
9162    const params = swiper.params;
9163    const {
9164      wrapperEl,
9165      slidesEl,
9166      rtlTranslate: rtl,
9167      wrongRTL
9168    } = swiper;
9169    const isVirtual = swiper.virtual && params.virtual.enabled;
9170    const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
9171    const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
9172    const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
9173    let snapGrid = [];
9174    const slidesGrid = [];
9175    const slidesSizesGrid = [];
9176    let offsetBefore = params.slidesOffsetBefore;
9177    if (typeof offsetBefore === 'function') {
9178      offsetBefore = params.slidesOffsetBefore.call(swiper);
9179    }
9180    let offsetAfter = params.slidesOffsetAfter;
9181    if (typeof offsetAfter === 'function') {
9182      offsetAfter = params.slidesOffsetAfter.call(swiper);
9183    }
9184    const previousSnapGridLength = swiper.snapGrid.length;
9185    const previousSlidesGridLength = swiper.slidesGrid.length;
9186    const swiperSize = swiper.size - offsetBefore - offsetAfter;
9187    let spaceBetween = params.spaceBetween;
9188    let slidePosition = -offsetBefore;
9189    let prevSlideSize = 0;
9190    let index = 0;
9191    if (typeof swiperSize === 'undefined') {
9192      return;
9193    }
9194    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
9195      spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
9196    } else if (typeof spaceBetween === 'string') {
9197      spaceBetween = parseFloat(spaceBetween);
9198    }
9199    swiper.virtualSize = -spaceBetween - offsetBefore - offsetAfter;
9200
9201    // reset margins
vendor: 5,708 bytes, lines 9202-9332
9202    slides.forEach(slideEl => {
9203      if (rtl) {
9204        slideEl.style.marginLeft = '';
9205      } else {
9206        slideEl.style.marginRight = '';
9207      }
9208      slideEl.style.marginBottom = '';
9209      slideEl.style.marginTop = '';
9210    });
9211
9212    // reset cssMode offsets
9213    if (params.centeredSlides && params.cssMode) {
9214      setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
9215      setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
9216    }
9217    const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
9218    if (gridEnabled) {
9219      swiper.grid.initSlides(slides);
9220    } else if (swiper.grid) {
9221      swiper.grid.unsetSlides();
9222    }
9223
9224    // Calc slides
9225    let slideSize;
9226    const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
9227      return typeof params.breakpoints[key].slidesPerView !== 'undefined';
9228    }).length > 0;
9229    for (let i = 0; i < slidesLength; i += 1) {
9230      slideSize = 0;
9231      const slide = slides[i];
9232      if (slide) {
9233        if (gridEnabled) {
9234          swiper.grid.updateSlide(i, slide, slides);
9235        }
9236        if (elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
9237      }
9238
9239      if (isVirtual && params.slidesPerView === 'auto') {
9240        if (params.virtual.slidesPerViewAutoSlideSize) {
9241          slideSize = params.virtual.slidesPerViewAutoSlideSize;
9242        }
9243        if (slideSize && slide) {
9244          if (params.roundLengths) slideSize = Math.floor(slideSize);
9245          slide.style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
9246        }
9247      } else if (params.slidesPerView === 'auto') {
9248        if (shouldResetSlideSize) {
9249          slide.style[swiper.getDirectionLabel('width')] = ``;
9250        }
9251        const slideStyles = getComputedStyle(slide);
9252        const currentTransform = slide.style.transform;
9253        const currentWebKitTransform = slide.style.webkitTransform;
9254        if (currentTransform) {
9255          slide.style.transform = 'none';
9256        }
9257        if (currentWebKitTransform) {
9258          slide.style.webkitTransform = 'none';
9259        }
9260        if (params.roundLengths) {
9261          slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
9262        } else {
9263          // eslint-disable-next-line
9264          const width = getDirectionPropertyValue(slideStyles, 'width');
9265          const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
9266          const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
9267          const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
9268          const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
9269          const boxSizing = slideStyles.getPropertyValue('box-sizing');
9270          if (boxSizing && boxSizing === 'border-box') {
9271            slideSize = width + marginLeft + marginRight;
9272          } else {
9273            const {
9274              clientWidth,
9275              offsetWidth
9276            } = slide;
9277            slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
9278          }
9279        }
9280        if (currentTransform) {
9281          slide.style.transform = currentTransform;
9282        }
9283        if (currentWebKitTransform) {
9284          slide.style.webkitTransform = currentWebKitTransform;
9285        }
9286        if (params.roundLengths) slideSize = Math.floor(slideSize);
9287      } else {
9288        slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
9289        if (params.roundLengths) slideSize = Math.floor(slideSize);
9290        if (slide) {
9291          slide.style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
9292        }
9293      }
9294      if (slide) {
9295        slide.swiperSlideSize = slideSize;
9296      }
9297      slidesSizesGrid.push(slideSize);
9298      if (params.centeredSlides) {
9299        slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
9300        if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
9301        if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
9302        if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
9303        if (params.roundLengths) slidePosition = Math.floor(slidePosition);
9304        if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
9305        slidesGrid.push(slidePosition);
9306      } else {
9307        if (params.roundLengths) slidePosition = Math.floor(slidePosition);
9308        if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
9309        slidesGrid.push(slidePosition);
9310        slidePosition = slidePosition + slideSize + spaceBetween;
9311      }
9312      swiper.virtualSize += slideSize + spaceBetween;
9313      prevSlideSize = slideSize;
9314      index += 1;
9315    }
9316    swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
9317    if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
9318      wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
9319    }
9320    if (params.setWrapperSize) {
9321      wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
9322    }
9323    if (gridEnabled) {
9324      swiper.grid.updateWrapperSize(slideSize, snapGrid);
9325    }
9326
9327    // Remove last grid elements depending on width
9328    if (!params.centeredSlides) {
9329      const newSlidesGrid = [];
9330      for (let i = 0; i < snapGrid.length; i += 1) {
9331        let slidesGridItem = snapGrid[i];
9332        if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
vendor: 1,485 bytes, lines 9333-9368
9333        if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
9334          newSlidesGrid.push(slidesGridItem);
9335        }
9336      }
9337      snapGrid = newSlidesGrid;
9338      if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
9339        snapGrid.push(swiper.virtualSize - swiperSize);
9340      }
9341    }
9342    if (isVirtual && params.loop) {
9343      const size = slidesSizesGrid[0] + spaceBetween;
9344      if (params.slidesPerGroup > 1) {
9345        const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
9346        const groupSize = size * params.slidesPerGroup;
9347        for (let i = 0; i < groups; i += 1) {
9348          snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
9349        }
9350      }
9351      for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
9352        if (params.slidesPerGroup === 1) {
9353          snapGrid.push(snapGrid[snapGrid.length - 1] + size);
9354        }
9355        slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
9356        swiper.virtualSize += size;
9357      }
9358    }
9359    if (snapGrid.length === 0) snapGrid = [0];
9360    if (spaceBetween !== 0) {
9361      const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
9362      slides.filter((_, slideIndex) => {
9363        if (!params.cssMode || params.loop) return true;
9364        if (slideIndex === slides.length - 1) {
9365          return false;
9366        }
9367        return true;
9368      }
vendor: 65,509 bytes, lines 9368-11114
9368).forEach(slideEl => {
9369        slideEl.style[key] = `${spaceBetween}px`;
9370      });
9371    }
9372    if (params.centeredSlides && params.centeredSlidesBounds) {
9373      let allSlidesSize = 0;
9374      slidesSizesGrid.forEach(slideSizeValue => {
9375        allSlidesSize += slideSizeValue + (spaceBetween || 0);
9376      });
9377      allSlidesSize -= spaceBetween;
9378      const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0;
9379      snapGrid = snapGrid.map(snap => {
9380        if (snap <= 0) return -offsetBefore;
9381        if (snap > maxSnap) return maxSnap + offsetAfter;
9382        return snap;
9383      });
9384    }
9385    if (params.centerInsufficientSlides) {
9386      let allSlidesSize = 0;
9387      slidesSizesGrid.forEach(slideSizeValue => {
9388        allSlidesSize += slideSizeValue + (spaceBetween || 0);
9389      });
9390      allSlidesSize -= spaceBetween;
9391      const offsetSize = (offsetBefore || 0) + (offsetAfter || 0);
9392      if (allSlidesSize + offsetSize < swiperSize) {
9393        const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
9394        snapGrid.forEach((snap, snapIndex) => {
9395          snapGrid[snapIndex] = snap - allSlidesOffset;
9396        });
9397        slidesGrid.forEach((snap, snapIndex) => {
9398          slidesGrid[snapIndex] = snap + allSlidesOffset;
9399        });
9400      }
9401    }
9402    Object.assign(swiper, {
9403      slides,
9404      snapGrid,
9405      slidesGrid,
9406      slidesSizesGrid
9407    });
9408    if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
9409      setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
9410      setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
9411      const addToSnapGrid = -swiper.snapGrid[0];
9412      const addToSlidesGrid = -swiper.slidesGrid[0];
9413      swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
9414      swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
9415    }
9416    if (slidesLength !== previousSlidesLength) {
9417      swiper.emit('slidesLengthChange');
9418    }
9419    if (snapGrid.length !== previousSnapGridLength) {
9420      if (swiper.params.watchOverflow) swiper.checkOverflow();
9421      swiper.emit('snapGridLengthChange');
9422    }
9423    if (slidesGrid.length !== previousSlidesGridLength) {
9424      swiper.emit('slidesGridLengthChange');
9425    }
9426    if (params.watchSlidesProgress) {
9427      swiper.updateSlidesOffset();
9428    }
9429    swiper.emit('slidesUpdated');
9430    if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
9431      const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
9432      const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
9433      if (slidesLength <= params.maxBackfaceHiddenSlides) {
9434        if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
9435      } else if (hasClassBackfaceClassAdded) {
9436        swiper.el.classList.remove(backFaceHiddenClass);
9437      }
9438    }
9439  }
9440
9441  function updateAutoHeight(speed) {
9442    const swiper = this;
9443    const activeSlides = [];
9444    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
9445    let newHeight = 0;
9446    let i;
9447    if (typeof speed === 'number') {
9448      swiper.setTransition(speed);
9449    } else if (speed === true) {
9450      swiper.setTransition(swiper.params.speed);
9451    }
9452    const getSlideByIndex = index => {
9453      if (isVirtual) {
9454        return swiper.slides[swiper.getSlideIndexByData(index)];
9455      }
9456      return swiper.slides[index];
9457    };
9458    // Find slides currently in view
9459    if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
9460      if (swiper.params.centeredSlides) {
9461        (swiper.visibleSlides || []).forEach(slide => {
9462          activeSlides.push(slide);
9463        });
9464      } else {
9465        for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
9466          const index = swiper.activeIndex + i;
9467          if (index > swiper.slides.length && !isVirtual) break;
9468          activeSlides.push(getSlideByIndex(index));
9469        }
9470      }
9471    } else {
9472      activeSlides.push(getSlideByIndex(swiper.activeIndex));
9473    }
9474
9475    // Find new height from highest slide in view
9476    for (i = 0; i < activeSlides.length; i += 1) {
9477      if (typeof activeSlides[i] !== 'undefined') {
9478        const height = activeSlides[i].offsetHeight;
9479        newHeight = height > newHeight ? height : newHeight;
9480      }
9481    }
9482
9483    // Update Height
9484    if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
9485  }
9486
9487  function updateSlidesOffset() {
9488    const swiper = this;
9489    const slides = swiper.slides;
9490    // eslint-disable-next-line
9491    const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
9492    for (let i = 0; i < slides.length; i += 1) {
9493      slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
9494    }
9495  }
9496
9497  const toggleSlideClasses$1 = (slideEl, condition, className) => {
9498    if (condition && !slideEl.classList.contains(className)) {
9499      slideEl.classList.add(className);
9500    } else if (!condition && slideEl.classList.contains(className)) {
9501      slideEl.classList.remove(className);
9502    }
9503  };
9504  function updateSlidesProgress(translate = this && this.translate || 0) {
9505    const swiper = this;
9506    const params = swiper.params;
9507    const {
9508      slides,
9509      rtlTranslate: rtl,
9510      snapGrid
9511    } = swiper;
9512    if (slides.length === 0) return;
9513    if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
9514    let offsetCenter = -translate;
9515    if (rtl) offsetCenter = translate;
9516    swiper.visibleSlidesIndexes = [];
9517    swiper.visibleSlides = [];
9518    let spaceBetween = params.spaceBetween;
9519    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
9520      spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
9521    } else if (typeof spaceBetween === 'string') {
9522      spaceBetween = parseFloat(spaceBetween);
9523    }
9524    for (let i = 0; i < slides.length; i += 1) {
9525      const slide = slides[i];
9526      let slideOffset = slide.swiperSlideOffset;
9527      if (params.cssMode && params.centeredSlides) {
9528        slideOffset -= slides[0].swiperSlideOffset;
9529      }
9530      const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
9531      const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
9532      const slideBefore = -(offsetCenter - slideOffset);
9533      const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
9534      const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
9535      const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
9536      if (isVisible) {
9537        swiper.visibleSlides.push(slide);
9538        swiper.visibleSlidesIndexes.push(i);
9539      }
9540      toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
9541      toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
9542      slide.progress = rtl ? -slideProgress : slideProgress;
9543      slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
9544    }
9545  }
9546
9547  function updateProgress(translate) {
9548    const swiper = this;
9549    if (typeof translate === 'undefined') {
9550      const multiplier = swiper.rtlTranslate ? -1 : 1;
9551      // eslint-disable-next-line
9552      translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
9553    }
9554    const params = swiper.params;
9555    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
9556    let {
9557      progress,
9558      isBeginning,
9559      isEnd,
9560      progressLoop
9561    } = swiper;
9562    const wasBeginning = isBeginning;
9563    const wasEnd = isEnd;
9564    if (translatesDiff === 0) {
9565      progress = 0;
9566      isBeginning = true;
9567      isEnd = true;
9568    } else {
9569      progress = (translate - swiper.minTranslate()) / translatesDiff;
9570      const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
9571      const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
9572      isBeginning = isBeginningRounded || progress <= 0;
9573      isEnd = isEndRounded || progress >= 1;
9574      if (isBeginningRounded) progress = 0;
9575      if (isEndRounded) progress = 1;
9576    }
9577    if (params.loop) {
9578      const firstSlideIndex = swiper.getSlideIndexByData(0);
9579      const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
9580      const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
9581      const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
9582      const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
9583      const translateAbs = Math.abs(translate);
9584      if (translateAbs >= firstSlideTranslate) {
9585        progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
9586      } else {
9587        progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
9588      }
9589      if (progressLoop > 1) progressLoop -= 1;
9590    }
9591    Object.assign(swiper, {
9592      progress,
9593      progressLoop,
9594      isBeginning,
9595      isEnd
9596    });
9597    if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
9598    if (isBeginning && !wasBeginning) {
9599      swiper.emit('reachBeginning toEdge');
9600    }
9601    if (isEnd && !wasEnd) {
9602      swiper.emit('reachEnd toEdge');
9603    }
9604    if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
9605      swiper.emit('fromEdge');
9606    }
9607    swiper.emit('progress', progress);
9608  }
9609
9610  const toggleSlideClasses = (slideEl, condition, className) => {
9611    if (condition && !slideEl.classList.contains(className)) {
9612      slideEl.classList.add(className);
9613    } else if (!condition && slideEl.classList.contains(className)) {
9614      slideEl.classList.remove(className);
9615    }
9616  };
9617  function updateSlidesClasses() {
9618    const swiper = this;
9619    const {
9620      slides,
9621      params,
9622      slidesEl,
9623      activeIndex
9624    } = swiper;
9625    const isVirtual = swiper.virtual && params.virtual.enabled;
9626    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
9627    const getFilteredSlide = selector => {
9628      return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
9629    };
9630    let activeSlide;
9631    let prevSlide;
9632    let nextSlide;
9633    if (isVirtual) {
9634      if (params.loop) {
9635        let slideIndex = activeIndex - swiper.virtual.slidesBefore;
9636        if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
9637        if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
9638        activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
9639      } else {
9640        activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
9641      }
9642    } else {
9643      if (gridEnabled) {
9644        activeSlide = slides.find(slideEl => slideEl.column === activeIndex);
9645        nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1);
9646        prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1);
9647      } else {
9648        activeSlide = slides[activeIndex];
9649      }
9650    }
9651    if (activeSlide) {
9652      if (!gridEnabled) {
9653        // Next Slide
9654        nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
9655        if (params.loop && !nextSlide) {
9656          nextSlide = slides[0];
9657        }
9658
9659        // Prev Slide
9660        prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
9661        if (params.loop && !prevSlide === 0) {
9662          prevSlide = slides[slides.length - 1];
9663        }
9664      }
9665    }
9666    slides.forEach(slideEl => {
9667      toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
9668      toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
9669      toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
9670    });
9671    swiper.emitSlidesClasses();
9672  }
9673
9674  const processLazyPreloader = (swiper, imageEl) => {
9675    if (!swiper || swiper.destroyed || !swiper.params) return;
9676    const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
9677    const slideEl = imageEl.closest(slideSelector());
9678    if (slideEl) {
9679      let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
9680      if (!lazyEl && swiper.isElement) {
9681        if (slideEl.shadowRoot) {
9682          lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
9683        } else {
9684          // init later
9685          requestAnimationFrame(() => {
9686            if (slideEl.shadowRoot) {
9687              lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
9688              if (lazyEl) lazyEl.remove();
9689            }
9690          });
9691        }
9692      }
9693      if (lazyEl) lazyEl.remove();
9694    }
9695  };
9696  const unlazy = (swiper, index) => {
9697    if (!swiper.slides[index]) return;
9698    const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
9699    if (imageEl) imageEl.removeAttribute('loading');
9700  };
9701  const preload = swiper => {
9702    if (!swiper || swiper.destroyed || !swiper.params) return;
9703    let amount = swiper.params.lazyPreloadPrevNext;
9704    const len = swiper.slides.length;
9705    if (!len || !amount || amount < 0) return;
9706    amount = Math.min(amount, len);
9707    const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
9708    const activeIndex = swiper.activeIndex;
9709    if (swiper.params.grid && swiper.params.grid.rows > 1) {
9710      const activeColumn = activeIndex;
9711      const preloadColumns = [activeColumn - amount];
9712      preloadColumns.push(...Array.from({
9713        length: amount
9714      }).map((_, i) => {
9715        return activeColumn + slidesPerView + i;
9716      }));
9717      swiper.slides.forEach((slideEl, i) => {
9718        if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
9719      });
9720      return;
9721    }
9722    const slideIndexLastInView = activeIndex + slidesPerView - 1;
9723    if (swiper.params.rewind || swiper.params.loop) {
9724      for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
9725        const realIndex = (i % len + len) % len;
9726        if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
9727      }
9728    } else {
9729      for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
9730        if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
9731          unlazy(swiper, i);
9732        }
9733      }
9734    }
9735  };
9736
9737  function getActiveIndexByTranslate(swiper) {
9738    const {
9739      slidesGrid,
9740      params
9741    } = swiper;
9742    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
9743    let activeIndex;
9744    for (let i = 0; i < slidesGrid.length; i += 1) {
9745      if (typeof slidesGrid[i + 1] !== 'undefined') {
9746        if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
9747          activeIndex = i;
9748        } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
9749          activeIndex = i + 1;
9750        }
9751      } else if (translate >= slidesGrid[i]) {
9752        activeIndex = i;
9753      }
9754    }
9755    // Normalize slideIndex
9756    if (params.normalizeSlideIndex) {
9757      if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
9758    }
9759    return activeIndex;
9760  }
9761  function updateActiveIndex(newActiveIndex) {
9762    const swiper = this;
9763    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
9764    const {
9765      snapGrid,
9766      params,
9767      activeIndex: previousIndex,
9768      realIndex: previousRealIndex,
9769      snapIndex: previousSnapIndex
9770    } = swiper;
9771    let activeIndex = newActiveIndex;
9772    let snapIndex;
9773    const getVirtualRealIndex = aIndex => {
9774      let realIndex = aIndex - swiper.virtual.slidesBefore;
9775      if (realIndex < 0) {
9776        realIndex = swiper.virtual.slides.length + realIndex;
9777      }
9778      if (realIndex >= swiper.virtual.slides.length) {
9779        realIndex -= swiper.virtual.slides.length;
9780      }
9781      return realIndex;
9782    };
9783    if (typeof activeIndex === 'undefined') {
9784      activeIndex = getActiveIndexByTranslate(swiper);
9785    }
9786    if (snapGrid.indexOf(translate) >= 0) {
9787      snapIndex = snapGrid.indexOf(translate);
9788    } else {
9789      const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
9790      snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
9791    }
9792    if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
9793    if (activeIndex === previousIndex && !swiper.params.loop) {
9794      if (snapIndex !== previousSnapIndex) {
9795        swiper.snapIndex = snapIndex;
9796        swiper.emit('snapIndexChange');
9797      }
9798      return;
9799    }
9800    if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
9801      swiper.realIndex = getVirtualRealIndex(activeIndex);
9802      return;
9803    }
9804    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
9805
9806    // Get real index
9807    let realIndex;
9808    if (swiper.virtual && params.virtual.enabled && params.loop) {
9809      realIndex = getVirtualRealIndex(activeIndex);
9810    } else if (gridEnabled) {
9811      const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex);
9812      let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
9813      if (Number.isNaN(activeSlideIndex)) {
9814        activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
9815      }
9816      realIndex = Math.floor(activeSlideIndex / params.grid.rows);
9817    } else if (swiper.slides[activeIndex]) {
9818      const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
9819      if (slideIndex) {
9820        realIndex = parseInt(slideIndex, 10);
9821      } else {
9822        realIndex = activeIndex;
9823      }
9824    } else {
9825      realIndex = activeIndex;
9826    }
9827    Object.assign(swiper, {
9828      previousSnapIndex,
9829      snapIndex,
9830      previousRealIndex,
9831      realIndex,
9832      previousIndex,
9833      activeIndex
9834    });
9835    if (swiper.initialized) {
9836      preload(swiper);
9837    }
9838    swiper.emit('activeIndexChange');
9839    swiper.emit('snapIndexChange');
9840    if (swiper.initialized || swiper.params.runCallbacksOnInit) {
9841      if (previousRealIndex !== realIndex) {
9842        swiper.emit('realIndexChange');
9843      }
9844      swiper.emit('slideChange');
9845    }
9846  }
9847
9848  function updateClickedSlide(el, path) {
9849    const swiper = this;
9850    const params = swiper.params;
9851    let slide = el.closest(`.${params.slideClass}, swiper-slide`);
9852    if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
9853      [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
9854        if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
9855          slide = pathEl;
9856        }
9857      });
9858    }
9859    let slideFound = false;
9860    let slideIndex;
9861    if (slide) {
9862      for (let i = 0; i < swiper.slides.length; i += 1) {
9863        if (swiper.slides[i] === slide) {
9864          slideFound = true;
9865          slideIndex = i;
9866          break;
9867        }
9868      }
9869    }
9870    if (slide && slideFound) {
9871      swiper.clickedSlide = slide;
9872      if (swiper.virtual && swiper.params.virtual.enabled) {
9873        swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
9874      } else {
9875        swiper.clickedIndex = slideIndex;
9876      }
9877    } else {
9878      swiper.clickedSlide = undefined;
9879      swiper.clickedIndex = undefined;
9880      return;
9881    }
9882    if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
9883      swiper.slideToClickedSlide();
9884    }
9885  }
9886
9887  var update = {
9888    updateSize,
9889    updateSlides,
9890    updateAutoHeight,
9891    updateSlidesOffset,
9892    updateSlidesProgress,
9893    updateProgress,
9894    updateSlidesClasses,
9895    updateActiveIndex,
9896    updateClickedSlide
9897  };
9898
9899  function getSwiperTranslate(axis = this.isHorizontal() ? 'x' : 'y') {
9900    const swiper = this;
9901    const {
9902      params,
9903      rtlTranslate: rtl,
9904      translate,
9905      wrapperEl
9906    } = swiper;
9907    if (params.virtualTranslate) {
9908      return rtl ? -translate : translate;
9909    }
9910    if (params.cssMode) {
9911      return translate;
9912    }
9913    let currentTranslate = getTranslate(wrapperEl, axis);
9914    currentTranslate += swiper.cssOverflowAdjustment();
9915    if (rtl) currentTranslate = -currentTranslate;
9916    return currentTranslate || 0;
9917  }
9918
9919  function setTranslate(translate, byController) {
9920    const swiper = this;
9921    const {
9922      rtlTranslate: rtl,
9923      params,
9924      wrapperEl,
9925      progress
9926    } = swiper;
9927    let x = 0;
9928    let y = 0;
9929    const z = 0;
9930    if (swiper.isHorizontal()) {
9931      x = rtl ? -translate : translate;
9932    } else {
9933      y = translate;
9934    }
9935    if (params.roundLengths) {
9936      x = Math.floor(x);
9937      y = Math.floor(y);
9938    }
9939    swiper.previousTranslate = swiper.translate;
9940    swiper.translate = swiper.isHorizontal() ? x : y;
9941    if (params.cssMode) {
9942      wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
9943    } else if (!params.virtualTranslate) {
9944      if (swiper.isHorizontal()) {
9945        x -= swiper.cssOverflowAdjustment();
9946      } else {
9947        y -= swiper.cssOverflowAdjustment();
9948      }
9949      wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
9950    }
9951
9952    // Check if we need to update progress
9953    let newProgress;
9954    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
9955    if (translatesDiff === 0) {
9956      newProgress = 0;
9957    } else {
9958      newProgress = (translate - swiper.minTranslate()) / translatesDiff;
9959    }
9960    if (newProgress !== progress) {
9961      swiper.updateProgress(translate);
9962    }
9963    swiper.emit('setTranslate', swiper.translate, byController);
9964  }
9965
9966  function minTranslate() {
9967    return -this.snapGrid[0];
9968  }
9969
9970  function maxTranslate() {
9971    return -this.snapGrid[this.snapGrid.length - 1];
9972  }
9973
9974  function translateTo(translate = 0, speed = this.params.speed, runCallbacks = true, translateBounds = true, internal) {
9975    const swiper = this;
9976    const {
9977      params,
9978      wrapperEl
9979    } = swiper;
9980    if (swiper.animating && params.preventInteractionOnTransition) {
9981      return false;
9982    }
9983    const minTranslate = swiper.minTranslate();
9984    const maxTranslate = swiper.maxTranslate();
9985    let newTranslate;
9986    if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
9987
9988    // Update progress
9989    swiper.updateProgress(newTranslate);
9990    if (params.cssMode) {
9991      const isH = swiper.isHorizontal();
9992      if (speed === 0) {
9993        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
9994      } else {
9995        if (!swiper.support.smoothScroll) {
9996          animateCSSModeScroll({
9997            swiper,
9998            targetPosition: -newTranslate,
9999            side: isH ? 'left' : 'top'
10000          });
10001          return true;
10002        }
10003        wrapperEl.scrollTo({
10004          [isH ? 'left' : 'top']: -newTranslate,
10005          behavior: 'smooth'
10006        });
10007      }
10008      return true;
10009    }
10010    if (speed === 0) {
10011      swiper.setTransition(0);
10012      swiper.setTranslate(newTranslate);
10013      if (runCallbacks) {
10014        swiper.emit('beforeTransitionStart', speed, internal);
10015        swiper.emit('transitionEnd');
10016      }
10017    } else {
10018      swiper.setTransition(speed);
10019      swiper.setTranslate(newTranslate);
10020      if (runCallbacks) {
10021        swiper.emit('beforeTransitionStart', speed, internal);
10022        swiper.emit('transitionStart');
10023      }
10024      if (!swiper.animating) {
10025        swiper.animating = true;
10026        if (!swiper.onTranslateToWrapperTransitionEnd) {
10027          swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
10028            if (!swiper || swiper.destroyed) return;
10029            if (e.target !== this) return;
10030            swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
10031            swiper.onTranslateToWrapperTransitionEnd = null;
10032            delete swiper.onTranslateToWrapperTransitionEnd;
10033            swiper.animating = false;
10034            if (runCallbacks) {
10035              swiper.emit('transitionEnd');
10036            }
10037          };
10038        }
10039        swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
10040      }
10041    }
10042    return true;
10043  }
10044
10045  var translate = {
10046    getTranslate: getSwiperTranslate,
10047    setTranslate,
10048    minTranslate,
10049    maxTranslate,
10050    translateTo
10051  };
10052
10053  function setTransition(duration, byController) {
10054    const swiper = this;
10055    if (!swiper.params.cssMode) {
10056      swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
10057      swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
10058    }
10059    swiper.emit('setTransition', duration, byController);
10060  }
10061
10062  function transitionEmit({
10063    swiper,
10064    runCallbacks,
10065    direction,
10066    step
10067  }) {
10068    const {
10069      activeIndex,
10070      previousIndex
10071    } = swiper;
10072    let dir = direction;
10073    if (!dir) {
10074      if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
10075    }
10076    swiper.emit(`transition${step}`);
10077    if (runCallbacks && dir === 'reset') {
10078      swiper.emit(`slideResetTransition${step}`);
10079    } else if (runCallbacks && activeIndex !== previousIndex) {
10080      swiper.emit(`slideChangeTransition${step}`);
10081      if (dir === 'next') {
10082        swiper.emit(`slideNextTransition${step}`);
10083      } else {
10084        swiper.emit(`slidePrevTransition${step}`);
10085      }
10086    }
10087  }
10088
10089  function transitionStart(runCallbacks = true, direction) {
10090    const swiper = this;
10091    const {
10092      params
10093    } = swiper;
10094    if (params.cssMode) return;
10095    if (params.autoHeight) {
10096      swiper.updateAutoHeight();
10097    }
10098    transitionEmit({
10099      swiper,
10100      runCallbacks,
10101      direction,
10102      step: 'Start'
10103    });
10104  }
10105
10106  function transitionEnd(runCallbacks = true, direction) {
10107    const swiper = this;
10108    const {
10109      params
10110    } = swiper;
10111    swiper.animating = false;
10112    if (params.cssMode) return;
10113    swiper.setTransition(0);
10114    transitionEmit({
10115      swiper,
10116      runCallbacks,
10117      direction,
10118      step: 'End'
10119    });
10120  }
10121
10122  var transition = {
10123    setTransition,
10124    transitionStart,
10125    transitionEnd
10126  };
10127
10128  function slideTo(index = 0, speed, runCallbacks = true, internal, initial) {
10129    if (typeof index === 'string') {
10130      index = parseInt(index, 10);
10131    }
10132    const swiper = this;
10133    let slideIndex = index;
10134    if (slideIndex < 0) slideIndex = 0;
10135    const {
10136      params,
10137      snapGrid,
10138      slidesGrid,
10139      previousIndex,
10140      activeIndex,
10141      rtlTranslate: rtl,
10142      wrapperEl,
10143      enabled
10144    } = swiper;
10145    if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
10146      return false;
10147    }
10148    if (typeof speed === 'undefined') {
10149      speed = swiper.params.speed;
10150    }
10151    const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
10152    let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
10153    if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
10154    const translate = -snapGrid[snapIndex];
10155    // Normalize slideIndex
10156    if (params.normalizeSlideIndex) {
10157      for (let i = 0; i < slidesGrid.length; i += 1) {
10158        const normalizedTranslate = -Math.floor(translate * 100);
10159        const normalizedGrid = Math.floor(slidesGrid[i] * 100);
10160        const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
10161        if (typeof slidesGrid[i + 1] !== 'undefined') {
10162          if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
10163            slideIndex = i;
10164          } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
10165            slideIndex = i + 1;
10166          }
10167        } else if (normalizedTranslate >= normalizedGrid) {
10168          slideIndex = i;
10169        }
10170      }
10171    }
10172    // Directions locks
10173    if (swiper.initialized && slideIndex !== activeIndex) {
10174      if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
10175        return false;
10176      }
10177      if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
10178        if ((activeIndex || 0) !== slideIndex) {
10179          return false;
10180        }
10181      }
10182    }
10183    if (slideIndex !== (previousIndex || 0) && runCallbacks) {
10184      swiper.emit('beforeSlideChangeStart');
10185    }
10186
10187    // Update progress
10188    swiper.updateProgress(translate);
10189    let direction;
10190    if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
10191
10192    // initial virtual
10193    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
10194    const isInitialVirtual = isVirtual && initial;
10195    // Update Index
10196    if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
10197      swiper.updateActiveIndex(slideIndex);
10198      // Update Height
10199      if (params.autoHeight) {
10200        swiper.updateAutoHeight();
10201      }
10202      swiper.updateSlidesClasses();
10203      if (params.effect !== 'slide') {
10204        swiper.setTranslate(translate);
10205      }
10206      if (direction !== 'reset') {
10207        swiper.transitionStart(runCallbacks, direction);
10208        swiper.transitionEnd(runCallbacks, direction);
10209      }
10210      return false;
10211    }
10212    if (params.cssMode) {
10213      const isH = swiper.isHorizontal();
10214      const t = rtl ? translate : -translate;
10215      if (speed === 0) {
10216        if (isVirtual) {
10217          swiper.wrapperEl.style.scrollSnapType = 'none';
10218          swiper._immediateVirtual = true;
10219        }
10220        if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
10221          swiper._cssModeVirtualInitialSet = true;
10222          requestAnimationFrame(() => {
10223            wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
10224          });
10225        } else {
10226          wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
10227        }
10228        if (isVirtual) {
10229          requestAnimationFrame(() => {
10230            swiper.wrapperEl.style.scrollSnapType = '';
10231            swiper._immediateVirtual = false;
10232          });
10233        }
10234      } else {
10235        if (!swiper.support.smoothScroll) {
10236          animateCSSModeScroll({
10237            swiper,
10238            targetPosition: t,
10239            side: isH ? 'left' : 'top'
10240          });
10241          return true;
10242        }
10243        wrapperEl.scrollTo({
10244          [isH ? 'left' : 'top']: t,
10245          behavior: 'smooth'
10246        });
10247      }
10248      return true;
10249    }
10250    const browser = getBrowser();
10251    const isSafari = browser.isSafari;
10252    if (isVirtual && !initial && isSafari && swiper.isElement) {
10253      swiper.virtual.update(false, false, slideIndex);
10254    }
10255    swiper.setTransition(speed);
10256    swiper.setTranslate(translate);
10257    swiper.updateActiveIndex(slideIndex);
10258    swiper.updateSlidesClasses();
10259    swiper.emit('beforeTransitionStart', speed, internal);
10260    swiper.transitionStart(runCallbacks, direction);
10261    if (speed === 0) {
10262      swiper.transitionEnd(runCallbacks, direction);
10263    } else if (!swiper.animating) {
10264      swiper.animating = true;
10265      if (!swiper.onSlideToWrapperTransitionEnd) {
10266        swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
10267          if (!swiper || swiper.destroyed) return;
10268          if (e.target !== this) return;
10269          swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
10270          swiper.onSlideToWrapperTransitionEnd = null;
10271          delete swiper.onSlideToWrapperTransitionEnd;
10272          swiper.transitionEnd(runCallbacks, direction);
10273        };
10274      }
10275      swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
10276    }
10277    return true;
10278  }
10279
10280  function slideToLoop(index = 0, speed, runCallbacks = true, internal) {
10281    if (typeof index === 'string') {
10282      const indexAsNumber = parseInt(index, 10);
10283      index = indexAsNumber;
10284    }
10285    const swiper = this;
10286    if (swiper.destroyed) return;
10287    if (typeof speed === 'undefined') {
10288      speed = swiper.params.speed;
10289    }
10290    const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
10291    let newIndex = index;
10292    if (swiper.params.loop) {
10293      if (swiper.virtual && swiper.params.virtual.enabled) {
10294        // eslint-disable-next-line
10295        newIndex = newIndex + swiper.virtual.slidesBefore;
10296      } else {
10297        let targetSlideIndex;
10298        if (gridEnabled) {
10299          const slideIndex = newIndex * swiper.params.grid.rows;
10300          targetSlideIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
10301        } else {
10302          targetSlideIndex = swiper.getSlideIndexByData(newIndex);
10303        }
10304        const cols = gridEnabled ? Math.ceil(swiper.slides.length / swiper.params.grid.rows) : swiper.slides.length;
10305        const {
10306          centeredSlides,
10307          slidesOffsetBefore,
10308          slidesOffsetAfter
10309        } = swiper.params;
10310        const bothDirections = centeredSlides || !!slidesOffsetBefore || !!slidesOffsetAfter;
10311        let slidesPerView = swiper.params.slidesPerView;
10312        if (slidesPerView === 'auto') {
10313          slidesPerView = swiper.slidesPerViewDynamic();
10314        } else {
10315          slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
10316          if (bothDirections && slidesPerView % 2 === 0) {
10317            slidesPerView = slidesPerView + 1;
10318          }
10319        }
10320        let needLoopFix = cols - targetSlideIndex < slidesPerView;
10321        if (bothDirections) {
10322          needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
10323        }
10324        if (internal && bothDirections && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
10325          needLoopFix = false;
10326        }
10327        if (needLoopFix) {
10328          const direction = bothDirections ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
10329          swiper.loopFix({
10330            direction,
10331            slideTo: true,
10332            activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
10333            slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
10334          });
10335        }
10336        if (gridEnabled) {
10337          const slideIndex = newIndex * swiper.params.grid.rows;
10338          newIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
10339        } else {
10340          newIndex = swiper.getSlideIndexByData(newIndex);
10341        }
10342      }
10343    }
10344    requestAnimationFrame(() => {
10345      swiper.slideTo(newIndex, speed, runCallbacks, internal);
10346    });
10347    return swiper;
10348  }
10349
10350  /* eslint no-unused-vars: "off" */
10351  function slideNext(speed, runCallbacks = true, internal) {
10352    const swiper = this;
10353    const {
10354      enabled,
10355      params,
10356      animating
10357    } = swiper;
10358    if (!enabled || swiper.destroyed) return swiper;
10359    if (typeof speed === 'undefined') {
10360      speed = swiper.params.speed;
10361    }
10362    let perGroup = params.slidesPerGroup;
10363    if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
10364      perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
10365    }
10366    const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
10367    const isVirtual = swiper.virtual && params.virtual.enabled;
10368    if (params.loop) {
10369      if (animating && !isVirtual && params.loopPreventsSliding) return false;
10370      swiper.loopFix({
10371        direction: 'next'
10372      });
10373      // eslint-disable-next-line
10374      swiper._clientLeft = swiper.wrapperEl.clientLeft;
10375      if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
10376        requestAnimationFrame(() => {
10377          swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
10378        });
10379        return true;
10380      }
10381    }
10382    if (params.rewind && swiper.isEnd) {
10383      return swiper.slideTo(0, speed, runCallbacks, internal);
10384    }
10385    return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
10386  }
10387
10388  /* eslint no-unused-vars: "off" */
10389  function slidePrev(speed, runCallbacks = true, internal) {
10390    const swiper = this;
10391    const {
10392      params,
10393      snapGrid,
10394      slidesGrid,
10395      rtlTranslate,
10396      enabled,
10397      animating
10398    } = swiper;
10399    if (!enabled || swiper.destroyed) return swiper;
10400    if (typeof speed === 'undefined') {
10401      speed = swiper.params.speed;
10402    }
10403    const isVirtual = swiper.virtual && params.virtual.enabled;
10404    if (params.loop) {
10405      if (animating && !isVirtual && params.loopPreventsSliding) return false;
10406      swiper.loopFix({
10407        direction: 'prev'
10408      });
10409      // eslint-disable-next-line
10410      swiper._clientLeft = swiper.wrapperEl.clientLeft;
10411    }
10412    const translate = rtlTranslate ? swiper.translate : -swiper.translate;
10413    function normalize(val) {
10414      if (val < 0) return -Math.floor(Math.abs(val));
10415      return Math.floor(val);
10416    }
10417    const normalizedTranslate = normalize(translate);
10418    const normalizedSnapGrid = snapGrid.map(val => normalize(val));
10419    const isFreeMode = params.freeMode && params.freeMode.enabled;
10420    let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
10421    if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) {
10422      let prevSnapIndex;
10423      snapGrid.forEach((snap, snapIndex) => {
10424        if (normalizedTranslate >= snap) {
10425          // prevSnap = snap;
10426          prevSnapIndex = snapIndex;
10427        }
10428      });
10429      if (typeof prevSnapIndex !== 'undefined') {
10430        prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
10431      }
10432    }
10433    let prevIndex = 0;
10434    if (typeof prevSnap !== 'undefined') {
10435      prevIndex = slidesGrid.indexOf(prevSnap);
10436      if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
10437      if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
10438        prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
10439        prevIndex = Math.max(prevIndex, 0);
10440      }
10441    }
10442    if (params.rewind && swiper.isBeginning) {
10443      const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
10444      return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
10445    } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
10446      requestAnimationFrame(() => {
10447        swiper.slideTo(prevIndex, speed, runCallbacks, internal);
10448      });
10449      return true;
10450    }
10451    return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
10452  }
10453
10454  /* eslint no-unused-vars: "off" */
10455  function slideReset(speed, runCallbacks = true, internal) {
10456    const swiper = this;
10457    if (swiper.destroyed) return;
10458    if (typeof speed === 'undefined') {
10459      speed = swiper.params.speed;
10460    }
10461    return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
10462  }
10463
10464  /* eslint no-unused-vars: "off" */
10465  function slideToClosest(speed, runCallbacks = true, internal, threshold = 0.5) {
10466    const swiper = this;
10467    if (swiper.destroyed) return;
10468    if (typeof speed === 'undefined') {
10469      speed = swiper.params.speed;
10470    }
10471    let index = swiper.activeIndex;
10472    const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
10473    const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
10474    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
10475    if (translate >= swiper.snapGrid[snapIndex]) {
10476      // The current translate is on or after the current snap index, so the choice
10477      // is between the current index and the one after it.
10478      const currentSnap = swiper.snapGrid[snapIndex];
10479      const nextSnap = swiper.snapGrid[snapIndex + 1];
10480      if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
10481        index += swiper.params.slidesPerGroup;
10482      }
10483    } else {
10484      // The current translate is before the current snap index, so the choice
10485      // is between the current index and the one before it.
10486      const prevSnap = swiper.snapGrid[snapIndex - 1];
10487      const currentSnap = swiper.snapGrid[snapIndex];
10488      if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
10489        index -= swiper.params.slidesPerGroup;
10490      }
10491    }
10492    index = Math.max(index, 0);
10493    index = Math.min(index, swiper.slidesGrid.length - 1);
10494    return swiper.slideTo(index, speed, runCallbacks, internal);
10495  }
10496
10497  function slideToClickedSlide() {
10498    const swiper = this;
10499    if (swiper.destroyed) return;
10500    const {
10501      params,
10502      slidesEl
10503    } = swiper;
10504    const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
10505    let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex);
10506    let realIndex;
10507    const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
10508    const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
10509    if (params.loop) {
10510      if (swiper.animating) return;
10511      realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
10512      if (params.centeredSlides) {
10513        swiper.slideToLoop(realIndex);
10514      } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) {
10515        swiper.loopFix();
10516        slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
10517        nextTick(() => {
10518          swiper.slideTo(slideToIndex);
10519        });
10520      } else {
10521        swiper.slideTo(slideToIndex);
10522      }
10523    } else {
10524      swiper.slideTo(slideToIndex);
10525    }
10526  }
10527
10528  var slide = {
10529    slideTo,
10530    slideToLoop,
10531    slideNext,
10532    slidePrev,
10533    slideReset,
10534    slideToClosest,
10535    slideToClickedSlide
10536  };
10537
10538  function loopCreate(slideRealIndex, initial) {
10539    const swiper = this;
10540    const {
10541      params,
10542      slidesEl
10543    } = swiper;
10544    if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
10545    const initSlides = () => {
10546      const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
10547      slides.forEach((el, index) => {
10548        el.setAttribute('data-swiper-slide-index', index);
10549      });
10550    };
10551    const clearBlankSlides = () => {
10552      const slides = elementChildren(slidesEl, `.${params.slideBlankClass}`);
10553      slides.forEach(el => {
10554        el.remove();
10555      });
10556      if (slides.length > 0) {
10557        swiper.recalcSlides();
10558        swiper.updateSlides();
10559      }
10560    };
10561    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
10562    if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) {
10563      clearBlankSlides();
10564    }
10565    const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
10566    const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
10567    const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
10568    const addBlankSlides = amountOfSlides => {
10569      for (let i = 0; i < amountOfSlides; i += 1) {
10570        const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
10571        swiper.slidesEl.append(slideEl);
10572      }
10573    };
10574    if (shouldFillGroup) {
10575      if (params.loopAddBlankSlides) {
10576        const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
10577        addBlankSlides(slidesToAdd);
10578        swiper.recalcSlides();
10579        swiper.updateSlides();
10580      } else {
10581        showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
10582      }
10583      initSlides();
10584    } else if (shouldFillGrid) {
10585      if (params.loopAddBlankSlides) {
10586        const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
10587        addBlankSlides(slidesToAdd);
10588        swiper.recalcSlides();
10589        swiper.updateSlides();
10590      } else {
10591        showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
10592      }
10593      initSlides();
10594    } else {
10595      initSlides();
10596    }
10597    const bothDirections = params.centeredSlides || !!params.slidesOffsetBefore || !!params.slidesOffsetAfter;
10598    swiper.loopFix({
10599      slideRealIndex,
10600      direction: bothDirections ? undefined : 'next',
10601      initial
10602    });
10603  }
10604
10605  function loopFix({
10606    slideRealIndex,
10607    slideTo = true,
10608    direction,
10609    setTranslate,
10610    activeSlideIndex,
10611    initial,
10612    byController,
10613    byMousewheel
10614  } = {}) {
10615    const swiper = this;
10616    if (!swiper.params.loop) return;
10617    swiper.emit('beforeLoopFix');
10618    const {
10619      slides,
10620      allowSlidePrev,
10621      allowSlideNext,
10622      slidesEl,
10623      params
10624    } = swiper;
10625    const {
10626      centeredSlides,
10627      slidesOffsetBefore,
10628      slidesOffsetAfter,
10629      initialSlide
10630    } = params;
10631    const bothDirections = centeredSlides || !!slidesOffsetBefore || !!slidesOffsetAfter;
10632    swiper.allowSlidePrev = true;
10633    swiper.allowSlideNext = true;
10634    if (swiper.virtual && params.virtual.enabled) {
10635      if (slideTo) {
10636        if (!bothDirections && swiper.snapIndex === 0) {
10637          swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
10638        } else if (bothDirections && swiper.snapIndex < params.slidesPerView) {
10639          swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
10640        } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
10641          swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
10642        }
10643      }
10644      swiper.allowSlidePrev = allowSlidePrev;
10645      swiper.allowSlideNext = allowSlideNext;
10646      swiper.emit('loopFix');
10647      return;
10648    }
10649    let slidesPerView = params.slidesPerView;
10650    if (slidesPerView === 'auto') {
10651      slidesPerView = swiper.slidesPerViewDynamic();
10652    } else {
10653      slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
10654      if (bothDirections && slidesPerView % 2 === 0) {
10655        slidesPerView = slidesPerView + 1;
10656      }
10657    }
10658    const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
10659    let loopedSlides = bothDirections ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup;
10660    if (loopedSlides % slidesPerGroup !== 0) {
10661      loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
10662    }
10663    loopedSlides += params.loopAdditionalSlides;
10664    swiper.loopedSlides = loopedSlides;
10665    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
10666    if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
10667      showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
10668    } else if (gridEnabled && params.grid.fill === 'row') {
10669      showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
10670    }
10671    const prependSlidesIndexes = [];
10672    const appendSlidesIndexes = [];
10673    const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
10674    const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !bothDirections;
10675    let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex;
10676    if (typeof activeSlideIndex === 'undefined') {
10677      activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass)));
10678    } else {
10679      activeIndex = activeSlideIndex;
10680    }
10681    const isNext = direction === 'next' || !direction;
10682    const isPrev = direction === 'prev' || !direction;
10683    let slidesPrepended = 0;
10684    let slidesAppended = 0;
10685    const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
10686    const activeColIndexWithShift = activeColIndex + (bothDirections && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
10687    // prepend last slides before start
10688    if (activeColIndexWithShift < loopedSlides) {
10689      slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
10690      for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
10691        const index = i - Math.floor(i / cols) * cols;
10692        if (gridEnabled) {
10693          const colIndexToPrepend = cols - index - 1;
10694          for (let i = slides.length - 1; i >= 0; i -= 1) {
10695            if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
10696          }
10697          // slides.forEach((slide, slideIndex) => {
10698          //   if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
10699          // });
10700        } else {
10701          prependSlidesIndexes.push(cols - index - 1);
10702        }
10703      }
10704    } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
10705      slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
10706      if (isInitialOverflow) {
10707        slidesAppended = Math.max(slidesAppended, slidesPerView - cols + initialSlide + 1);
10708      }
10709      for (let i = 0; i < slidesAppended; i += 1) {
10710        const index = i - Math.floor(i / cols) * cols;
10711        if (gridEnabled) {
10712          slides.forEach((slide, slideIndex) => {
10713            if (slide.column === index) appendSlidesIndexes.push(slideIndex);
10714          });
10715        } else {
10716          appendSlidesIndexes.push(index);
10717        }
10718      }
10719    }
10720    swiper.__preventObserver__ = true;
10721    requestAnimationFrame(() => {
10722      swiper.__preventObserver__ = false;
10723    });
10724    if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
10725      if (appendSlidesIndexes.includes(activeSlideIndex)) {
10726        appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1);
10727      }
10728      if (prependSlidesIndexes.includes(activeSlideIndex)) {
10729        prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1);
10730      }
10731    }
10732    if (isPrev) {
10733      prependSlidesIndexes.forEach(index => {
10734        slides[index].swiperLoopMoveDOM = true;
10735        slidesEl.prepend(slides[index]);
10736        slides[index].swiperLoopMoveDOM = false;
10737      });
10738    }
10739    if (isNext) {
10740      appendSlidesIndexes.forEach(index => {
10741        slides[index].swiperLoopMoveDOM = true;
10742        slidesEl.append(slides[index]);
10743        slides[index].swiperLoopMoveDOM = false;
10744      });
10745    }
10746    swiper.recalcSlides();
10747    if (params.slidesPerView === 'auto') {
10748      swiper.updateSlides();
10749    } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
10750      swiper.slides.forEach((slide, slideIndex) => {
10751        swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
10752      });
10753    }
10754    if (params.watchSlidesProgress) {
10755      swiper.updateSlidesOffset();
10756    }
10757    if (slideTo) {
10758      if (prependSlidesIndexes.length > 0 && isPrev) {
10759        if (typeof slideRealIndex === 'undefined') {
10760          const currentSlideTranslate = swiper.slidesGrid[activeIndex];
10761          const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
10762          const diff = newSlideTranslate - currentSlideTranslate;
10763          if (byMousewheel) {
10764            swiper.setTranslate(swiper.translate - diff);
10765          } else {
10766            swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
10767            if (setTranslate) {
10768              swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
10769              swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
10770            }
10771          }
10772        } else {
10773          if (setTranslate) {
10774            const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
10775            swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
10776            swiper.touchEventsData.currentTranslate = swiper.translate;
10777          }
10778        }
10779      } else if (appendSlidesIndexes.length > 0 && isNext) {
10780        if (typeof slideRealIndex === 'undefined') {
10781          const currentSlideTranslate = swiper.slidesGrid[activeIndex];
10782          const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
10783          const diff = newSlideTranslate - currentSlideTranslate;
10784          if (byMousewheel) {
10785            swiper.setTranslate(swiper.translate - diff);
10786          } else {
10787            swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
10788            if (setTranslate) {
10789              swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
10790              swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
10791            }
10792          }
10793        } else {
10794          const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
10795          swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
10796        }
10797      }
10798    }
10799    swiper.allowSlidePrev = allowSlidePrev;
10800    swiper.allowSlideNext = allowSlideNext;
10801    if (swiper.controller && swiper.controller.control && !byController) {
10802      const loopParams = {
10803        slideRealIndex,
10804        direction,
10805        setTranslate,
10806        activeSlideIndex,
10807        byController: true
10808      };
10809      if (Array.isArray(swiper.controller.control)) {
10810        swiper.controller.control.forEach(c => {
10811          if (!c.destroyed && c.params.loop) c.loopFix({
10812            ...loopParams,
10813            slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
10814          });
10815        });
10816      } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
10817        swiper.controller.control.loopFix({
10818          ...loopParams,
10819          slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
10820        });
10821      }
10822    }
10823    swiper.emit('loopFix');
10824  }
10825
10826  function loopDestroy() {
10827    const swiper = this;
10828    const {
10829      params,
10830      slidesEl
10831    } = swiper;
10832    if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return;
10833    swiper.recalcSlides();
10834    const newSlidesOrder = [];
10835    swiper.slides.forEach(slideEl => {
10836      const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
10837      newSlidesOrder[index] = slideEl;
10838    });
10839    swiper.slides.forEach(slideEl => {
10840      slideEl.removeAttribute('data-swiper-slide-index');
10841    });
10842    newSlidesOrder.forEach(slideEl => {
10843      slidesEl.append(slideEl);
10844    });
10845    swiper.recalcSlides();
10846    swiper.slideTo(swiper.realIndex, 0);
10847  }
10848
10849  var loop = {
10850    loopCreate,
10851    loopFix,
10852    loopDestroy
10853  };
10854
10855  function setGrabCursor(moving) {
10856    const swiper = this;
10857    if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
10858    const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
10859    if (swiper.isElement) {
10860      swiper.__preventObserver__ = true;
10861    }
10862    el.style.cursor = 'move';
10863    el.style.cursor = moving ? 'grabbing' : 'grab';
10864    if (swiper.isElement) {
10865      requestAnimationFrame(() => {
10866        swiper.__preventObserver__ = false;
10867      });
10868    }
10869  }
10870
10871  function unsetGrabCursor() {
10872    const swiper = this;
10873    if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
10874      return;
10875    }
10876    if (swiper.isElement) {
10877      swiper.__preventObserver__ = true;
10878    }
10879    swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
10880    if (swiper.isElement) {
10881      requestAnimationFrame(() => {
10882        swiper.__preventObserver__ = false;
10883      });
10884    }
10885  }
10886
10887  var grabCursor = {
10888    setGrabCursor,
10889    unsetGrabCursor
10890  };
10891
10892  // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
10893  function closestElement(selector, base = this) {
10894    function __closestFrom(el) {
10895      if (!el || el === getDocument() || el === getWindow()) return null;
10896      if (el.assignedSlot) el = el.assignedSlot;
10897      const found = el.closest(selector);
10898      if (!found && !el.getRootNode) {
10899        return null;
10900      }
10901      return found || __closestFrom(el.getRootNode().host);
10902    }
10903    return __closestFrom(base);
10904  }
10905  function preventEdgeSwipe(swiper, event, startX) {
10906    const window = getWindow();
10907    const {
10908      params
10909    } = swiper;
10910    const edgeSwipeDetection = params.edgeSwipeDetection;
10911    const edgeSwipeThreshold = params.edgeSwipeThreshold;
10912    if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
10913      if (edgeSwipeDetection === 'prevent') {
10914        event.preventDefault();
10915        return true;
10916      }
10917      return false;
10918    }
10919    return true;
10920  }
10921  function onTouchStart(event) {
10922    const swiper = this;
10923    const document = getDocument();
10924    let e = event;
10925    if (e.originalEvent) e = e.originalEvent;
10926    const data = swiper.touchEventsData;
10927    if (e.type === 'pointerdown') {
10928      if (data.pointerId !== null && data.pointerId !== e.pointerId) {
10929        return;
10930      }
10931      data.pointerId = e.pointerId;
10932    } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
10933      data.touchId = e.targetTouches[0].identifier;
10934    }
10935    if (e.type === 'touchstart') {
10936      // don't proceed touch event
10937      preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
10938      return;
10939    }
10940    const {
10941      params,
10942      touches,
10943      enabled
10944    } = swiper;
10945    if (!enabled) return;
10946    if (!params.simulateTouch && e.pointerType === 'mouse') return;
10947    if (swiper.animating && params.preventInteractionOnTransition) {
10948      return;
10949    }
10950    if (!swiper.animating && params.cssMode && params.loop) {
10951      swiper.loopFix();
10952    }
10953    let targetEl = e.target;
10954    if (params.touchEventsTarget === 'wrapper') {
10955      if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return;
10956    }
10957    if ('which' in e && e.which === 3) return;
10958    if ('button' in e && e.button > 0) return;
10959    if (data.isTouched && data.isMoved) return;
10960
10961    // change target el for shadow root component
10962    const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
10963    // eslint-disable-next-line
10964    const eventPath = e.composedPath ? e.composedPath() : e.path;
10965    if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
10966      targetEl = eventPath[0];
10967    }
10968    const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
10969    const isTargetShadow = !!(e.target && e.target.shadowRoot);
10970
10971    // use closestElement for shadow root element to get the actual closest for nested shadow root element
10972    if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
10973      swiper.allowClick = true;
10974      return;
10975    }
10976    if (params.swipeHandler) {
10977      if (!targetEl.closest(params.swipeHandler)) return;
10978    }
10979    touches.currentX = e.pageX;
10980    touches.currentY = e.pageY;
10981    const startX = touches.currentX;
10982    const startY = touches.currentY;
10983
10984    // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
10985
10986    if (!preventEdgeSwipe(swiper, e, startX)) {
10987      return;
10988    }
10989    Object.assign(data, {
10990      isTouched: true,
10991      isMoved: false,
10992      allowTouchCallbacks: true,
10993      isScrolling: undefined,
10994      startMoving: undefined
10995    });
10996    touches.startX = startX;
10997    touches.startY = startY;
10998    data.touchStartTime = now();
10999    swiper.allowClick = true;
11000    swiper.updateSize();
11001    swiper.swipeDirection = undefined;
11002    if (params.threshold > 0) data.allowThresholdMove = false;
11003    let preventDefault = true;
11004    if (targetEl.matches(data.focusableElements)) {
11005      preventDefault = false;
11006      if (targetEl.nodeName === 'SELECT') {
11007        data.isTouched = false;
11008      }
11009    }
11010    if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) {
11011      document.activeElement.blur();
11012    }
11013    const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
11014    if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
11015      e.preventDefault();
11016    }
11017    if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
11018      swiper.freeMode.onTouchStart();
11019    }
11020    swiper.emit('touchStart', e);
11021  }
11022
11023  function onTouchMove(event) {
11024    const document = getDocument();
11025    const swiper = this;
11026    const data = swiper.touchEventsData;
11027    const {
11028      params,
11029      touches,
11030      rtlTranslate: rtl,
11031      enabled
11032    } = swiper;
11033    if (!enabled) return;
11034    if (!params.simulateTouch && event.pointerType === 'mouse') return;
11035    let e = event;
11036    if (e.originalEvent) e = e.originalEvent;
11037    if (e.type === 'pointermove') {
11038      if (data.touchId !== null) return; // return from pointer if we use touch
11039      const id = e.pointerId;
11040      if (id !== data.pointerId) return;
11041    }
11042    let targetTouch;
11043    if (e.type === 'touchmove') {
11044      targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
11045      if (!targetTouch || targetTouch.identifier !== data.touchId) return;
11046    } else {
11047      targetTouch = e;
11048    }
11049    if (!data.isTouched) {
11050      if (data.startMoving && data.isScrolling) {
11051        swiper.emit('touchMoveOpposite', e);
11052      }
11053      return;
11054    }
11055    const pageX = targetTouch.pageX;
11056    const pageY = targetTouch.pageY;
11057    if (e.preventedByNestedSwiper) {
11058      touches.startX = pageX;
11059      touches.startY = pageY;
11060      return;
11061    }
11062    if (!swiper.allowTouchMove) {
11063      if (!e.target.matches(data.focusableElements)) {
11064        swiper.allowClick = false;
11065      }
11066      if (data.isTouched) {
11067        Object.assign(touches, {
11068          startX: pageX,
11069          startY: pageY,
11070          currentX: pageX,
11071          currentY: pageY
11072        });
11073        data.touchStartTime = now();
11074      }
11075      return;
11076    }
11077    if (params.touchReleaseOnEdges && !params.loop) {
11078      if (swiper.isVertical()) {
11079        // Vertical
11080        if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
11081          data.isTouched = false;
11082          data.isMoved = false;
11083          return;
11084        }
11085      } else if (rtl && (pageX > touches.startX && -swiper.translate <= swiper.maxTranslate() || pageX < touches.startX && -swiper.translate >= swiper.minTranslate())) {
11086        return;
11087      } else if (!rtl && (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate())) {
11088        return;
11089      }
11090    }
11091    if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') {
11092      document.activeElement.blur();
11093    }
11094    if (document.activeElement) {
11095      if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
11096        data.isMoved = true;
11097        swiper.allowClick = false;
11098        return;
11099      }
11100    }
11101    if (data.allowTouchCallbacks) {
11102      swiper.emit('touchMove', e);
11103    }
11104    touches.previousX = touches.currentX;
11105    touches.previousY = touches.currentY;
11106    touches.currentX = pageX;
11107    touches.currentY = pageY;
11108    const diffX = touches.currentX - touches.startX;
11109    const diffY = touches.currentY - touches.startY;
11110    if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
11111    if (typeof data.isScrolling === 'undefined') {
11112      let touchAngle;
11113      if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
11114        data.isScrolling = false;
vendor: 8,243 bytes, lines 11115-11320
11115      } else {
11116        // eslint-disable-next-line
11117        if (diffX * diffX + diffY * diffY >= 25) {
11118          touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
11119          data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
11120        }
11121      }
11122    }
11123    if (data.isScrolling) {
11124      swiper.emit('touchMoveOpposite', e);
11125    }
11126    if (typeof data.startMoving === 'undefined') {
11127      if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
11128        data.startMoving = true;
11129      }
11130    }
11131    if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
11132      data.isTouched = false;
11133      return;
11134    }
11135    if (!data.startMoving) {
11136      return;
11137    }
11138    swiper.allowClick = false;
11139    if (!params.cssMode && e.cancelable) {
11140      e.preventDefault();
11141    }
11142    if (params.touchMoveStopPropagation && !params.nested) {
11143      e.stopPropagation();
11144    }
11145    let diff = swiper.isHorizontal() ? diffX : diffY;
11146    let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
11147    if (params.oneWayMovement) {
11148      diff = Math.abs(diff) * (rtl ? 1 : -1);
11149      touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
11150    }
11151    touches.diff = diff;
11152    diff *= params.touchRatio;
11153    if (rtl) {
11154      diff = -diff;
11155      touchesDiff = -touchesDiff;
11156    }
11157    const prevTouchesDirection = swiper.touchesDirection;
11158    swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
11159    swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
11160    const isLoop = swiper.params.loop && !params.cssMode;
11161    const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
11162    if (!data.isMoved) {
11163      if (isLoop && allowLoopFix) {
11164        swiper.loopFix({
11165          direction: swiper.swipeDirection
11166        });
11167      }
11168      data.startTranslate = swiper.getTranslate();
11169      swiper.setTransition(0);
11170      if (swiper.animating) {
11171        const evt = new window.CustomEvent('transitionend', {
11172          bubbles: true,
11173          cancelable: true,
11174          detail: {
11175            bySwiperTouchMove: true
11176          }
11177        });
11178        swiper.wrapperEl.dispatchEvent(evt);
11179      }
11180      data.allowMomentumBounce = false;
11181      // Grab Cursor
11182      if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
11183        swiper.setGrabCursor(true);
11184      }
11185      swiper.emit('sliderFirstMove', e);
11186    }
11187    let loopFixed;
11188    new Date().getTime();
11189    if (params._loopSwapReset !== false && data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
11190      Object.assign(touches, {
11191        startX: pageX,
11192        startY: pageY,
11193        currentX: pageX,
11194        currentY: pageY,
11195        startTranslate: data.currentTranslate
11196      });
11197      data.loopSwapReset = true;
11198      data.startTranslate = data.currentTranslate;
11199      return;
11200    }
11201    swiper.emit('sliderMove', e);
11202    data.isMoved = true;
11203    data.currentTranslate = diff + data.startTranslate;
11204    let disableParentSwiper = true;
11205    let resistanceRatio = params.resistanceRatio;
11206    if (params.touchReleaseOnEdges) {
11207      resistanceRatio = 0;
11208    }
11209    if (diff > 0) {
11210      if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.slidesSizesGrid[swiper.activeIndex + 1] - (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.activeIndex + 1] + swiper.params.spaceBetween : 0) - swiper.params.spaceBetween : swiper.minTranslate())) {
11211        swiper.loopFix({
11212          direction: 'prev',
11213          setTranslate: true,
11214          activeSlideIndex: 0
11215        });
11216      }
11217      if (data.currentTranslate > swiper.minTranslate()) {
11218        disableParentSwiper = false;
11219        if (params.resistance) {
11220          data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
11221        }
11222      }
11223    } else if (diff < 0) {
11224      if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween + (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween : 0) : swiper.maxTranslate())) {
11225        swiper.loopFix({
11226          direction: 'next',
11227          setTranslate: true,
11228          activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
11229        });
11230      }
11231      if (data.currentTranslate < swiper.maxTranslate()) {
11232        disableParentSwiper = false;
11233        if (params.resistance) {
11234          data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
11235        }
11236      }
11237    }
11238    if (disableParentSwiper) {
11239      e.preventedByNestedSwiper = true;
11240    }
11241
11242    // Directions locks
11243    if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
11244      data.currentTranslate = data.startTranslate;
11245    }
11246    if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
11247      data.currentTranslate = data.startTranslate;
11248    }
11249    if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
11250      data.currentTranslate = data.startTranslate;
11251    }
11252
11253    // Threshold
11254    if (params.threshold > 0) {
11255      if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
11256        if (!data.allowThresholdMove) {
11257          data.allowThresholdMove = true;
11258          touches.startX = touches.currentX;
11259          touches.startY = touches.currentY;
11260          data.currentTranslate = data.startTranslate;
11261          touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
11262          return;
11263        }
11264      } else {
11265        data.currentTranslate = data.startTranslate;
11266        return;
11267      }
11268    }
11269    if (!params.followFinger || params.cssMode) return;
11270
11271    // Update active index in free mode
11272    if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
11273      swiper.updateActiveIndex();
11274      swiper.updateSlidesClasses();
11275    }
11276    if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
11277      swiper.freeMode.onTouchMove();
11278    }
11279    // Update progress
11280    swiper.updateProgress(data.currentTranslate);
11281    // Update translate
11282    swiper.setTranslate(data.currentTranslate);
11283  }
11284
11285  function onTouchEnd(event) {
11286    const swiper = this;
11287    const data = swiper.touchEventsData;
11288    let e = event;
11289    if (e.originalEvent) e = e.originalEvent;
11290    let targetTouch;
11291    const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
11292    if (!isTouchEvent) {
11293      if (data.touchId !== null) return; // return from pointer if we use touch
11294      if (e.pointerId !== data.pointerId) return;
11295      targetTouch = e;
11296    } else {
11297      targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
11298      if (!targetTouch || targetTouch.identifier !== data.touchId) return;
11299    }
11300    if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
11301      const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
11302      if (!proceed) {
11303        return;
11304      }
11305    }
11306    data.pointerId = null;
11307    data.touchId = null;
11308    const {
11309      params,
11310      touches,
11311      rtlTranslate: rtl,
11312      slidesGrid,
11313      enabled
11314    } = swiper;
11315    if (!enabled) return;
11316    if (!params.simulateTouch && e.pointerType === 'mouse') return;
11317    if (data.allowTouchCallbacks) {
11318      swiper.emit('touchEnd', e);
11319    }
11320    data.allowTouchCallbacks = false;
vendor: 4,775 bytes, lines 11321-11452
11321    if (!data.isTouched) {
11322      if (data.isMoved && params.grabCursor) {
11323        swiper.setGrabCursor(false);
11324      }
11325      data.isMoved = false;
11326      data.startMoving = false;
11327      return;
11328    }
11329
11330    // Return Grab Cursor
11331    if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
11332      swiper.setGrabCursor(false);
11333    }
11334
11335    // Time diff
11336    const touchEndTime = now();
11337    const timeDiff = touchEndTime - data.touchStartTime;
11338
11339    // Tap, doubleTap, Click
11340    if (swiper.allowClick) {
11341      const pathTree = e.path || e.composedPath && e.composedPath();
11342      swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
11343      swiper.emit('tap click', e);
11344      if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
11345        swiper.emit('doubleTap doubleClick', e);
11346      }
11347    }
11348    data.lastClickTime = now();
11349    nextTick(() => {
11350      if (!swiper.destroyed) swiper.allowClick = true;
11351    });
11352    if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
11353      data.isTouched = false;
11354      data.isMoved = false;
11355      data.startMoving = false;
11356      return;
11357    }
11358    data.isTouched = false;
11359    data.isMoved = false;
11360    data.startMoving = false;
11361    let currentPos;
11362    if (params.followFinger) {
11363      currentPos = rtl ? swiper.translate : -swiper.translate;
11364    } else {
11365      currentPos = -data.currentTranslate;
11366    }
11367    if (params.cssMode) {
11368      return;
11369    }
11370    if (params.freeMode && params.freeMode.enabled) {
11371      swiper.freeMode.onTouchEnd({
11372        currentPos
11373      });
11374      return;
11375    }
11376
11377    // Find current slide
11378    const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
11379    let stopIndex = 0;
11380    let groupSize = swiper.slidesSizesGrid[0];
11381    for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
11382      const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
11383      if (typeof slidesGrid[i + increment] !== 'undefined') {
11384        if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
11385          stopIndex = i;
11386          groupSize = slidesGrid[i + increment] - slidesGrid[i];
11387        }
11388      } else if (swipeToLast || currentPos >= slidesGrid[i]) {
11389        stopIndex = i;
11390        groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
11391      }
11392    }
11393    let rewindFirstIndex = null;
11394    let rewindLastIndex = null;
11395    if (params.rewind) {
11396      if (swiper.isBeginning) {
11397        rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
11398      } else if (swiper.isEnd) {
11399        rewindFirstIndex = 0;
11400      }
11401    }
11402    // Find current slide size
11403    const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
11404    const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
11405    if (timeDiff > params.longSwipesMs) {
11406      // Long touches
11407      if (!params.longSwipes) {
11408        swiper.slideTo(swiper.activeIndex);
11409        return;
11410      }
11411      if (swiper.swipeDirection === 'next') {
11412        if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
11413      }
11414      if (swiper.swipeDirection === 'prev') {
11415        if (ratio > 1 - params.longSwipesRatio) {
11416          swiper.slideTo(stopIndex + increment);
11417        } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
11418          swiper.slideTo(rewindLastIndex);
11419        } else {
11420          swiper.slideTo(stopIndex);
11421        }
11422      }
11423    } else {
11424      // Short swipes
11425      if (!params.shortSwipes) {
11426        swiper.slideTo(swiper.activeIndex);
11427        return;
11428      }
11429      const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
11430      if (!isNavButtonTarget) {
11431        if (swiper.swipeDirection === 'next') {
11432          swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
11433        }
11434        if (swiper.swipeDirection === 'prev') {
11435          swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
11436        }
11437      } else if (e.target === swiper.navigation.nextEl) {
11438        swiper.slideTo(stopIndex + increment);
11439      } else {
11440        swiper.slideTo(stopIndex);
11441      }
11442    }
11443  }
11444
11445  function onResize() {
11446    const swiper = this;
11447    const {
11448      params,
11449      el
11450    } = swiper;
11451    if (el && el.offsetWidth === 0) return;
11452
vendor: 6,853 bytes, lines 11453-11675
11453    // Breakpoints
11454    if (params.breakpoints) {
11455      swiper.setBreakpoint();
11456    }
11457
11458    // Save locks
11459    const {
11460      allowSlideNext,
11461      allowSlidePrev,
11462      snapGrid
11463    } = swiper;
11464    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
11465
11466    // Disable locks on resize
11467    swiper.allowSlideNext = true;
11468    swiper.allowSlidePrev = true;
11469    swiper.updateSize();
11470    swiper.updateSlides();
11471    swiper.updateSlidesClasses();
11472    const isVirtualLoop = isVirtual && params.loop;
11473    if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
11474      swiper.slideTo(swiper.slides.length - 1, 0, false, true);
11475    } else {
11476      if (swiper.params.loop && !isVirtual) {
11477        swiper.slideToLoop(swiper.realIndex, 0, false, true);
11478      } else {
11479        swiper.slideTo(swiper.activeIndex, 0, false, true);
11480      }
11481    }
11482    if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
11483      clearTimeout(swiper.autoplay.resizeTimeout);
11484      swiper.autoplay.resizeTimeout = setTimeout(() => {
11485        if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
11486          swiper.autoplay.resume();
11487        }
11488      }, 500);
11489    }
11490    // Return locks after resize
11491    swiper.allowSlidePrev = allowSlidePrev;
11492    swiper.allowSlideNext = allowSlideNext;
11493    if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
11494      swiper.checkOverflow();
11495    }
11496  }
11497
11498  function onClick(e) {
11499    const swiper = this;
11500    if (!swiper.enabled) return;
11501    if (!swiper.allowClick) {
11502      if (swiper.params.preventClicks) e.preventDefault();
11503      if (swiper.params.preventClicksPropagation && swiper.animating) {
11504        e.stopPropagation();
11505        e.stopImmediatePropagation();
11506      }
11507    }
11508  }
11509
11510  function onScroll() {
11511    const swiper = this;
11512    const {
11513      wrapperEl,
11514      rtlTranslate,
11515      enabled
11516    } = swiper;
11517    if (!enabled) return;
11518    swiper.previousTranslate = swiper.translate;
11519    if (swiper.isHorizontal()) {
11520      swiper.translate = -wrapperEl.scrollLeft;
11521    } else {
11522      swiper.translate = -wrapperEl.scrollTop;
11523    }
11524    // eslint-disable-next-line
11525    if (swiper.translate === 0) swiper.translate = 0;
11526    swiper.updateActiveIndex();
11527    swiper.updateSlidesClasses();
11528    let newProgress;
11529    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
11530    if (translatesDiff === 0) {
11531      newProgress = 0;
11532    } else {
11533      newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
11534    }
11535    if (newProgress !== swiper.progress) {
11536      swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
11537    }
11538    swiper.emit('setTranslate', swiper.translate, false);
11539  }
11540
11541  function onLoad(e) {
11542    const swiper = this;
11543    processLazyPreloader(swiper, e.target);
11544    if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
11545      return;
11546    }
11547    swiper.update();
11548  }
11549
11550  function onDocumentTouchStart() {
11551    const swiper = this;
11552    if (swiper.documentTouchHandlerProceeded) return;
11553    swiper.documentTouchHandlerProceeded = true;
11554    if (swiper.params.touchReleaseOnEdges) {
11555      swiper.el.style.touchAction = 'auto';
11556    }
11557  }
11558
11559  const events = (swiper, method) => {
11560    const document = getDocument();
11561    const {
11562      params,
11563      el,
11564      wrapperEl,
11565      device
11566    } = swiper;
11567    const capture = !!params.nested;
11568    const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
11569    const swiperMethod = method;
11570    if (!el || typeof el === 'string') return;
11571
11572    // Touch Events
11573    document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
11574      passive: false,
11575      capture
11576    });
11577    el[domMethod]('touchstart', swiper.onTouchStart, {
11578      passive: false
11579    });
11580    el[domMethod]('pointerdown', swiper.onTouchStart, {
11581      passive: false
11582    });
11583    document[domMethod]('touchmove', swiper.onTouchMove, {
11584      passive: false,
11585      capture
11586    });
11587    document[domMethod]('pointermove', swiper.onTouchMove, {
11588      passive: false,
11589      capture
11590    });
11591    document[domMethod]('touchend', swiper.onTouchEnd, {
11592      passive: true
11593    });
11594    document[domMethod]('pointerup', swiper.onTouchEnd, {
11595      passive: true
11596    });
11597    document[domMethod]('pointercancel', swiper.onTouchEnd, {
11598      passive: true
11599    });
11600    document[domMethod]('touchcancel', swiper.onTouchEnd, {
11601      passive: true
11602    });
11603    document[domMethod]('pointerout', swiper.onTouchEnd, {
11604      passive: true
11605    });
11606    document[domMethod]('pointerleave', swiper.onTouchEnd, {
11607      passive: true
11608    });
11609    document[domMethod]('contextmenu', swiper.onTouchEnd, {
11610      passive: true
11611    });
11612
11613    // Prevent Links Clicks
11614    if (params.preventClicks || params.preventClicksPropagation) {
11615      el[domMethod]('click', swiper.onClick, true);
11616    }
11617    if (params.cssMode) {
11618      wrapperEl[domMethod]('scroll', swiper.onScroll);
11619    }
11620
11621    // Resize handler
11622    if (params.updateOnWindowResize) {
11623      swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
11624    } else {
11625      swiper[swiperMethod]('observerUpdate', onResize, true);
11626    }
11627
11628    // Images loader
11629    el[domMethod]('load', swiper.onLoad, {
11630      capture: true
11631    });
11632  };
11633  function attachEvents() {
11634    const swiper = this;
11635    const {
11636      params
11637    } = swiper;
11638    swiper.onTouchStart = onTouchStart.bind(swiper);
11639    swiper.onTouchMove = onTouchMove.bind(swiper);
11640    swiper.onTouchEnd = onTouchEnd.bind(swiper);
11641    swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
11642    if (params.cssMode) {
11643      swiper.onScroll = onScroll.bind(swiper);
11644    }
11645    swiper.onClick = onClick.bind(swiper);
11646    swiper.onLoad = onLoad.bind(swiper);
11647    events(swiper, 'on');
11648  }
11649  function detachEvents() {
11650    const swiper = this;
11651    events(swiper, 'off');
11652  }
11653  var events$1 = {
11654    attachEvents,
11655    detachEvents
11656  };
11657
11658  const isGridEnabled = (swiper, params) => {
11659    return swiper.grid && params.grid && params.grid.rows > 1;
11660  };
11661  function setBreakpoint() {
11662    const swiper = this;
11663    const {
11664      realIndex,
11665      initialized,
11666      params,
11667      el
11668    } = swiper;
11669    const breakpoints = params.breakpoints;
11670    if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
11671    const document = getDocument();
11672
11673    // Get breakpoint for window/container width and update parameters
11674    const breakpointsBase = params.breakpointsBase === 'window' || !params.breakpointsBase ? params.breakpointsBase : 'container';
11675    const breakpointContainer = ['window', 'container'].includes(params.breakpointsBase) || !params.breakpointsBase ? swiper.el : document.querySelector(params.breakpointsBase);
vendor: 26,382 bytes, lines 11676-12490
11676    const breakpoint = swiper.getBreakpoint(breakpoints, breakpointsBase, breakpointContainer);
11677    if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
11678    const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
11679    const breakpointParams = breakpointOnlyParams || swiper.originalParams;
11680    const wasMultiRow = isGridEnabled(swiper, params);
11681    const isMultiRow = isGridEnabled(swiper, breakpointParams);
11682    const wasGrabCursor = swiper.params.grabCursor;
11683    const isGrabCursor = breakpointParams.grabCursor;
11684    const wasEnabled = params.enabled;
11685    if (wasMultiRow && !isMultiRow) {
11686      el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
11687      swiper.emitContainerClasses();
11688    } else if (!wasMultiRow && isMultiRow) {
11689      el.classList.add(`${params.containerModifierClass}grid`);
11690      if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
11691        el.classList.add(`${params.containerModifierClass}grid-column`);
11692      }
11693      swiper.emitContainerClasses();
11694    }
11695    if (wasGrabCursor && !isGrabCursor) {
11696      swiper.unsetGrabCursor();
11697    } else if (!wasGrabCursor && isGrabCursor) {
11698      swiper.setGrabCursor();
11699    }
11700
11701    // Toggle navigation, pagination, scrollbar
11702    ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
11703      if (typeof breakpointParams[prop] === 'undefined') return;
11704      const wasModuleEnabled = params[prop] && params[prop].enabled;
11705      const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
11706      if (wasModuleEnabled && !isModuleEnabled) {
11707        swiper[prop].disable();
11708      }
11709      if (!wasModuleEnabled && isModuleEnabled) {
11710        swiper[prop].enable();
11711      }
11712    });
11713    const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
11714    const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
11715    const wasLoop = params.loop;
11716    if (directionChanged && initialized) {
11717      swiper.changeDirection();
11718    }
11719    extend(swiper.params, breakpointParams);
11720    const isEnabled = swiper.params.enabled;
11721    const hasLoop = swiper.params.loop;
11722    Object.assign(swiper, {
11723      allowTouchMove: swiper.params.allowTouchMove,
11724      allowSlideNext: swiper.params.allowSlideNext,
11725      allowSlidePrev: swiper.params.allowSlidePrev
11726    });
11727    if (wasEnabled && !isEnabled) {
11728      swiper.disable();
11729    } else if (!wasEnabled && isEnabled) {
11730      swiper.enable();
11731    }
11732    swiper.currentBreakpoint = breakpoint;
11733    swiper.emit('_beforeBreakpoint', breakpointParams);
11734    if (initialized) {
11735      if (needsReLoop) {
11736        swiper.loopDestroy();
11737        swiper.loopCreate(realIndex);
11738        swiper.updateSlides();
11739      } else if (!wasLoop && hasLoop) {
11740        swiper.loopCreate(realIndex);
11741        swiper.updateSlides();
11742      } else if (wasLoop && !hasLoop) {
11743        swiper.loopDestroy();
11744      }
11745    }
11746    swiper.emit('breakpoint', breakpointParams);
11747  }
11748
11749  function getBreakpoint(breakpoints, base = 'window', containerEl) {
11750    if (!breakpoints || base === 'container' && !containerEl) return undefined;
11751    let breakpoint = false;
11752    const window = getWindow();
11753    const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
11754    const points = Object.keys(breakpoints).map(point => {
11755      if (typeof point === 'string' && point.indexOf('@') === 0) {
11756        const minRatio = parseFloat(point.substr(1));
11757        const value = currentHeight * minRatio;
11758        return {
11759          value,
11760          point
11761        };
11762      }
11763      return {
11764        value: point,
11765        point
11766      };
11767    });
11768    points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
11769    for (let i = 0; i < points.length; i += 1) {
11770      const {
11771        point,
11772        value
11773      } = points[i];
11774      if (base === 'window') {
11775        if (window.matchMedia(`(min-width: ${value}px)`).matches) {
11776          breakpoint = point;
11777        }
11778      } else if (value <= containerEl.clientWidth) {
11779        breakpoint = point;
11780      }
11781    }
11782    return breakpoint || 'max';
11783  }
11784
11785  var breakpoints = {
11786    setBreakpoint,
11787    getBreakpoint
11788  };
11789
11790  function prepareClasses(entries, prefix) {
11791    const resultClasses = [];
11792    entries.forEach(item => {
11793      if (typeof item === 'object') {
11794        Object.keys(item).forEach(classNames => {
11795          if (item[classNames]) {
11796            resultClasses.push(prefix + classNames);
11797          }
11798        });
11799      } else if (typeof item === 'string') {
11800        resultClasses.push(prefix + item);
11801      }
11802    });
11803    return resultClasses;
11804  }
11805  function addClasses() {
11806    const swiper = this;
11807    const {
11808      classNames,
11809      params,
11810      rtl,
11811      el,
11812      device
11813    } = swiper;
11814    // prettier-ignore
11815    const suffixes = prepareClasses(['initialized', params.direction, {
11816      'free-mode': swiper.params.freeMode && params.freeMode.enabled
11817    }, {
11818      'autoheight': params.autoHeight
11819    }, {
11820      'rtl': rtl
11821    }, {
11822      'grid': params.grid && params.grid.rows > 1
11823    }, {
11824      'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
11825    }, {
11826      'android': device.android
11827    }, {
11828      'ios': device.ios
11829    }, {
11830      'css-mode': params.cssMode
11831    }, {
11832      'centered': params.cssMode && params.centeredSlides
11833    }, {
11834      'watch-progress': params.watchSlidesProgress
11835    }], params.containerModifierClass);
11836    classNames.push(...suffixes);
11837    el.classList.add(...classNames);
11838    swiper.emitContainerClasses();
11839  }
11840
11841  function removeClasses() {
11842    const swiper = this;
11843    const {
11844      el,
11845      classNames
11846    } = swiper;
11847    if (!el || typeof el === 'string') return;
11848    el.classList.remove(...classNames);
11849    swiper.emitContainerClasses();
11850  }
11851
11852  var classes = {
11853    addClasses,
11854    removeClasses
11855  };
11856
11857  function checkOverflow() {
11858    const swiper = this;
11859    const {
11860      isLocked: wasLocked,
11861      params
11862    } = swiper;
11863    const {
11864      slidesOffsetBefore
11865    } = params;
11866    if (slidesOffsetBefore) {
11867      const lastSlideIndex = swiper.slides.length - 1;
11868      const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
11869      swiper.isLocked = swiper.size > lastSlideRightEdge;
11870    } else {
11871      swiper.isLocked = swiper.snapGrid.length === 1;
11872    }
11873    if (params.allowSlideNext === true) {
11874      swiper.allowSlideNext = !swiper.isLocked;
11875    }
11876    if (params.allowSlidePrev === true) {
11877      swiper.allowSlidePrev = !swiper.isLocked;
11878    }
11879    if (wasLocked && wasLocked !== swiper.isLocked) {
11880      swiper.isEnd = false;
11881    }
11882    if (wasLocked !== swiper.isLocked) {
11883      swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
11884    }
11885  }
11886  var checkOverflow$1 = {
11887    checkOverflow
11888  };
11889
11890  var defaults = {
11891    init: true,
11892    direction: 'horizontal',
11893    oneWayMovement: false,
11894    swiperElementNodeName: 'SWIPER-CONTAINER',
11895    touchEventsTarget: 'wrapper',
11896    initialSlide: 0,
11897    speed: 300,
11898    cssMode: false,
11899    updateOnWindowResize: true,
11900    resizeObserver: true,
11901    nested: false,
11902    createElements: false,
11903    eventsPrefix: 'swiper',
11904    enabled: true,
11905    focusableElements: 'input, select, option, textarea, button, video, label',
11906    // Overrides
11907    width: null,
11908    height: null,
11909    //
11910    preventInteractionOnTransition: false,
11911    // ssr
11912    userAgent: null,
11913    url: null,
11914    // To support iOS's swipe-to-go-back gesture (when being used in-app).
11915    edgeSwipeDetection: false,
11916    edgeSwipeThreshold: 20,
11917    // Autoheight
11918    autoHeight: false,
11919    // Set wrapper width
11920    setWrapperSize: false,
11921    // Virtual Translate
11922    virtualTranslate: false,
11923    // Effects
11924    effect: 'slide',
11925    // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
11926
11927    // Breakpoints
11928    breakpoints: undefined,
11929    breakpointsBase: 'window',
11930    // Slides grid
11931    spaceBetween: 0,
11932    slidesPerView: 1,
11933    slidesPerGroup: 1,
11934    slidesPerGroupSkip: 0,
11935    slidesPerGroupAuto: false,
11936    centeredSlides: false,
11937    centeredSlidesBounds: false,
11938    slidesOffsetBefore: 0,
11939    // in px
11940    slidesOffsetAfter: 0,
11941    // in px
11942    normalizeSlideIndex: true,
11943    centerInsufficientSlides: false,
11944    // Disable swiper and hide navigation when container not overflow
11945    watchOverflow: true,
11946    // Round length
11947    roundLengths: false,
11948    // Touches
11949    touchRatio: 1,
11950    touchAngle: 45,
11951    simulateTouch: true,
11952    shortSwipes: true,
11953    longSwipes: true,
11954    longSwipesRatio: 0.5,
11955    longSwipesMs: 300,
11956    followFinger: true,
11957    allowTouchMove: true,
11958    threshold: 5,
11959    touchMoveStopPropagation: false,
11960    touchStartPreventDefault: true,
11961    touchStartForcePreventDefault: false,
11962    touchReleaseOnEdges: false,
11963    // Unique Navigation Elements
11964    uniqueNavElements: true,
11965    // Resistance
11966    resistance: true,
11967    resistanceRatio: 0.85,
11968    // Progress
11969    watchSlidesProgress: false,
11970    // Cursor
11971    grabCursor: false,
11972    // Clicks
11973    preventClicks: true,
11974    preventClicksPropagation: true,
11975    slideToClickedSlide: false,
11976    // loop
11977    loop: false,
11978    loopAddBlankSlides: true,
11979    loopAdditionalSlides: 0,
11980    loopPreventsSliding: true,
11981    // rewind
11982    rewind: false,
11983    // Swiping/no swiping
11984    allowSlidePrev: true,
11985    allowSlideNext: true,
11986    swipeHandler: null,
11987    // '.swipe-handler',
11988    noSwiping: true,
11989    noSwipingClass: 'swiper-no-swiping',
11990    noSwipingSelector: null,
11991    // Passive Listeners
11992    passiveListeners: true,
11993    maxBackfaceHiddenSlides: 10,
11994    // NS
11995    containerModifierClass: 'swiper-',
11996    // NEW
11997    slideClass: 'swiper-slide',
11998    slideBlankClass: 'swiper-slide-blank',
11999    slideActiveClass: 'swiper-slide-active',
12000    slideVisibleClass: 'swiper-slide-visible',
12001    slideFullyVisibleClass: 'swiper-slide-fully-visible',
12002    slideNextClass: 'swiper-slide-next',
12003    slidePrevClass: 'swiper-slide-prev',
12004    wrapperClass: 'swiper-wrapper',
12005    lazyPreloaderClass: 'swiper-lazy-preloader',
12006    lazyPreloadPrevNext: 0,
12007    // Callbacks
12008    runCallbacksOnInit: true,
12009    // Internals
12010    _emitClasses: false
12011  };
12012
12013  function moduleExtendParams(params, allModulesParams) {
12014    return function extendParams(obj = {}) {
12015      const moduleParamName = Object.keys(obj)[0];
12016      const moduleParams = obj[moduleParamName];
12017      if (typeof moduleParams !== 'object' || moduleParams === null) {
12018        extend(allModulesParams, obj);
12019        return;
12020      }
12021      if (params[moduleParamName] === true) {
12022        params[moduleParamName] = {
12023          enabled: true
12024        };
12025      }
12026      if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
12027        params[moduleParamName].auto = true;
12028      }
12029      if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
12030        params[moduleParamName].auto = true;
12031      }
12032      if (!(moduleParamName in params && 'enabled' in moduleParams)) {
12033        extend(allModulesParams, obj);
12034        return;
12035      }
12036      if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
12037        params[moduleParamName].enabled = true;
12038      }
12039      if (!params[moduleParamName]) params[moduleParamName] = {
12040        enabled: false
12041      };
12042      extend(allModulesParams, obj);
12043    };
12044  }
12045
12046  /* eslint no-param-reassign: "off" */
12047  const prototypes = {
12048    eventsEmitter,
12049    update,
12050    translate,
12051    transition,
12052    slide,
12053    loop,
12054    grabCursor,
12055    events: events$1,
12056    breakpoints,
12057    checkOverflow: checkOverflow$1,
12058    classes
12059  };
12060  const extendedDefaults = {};
12061  class Swiper {
12062    constructor(...args) {
12063      let el;
12064      let params;
12065      if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
12066        params = args[0];
12067      } else {
12068        [el, params] = args;
12069      }
12070      if (!params) params = {};
12071      params = extend({}, params);
12072      if (el && !params.el) params.el = el;
12073      const document = getDocument();
12074      if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
12075        const swipers = [];
12076        document.querySelectorAll(params.el).forEach(containerEl => {
12077          const newParams = extend({}, params, {
12078            el: containerEl
12079          });
12080          swipers.push(new Swiper(newParams));
12081        });
12082        // eslint-disable-next-line no-constructor-return
12083        return swipers;
12084      }
12085
12086      // Swiper Instance
12087      const swiper = this;
12088      swiper.__swiper__ = true;
12089      swiper.support = getSupport();
12090      swiper.device = getDevice({
12091        userAgent: params.userAgent
12092      });
12093      swiper.browser = getBrowser();
12094      swiper.eventsListeners = {};
12095      swiper.eventsAnyListeners = [];
12096      swiper.modules = [...swiper.__modules__];
12097      if (params.modules && Array.isArray(params.modules)) {
12098        swiper.modules.push(...params.modules);
12099      }
12100      const allModulesParams = {};
12101      swiper.modules.forEach(mod => {
12102        mod({
12103          params,
12104          swiper,
12105          extendParams: moduleExtendParams(params, allModulesParams),
12106          on: swiper.on.bind(swiper),
12107          once: swiper.once.bind(swiper),
12108          off: swiper.off.bind(swiper),
12109          emit: swiper.emit.bind(swiper)
12110        });
12111      });
12112
12113      // Extend defaults with modules params
12114      const swiperParams = extend({}, defaults, allModulesParams);
12115
12116      // Extend defaults with passed params
12117      swiper.params = extend({}, swiperParams, extendedDefaults, params);
12118      swiper.originalParams = extend({}, swiper.params);
12119      swiper.passedParams = extend({}, params);
12120
12121      // add event listeners
12122      if (swiper.params && swiper.params.on) {
12123        Object.keys(swiper.params.on).forEach(eventName => {
12124          swiper.on(eventName, swiper.params.on[eventName]);
12125        });
12126      }
12127      if (swiper.params && swiper.params.onAny) {
12128        swiper.onAny(swiper.params.onAny);
12129      }
12130
12131      // Extend Swiper
12132      Object.assign(swiper, {
12133        enabled: swiper.params.enabled,
12134        el,
12135        // Classes
12136        classNames: [],
12137        // Slides
12138        slides: [],
12139        slidesGrid: [],
12140        snapGrid: [],
12141        slidesSizesGrid: [],
12142        // isDirection
12143        isHorizontal() {
12144          return swiper.params.direction === 'horizontal';
12145        },
12146        isVertical() {
12147          return swiper.params.direction === 'vertical';
12148        },
12149        // Indexes
12150        activeIndex: 0,
12151        realIndex: 0,
12152        //
12153        isBeginning: true,
12154        isEnd: false,
12155        // Props
12156        translate: 0,
12157        previousTranslate: 0,
12158        progress: 0,
12159        velocity: 0,
12160        animating: false,
12161        cssOverflowAdjustment() {
12162          // Returns 0 unless `translate` is > 2**23
12163          // Should be subtracted from css values to prevent overflow
12164          return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
12165        },
12166        // Locks
12167        allowSlideNext: swiper.params.allowSlideNext,
12168        allowSlidePrev: swiper.params.allowSlidePrev,
12169        // Touch Events
12170        touchEventsData: {
12171          isTouched: undefined,
12172          isMoved: undefined,
12173          allowTouchCallbacks: undefined,
12174          touchStartTime: undefined,
12175          isScrolling: undefined,
12176          currentTranslate: undefined,
12177          startTranslate: undefined,
12178          allowThresholdMove: undefined,
12179          // Form elements to match
12180          focusableElements: swiper.params.focusableElements,
12181          // Last click time
12182          lastClickTime: 0,
12183          clickTimeout: undefined,
12184          // Velocities
12185          velocities: [],
12186          allowMomentumBounce: undefined,
12187          startMoving: undefined,
12188          pointerId: null,
12189          touchId: null
12190        },
12191        // Clicks
12192        allowClick: true,
12193        // Touches
12194        allowTouchMove: swiper.params.allowTouchMove,
12195        touches: {
12196          startX: 0,
12197          startY: 0,
12198          currentX: 0,
12199          currentY: 0,
12200          diff: 0
12201        },
12202        // Images
12203        imagesToLoad: [],
12204        imagesLoaded: 0
12205      });
12206      swiper.emit('_swiper');
12207
12208      // Init
12209      if (swiper.params.init) {
12210        swiper.init();
12211      }
12212
12213      // Return app instance
12214      // eslint-disable-next-line no-constructor-return
12215      return swiper;
12216    }
12217    getDirectionLabel(property) {
12218      if (this.isHorizontal()) {
12219        return property;
12220      }
12221      // prettier-ignore
12222      return {
12223        'width': 'height',
12224        'margin-top': 'margin-left',
12225        'margin-bottom ': 'margin-right',
12226        'margin-left': 'margin-top',
12227        'margin-right': 'margin-bottom',
12228        'padding-left': 'padding-top',
12229        'padding-right': 'padding-bottom',
12230        'marginRight': 'marginBottom'
12231      }[property];
12232    }
12233    getSlideIndex(slideEl) {
12234      const {
12235        slidesEl,
12236        params
12237      } = this;
12238      const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
12239      const firstSlideIndex = elementIndex(slides[0]);
12240      return elementIndex(slideEl) - firstSlideIndex;
12241    }
12242    getSlideIndexByData(index) {
12243      return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index));
12244    }
12245    getSlideIndexWhenGrid(index) {
12246      if (this.grid && this.params.grid && this.params.grid.rows > 1) {
12247        if (this.params.grid.fill === 'column') {
12248          index = Math.floor(index / this.params.grid.rows);
12249        } else if (this.params.grid.fill === 'row') {
12250          index = index % Math.ceil(this.slides.length / this.params.grid.rows);
12251        }
12252      }
12253      return index;
12254    }
12255    recalcSlides() {
12256      const swiper = this;
12257      const {
12258        slidesEl,
12259        params
12260      } = swiper;
12261      swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
12262    }
12263    enable() {
12264      const swiper = this;
12265      if (swiper.enabled) return;
12266      swiper.enabled = true;
12267      if (swiper.params.grabCursor) {
12268        swiper.setGrabCursor();
12269      }
12270      swiper.emit('enable');
12271    }
12272    disable() {
12273      const swiper = this;
12274      if (!swiper.enabled) return;
12275      swiper.enabled = false;
12276      if (swiper.params.grabCursor) {
12277        swiper.unsetGrabCursor();
12278      }
12279      swiper.emit('disable');
12280    }
12281    setProgress(progress, speed) {
12282      const swiper = this;
12283      progress = Math.min(Math.max(progress, 0), 1);
12284      const min = swiper.minTranslate();
12285      const max = swiper.maxTranslate();
12286      const current = (max - min) * progress + min;
12287      swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
12288      swiper.updateActiveIndex();
12289      swiper.updateSlidesClasses();
12290    }
12291    emitContainerClasses() {
12292      const swiper = this;
12293      if (!swiper.params._emitClasses || !swiper.el) return;
12294      const cls = swiper.el.className.split(' ').filter(className => {
12295        return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
12296      });
12297      swiper.emit('_containerClasses', cls.join(' '));
12298    }
12299    getSlideClasses(slideEl) {
12300      const swiper = this;
12301      if (swiper.destroyed) return '';
12302      return slideEl.className.split(' ').filter(className => {
12303        return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
12304      }).join(' ');
12305    }
12306    emitSlidesClasses() {
12307      const swiper = this;
12308      if (!swiper.params._emitClasses || !swiper.el) return;
12309      const updates = [];
12310      swiper.slides.forEach(slideEl => {
12311        const classNames = swiper.getSlideClasses(slideEl);
12312        updates.push({
12313          slideEl,
12314          classNames
12315        });
12316        swiper.emit('_slideClass', slideEl, classNames);
12317      });
12318      swiper.emit('_slideClasses', updates);
12319    }
12320    slidesPerViewDynamic(view = 'current', exact = false) {
12321      const swiper = this;
12322      const {
12323        params,
12324        slides,
12325        slidesGrid,
12326        slidesSizesGrid,
12327        size: swiperSize,
12328        activeIndex
12329      } = swiper;
12330      let spv = 1;
12331      if (typeof params.slidesPerView === 'number') return params.slidesPerView;
12332      if (params.centeredSlides) {
12333        let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
12334        let breakLoop;
12335        for (let i = activeIndex + 1; i < slides.length; i += 1) {
12336          if (slides[i] && !breakLoop) {
12337            slideSize += Math.ceil(slides[i].swiperSlideSize);
12338            spv += 1;
12339            if (slideSize > swiperSize) breakLoop = true;
12340          }
12341        }
12342        for (let i = activeIndex - 1; i >= 0; i -= 1) {
12343          if (slides[i] && !breakLoop) {
12344            slideSize += slides[i].swiperSlideSize;
12345            spv += 1;
12346            if (slideSize > swiperSize) breakLoop = true;
12347          }
12348        }
12349      } else {
12350        // eslint-disable-next-line
12351        if (view === 'current') {
12352          for (let i = activeIndex + 1; i < slides.length; i += 1) {
12353            const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
12354            if (slideInView) {
12355              spv += 1;
12356            }
12357          }
12358        } else {
12359          // previous
12360          for (let i = activeIndex - 1; i >= 0; i -= 1) {
12361            const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
12362            if (slideInView) {
12363              spv += 1;
12364            }
12365          }
12366        }
12367      }
12368      return spv;
12369    }
12370    update() {
12371      const swiper = this;
12372      if (!swiper || swiper.destroyed) return;
12373      const {
12374        snapGrid,
12375        params
12376      } = swiper;
12377      // Breakpoints
12378      if (params.breakpoints) {
12379        swiper.setBreakpoint();
12380      }
12381      [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
12382        if (imageEl.complete) {
12383          processLazyPreloader(swiper, imageEl);
12384        }
12385      });
12386      swiper.updateSize();
12387      swiper.updateSlides();
12388      swiper.updateProgress();
12389      swiper.updateSlidesClasses();
12390      function setTranslate() {
12391        const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
12392        const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
12393        swiper.setTranslate(newTranslate);
12394        swiper.updateActiveIndex();
12395        swiper.updateSlidesClasses();
12396      }
12397      let translated;
12398      if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
12399        setTranslate();
12400        if (params.autoHeight) {
12401          swiper.updateAutoHeight();
12402        }
12403      } else {
12404        if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
12405          const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
12406          translated = swiper.slideTo(slides.length - 1, 0, false, true);
12407        } else {
12408          translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
12409        }
12410        if (!translated) {
12411          setTranslate();
12412        }
12413      }
12414      if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
12415        swiper.checkOverflow();
12416      }
12417      swiper.emit('update');
12418    }
12419    changeDirection(newDirection, needUpdate = true) {
12420      const swiper = this;
12421      const currentDirection = swiper.params.direction;
12422      if (!newDirection) {
12423        // eslint-disable-next-line
12424        newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
12425      }
12426      if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
12427        return swiper;
12428      }
12429      swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
12430      swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
12431      swiper.emitContainerClasses();
12432      swiper.params.direction = newDirection;
12433      swiper.slides.forEach(slideEl => {
12434        if (newDirection === 'vertical') {
12435          slideEl.style.width = '';
12436        } else {
12437          slideEl.style.height = '';
12438        }
12439      });
12440      swiper.emit('changeDirection');
12441      if (needUpdate) swiper.update();
12442      return swiper;
12443    }
12444    changeLanguageDirection(direction) {
12445      const swiper = this;
12446      if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
12447      swiper.rtl = direction === 'rtl';
12448      swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
12449      if (swiper.rtl) {
12450        swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
12451        swiper.el.dir = 'rtl';
12452      } else {
12453        swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
12454        swiper.el.dir = 'ltr';
12455      }
12456      swiper.update();
12457    }
12458    mount(element) {
12459      const swiper = this;
12460      if (swiper.mounted) return true;
12461
12462      // Find el
12463      let el = element || swiper.params.el;
12464      if (typeof el === 'string') {
12465        el = document.querySelector(el);
12466      }
12467      if (!el) {
12468        return false;
12469      }
12470      el.swiper = swiper;
12471      if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
12472        swiper.isElement = true;
12473      }
12474      const getWrapperSelector = () => {
12475        return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
12476      };
12477      const getWrapper = () => {
12478        if (el && el.shadowRoot && el.shadowRoot.querySelector) {
12479          const res = el.shadowRoot.querySelector(getWrapperSelector());
12480          // Children needs to return slot items
12481          return res;
12482        }
12483        return elementChildren(el, getWrapperSelector())[0];
12484      };
12485      // Find Wrapper
12486      let wrapperEl = getWrapper();
12487      if (!wrapperEl && swiper.params.createElements) {
12488        wrapperEl = createElement('div', swiper.params.wrapperClass);
12489        el.append(wrapperEl);
12490        elementChildren(el, `.${swiper.params.slideClass}
12490`).forEach(slideEl => {
12491          wrapperEl.append(slideEl);
12492        });
12493      }
12494      Object.assign(swiper, {
12495        el,
12496        wrapperEl,
12497        slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
12498        hostEl: swiper.isElement ? el.parentNode.host : el,
12499        mounted: true,
12500        // RTL
12501        rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
12502        rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
12503        wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
12504      });
12505      return true;
12506    }
12507    init(el) {
12508      const swiper = this;
12509      if (swiper.initialized) return swiper;
12510      const mounted = swiper.mount(el);
12511      if (mounted === false) return swiper;
12512      swiper.emit('beforeInit');
12513
12514      // Set breakpoint
12515      if (swiper.params.breakpoints) {
12516        swiper.setBreakpoint();
12517      }
12518
12519      // Add Classes
12520      swiper.addClasses();
12521
12522      // Update size
12523      swiper.updateSize();
12524
12525      // Update slides
12526      swiper.updateSlides();
12527      if (swiper.params.watchOverflow) {
12528        swiper.checkOverflow();
12529      }
12530
12531      // Set Grab Cursor
12532      if (swiper.params.grabCursor && swiper.enabled) {
12533        swiper.setGrabCursor();
12534      }
12535
12536      // Slide To Initial Slide
12537      if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
12538        swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
12539      } else {
12540        swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
12541      }
12542
12543      // Create loop
12544      if (swiper.params.loop) {
12545        swiper.loopCreate(undefined, true);
12546      }
12547
12548      // Attach events
12549      swiper.attachEvents();
12550      const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
12551      if (swiper.isElement) {
12552        lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
12553      }
12554      lazyElements.forEach(imageEl => {
12555        if (imageEl.complete) {
12556          processLazyPreloader(swiper, imageEl);
12557        } else {
12558          imageEl.addEventListener('load', e => {
12559            processLazyPreloader(swiper, e.target);
12560          });
12561        }
12562      });
12563      preload(swiper);
12564
12565      // Init Flag
12566      swiper.initialized = true;
12567      preload(swiper);
12568
12569      // Emit
12570      swiper.emit('init');
12571      swiper.emit('afterInit');
12572      return swiper;
12573    }
12574    destroy(deleteInstance = true, cleanStyles = true) {
12575      const swiper = this;
12576      const {
12577        params,
12578        el,
12579        wrapperEl,
12580        slides
12581      } = swiper;
12582      if (typeof swiper.params === 'undefined' || swiper.destroyed) {
12583        return null;
12584      }
12585      swiper.emit('beforeDestroy');
12586
12587      // Init Flag
12588      swiper.initialized = false;
12589
12590      // Detach events
12591      swiper.detachEvents();
12592
12593      // Destroy loop
12594      if (params.loop) {
12595        swiper.loopDestroy();
12596      }
12597
12598      // Cleanup styles
12599      if (cleanStyles) {
12600        swiper.removeClasses();
12601        if (el && typeof el !== 'string') {
12602          el.removeAttribute('style');
12603        }
12604        if (wrapperEl) {
12605          wrapperEl.removeAttribute('style');
12606        }
12607        if (slides && slides.length) {
vendor: 6,255 bytes, lines 12608-12800
12608          slides.forEach(slideEl => {
12609            slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
12610            slideEl.removeAttribute('style');
12611            slideEl.removeAttribute('data-swiper-slide-index');
12612          });
12613        }
12614      }
12615      swiper.emit('destroy');
12616
12617      // Detach emitter events
12618      Object.keys(swiper.eventsListeners).forEach(eventName => {
12619        swiper.off(eventName);
12620      });
12621      if (deleteInstance !== false) {
12622        if (swiper.el && typeof swiper.el !== 'string') {
12623          swiper.el.swiper = null;
12624        }
12625        deleteProps(swiper);
12626      }
12627      swiper.destroyed = true;
12628      return null;
12629    }
12630    static extendDefaults(newDefaults) {
12631      extend(extendedDefaults, newDefaults);
12632    }
12633    static get extendedDefaults() {
12634      return extendedDefaults;
12635    }
12636    static get defaults() {
12637      return defaults;
12638    }
12639    static installModule(mod) {
12640      if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
12641      const modules = Swiper.prototype.__modules__;
12642      if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
12643        modules.push(mod);
12644      }
12645    }
12646    static use(module) {
12647      if (Array.isArray(module)) {
12648        module.forEach(m => Swiper.installModule(m));
12649        return Swiper;
12650      }
12651      Swiper.installModule(module);
12652      return Swiper;
12653    }
12654  }
12655  Object.keys(prototypes).forEach(prototypeGroup => {
12656    Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
12657      Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
12658    });
12659  });
12660  Swiper.use([Resize, Observer]);
12661
12662  function Virtual({
12663    swiper,
12664    extendParams,
12665    on,
12666    emit
12667  }) {
12668    extendParams({
12669      virtual: {
12670        enabled: false,
12671        slides: [],
12672        cache: true,
12673        slidesPerViewAutoSlideSize: 320,
12674        renderSlide: null,
12675        renderExternal: null,
12676        renderExternalUpdate: true,
12677        addSlidesBefore: 0,
12678        addSlidesAfter: 0
12679      }
12680    });
12681    let cssModeTimeout;
12682    const document = getDocument();
12683    swiper.virtual = {
12684      cache: {},
12685      from: undefined,
12686      to: undefined,
12687      slides: [],
12688      offset: 0,
12689      slidesGrid: []
12690    };
12691    const tempDOM = document.createElement('div');
12692    function renderSlide(slide, index) {
12693      const params = swiper.params.virtual;
12694      if (params.cache && swiper.virtual.cache[index]) {
12695        return swiper.virtual.cache[index];
12696      }
12697      // eslint-disable-next-line
12698      let slideEl;
12699      if (params.renderSlide) {
12700        slideEl = params.renderSlide.call(swiper, slide, index);
12701        if (typeof slideEl === 'string') {
12702          setInnerHTML(tempDOM, slideEl);
12703          slideEl = tempDOM.children[0];
12704        }
12705      } else if (swiper.isElement) {
12706        slideEl = createElement('swiper-slide');
12707      } else {
12708        slideEl = createElement('div', swiper.params.slideClass);
12709      }
12710      slideEl.setAttribute('data-swiper-slide-index', index);
12711      if (!params.renderSlide) {
12712        setInnerHTML(slideEl, slide);
12713      }
12714      if (params.cache) {
12715        swiper.virtual.cache[index] = slideEl;
12716      }
12717      return slideEl;
12718    }
12719    function update(force, beforeInit, forceActiveIndex) {
12720      const {
12721        slidesPerGroup,
12722        centeredSlides,
12723        slidesPerView,
12724        loop: isLoop,
12725        initialSlide
12726      } = swiper.params;
12727      if (beforeInit && !isLoop && initialSlide > 0) {
12728        return;
12729      }
12730      const {
12731        addSlidesBefore,
12732        addSlidesAfter,
12733        slidesPerViewAutoSlideSize
12734      } = swiper.params.virtual;
12735      const {
12736        from: previousFrom,
12737        to: previousTo,
12738        slides,
12739        slidesGrid: previousSlidesGrid,
12740        offset: previousOffset
12741      } = swiper.virtual;
12742      if (!swiper.params.cssMode) {
12743        swiper.updateActiveIndex();
12744      }
12745      const activeIndex = typeof forceActiveIndex === 'undefined' ? swiper.activeIndex || 0 : forceActiveIndex;
12746      let offsetProp;
12747      if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
12748      let slidesPerViewNumeric;
12749      if (slidesPerView === 'auto') {
12750        if (slidesPerViewAutoSlideSize) {
12751          let swiperSize = swiper.size;
12752          if (!swiperSize) {
12753            swiperSize = swiper.isHorizontal() ? swiper.el.getBoundingClientRect().width : swiper.el.getBoundingClientRect().height;
12754          }
12755          slidesPerViewNumeric = Math.max(1, Math.ceil(swiperSize / slidesPerViewAutoSlideSize));
12756        } else {
12757          slidesPerViewNumeric = 1;
12758        }
12759      } else {
12760        slidesPerViewNumeric = slidesPerView;
12761      }
12762      let slidesAfter;
12763      let slidesBefore;
12764      if (centeredSlides) {
12765        slidesAfter = Math.floor(slidesPerViewNumeric / 2) + slidesPerGroup + addSlidesAfter;
12766        slidesBefore = Math.floor(slidesPerViewNumeric / 2) + slidesPerGroup + addSlidesBefore;
12767      } else {
12768        slidesAfter = slidesPerViewNumeric + (slidesPerGroup - 1) + addSlidesAfter;
12769        slidesBefore = (isLoop ? slidesPerViewNumeric : slidesPerGroup) + addSlidesBefore;
12770      }
12771      let from = activeIndex - slidesBefore;
12772      let to = activeIndex + slidesAfter;
12773      if (!isLoop) {
12774        from = Math.max(from, 0);
12775        to = Math.min(to, slides.length - 1);
12776      }
12777      let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
12778      if (isLoop && activeIndex >= slidesBefore) {
12779        from -= slidesBefore;
12780        if (!centeredSlides) offset += swiper.slidesGrid[0];
12781      } else if (isLoop && activeIndex < slidesBefore) {
12782        from = -slidesBefore;
12783        if (centeredSlides) offset += swiper.slidesGrid[0];
12784      }
12785      Object.assign(swiper.virtual, {
12786        from,
12787        to,
12788        offset,
12789        slidesGrid: swiper.slidesGrid,
12790        slidesBefore,
12791        slidesAfter
12792      });
12793      function onRendered() {
12794        swiper.updateSlides();
12795        swiper.updateProgress();
12796        swiper.updateSlidesClasses();
12797        emit('virtualUpdate');
12798      }
12799      if (previousFrom === from && previousTo === to && !force) {
12800        if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
vendor: 1,316 bytes, lines 12801-12842
12801          swiper.slides.forEach(slideEl => {
12802            slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
12803          });
12804        }
12805        swiper.updateProgress();
12806        emit('virtualUpdate');
12807        return;
12808      }
12809      if (swiper.params.virtual.renderExternal) {
12810        swiper.params.virtual.renderExternal.call(swiper, {
12811          offset,
12812          from,
12813          to,
12814          slides: function getSlides() {
12815            const slidesToRender = [];
12816            for (let i = from; i <= to; i += 1) {
12817              slidesToRender.push(slides[i]);
12818            }
12819            return slidesToRender;
12820          }()
12821        });
12822        if (swiper.params.virtual.renderExternalUpdate) {
12823          onRendered();
12824        } else {
12825          emit('virtualUpdate');
12826        }
12827        return;
12828      }
12829      const prependIndexes = [];
12830      const appendIndexes = [];
12831      const getSlideIndex = index => {
12832        let slideIndex = index;
12833        if (index < 0) {
12834          slideIndex = slides.length + index;
12835        } else if (slideIndex >= slides.length) {
12836          // eslint-disable-next-line
12837          slideIndex = slideIndex - slides.length;
12838        }
12839        return slideIndex;
12840      };
12841      if (force) {
12842        swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}
12842, swiper-slide`)).forEach(slideEl => {
12843          slideEl.remove();
12844        });
12845      } else {
12846        for (let i = previousFrom; i <= previousTo; i += 1) {
12847          if (i < from || i > to) {
12848            const slideIndex = getSlideIndex(i);
12849            swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
12850              slideEl.remove();
12851            });
12852          }
12853        }
12854      }
12855      const loopFrom = isLoop ? -slides.length : 0;
12856      const loopTo = isLoop ? slides.length * 2 : slides.length;
12857      for (let i = loopFrom; i < loopTo; i += 1) {
12858        if (i >= from && i <= to) {
12859          const slideIndex = getSlideIndex(i);
12860          if (typeof previousTo === 'undefined' || force) {
12861            appendIndexes.push(slideIndex);
12862          } else {
12863            if (i > previousTo) appendIndexes.push(slideIndex);
12864            if (i < previousFrom) prependIndexes.push(slideIndex);
12865          }
12866        }
12867      }
12868      appendIndexes.forEach(index => {
12869        swiper.slidesEl.append(renderSlide(slides[index], index));
12870      });
12871      if (isLoop) {
12872        for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
12873          const index = prependIndexes[i];
12874          swiper.slidesEl.prepend(renderSlide(slides[index], index));
12875        }
12876      } else {
12877        prependIndexes.sort((a, b) => b - a);
12878        prependIndexes.forEach(index => {
12879          swiper.slidesEl.prepend(renderSlide(slides[index], index));
12880        });
12881      }
12882      elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(sli
vendor: 28,679 bytes, lines 12882-13622
12882deEl => {
12883        slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
12884      });
12885      onRendered();
12886    }
12887    function appendSlide(slides) {
12888      if (typeof slides === 'object' && 'length' in slides) {
12889        for (let i = 0; i < slides.length; i += 1) {
12890          if (slides[i]) swiper.virtual.slides.push(slides[i]);
12891        }
12892      } else {
12893        swiper.virtual.slides.push(slides);
12894      }
12895      update(true);
12896    }
12897    function prependSlide(slides) {
12898      const activeIndex = swiper.activeIndex;
12899      let newActiveIndex = activeIndex + 1;
12900      let numberOfNewSlides = 1;
12901      if (Array.isArray(slides)) {
12902        for (let i = 0; i < slides.length; i += 1) {
12903          if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
12904        }
12905        newActiveIndex = activeIndex + slides.length;
12906        numberOfNewSlides = slides.length;
12907      } else {
12908        swiper.virtual.slides.unshift(slides);
12909      }
12910      if (swiper.params.virtual.cache) {
12911        const cache = swiper.virtual.cache;
12912        const newCache = {};
12913        Object.keys(cache).forEach(cachedIndex => {
12914          const cachedEl = cache[cachedIndex];
12915          const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
12916          if (cachedElIndex) {
12917            cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
12918          }
12919          newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
12920        });
12921        swiper.virtual.cache = newCache;
12922      }
12923      update(true);
12924      swiper.slideTo(newActiveIndex, 0);
12925    }
12926    function removeSlide(slidesIndexes) {
12927      if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
12928      let activeIndex = swiper.activeIndex;
12929      if (Array.isArray(slidesIndexes)) {
12930        for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
12931          if (swiper.params.virtual.cache) {
12932            delete swiper.virtual.cache[slidesIndexes[i]];
12933            // shift cache indexes
12934            Object.keys(swiper.virtual.cache).forEach(key => {
12935              if (key > slidesIndexes) {
12936                swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
12937                swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
12938                delete swiper.virtual.cache[key];
12939              }
12940            });
12941          }
12942          swiper.virtual.slides.splice(slidesIndexes[i], 1);
12943          if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
12944          activeIndex = Math.max(activeIndex, 0);
12945        }
12946      } else {
12947        if (swiper.params.virtual.cache) {
12948          delete swiper.virtual.cache[slidesIndexes];
12949          // shift cache indexes
12950          Object.keys(swiper.virtual.cache).forEach(key => {
12951            if (key > slidesIndexes) {
12952              swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
12953              swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
12954              delete swiper.virtual.cache[key];
12955            }
12956          });
12957        }
12958        swiper.virtual.slides.splice(slidesIndexes, 1);
12959        if (slidesIndexes < activeIndex) activeIndex -= 1;
12960        activeIndex = Math.max(activeIndex, 0);
12961      }
12962      update(true);
12963      swiper.slideTo(activeIndex, 0);
12964    }
12965    function removeAllSlides() {
12966      swiper.virtual.slides = [];
12967      if (swiper.params.virtual.cache) {
12968        swiper.virtual.cache = {};
12969      }
12970      update(true);
12971      swiper.slideTo(0, 0);
12972    }
12973    on('beforeInit', () => {
12974      if (!swiper.params.virtual.enabled) return;
12975      let domSlidesAssigned;
12976      if (typeof swiper.passedParams.virtual.slides === 'undefined') {
12977        const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
12978        if (slides && slides.length) {
12979          swiper.virtual.slides = [...slides];
12980          domSlidesAssigned = true;
12981          slides.forEach((slideEl, slideIndex) => {
12982            slideEl.setAttribute('data-swiper-slide-index', slideIndex);
12983            swiper.virtual.cache[slideIndex] = slideEl;
12984            slideEl.remove();
12985          });
12986        }
12987      }
12988      if (!domSlidesAssigned) {
12989        swiper.virtual.slides = swiper.params.virtual.slides;
12990      }
12991      swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
12992      swiper.params.watchSlidesProgress = true;
12993      swiper.originalParams.watchSlidesProgress = true;
12994      update(false, true);
12995    });
12996    on('setTranslate', () => {
12997      if (!swiper.params.virtual.enabled) return;
12998      if (swiper.params.cssMode && !swiper._immediateVirtual) {
12999        clearTimeout(cssModeTimeout);
13000        cssModeTimeout = setTimeout(() => {
13001          update();
13002        }, 100);
13003      } else {
13004        update();
13005      }
13006    });
13007    on('init update resize', () => {
13008      if (!swiper.params.virtual.enabled) return;
13009      if (swiper.params.cssMode) {
13010        setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
13011      }
13012    });
13013    Object.assign(swiper.virtual, {
13014      appendSlide,
13015      prependSlide,
13016      removeSlide,
13017      removeAllSlides,
13018      update
13019    });
13020  }
13021
13022  /* eslint-disable consistent-return */
13023  function Keyboard({
13024    swiper,
13025    extendParams,
13026    on,
13027    emit
13028  }) {
13029    const document = getDocument();
13030    const window = getWindow();
13031    swiper.keyboard = {
13032      enabled: false
13033    };
13034    extendParams({
13035      keyboard: {
13036        enabled: false,
13037        onlyInViewport: true,
13038        pageUpDown: true
13039      }
13040    });
13041    function handle(event) {
13042      if (!swiper.enabled) return;
13043      const {
13044        rtlTranslate: rtl
13045      } = swiper;
13046      let e = event;
13047      if (e.originalEvent) e = e.originalEvent; // jquery fix
13048      const kc = e.keyCode || e.charCode;
13049      const pageUpDown = swiper.params.keyboard.pageUpDown;
13050      const isPageUp = pageUpDown && kc === 33;
13051      const isPageDown = pageUpDown && kc === 34;
13052      const isArrowLeft = kc === 37;
13053      const isArrowRight = kc === 39;
13054      const isArrowUp = kc === 38;
13055      const isArrowDown = kc === 40;
13056      // Directions locks
13057      if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
13058        return false;
13059      }
13060      if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
13061        return false;
13062      }
13063      if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
13064        return undefined;
13065      }
13066      if (document.activeElement && (document.activeElement.isContentEditable || document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea'))) {
13067        return undefined;
13068      }
13069      if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
13070        let inView = false;
13071        // Check that swiper should be inside of visible area of window
13072        if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) {
13073          return undefined;
13074        }
13075        const el = swiper.el;
13076        const swiperWidth = el.clientWidth;
13077        const swiperHeight = el.clientHeight;
13078        const windowWidth = window.innerWidth;
13079        const windowHeight = window.innerHeight;
13080        const swiperOffset = elementOffset(el);
13081        if (rtl) swiperOffset.left -= el.scrollLeft;
13082        const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
13083        for (let i = 0; i < swiperCoord.length; i += 1) {
13084          const point = swiperCoord[i];
13085          if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
13086            if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
13087            inView = true;
13088          }
13089        }
13090        if (!inView) return undefined;
13091      }
13092      if (swiper.isHorizontal()) {
13093        if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
13094          if (e.preventDefault) e.preventDefault();else e.returnValue = false;
13095        }
13096        if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
13097        if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
13098      } else {
13099        if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
13100          if (e.preventDefault) e.preventDefault();else e.returnValue = false;
13101        }
13102        if (isPageDown || isArrowDown) swiper.slideNext();
13103        if (isPageUp || isArrowUp) swiper.slidePrev();
13104      }
13105      emit('keyPress', kc);
13106      return undefined;
13107    }
13108    function enable() {
13109      if (swiper.keyboard.enabled) return;
13110      document.addEventListener('keydown', handle);
13111      swiper.keyboard.enabled = true;
13112    }
13113    function disable() {
13114      if (!swiper.keyboard.enabled) return;
13115      document.removeEventListener('keydown', handle);
13116      swiper.keyboard.enabled = false;
13117    }
13118    on('init', () => {
13119      if (swiper.params.keyboard.enabled) {
13120        enable();
13121      }
13122    });
13123    on('destroy', () => {
13124      if (swiper.keyboard.enabled) {
13125        disable();
13126      }
13127    });
13128    Object.assign(swiper.keyboard, {
13129      enable,
13130      disable
13131    });
13132  }
13133
13134  /* eslint-disable consistent-return */
13135  function Mousewheel({
13136    swiper,
13137    extendParams,
13138    on,
13139    emit
13140  }) {
13141    const window = getWindow();
13142    extendParams({
13143      mousewheel: {
13144        enabled: false,
13145        releaseOnEdges: false,
13146        invert: false,
13147        forceToAxis: false,
13148        sensitivity: 1,
13149        eventsTarget: 'container',
13150        thresholdDelta: null,
13151        thresholdTime: null,
13152        noMousewheelClass: 'swiper-no-mousewheel'
13153      }
13154    });
13155    swiper.mousewheel = {
13156      enabled: false
13157    };
13158    let timeout;
13159    let lastScrollTime = now();
13160    let lastEventBeforeSnap;
13161    const recentWheelEvents = [];
13162    function normalize(e) {
13163      // Reasonable defaults
13164      const PIXEL_STEP = 10;
13165      const LINE_HEIGHT = 40;
13166      const PAGE_HEIGHT = 800;
13167      let sX = 0;
13168      let sY = 0; // spinX, spinY
13169      let pX = 0;
13170      let pY = 0; // pixelX, pixelY
13171
13172      // Legacy
13173      if ('detail' in e) {
13174        sY = e.detail;
13175      }
13176      if ('wheelDelta' in e) {
13177        sY = -e.wheelDelta / 120;
13178      }
13179      if ('wheelDeltaY' in e) {
13180        sY = -e.wheelDeltaY / 120;
13181      }
13182      if ('wheelDeltaX' in e) {
13183        sX = -e.wheelDeltaX / 120;
13184      }
13185
13186      // side scrolling on FF with DOMMouseScroll
13187      if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
13188        sX = sY;
13189        sY = 0;
13190      }
13191      pX = sX * PIXEL_STEP;
13192      pY = sY * PIXEL_STEP;
13193      if ('deltaY' in e) {
13194        pY = e.deltaY;
13195      }
13196      if ('deltaX' in e) {
13197        pX = e.deltaX;
13198      }
13199      if (e.shiftKey && !pX) {
13200        // if user scrolls with shift he wants horizontal scroll
13201        pX = pY;
13202        pY = 0;
13203      }
13204      if ((pX || pY) && e.deltaMode) {
13205        if (e.deltaMode === 1) {
13206          // delta in LINE units
13207          pX *= LINE_HEIGHT;
13208          pY *= LINE_HEIGHT;
13209        } else {
13210          // delta in PAGE units
13211          pX *= PAGE_HEIGHT;
13212          pY *= PAGE_HEIGHT;
13213        }
13214      }
13215
13216      // Fall-back if spin cannot be determined
13217      if (pX && !sX) {
13218        sX = pX < 1 ? -1 : 1;
13219      }
13220      if (pY && !sY) {
13221        sY = pY < 1 ? -1 : 1;
13222      }
13223      return {
13224        spinX: sX,
13225        spinY: sY,
13226        pixelX: pX,
13227        pixelY: pY
13228      };
13229    }
13230    function handleMouseEnter() {
13231      if (!swiper.enabled) return;
13232      swiper.mouseEntered = true;
13233    }
13234    function handleMouseLeave() {
13235      if (!swiper.enabled) return;
13236      swiper.mouseEntered = false;
13237    }
13238    function animateSlider(newEvent) {
13239      if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
13240        // Prevent if delta of wheel scroll delta is below configured threshold
13241        return false;
13242      }
13243      if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
13244        // Prevent if time between scrolls is below configured threshold
13245        return false;
13246      }
13247
13248      // If the movement is NOT big enough and
13249      // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
13250      //   Don't go any further (avoid insignificant scroll movement).
13251      if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
13252        // Return false as a default
13253        return true;
13254      }
13255      // If user is scrolling towards the end:
13256      //   If the slider hasn't hit the latest slide or
13257      //   if the slider is a loop and
13258      //   if the slider isn't moving right now:
13259      //     Go to next slide and
13260      //     emit a scroll event.
13261      // Else (the user is scrolling towards the beginning) and
13262      // if the slider hasn't hit the first slide or
13263      // if the slider is a loop and
13264      // if the slider isn't moving right now:
13265      //   Go to prev slide and
13266      //   emit a scroll event.
13267      if (newEvent.direction < 0) {
13268        if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
13269          swiper.slideNext();
13270          emit('scroll', newEvent.raw);
13271        }
13272      } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
13273        swiper.slidePrev();
13274        emit('scroll', newEvent.raw);
13275      }
13276      // If you got here is because an animation has been triggered so store the current time
13277      lastScrollTime = new window.Date().getTime();
13278      // Return false as a default
13279      return false;
13280    }
13281    function releaseScroll(newEvent) {
13282      const params = swiper.params.mousewheel;
13283      if (newEvent.direction < 0) {
13284        if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
13285          // Return true to animate scroll on edges
13286          return true;
13287        }
13288      } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
13289        // Return true to animate scroll on edges
13290        return true;
13291      }
13292      return false;
13293    }
13294    function handle(event) {
13295      let e = event;
13296      let disableParentSwiper = true;
13297      if (!swiper.enabled) return;
13298
13299      // Ignore event if the target or its parents have the swiper-no-mousewheel class
13300      if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
13301      const params = swiper.params.mousewheel;
13302      if (swiper.params.cssMode) {
13303        e.preventDefault();
13304      }
13305      let targetEl = swiper.el;
13306      if (swiper.params.mousewheel.eventsTarget !== 'container') {
13307        targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
13308      }
13309      const targetElContainsTarget = targetEl && targetEl.contains(e.target);
13310      if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
13311      if (e.originalEvent) e = e.originalEvent; // jquery fix
13312      let delta = 0;
13313      const rtlFactor = swiper.rtlTranslate ? -1 : 1;
13314      const data = normalize(e);
13315      if (params.forceToAxis) {
13316        if (swiper.isHorizontal()) {
13317          if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;
13318        } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;
13319      } else {
13320        delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
13321      }
13322      if (delta === 0) return true;
13323      if (params.invert) delta = -delta;
13324
13325      // Get the scroll positions
13326      let positions = swiper.getTranslate() + delta * params.sensitivity;
13327      if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
13328      if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
13329
13330      // When loop is true:
13331      //     the disableParentSwiper will be true.
13332      // When loop is false:
13333      //     if the scroll positions is not on edge,
13334      //     then the disableParentSwiper will be true.
13335      //     if the scroll on edge positions,
13336      //     then the disableParentSwiper will be false.
13337      disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
13338      if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
13339      if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
13340        // Register the new event in a variable which stores the relevant data
13341        const newEvent = {
13342          time: now(),
13343          delta: Math.abs(delta),
13344          direction: Math.sign(delta),
13345          raw: event
13346        };
13347
13348        // Keep the most recent events
13349        if (recentWheelEvents.length >= 2) {
13350          recentWheelEvents.shift(); // only store the last N events
13351        }
13352
13353        const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
13354        recentWheelEvents.push(newEvent);
13355
13356        // If there is at least one previous recorded event:
13357        //   If direction has changed or
13358        //   if the scroll is quicker than the previous one:
13359        //     Animate the slider.
13360        // Else (this is the first time the wheel is moved):
13361        //     Animate the slider.
13362        if (prevEvent) {
13363          if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
13364            animateSlider(newEvent);
13365          }
13366        } else {
13367          animateSlider(newEvent);
13368        }
13369
13370        // If it's time to release the scroll:
13371        //   Return now so you don't hit the preventDefault.
13372        if (releaseScroll(newEvent)) {
13373          return true;
13374        }
13375      } else {
13376        // Freemode or scrollContainer:
13377
13378        // If we recently snapped after a momentum scroll, then ignore wheel events
13379        // to give time for the deceleration to finish. Stop ignoring after 500 msecs
13380        // or if it's a new scroll (larger delta or inverse sign as last event before
13381        // an end-of-momentum snap).
13382        const newEvent = {
13383          time: now(),
13384          delta: Math.abs(delta),
13385          direction: Math.sign(delta)
13386        };
13387        const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;
13388        if (!ignoreWheelEvents) {
13389          lastEventBeforeSnap = undefined;
13390          let position = swiper.getTranslate() + delta * params.sensitivity;
13391          const wasBeginning = swiper.isBeginning;
13392          const wasEnd = swiper.isEnd;
13393          if (position >= swiper.minTranslate()) position = swiper.minTranslate();
13394          if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
13395          swiper.setTransition(0);
13396          swiper.setTranslate(position);
13397          swiper.updateProgress();
13398          swiper.updateActiveIndex();
13399          swiper.updateSlidesClasses();
13400          if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
13401            swiper.updateSlidesClasses();
13402          }
13403          if (swiper.params.loop) {
13404            swiper.loopFix({
13405              direction: newEvent.direction < 0 ? 'next' : 'prev',
13406              byMousewheel: true
13407            });
13408          }
13409          if (swiper.params.freeMode.sticky) {
13410            // When wheel scrolling starts with sticky (aka snap) enabled, then detect
13411            // the end of a momentum scroll by storing recent (N=15?) wheel events.
13412            // 1. do all N events have decreasing or same (absolute value) delta?
13413            // 2. did all N events arrive in the last M (M=500?) msecs?
13414            // 3. does the earliest event have an (absolute value) delta that's
13415            //    at least P (P=1?) larger than the most recent event's delta?
13416            // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
13417            // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
13418            // Snap immediately and ignore remaining wheel events in this scroll.
13419            // See comment above for "remaining wheel events in this scroll" determination.
13420            // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
13421            clearTimeout(timeout);
13422            timeout = undefined;
13423            if (recentWheelEvents.length >= 15) {
13424              recentWheelEvents.shift(); // only store the last N events
13425            }
13426
13427            const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
13428            const firstEvent = recentWheelEvents[0];
13429            recentWheelEvents.push(newEvent);
13430            if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
13431              // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
13432              recentWheelEvents.splice(0);
13433            } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {
13434              // We're at the end of the deceleration of a momentum scroll, so there's no need
13435              // to wait for more events. Snap ASAP on the next tick.
13436              // Also, because there's some remaining momentum we'll bias the snap in the
13437              // direction of the ongoing scroll because it's better UX for the scroll to snap
13438              // in the same direction as the scroll instead of reversing to snap.  Therefore,
13439              // if it's already scrolled more than 20% in the current direction, keep going.
13440              const snapToThreshold = delta > 0 ? 0.8 : 0.2;
13441              lastEventBeforeSnap = newEvent;
13442              recentWheelEvents.splice(0);
13443              timeout = nextTick(() => {
13444                if (swiper.destroyed || !swiper.params) return;
13445                swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
13446              }, 0); // no delay; move on next tick
13447            }
13448
13449            if (!timeout) {
13450              // if we get here, then we haven't detected the end of a momentum scroll, so
13451              // we'll consider a scroll "complete" when there haven't been any wheel events
13452              // for 500ms.
13453              timeout = nextTick(() => {
13454                if (swiper.destroyed || !swiper.params) return;
13455                const snapToThreshold = 0.5;
13456                lastEventBeforeSnap = newEvent;
13457                recentWheelEvents.splice(0);
13458                swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
13459              }, 500);
13460            }
13461          }
13462
13463          // Emit event
13464          if (!ignoreWheelEvents) emit('scroll', e);
13465
13466          // Stop autoplay
13467          if (swiper.params.autoplay && swiper.params.autoplay.disableOnInteraction) swiper.autoplay.stop();
13468          // Return page scroll on edge positions
13469          if (params.releaseOnEdges && (position === swiper.minTranslate() || position === swiper.maxTranslate())) {
13470            return true;
13471          }
13472        }
13473      }
13474      if (e.preventDefault) e.preventDefault();else e.returnValue = false;
13475      return false;
13476    }
13477    function events(method) {
13478      let targetEl = swiper.el;
13479      if (swiper.params.mousewheel.eventsTarget !== 'container') {
13480        targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
13481      }
13482      targetEl[method]('mouseenter', handleMouseEnter);
13483      targetEl[method]('mouseleave', handleMouseLeave);
13484      targetEl[method]('wheel', handle);
13485    }
13486    function enable() {
13487      if (swiper.params.cssMode) {
13488        swiper.wrapperEl.removeEventListener('wheel', handle);
13489        return true;
13490      }
13491      if (swiper.mousewheel.enabled) return false;
13492      events('addEventListener');
13493      swiper.mousewheel.enabled = true;
13494      return true;
13495    }
13496    function disable() {
13497      if (swiper.params.cssMode) {
13498        swiper.wrapperEl.addEventListener(event, handle);
13499        return true;
13500      }
13501      if (!swiper.mousewheel.enabled) return false;
13502      events('removeEventListener');
13503      swiper.mousewheel.enabled = false;
13504      return true;
13505    }
13506    on('init', () => {
13507      if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
13508        disable();
13509      }
13510      if (swiper.params.mousewheel.enabled) enable();
13511    });
13512    on('destroy', () => {
13513      if (swiper.params.cssMode) {
13514        enable();
13515      }
13516      if (swiper.mousewheel.enabled) disable();
13517    });
13518    Object.assign(swiper.mousewheel, {
13519      enable,
13520      disable
13521    });
13522  }
13523
13524  function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
13525    if (swiper.params.createElements) {
13526      Object.keys(checkProps).forEach(key => {
13527        if (!params[key] && params.auto === true) {
13528          let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
13529          if (!element) {
13530            element = createElement('div', checkProps[key]);
13531            element.className = checkProps[key];
13532            swiper.el.append(element);
13533          }
13534          params[key] = element;
13535          originalParams[key] = element;
13536        }
13537      });
13538    }
13539    return params;
13540  }
13541
13542  const arrowSvg = `<svg class="swiper-navigation-icon" width="11" height="20" viewBox="0 0 11 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.38296 20.0762C0.111788 19.805 0.111788 19.3654 0.38296 19.0942L9.19758 10.2796L0.38296 1.46497C0.111788 1.19379 0.111788 0.754138 0.38296 0.482966C0.654131 0.211794 1.09379 0.211794 1.36496 0.482966L10.4341 9.55214C10.8359 9.9539 10.8359 10.6053 10.4341 11.007L1.36496 20.0762C1.09379 20.3474 0.654131 20.3474 0.38296 20.0762Z" fill="currentColor"/></svg>`;
13543  function Navigation({
13544    swiper,
13545    extendParams,
13546    on,
13547    emit
13548  }) {
13549    extendParams({
13550      navigation: {
13551        nextEl: null,
13552        prevEl: null,
13553        addIcons: true,
13554        hideOnClick: false,
13555        disabledClass: 'swiper-button-disabled',
13556        hiddenClass: 'swiper-button-hidden',
13557        lockClass: 'swiper-button-lock',
13558        navigationDisabledClass: 'swiper-navigation-disabled'
13559      }
13560    });
13561    swiper.navigation = {
13562      nextEl: null,
13563      prevEl: null,
13564      arrowSvg
13565    };
13566    function getEl(el) {
13567      let res;
13568      if (el && typeof el === 'string' && swiper.isElement) {
13569        res = swiper.el.querySelector(el) || swiper.hostEl.querySelector(el);
13570        if (res) return res;
13571      }
13572      if (el) {
13573        if (typeof el === 'string') res = [...document.querySelectorAll(el)];
13574        if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
13575          res = swiper.el.querySelector(el);
13576        } else if (res && res.length === 1) {
13577          res = res[0];
13578        }
13579      }
13580      if (el && !res) return el;
13581      // if (Array.isArray(res) && res.length === 1) res = res[0];
13582      return res;
13583    }
13584    function toggleEl(el, disabled) {
13585      const params = swiper.params.navigation;
13586      el = makeElementsArray(el);
13587      el.forEach(subEl => {
13588        if (subEl) {
13589          subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
13590          if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
13591          if (swiper.params.watchOverflow && swiper.enabled) {
13592            subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
13593          }
13594        }
13595      });
13596    }
13597    function update() {
13598      // Update Navigation Buttons
13599      const {
13600        nextEl,
13601        prevEl
13602      } = swiper.navigation;
13603      if (swiper.params.loop) {
13604        toggleEl(prevEl, false);
13605        toggleEl(nextEl, false);
13606        return;
13607      }
13608      toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
13609      toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
13610    }
13611    function onPrevClick(e) {
13612      e.preventDefault();
13613      if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
13614      swiper.slidePrev();
13615      emit('navigationPrev');
13616    }
13617    function onNextClick(e) {
13618      e.preventDefault();
13619      if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
13620      swiper.slideNext();
13621      emit('navigationNext');
13622    }
vendor: 4,164 bytes, lines 13623-13736
13623    function init() {
13624      const params = swiper.params.navigation;
13625      swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
13626        nextEl: 'swiper-button-next',
13627        prevEl: 'swiper-button-prev'
13628      });
13629      if (!(params.nextEl || params.prevEl)) return;
13630      let nextEl = getEl(params.nextEl);
13631      let prevEl = getEl(params.prevEl);
13632      Object.assign(swiper.navigation, {
13633        nextEl,
13634        prevEl
13635      });
13636      nextEl = makeElementsArray(nextEl);
13637      prevEl = makeElementsArray(prevEl);
13638      const initButton = (el, dir) => {
13639        if (el) {
13640          if (params.addIcons && el.matches('.swiper-button-next,.swiper-button-prev') && !el.querySelector('svg')) {
13641            const tempEl = document.createElement('div');
13642            setInnerHTML(tempEl, arrowSvg);
13643            el.appendChild(tempEl.querySelector('svg'));
13644            tempEl.remove();
13645          }
13646          el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
13647        }
13648        if (!swiper.enabled && el) {
13649          el.classList.add(...params.lockClass.split(' '));
13650        }
13651      };
13652      nextEl.forEach(el => initButton(el, 'next'));
13653      prevEl.forEach(el => initButton(el, 'prev'));
13654    }
13655    function destroy() {
13656      let {
13657        nextEl,
13658        prevEl
13659      } = swiper.navigation;
13660      nextEl = makeElementsArray(nextEl);
13661      prevEl = makeElementsArray(prevEl);
13662      const destroyButton = (el, dir) => {
13663        el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
13664        el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
13665      };
13666      nextEl.forEach(el => destroyButton(el, 'next'));
13667      prevEl.forEach(el => destroyButton(el, 'prev'));
13668    }
13669    on('init', () => {
13670      if (swiper.params.navigation.enabled === false) {
13671        // eslint-disable-next-line
13672        disable();
13673      } else {
13674        init();
13675        update();
13676      }
13677    });
13678    on('toEdge fromEdge lock unlock', () => {
13679      update();
13680    });
13681    on('destroy', () => {
13682      destroy();
13683    });
13684    on('enable disable', () => {
13685      let {
13686        nextEl,
13687        prevEl
13688      } = swiper.navigation;
13689      nextEl = makeElementsArray(nextEl);
13690      prevEl = makeElementsArray(prevEl);
13691      if (swiper.enabled) {
13692        update();
13693        return;
13694      }
13695      [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass));
13696    });
13697    on('click', (_s, e) => {
13698      let {
13699        nextEl,
13700        prevEl
13701      } = swiper.navigation;
13702      nextEl = makeElementsArray(nextEl);
13703      prevEl = makeElementsArray(prevEl);
13704      const targetEl = e.target;
13705      let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
13706      if (swiper.isElement && !targetIsButton) {
13707        const path = e.path || e.composedPath && e.composedPath();
13708        if (path) {
13709          targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
13710        }
13711      }
13712      if (swiper.params.navigation.hideOnClick && !targetIsButton) {
13713        if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
13714        let isHidden;
13715        if (nextEl.length) {
13716          isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
13717        } else if (prevEl.length) {
13718          isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
13719        }
13720        if (isHidden === true) {
13721          emit('navigationShow');
13722        } else {
13723          emit('navigationHide');
13724        }
13725        [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
13726      }
13727    });
13728    const enable = () => {
13729      swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
13730      init();
13731      update();
13732    };
13733    const disable = () => {
13734      swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
13735      destroy();
13736    };
vendor: 5,665 bytes, lines 13737-13888
13737    Object.assign(swiper.navigation, {
13738      enable,
13739      disable,
13740      update,
13741      init,
13742      destroy
13743    });
13744  }
13745
13746  function classesToSelector(classes = '') {
13747    return `.${classes.trim().replace(/([\.:!+\/()[\]])/g, '\\$1') // eslint-disable-line
13748  .replace(/ /g, '.')}`;
13749  }
13750
13751  function Pagination({
13752    swiper,
13753    extendParams,
13754    on,
13755    emit
13756  }) {
13757    const pfx = 'swiper-pagination';
13758    extendParams({
13759      pagination: {
13760        el: null,
13761        bulletElement: 'span',
13762        clickable: false,
13763        hideOnClick: false,
13764        renderBullet: null,
13765        renderProgressbar: null,
13766        renderFraction: null,
13767        renderCustom: null,
13768        progressbarOpposite: false,
13769        type: 'bullets',
13770        // 'bullets' or 'progressbar' or 'fraction' or 'custom'
13771        dynamicBullets: false,
13772        dynamicMainBullets: 1,
13773        formatFractionCurrent: number => number,
13774        formatFractionTotal: number => number,
13775        bulletClass: `${pfx}-bullet`,
13776        bulletActiveClass: `${pfx}-bullet-active`,
13777        modifierClass: `${pfx}-`,
13778        currentClass: `${pfx}-current`,
13779        totalClass: `${pfx}-total`,
13780        hiddenClass: `${pfx}-hidden`,
13781        progressbarFillClass: `${pfx}-progressbar-fill`,
13782        progressbarOppositeClass: `${pfx}-progressbar-opposite`,
13783        clickableClass: `${pfx}-clickable`,
13784        lockClass: `${pfx}-lock`,
13785        horizontalClass: `${pfx}-horizontal`,
13786        verticalClass: `${pfx}-vertical`,
13787        paginationDisabledClass: `${pfx}-disabled`
13788      }
13789    });
13790    swiper.pagination = {
13791      el: null,
13792      bullets: []
13793    };
13794    let bulletSize;
13795    let dynamicBulletIndex = 0;
13796    function isPaginationDisabled() {
13797      return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;
13798    }
13799    function setSideBullets(bulletEl, position) {
13800      const {
13801        bulletActiveClass
13802      } = swiper.params.pagination;
13803      if (!bulletEl) return;
13804      bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
13805      if (bulletEl) {
13806        bulletEl.classList.add(`${bulletActiveClass}-${position}`);
13807        bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
13808        if (bulletEl) {
13809          bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
13810        }
13811      }
13812    }
13813    function getMoveDirection(prevIndex, nextIndex, length) {
13814      prevIndex = prevIndex % length;
13815      nextIndex = nextIndex % length;
13816      if (nextIndex === prevIndex + 1) {
13817        return 'next';
13818      } else if (nextIndex === prevIndex - 1) {
13819        return 'previous';
13820      }
13821      return;
13822    }
13823    function onBulletClick(e) {
13824      const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));
13825      if (!bulletEl) {
13826        return;
13827      }
13828      e.preventDefault();
13829      const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
13830      if (swiper.params.loop) {
13831        if (swiper.realIndex === index) return;
13832        const moveDirection = getMoveDirection(swiper.realIndex, index, swiper.slides.length);
13833        if (moveDirection === 'next') {
13834          swiper.slideNext();
13835        } else if (moveDirection === 'previous') {
13836          swiper.slidePrev();
13837        } else {
13838          swiper.slideToLoop(index);
13839        }
13840      } else {
13841        swiper.slideTo(index);
13842      }
13843    }
13844    function update() {
13845      // Render || Update Pagination bullets/items
13846      const rtl = swiper.rtl;
13847      const params = swiper.params.pagination;
13848      if (isPaginationDisabled()) return;
13849      let el = swiper.pagination.el;
13850      el = makeElementsArray(el);
13851      // Current/Total
13852      let current;
13853      let previousIndex;
13854      const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
13855      const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
13856      if (swiper.params.loop) {
13857        previousIndex = swiper.previousRealIndex || 0;
13858        current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;
13859      } else if (typeof swiper.snapIndex !== 'undefined') {
13860        current = swiper.snapIndex;
13861        previousIndex = swiper.previousSnapIndex;
13862      } else {
13863        previousIndex = swiper.previousIndex || 0;
13864        current = swiper.activeIndex || 0;
13865      }
13866      // Types
13867      if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
13868        const bullets = swiper.pagination.bullets;
13869        let firstIndex;
13870        let lastIndex;
13871        let midIndex;
13872        if (params.dynamicBullets) {
13873          bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);
13874          el.forEach(subEl => {
13875            subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
13876          });
13877          if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
13878            dynamicBulletIndex += current - (previousIndex || 0);
13879            if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
13880              dynamicBulletIndex = params.dynamicMainBullets - 1;
13881            } else if (dynamicBulletIndex < 0) {
13882              dynamicBulletIndex = 0;
13883            }
13884          }
13885          firstIndex = Math.max(current - dynamicBulletIndex, 0);
13886          lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
13887          midIndex = (lastIndex + firstIndex) / 2;
13888        }
vendor: 9,584 bytes, lines 13889-14106
13889        bullets.forEach(bulletEl => {
13890          const classesToRemove = [...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`)].map(s => typeof s === 'string' && s.includes(' ') ? s.split(' ') : s).flat();
13891          bulletEl.classList.remove(...classesToRemove);
13892        });
13893        if (el.length > 1) {
13894          bullets.forEach(bullet => {
13895            const bulletIndex = elementIndex(bullet);
13896            if (bulletIndex === current) {
13897              bullet.classList.add(...params.bulletActiveClass.split(' '));
13898            } else if (swiper.isElement) {
13899              bullet.setAttribute('part', 'bullet');
13900            }
13901            if (params.dynamicBullets) {
13902              if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
13903                bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
13904              }
13905              if (bulletIndex === firstIndex) {
13906                setSideBullets(bullet, 'prev');
13907              }
13908              if (bulletIndex === lastIndex) {
13909                setSideBullets(bullet, 'next');
13910              }
13911            }
13912          });
13913        } else {
13914          const bullet = bullets[current];
13915          if (bullet) {
13916            bullet.classList.add(...params.bulletActiveClass.split(' '));
13917          }
13918          if (swiper.isElement) {
13919            bullets.forEach((bulletEl, bulletIndex) => {
13920              bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
13921            });
13922          }
13923          if (params.dynamicBullets) {
13924            const firstDisplayedBullet = bullets[firstIndex];
13925            const lastDisplayedBullet = bullets[lastIndex];
13926            for (let i = firstIndex; i <= lastIndex; i += 1) {
13927              if (bullets[i]) {
13928                bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
13929              }
13930            }
13931            setSideBullets(firstDisplayedBullet, 'prev');
13932            setSideBullets(lastDisplayedBullet, 'next');
13933          }
13934        }
13935        if (params.dynamicBullets) {
13936          const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
13937          const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
13938          const offsetProp = rtl ? 'right' : 'left';
13939          bullets.forEach(bullet => {
13940            bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
13941          });
13942        }
13943      }
13944      el.forEach((subEl, subElIndex) => {
13945        if (params.type === 'fraction') {
13946          subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach(fractionEl => {
13947            fractionEl.textContent = params.formatFractionCurrent(current + 1);
13948          });
13949          subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach(totalEl => {
13950            totalEl.textContent = params.formatFractionTotal(total);
13951          });
13952        }
13953        if (params.type === 'progressbar') {
13954          let progressbarDirection;
13955          if (params.progressbarOpposite) {
13956            progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
13957          } else {
13958            progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
13959          }
13960          const scale = (current + 1) / total;
13961          let scaleX = 1;
13962          let scaleY = 1;
13963          if (progressbarDirection === 'horizontal') {
13964            scaleX = scale;
13965          } else {
13966            scaleY = scale;
13967          }
13968          subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach(progressEl => {
13969            progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
13970            progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
13971          });
13972        }
13973        if (params.type === 'custom' && params.renderCustom) {
13974          setInnerHTML(subEl, params.renderCustom(swiper, current + 1, total));
13975          if (subElIndex === 0) emit('paginationRender', subEl);
13976        } else {
13977          if (subElIndex === 0) emit('paginationRender', subEl);
13978          emit('paginationUpdate', subEl);
13979        }
13980        if (swiper.params.watchOverflow && swiper.enabled) {
13981          subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
13982        }
13983      });
13984    }
13985    function render() {
13986      // Render Container
13987      const params = swiper.params.pagination;
13988      if (isPaginationDisabled()) return;
13989      const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.grid && swiper.params.grid.rows > 1 ? swiper.slides.length / Math.ceil(swiper.params.grid.rows) : swiper.slides.length;
13990      let el = swiper.pagination.el;
13991      el = makeElementsArray(el);
13992      let paginationHTML = '';
13993      if (params.type === 'bullets') {
13994        let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
13995        if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
13996          numberOfBullets = slidesLength;
13997        }
13998        for (let i = 0; i < numberOfBullets; i += 1) {
13999          if (params.renderBullet) {
14000            paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
14001          } else {
14002            // prettier-ignore
14003            paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
14004          }
14005        }
14006      }
14007      if (params.type === 'fraction') {
14008        if (params.renderFraction) {
14009          paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
14010        } else {
14011          paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
14012        }
14013      }
14014      if (params.type === 'progressbar') {
14015        if (params.renderProgressbar) {
14016          paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
14017        } else {
14018          paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
14019        }
14020      }
14021      swiper.pagination.bullets = [];
14022      el.forEach(subEl => {
14023        if (params.type !== 'custom') {
14024          setInnerHTML(subEl, paginationHTML || '');
14025        }
14026        if (params.type === 'bullets') {
14027          swiper.pagination.bullets.push(...subEl.querySelectorAll(classesToSelector(params.bulletClass)));
14028        }
14029      });
14030      if (params.type !== 'custom') {
14031        emit('paginationRender', el[0]);
14032      }
14033    }
14034    function init() {
14035      swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
14036        el: 'swiper-pagination'
14037      });
14038      const params = swiper.params.pagination;
14039      if (!params.el) return;
14040      let el;
14041      if (typeof params.el === 'string' && swiper.isElement) {
14042        el = swiper.el.querySelector(params.el);
14043      }
14044      if (!el && typeof params.el === 'string') {
14045        el = [...document.querySelectorAll(params.el)];
14046      }
14047      if (!el) {
14048        el = params.el;
14049      }
14050      if (!el || el.length === 0) return;
14051      if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
14052        el = [...swiper.el.querySelectorAll(params.el)];
14053        // check if it belongs to another nested Swiper
14054        if (el.length > 1) {
14055          el = el.find(subEl => {
14056            if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
14057            return true;
14058          });
14059        }
14060      }
14061      if (Array.isArray(el) && el.length === 1) el = el[0];
14062      Object.assign(swiper.pagination, {
14063        el
14064      });
14065      el = makeElementsArray(el);
14066      el.forEach(subEl => {
14067        if (params.type === 'bullets' && params.clickable) {
14068          subEl.classList.add(...(params.clickableClass || '').split(' '));
14069        }
14070        subEl.classList.add(params.modifierClass + params.type);
14071        subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
14072        if (params.type === 'bullets' && params.dynamicBullets) {
14073          subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
14074          dynamicBulletIndex = 0;
14075          if (params.dynamicMainBullets < 1) {
14076            params.dynamicMainBullets = 1;
14077          }
14078        }
14079        if (params.type === 'progressbar' && params.progressbarOpposite) {
14080          subEl.classList.add(params.progressbarOppositeClass);
14081        }
14082        if (params.clickable) {
14083          subEl.addEventListener('click', onBulletClick);
14084        }
14085        if (!swiper.enabled) {
14086          subEl.classList.add(params.lockClass);
14087        }
14088      });
14089    }
14090    function destroy() {
14091      const params = swiper.params.pagination;
14092      if (isPaginationDisabled()) return;
14093      let el = swiper.pagination.el;
14094      if (el) {
14095        el = makeElementsArray(el);
14096        el.forEach(subEl => {
14097          subEl.classList.remove(params.hiddenClass);
14098          subEl.classList.remove(params.modifierClass + params.type);
14099          subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
14100          if (params.clickable) {
14101            subEl.classList.remove(...(params.clickableClass || '').split(' '));
14102            subEl.removeEventListener('click', onBulletClick);
14103          }
14104        });
14105      }
14106      if (swiper.pagination.bullets) swiper.pagination.bullets.forEac
vendor: 8,195 bytes, lines 14106-14365
14106h(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
14107    }
14108    on('changeDirection', () => {
14109      if (!swiper.pagination || !swiper.pagination.el) return;
14110      const params = swiper.params.pagination;
14111      let {
14112        el
14113      } = swiper.pagination;
14114      el = makeElementsArray(el);
14115      el.forEach(subEl => {
14116        subEl.classList.remove(params.horizontalClass, params.verticalClass);
14117        subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
14118      });
14119    });
14120    on('init', () => {
14121      if (swiper.params.pagination.enabled === false) {
14122        // eslint-disable-next-line
14123        disable();
14124      } else {
14125        init();
14126        render();
14127        update();
14128      }
14129    });
14130    on('activeIndexChange', () => {
14131      if (typeof swiper.snapIndex === 'undefined') {
14132        update();
14133      }
14134    });
14135    on('snapIndexChange', () => {
14136      update();
14137    });
14138    on('snapGridLengthChange', () => {
14139      render();
14140      update();
14141    });
14142    on('destroy', () => {
14143      destroy();
14144    });
14145    on('enable disable', () => {
14146      let {
14147        el
14148      } = swiper.pagination;
14149      if (el) {
14150        el = makeElementsArray(el);
14151        el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
14152      }
14153    });
14154    on('lock unlock', () => {
14155      update();
14156    });
14157    on('click', (_s, e) => {
14158      const targetEl = e.target;
14159      const el = makeElementsArray(swiper.pagination.el);
14160      if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {
14161        if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
14162        const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
14163        if (isHidden === true) {
14164          emit('paginationShow');
14165        } else {
14166          emit('paginationHide');
14167        }
14168        el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
14169      }
14170    });
14171    const enable = () => {
14172      swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
14173      let {
14174        el
14175      } = swiper.pagination;
14176      if (el) {
14177        el = makeElementsArray(el);
14178        el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
14179      }
14180      init();
14181      render();
14182      update();
14183    };
14184    const disable = () => {
14185      swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
14186      let {
14187        el
14188      } = swiper.pagination;
14189      if (el) {
14190        el = makeElementsArray(el);
14191        el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
14192      }
14193      destroy();
14194    };
14195    Object.assign(swiper.pagination, {
14196      enable,
14197      disable,
14198      render,
14199      update,
14200      init,
14201      destroy
14202    });
14203  }
14204
14205  function Scrollbar({
14206    swiper,
14207    extendParams,
14208    on,
14209    emit
14210  }) {
14211    const document = getDocument();
14212    let isTouched = false;
14213    let timeout = null;
14214    let dragTimeout = null;
14215    let dragStartPos;
14216    let dragSize;
14217    let trackSize;
14218    let divider;
14219    extendParams({
14220      scrollbar: {
14221        el: null,
14222        dragSize: 'auto',
14223        hide: false,
14224        draggable: false,
14225        snapOnRelease: true,
14226        lockClass: 'swiper-scrollbar-lock',
14227        dragClass: 'swiper-scrollbar-drag',
14228        scrollbarDisabledClass: 'swiper-scrollbar-disabled',
14229        horizontalClass: `swiper-scrollbar-horizontal`,
14230        verticalClass: `swiper-scrollbar-vertical`
14231      }
14232    });
14233    swiper.scrollbar = {
14234      el: null,
14235      dragEl: null
14236    };
14237    function setTranslate() {
14238      if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
14239      const {
14240        scrollbar,
14241        rtlTranslate: rtl
14242      } = swiper;
14243      const {
14244        dragEl,
14245        el
14246      } = scrollbar;
14247      const params = swiper.params.scrollbar;
14248      const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
14249      let newSize = dragSize;
14250      let newPos = (trackSize - dragSize) * progress;
14251      if (rtl) {
14252        newPos = -newPos;
14253        if (newPos > 0) {
14254          newSize = dragSize - newPos;
14255          newPos = 0;
14256        } else if (-newPos + dragSize > trackSize) {
14257          newSize = trackSize + newPos;
14258        }
14259      } else if (newPos < 0) {
14260        newSize = dragSize + newPos;
14261        newPos = 0;
14262      } else if (newPos + dragSize > trackSize) {
14263        newSize = trackSize - newPos;
14264      }
14265      if (swiper.isHorizontal()) {
14266        dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
14267        dragEl.style.width = `${newSize}px`;
14268      } else {
14269        dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
14270        dragEl.style.height = `${newSize}px`;
14271      }
14272      if (params.hide) {
14273        clearTimeout(timeout);
14274        el.style.opacity = 1;
14275        timeout = setTimeout(() => {
14276          el.style.opacity = 0;
14277          el.style.transitionDuration = '400ms';
14278        }, 1000);
14279      }
14280    }
14281    function setTransition(duration) {
14282      if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
14283      swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
14284    }
14285    function updateSize() {
14286      if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
14287      const {
14288        scrollbar
14289      } = swiper;
14290      const {
14291        dragEl,
14292        el
14293      } = scrollbar;
14294      dragEl.style.width = '';
14295      dragEl.style.height = '';
14296      trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
14297      divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
14298      if (swiper.params.scrollbar.dragSize === 'auto') {
14299        dragSize = trackSize * divider;
14300      } else {
14301        dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
14302      }
14303      if (swiper.isHorizontal()) {
14304        dragEl.style.width = `${dragSize}px`;
14305      } else {
14306        dragEl.style.height = `${dragSize}px`;
14307      }
14308      if (divider >= 1) {
14309        el.style.display = 'none';
14310      } else {
14311        el.style.display = '';
14312      }
14313      if (swiper.params.scrollbar.hide) {
14314        el.style.opacity = 0;
14315      }
14316      if (swiper.params.watchOverflow && swiper.enabled) {
14317        scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
14318      }
14319    }
14320    function getPointerPosition(e) {
14321      return swiper.isHorizontal() ? e.clientX : e.clientY;
14322    }
14323    function setDragPosition(e) {
14324      const {
14325        scrollbar,
14326        rtlTranslate: rtl
14327      } = swiper;
14328      const {
14329        el
14330      } = scrollbar;
14331      let positionRatio;
14332      positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
14333      positionRatio = Math.max(Math.min(positionRatio, 1), 0);
14334      if (rtl) {
14335        positionRatio = 1 - positionRatio;
14336      }
14337      const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
14338      swiper.updateProgress(position);
14339      swiper.setTranslate(position);
14340      swiper.updateActiveIndex();
14341      swiper.updateSlidesClasses();
14342    }
14343    function onDragStart(e) {
14344      const params = swiper.params.scrollbar;
14345      const {
14346        scrollbar,
14347        wrapperEl
14348      } = swiper;
14349      const {
14350        el,
14351        dragEl
14352      } = scrollbar;
14353      isTouched = true;
14354      dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
14355      e.preventDefault();
14356      e.stopPropagation();
14357      wrapperEl.style.transitionDuration = '100ms';
14358      dragEl.style.transitionDuration = '100ms';
14359      setDragPosition(e);
14360      clearTimeout(dragTimeout);
14361      el.style.transitionDuration = '0ms';
14362      if (params.hide) {
14363        el.style.opacity = 1;
14364      }
14365      if (swiper.params.cssMode) {
vendor: 6,010 bytes, lines 14366-14553
14366        swiper.wrapperEl.style['scroll-snap-type'] = 'none';
14367      }
14368      emit('scrollbarDragStart', e);
14369    }
14370    function onDragMove(e) {
14371      const {
14372        scrollbar,
14373        wrapperEl
14374      } = swiper;
14375      const {
14376        el,
14377        dragEl
14378      } = scrollbar;
14379      if (!isTouched) return;
14380      if (e.preventDefault && e.cancelable) e.preventDefault();else e.returnValue = false;
14381      setDragPosition(e);
14382      wrapperEl.style.transitionDuration = '0ms';
14383      el.style.transitionDuration = '0ms';
14384      dragEl.style.transitionDuration = '0ms';
14385      emit('scrollbarDragMove', e);
14386    }
14387    function onDragEnd(e) {
14388      const params = swiper.params.scrollbar;
14389      const {
14390        scrollbar,
14391        wrapperEl
14392      } = swiper;
14393      const {
14394        el
14395      } = scrollbar;
14396      if (!isTouched) return;
14397      isTouched = false;
14398      if (swiper.params.cssMode) {
14399        swiper.wrapperEl.style['scroll-snap-type'] = '';
14400        wrapperEl.style.transitionDuration = '';
14401      }
14402      if (params.hide) {
14403        clearTimeout(dragTimeout);
14404        dragTimeout = nextTick(() => {
14405          el.style.opacity = 0;
14406          el.style.transitionDuration = '400ms';
14407        }, 1000);
14408      }
14409      emit('scrollbarDragEnd', e);
14410      if (params.snapOnRelease) {
14411        swiper.slideToClosest();
14412      }
14413    }
14414    function events(method) {
14415      const {
14416        scrollbar,
14417        params
14418      } = swiper;
14419      const el = scrollbar.el;
14420      if (!el) return;
14421      const target = el;
14422      const activeListener = params.passiveListeners ? {
14423        passive: false,
14424        capture: false
14425      } : false;
14426      const passiveListener = params.passiveListeners ? {
14427        passive: true,
14428        capture: false
14429      } : false;
14430      if (!target) return;
14431      const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
14432      target[eventMethod]('pointerdown', onDragStart, activeListener);
14433      document[eventMethod]('pointermove', onDragMove, activeListener);
14434      document[eventMethod]('pointerup', onDragEnd, passiveListener);
14435    }
14436    function enableDraggable() {
14437      if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
14438      events('on');
14439    }
14440    function disableDraggable() {
14441      if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
14442      events('off');
14443    }
14444    function init() {
14445      const {
14446        scrollbar,
14447        el: swiperEl
14448      } = swiper;
14449      swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {
14450        el: 'swiper-scrollbar'
14451      });
14452      const params = swiper.params.scrollbar;
14453      if (!params.el) return;
14454      let el;
14455      if (typeof params.el === 'string' && swiper.isElement) {
14456        el = swiper.el.querySelector(params.el);
14457      }
14458      if (!el && typeof params.el === 'string') {
14459        el = document.querySelectorAll(params.el);
14460        if (!el.length) return;
14461      } else if (!el) {
14462        el = params.el;
14463      }
14464      if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) {
14465        el = swiperEl.querySelector(params.el);
14466      }
14467      if (el.length > 0) el = el[0];
14468      el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
14469      let dragEl;
14470      if (el) {
14471        dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass));
14472        if (!dragEl) {
14473          dragEl = createElement('div', swiper.params.scrollbar.dragClass);
14474          el.append(dragEl);
14475        }
14476      }
14477      Object.assign(scrollbar, {
14478        el,
14479        dragEl
14480      });
14481      if (params.draggable) {
14482        enableDraggable();
14483      }
14484      if (el) {
14485        el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
14486      }
14487    }
14488    function destroy() {
14489      const params = swiper.params.scrollbar;
14490      const el = swiper.scrollbar.el;
14491      if (el) {
14492        el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass));
14493      }
14494      disableDraggable();
14495    }
14496    on('changeDirection', () => {
14497      if (!swiper.scrollbar || !swiper.scrollbar.el) return;
14498      const params = swiper.params.scrollbar;
14499      let {
14500        el
14501      } = swiper.scrollbar;
14502      el = makeElementsArray(el);
14503      el.forEach(subEl => {
14504        subEl.classList.remove(params.horizontalClass, params.verticalClass);
14505        subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
14506      });
14507    });
14508    on('init', () => {
14509      if (swiper.params.scrollbar.enabled === false) {
14510        // eslint-disable-next-line
14511        disable();
14512      } else {
14513        init();
14514        updateSize();
14515        setTranslate();
14516      }
14517    });
14518    on('update resize observerUpdate lock unlock changeDirection', () => {
14519      updateSize();
14520    });
14521    on('setTranslate', () => {
14522      setTranslate();
14523    });
14524    on('setTransition', (_s, duration) => {
14525      setTransition(duration);
14526    });
14527    on('enable disable', () => {
14528      const {
14529        el
14530      } = swiper.scrollbar;
14531      if (el) {
14532        el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
14533      }
14534    });
14535    on('destroy', () => {
14536      destroy();
14537    });
14538    const enable = () => {
14539      swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
14540      if (swiper.scrollbar.el) {
14541        swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
14542      }
14543      init();
14544      updateSize();
14545      setTranslate();
14546    };
14547    const disable = () => {
14548      swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
14549      if (swiper.scrollbar.el) {
14550        swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
14551      }
14552      destroy();
14553    };
vendor: 14,492 bytes, lines 14554-14961
14554    Object.assign(swiper.scrollbar, {
14555      enable,
14556      disable,
14557      updateSize,
14558      setTranslate,
14559      init,
14560      destroy
14561    });
14562  }
14563
14564  function Parallax({
14565    swiper,
14566    extendParams,
14567    on
14568  }) {
14569    extendParams({
14570      parallax: {
14571        enabled: false
14572      }
14573    });
14574    const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]';
14575    const setTransform = (el, progress) => {
14576      const {
14577        rtl
14578      } = swiper;
14579      const rtlFactor = rtl ? -1 : 1;
14580      const p = el.getAttribute('data-swiper-parallax') || '0';
14581      let x = el.getAttribute('data-swiper-parallax-x');
14582      let y = el.getAttribute('data-swiper-parallax-y');
14583      const scale = el.getAttribute('data-swiper-parallax-scale');
14584      const opacity = el.getAttribute('data-swiper-parallax-opacity');
14585      const rotate = el.getAttribute('data-swiper-parallax-rotate');
14586      if (x || y) {
14587        x = x || '0';
14588        y = y || '0';
14589      } else if (swiper.isHorizontal()) {
14590        x = p;
14591        y = '0';
14592      } else {
14593        y = p;
14594        x = '0';
14595      }
14596      if (x.indexOf('%') >= 0) {
14597        x = `${parseInt(x, 10) * progress * rtlFactor}%`;
14598      } else {
14599        x = `${x * progress * rtlFactor}px`;
14600      }
14601      if (y.indexOf('%') >= 0) {
14602        y = `${parseInt(y, 10) * progress}%`;
14603      } else {
14604        y = `${y * progress}px`;
14605      }
14606      if (typeof opacity !== 'undefined' && opacity !== null) {
14607        const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
14608        el.style.opacity = currentOpacity;
14609      }
14610      let transform = `translate3d(${x}, ${y}, 0px)`;
14611      if (typeof scale !== 'undefined' && scale !== null) {
14612        const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
14613        transform += ` scale(${currentScale})`;
14614      }
14615      if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
14616        const currentRotate = rotate * progress * -1;
14617        transform += ` rotate(${currentRotate}deg)`;
14618      }
14619      el.style.transform = transform;
14620    };
14621    const setTranslate = () => {
14622      const {
14623        el,
14624        slides,
14625        progress,
14626        snapGrid,
14627        isElement
14628      } = swiper;
14629      const elements = elementChildren(el, elementsSelector);
14630      if (swiper.isElement) {
14631        elements.push(...elementChildren(swiper.hostEl, elementsSelector));
14632      }
14633      elements.forEach(subEl => {
14634        setTransform(subEl, progress);
14635      });
14636      slides.forEach((slideEl, slideIndex) => {
14637        let slideProgress = slideEl.progress;
14638        if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
14639          slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
14640        }
14641        slideProgress = Math.min(Math.max(slideProgress, -1), 1);
14642        slideEl.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`).forEach(subEl => {
14643          setTransform(subEl, slideProgress);
14644        });
14645      });
14646    };
14647    const setTransition = (duration = swiper.params.speed) => {
14648      const {
14649        el,
14650        hostEl
14651      } = swiper;
14652      const elements = [...el.querySelectorAll(elementsSelector)];
14653      if (swiper.isElement) {
14654        elements.push(...hostEl.querySelectorAll(elementsSelector));
14655      }
14656      elements.forEach(parallaxEl => {
14657        let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
14658        if (duration === 0) parallaxDuration = 0;
14659        parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
14660      });
14661    };
14662    on('beforeInit', () => {
14663      if (!swiper.params.parallax.enabled) return;
14664      swiper.params.watchSlidesProgress = true;
14665      swiper.originalParams.watchSlidesProgress = true;
14666    });
14667    on('init', () => {
14668      if (!swiper.params.parallax.enabled) return;
14669      setTranslate();
14670    });
14671    on('setTranslate', () => {
14672      if (!swiper.params.parallax.enabled) return;
14673      setTranslate();
14674    });
14675    on('setTransition', (_swiper, duration) => {
14676      if (!swiper.params.parallax.enabled) return;
14677      setTransition(duration);
14678    });
14679  }
14680
14681  function Zoom({
14682    swiper,
14683    extendParams,
14684    on,
14685    emit
14686  }) {
14687    const window = getWindow();
14688    extendParams({
14689      zoom: {
14690        enabled: false,
14691        limitToOriginalSize: false,
14692        maxRatio: 3,
14693        minRatio: 1,
14694        panOnMouseMove: false,
14695        toggle: true,
14696        containerClass: 'swiper-zoom-container',
14697        zoomedSlideClass: 'swiper-slide-zoomed'
14698      }
14699    });
14700    swiper.zoom = {
14701      enabled: false
14702    };
14703    let currentScale = 1;
14704    let isScaling = false;
14705    let isPanningWithMouse = false;
14706    let mousePanStart = {
14707      x: 0,
14708      y: 0
14709    };
14710    const mousePanSensitivity = -3; // Negative to invert pan direction
14711    let fakeGestureTouched;
14712    let fakeGestureMoved;
14713    const evCache = [];
14714    const gesture = {
14715      originX: 0,
14716      originY: 0,
14717      slideEl: undefined,
14718      slideWidth: undefined,
14719      slideHeight: undefined,
14720      imageEl: undefined,
14721      imageWrapEl: undefined,
14722      maxRatio: 3
14723    };
14724    const image = {
14725      isTouched: undefined,
14726      isMoved: undefined,
14727      currentX: undefined,
14728      currentY: undefined,
14729      minX: undefined,
14730      minY: undefined,
14731      maxX: undefined,
14732      maxY: undefined,
14733      width: undefined,
14734      height: undefined,
14735      startX: undefined,
14736      startY: undefined,
14737      touchesStart: {},
14738      touchesCurrent: {}
14739    };
14740    const velocity = {
14741      x: undefined,
14742      y: undefined,
14743      prevPositionX: undefined,
14744      prevPositionY: undefined,
14745      prevTime: undefined
14746    };
14747    let scale = 1;
14748    Object.defineProperty(swiper.zoom, 'scale', {
14749      get() {
14750        return scale;
14751      },
14752      set(value) {
14753        if (scale !== value) {
14754          const imageEl = gesture.imageEl;
14755          const slideEl = gesture.slideEl;
14756          emit('zoomChange', value, imageEl, slideEl);
14757        }
14758        scale = value;
14759      }
14760    });
14761    function getDistanceBetweenTouches() {
14762      if (evCache.length < 2) return 1;
14763      const x1 = evCache[0].pageX;
14764      const y1 = evCache[0].pageY;
14765      const x2 = evCache[1].pageX;
14766      const y2 = evCache[1].pageY;
14767      const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
14768      return distance;
14769    }
14770    function getMaxRatio() {
14771      const params = swiper.params.zoom;
14772      const maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
14773      if (params.limitToOriginalSize && gesture.imageEl && gesture.imageEl.naturalWidth) {
14774        const imageMaxRatio = gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth;
14775        return Math.min(imageMaxRatio, maxRatio);
14776      }
14777      return maxRatio;
14778    }
14779    function getScaleOrigin() {
14780      if (evCache.length < 2) return {
14781        x: null,
14782        y: null
14783      };
14784      const box = gesture.imageEl.getBoundingClientRect();
14785      return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x - window.scrollX) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y - window.scrollY) / currentScale];
14786    }
14787    function getSlideSelector() {
14788      return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
14789    }
14790    function eventWithinSlide(e) {
14791      const slideSelector = getSlideSelector();
14792      if (e.target.matches(slideSelector)) return true;
14793      if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;
14794      return false;
14795    }
14796    function eventWithinZoomContainer(e) {
14797      const selector = `.${swiper.params.zoom.containerClass}`;
14798      if (e.target.matches(selector)) return true;
14799      if ([...swiper.hostEl.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;
14800      return false;
14801    }
14802
14803    // Events
14804    function onGestureStart(e) {
14805      if (e.pointerType === 'mouse') {
14806        evCache.splice(0, evCache.length);
14807      }
14808      if (!eventWithinSlide(e)) return;
14809      const params = swiper.params.zoom;
14810      fakeGestureTouched = false;
14811      fakeGestureMoved = false;
14812      evCache.push(e);
14813      if (evCache.length < 2) {
14814        return;
14815      }
14816      fakeGestureTouched = true;
14817      gesture.scaleStart = getDistanceBetweenTouches();
14818      if (!gesture.slideEl) {
14819        gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
14820        if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
14821        let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
14822        if (imageEl) {
14823          imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
14824        }
14825        gesture.imageEl = imageEl;
14826        if (imageEl) {
14827          gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
14828        } else {
14829          gesture.imageWrapEl = undefined;
14830        }
14831        if (!gesture.imageWrapEl) {
14832          gesture.imageEl = undefined;
14833          return;
14834        }
14835        gesture.maxRatio = getMaxRatio();
14836      }
14837      if (gesture.imageEl) {
14838        const [originX, originY] = getScaleOrigin();
14839        gesture.originX = originX;
14840        gesture.originY = originY;
14841        gesture.imageEl.style.transitionDuration = '0ms';
14842      }
14843      isScaling = true;
14844    }
14845    function onGestureChange(e) {
14846      if (!eventWithinSlide(e)) return;
14847      const params = swiper.params.zoom;
14848      const zoom = swiper.zoom;
14849      const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
14850      if (pointerIndex >= 0) evCache[pointerIndex] = e;
14851      if (evCache.length < 2) {
14852        return;
14853      }
14854      fakeGestureMoved = true;
14855      gesture.scaleMove = getDistanceBetweenTouches();
14856      if (!gesture.imageEl) {
14857        return;
14858      }
14859      zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;
14860      if (zoom.scale > gesture.maxRatio) {
14861        zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
14862      }
14863      if (zoom.scale < params.minRatio) {
14864        zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
14865      }
14866      gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
14867    }
14868    function onGestureEnd(e) {
14869      if (!eventWithinSlide(e)) return;
14870      if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
14871      const params = swiper.params.zoom;
14872      const zoom = swiper.zoom;
14873      const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
14874      if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
14875      if (!fakeGestureTouched || !fakeGestureMoved) {
14876        return;
14877      }
14878      fakeGestureTouched = false;
14879      fakeGestureMoved = false;
14880      if (!gesture.imageEl) return;
14881      zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
14882      gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
14883      gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
14884      currentScale = zoom.scale;
14885      isScaling = false;
14886      if (zoom.scale > 1 && gesture.slideEl) {
14887        gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
14888      } else if (zoom.scale <= 1 && gesture.slideEl) {
14889        gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
14890      }
14891      if (zoom.scale === 1) {
14892        gesture.originX = 0;
14893        gesture.originY = 0;
14894        gesture.slideEl = undefined;
14895      }
14896    }
14897    let allowTouchMoveTimeout;
14898    function allowTouchMove() {
14899      swiper.touchEventsData.preventTouchMoveFromPointerMove = false;
14900    }
14901    function preventTouchMove() {
14902      clearTimeout(allowTouchMoveTimeout);
14903      swiper.touchEventsData.preventTouchMoveFromPointerMove = true;
14904      allowTouchMoveTimeout = setTimeout(() => {
14905        if (swiper.destroyed) return;
14906        allowTouchMove();
14907      });
14908    }
14909    function onTouchStart(e) {
14910      const device = swiper.device;
14911      if (!gesture.imageEl) return;
14912      if (image.isTouched) return;
14913      if (device.android && e.cancelable) e.preventDefault();
14914      image.isTouched = true;
14915      const event = evCache.length > 0 ? evCache[0] : e;
14916      image.touchesStart.x = event.pageX;
14917      image.touchesStart.y = event.pageY;
14918    }
14919    function onTouchMove(e) {
14920      const isMouseEvent = e.pointerType === 'mouse';
14921      const isMousePan = isMouseEvent && swiper.params.zoom.panOnMouseMove;
14922      if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) {
14923        return;
14924      }
14925      const zoom = swiper.zoom;
14926      if (!gesture.imageEl) {
14927        return;
14928      }
14929      if (!image.isTouched || !gesture.slideEl) {
14930        if (isMousePan) onMouseMove(e);
14931        return;
14932      }
14933      if (isMousePan) {
14934        onMouseMove(e);
14935        return;
14936      }
14937      if (!image.isMoved) {
14938        image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
14939        image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
14940        image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
14941        image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
14942        gesture.slideWidth = gesture.slideEl.offsetWidth;
14943        gesture.slideHeight = gesture.slideEl.offsetHeight;
14944        gesture.imageWrapEl.style.transitionDuration = '0ms';
14945      }
14946      // Define if we need image drag
14947      const scaledWidth = image.width * zoom.scale;
14948      const scaledHeight = image.height * zoom.scale;
14949      image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
14950      image.maxX = -image.minX;
14951      image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
14952      image.maxY = -image.minY;
14953      image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
14954      image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
14955      const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y));
14956      if (touchesDiff > 5) {
14957        swiper.allowClick = false;
14958      }
14959      if (!image.isMoved && !isScaling) {
14960        if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {
14961          image.isTouched = false;
vendor: 4,335 bytes, lines 14962-15049
14962          allowTouchMove();
14963          return;
14964        }
14965        if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {
14966          image.isTouched = false;
14967          allowTouchMove();
14968          return;
14969        }
14970      }
14971      if (e.cancelable) {
14972        e.preventDefault();
14973      }
14974      e.stopPropagation();
14975      preventTouchMove();
14976      image.isMoved = true;
14977      const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
14978      const {
14979        originX,
14980        originY
14981      } = gesture;
14982      image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
14983      image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
14984      if (image.currentX < image.minX) {
14985        image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
14986      }
14987      if (image.currentX > image.maxX) {
14988        image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
14989      }
14990      if (image.currentY < image.minY) {
14991        image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
14992      }
14993      if (image.currentY > image.maxY) {
14994        image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
14995      }
14996
14997      // Velocity
14998      if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
14999      if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
15000      if (!velocity.prevTime) velocity.prevTime = Date.now();
15001      velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
15002      velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
15003      if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
15004      if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
15005      velocity.prevPositionX = image.touchesCurrent.x;
15006      velocity.prevPositionY = image.touchesCurrent.y;
15007      velocity.prevTime = Date.now();
15008      gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
15009    }
15010    function onTouchEnd() {
15011      const zoom = swiper.zoom;
15012      evCache.length = 0;
15013      if (!gesture.imageEl) return;
15014      if (!image.isTouched || !image.isMoved) {
15015        image.isTouched = false;
15016        image.isMoved = false;
15017        return;
15018      }
15019      image.isTouched = false;
15020      image.isMoved = false;
15021      let momentumDurationX = 300;
15022      let momentumDurationY = 300;
15023      const momentumDistanceX = velocity.x * momentumDurationX;
15024      const newPositionX = image.currentX + momentumDistanceX;
15025      const momentumDistanceY = velocity.y * momentumDurationY;
15026      const newPositionY = image.currentY + momentumDistanceY;
15027
15028      // Fix duration
15029      if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
15030      if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
15031      const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
15032      image.currentX = newPositionX;
15033      image.currentY = newPositionY;
15034      // Define if we need image drag
15035      const scaledWidth = image.width * zoom.scale;
15036      const scaledHeight = image.height * zoom.scale;
15037      image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
15038      image.maxX = -image.minX;
15039      image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
15040      image.maxY = -image.minY;
15041      image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
15042      image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
15043      gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
15044      gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
15045    }
15046    function onTransitionEnd() {
15047      const zoom = swiper.zoom;
15048      if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
15049        if (gesture.imageEl) {
vendor: 65,834 bytes, lines 15050-16895
15050          gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
15051        }
15052        if (gesture.imageWrapEl) {
15053          gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
15054        }
15055        gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
15056        zoom.scale = 1;
15057        currentScale = 1;
15058        gesture.slideEl = undefined;
15059        gesture.imageEl = undefined;
15060        gesture.imageWrapEl = undefined;
15061        gesture.originX = 0;
15062        gesture.originY = 0;
15063      }
15064    }
15065    function onMouseMove(e) {
15066      // Only pan if zoomed in and mouse panning is enabled
15067      if (currentScale <= 1 || !gesture.imageWrapEl) return;
15068      if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
15069      const currentTransform = window.getComputedStyle(gesture.imageWrapEl).transform;
15070      const matrix = new window.DOMMatrix(currentTransform);
15071      if (!isPanningWithMouse) {
15072        isPanningWithMouse = true;
15073        mousePanStart.x = e.clientX;
15074        mousePanStart.y = e.clientY;
15075        image.startX = matrix.e;
15076        image.startY = matrix.f;
15077        image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
15078        image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
15079        gesture.slideWidth = gesture.slideEl.offsetWidth;
15080        gesture.slideHeight = gesture.slideEl.offsetHeight;
15081        return;
15082      }
15083      const deltaX = (e.clientX - mousePanStart.x) * mousePanSensitivity;
15084      const deltaY = (e.clientY - mousePanStart.y) * mousePanSensitivity;
15085      const scaledWidth = image.width * currentScale;
15086      const scaledHeight = image.height * currentScale;
15087      const slideWidth = gesture.slideWidth;
15088      const slideHeight = gesture.slideHeight;
15089      const minX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
15090      const maxX = -minX;
15091      const minY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
15092      const maxY = -minY;
15093      const newX = Math.max(Math.min(image.startX + deltaX, maxX), minX);
15094      const newY = Math.max(Math.min(image.startY + deltaY, maxY), minY);
15095      gesture.imageWrapEl.style.transitionDuration = '0ms';
15096      gesture.imageWrapEl.style.transform = `translate3d(${newX}px, ${newY}px, 0)`;
15097      mousePanStart.x = e.clientX;
15098      mousePanStart.y = e.clientY;
15099      image.startX = newX;
15100      image.startY = newY;
15101      image.currentX = newX;
15102      image.currentY = newY;
15103    }
15104    function zoomIn(e) {
15105      const zoom = swiper.zoom;
15106      const params = swiper.params.zoom;
15107      if (!gesture.slideEl) {
15108        if (e && e.target) {
15109          gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
15110        }
15111        if (!gesture.slideEl) {
15112          if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
15113            gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
15114          } else {
15115            gesture.slideEl = swiper.slides[swiper.activeIndex];
15116          }
15117        }
15118        let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
15119        if (imageEl) {
15120          imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
15121        }
15122        gesture.imageEl = imageEl;
15123        if (imageEl) {
15124          gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
15125        } else {
15126          gesture.imageWrapEl = undefined;
15127        }
15128      }
15129      if (!gesture.imageEl || !gesture.imageWrapEl) return;
15130      if (swiper.params.cssMode) {
15131        swiper.wrapperEl.style.overflow = 'hidden';
15132        swiper.wrapperEl.style.touchAction = 'none';
15133      }
15134      gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
15135      let touchX;
15136      let touchY;
15137      let offsetX;
15138      let offsetY;
15139      let diffX;
15140      let diffY;
15141      let translateX;
15142      let translateY;
15143      let imageWidth;
15144      let imageHeight;
15145      let scaledWidth;
15146      let scaledHeight;
15147      let translateMinX;
15148      let translateMinY;
15149      let translateMaxX;
15150      let translateMaxY;
15151      let slideWidth;
15152      let slideHeight;
15153      if (typeof image.touchesStart.x === 'undefined' && e) {
15154        touchX = e.pageX;
15155        touchY = e.pageY;
15156      } else {
15157        touchX = image.touchesStart.x;
15158        touchY = image.touchesStart.y;
15159      }
15160      const prevScale = currentScale;
15161      const forceZoomRatio = typeof e === 'number' ? e : null;
15162      if (currentScale === 1 && forceZoomRatio) {
15163        touchX = undefined;
15164        touchY = undefined;
15165        image.touchesStart.x = undefined;
15166        image.touchesStart.y = undefined;
15167      }
15168      const maxRatio = getMaxRatio();
15169      zoom.scale = forceZoomRatio || maxRatio;
15170      currentScale = forceZoomRatio || maxRatio;
15171      if (e && !(currentScale === 1 && forceZoomRatio)) {
15172        slideWidth = gesture.slideEl.offsetWidth;
15173        slideHeight = gesture.slideEl.offsetHeight;
15174        offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
15175        offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
15176        diffX = offsetX + slideWidth / 2 - touchX;
15177        diffY = offsetY + slideHeight / 2 - touchY;
15178        imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
15179        imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
15180        scaledWidth = imageWidth * zoom.scale;
15181        scaledHeight = imageHeight * zoom.scale;
15182        translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
15183        translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
15184        translateMaxX = -translateMinX;
15185        translateMaxY = -translateMinY;
15186        if (prevScale > 0 && forceZoomRatio && typeof image.currentX === 'number' && typeof image.currentY === 'number') {
15187          translateX = image.currentX * zoom.scale / prevScale;
15188          translateY = image.currentY * zoom.scale / prevScale;
15189        } else {
15190          translateX = diffX * zoom.scale;
15191          translateY = diffY * zoom.scale;
15192        }
15193        if (translateX < translateMinX) {
15194          translateX = translateMinX;
15195        }
15196        if (translateX > translateMaxX) {
15197          translateX = translateMaxX;
15198        }
15199        if (translateY < translateMinY) {
15200          translateY = translateMinY;
15201        }
15202        if (translateY > translateMaxY) {
15203          translateY = translateMaxY;
15204        }
15205      } else {
15206        translateX = 0;
15207        translateY = 0;
15208      }
15209      if (forceZoomRatio && zoom.scale === 1) {
15210        gesture.originX = 0;
15211        gesture.originY = 0;
15212      }
15213      image.currentX = translateX;
15214      image.currentY = translateY;
15215      gesture.imageWrapEl.style.transitionDuration = '300ms';
15216      gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
15217      gesture.imageEl.style.transitionDuration = '300ms';
15218      gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
15219    }
15220    function zoomOut() {
15221      const zoom = swiper.zoom;
15222      const params = swiper.params.zoom;
15223      if (!gesture.slideEl) {
15224        if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
15225          gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
15226        } else {
15227          gesture.slideEl = swiper.slides[swiper.activeIndex];
15228        }
15229        let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
15230        if (imageEl) {
15231          imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
15232        }
15233        gesture.imageEl = imageEl;
15234        if (imageEl) {
15235          gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
15236        } else {
15237          gesture.imageWrapEl = undefined;
15238        }
15239      }
15240      if (!gesture.imageEl || !gesture.imageWrapEl) return;
15241      if (swiper.params.cssMode) {
15242        swiper.wrapperEl.style.overflow = '';
15243        swiper.wrapperEl.style.touchAction = '';
15244      }
15245      zoom.scale = 1;
15246      currentScale = 1;
15247      image.currentX = undefined;
15248      image.currentY = undefined;
15249      image.touchesStart.x = undefined;
15250      image.touchesStart.y = undefined;
15251      gesture.imageWrapEl.style.transitionDuration = '300ms';
15252      gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
15253      gesture.imageEl.style.transitionDuration = '300ms';
15254      gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
15255      gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
15256      gesture.slideEl = undefined;
15257      gesture.originX = 0;
15258      gesture.originY = 0;
15259      if (swiper.params.zoom.panOnMouseMove) {
15260        mousePanStart = {
15261          x: 0,
15262          y: 0
15263        };
15264        if (isPanningWithMouse) {
15265          isPanningWithMouse = false;
15266          image.startX = 0;
15267          image.startY = 0;
15268        }
15269      }
15270    }
15271
15272    // Toggle Zoom
15273    function zoomToggle(e) {
15274      const zoom = swiper.zoom;
15275      if (zoom.scale && zoom.scale !== 1) {
15276        // Zoom Out
15277        zoomOut();
15278      } else {
15279        // Zoom In
15280        zoomIn(e);
15281      }
15282    }
15283    function getListeners() {
15284      const passiveListener = swiper.params.passiveListeners ? {
15285        passive: true,
15286        capture: false
15287      } : false;
15288      const activeListenerWithCapture = swiper.params.passiveListeners ? {
15289        passive: false,
15290        capture: true
15291      } : true;
15292      return {
15293        passiveListener,
15294        activeListenerWithCapture
15295      };
15296    }
15297
15298    // Attach/Detach Events
15299    function enable() {
15300      const zoom = swiper.zoom;
15301      if (zoom.enabled) return;
15302      zoom.enabled = true;
15303      const {
15304        passiveListener,
15305        activeListenerWithCapture
15306      } = getListeners();
15307
15308      // Scale image
15309      swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
15310      swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
15311      ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
15312        swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
15313      });
15314
15315      // Move image
15316      swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
15317    }
15318    function disable() {
15319      const zoom = swiper.zoom;
15320      if (!zoom.enabled) return;
15321      zoom.enabled = false;
15322      const {
15323        passiveListener,
15324        activeListenerWithCapture
15325      } = getListeners();
15326
15327      // Scale image
15328      swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
15329      swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
15330      ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
15331        swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
15332      });
15333
15334      // Move image
15335      swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
15336    }
15337    on('init', () => {
15338      if (swiper.params.zoom.enabled) {
15339        enable();
15340      }
15341    });
15342    on('destroy', () => {
15343      disable();
15344    });
15345    on('touchStart', (_s, e) => {
15346      if (!swiper.zoom.enabled) return;
15347      onTouchStart(e);
15348    });
15349    on('touchEnd', (_s, e) => {
15350      if (!swiper.zoom.enabled) return;
15351      onTouchEnd();
15352    });
15353    on('doubleTap', (_s, e) => {
15354      if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
15355        zoomToggle(e);
15356      }
15357    });
15358    on('transitionEnd', () => {
15359      if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
15360        onTransitionEnd();
15361      }
15362    });
15363    on('slideChange', () => {
15364      if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
15365        onTransitionEnd();
15366      }
15367    });
15368    Object.assign(swiper.zoom, {
15369      enable,
15370      disable,
15371      in: zoomIn,
15372      out: zoomOut,
15373      toggle: zoomToggle
15374    });
15375  }
15376
15377  /* eslint no-bitwise: ["error", { "allow": [">>"] }] */
15378  function Controller({
15379    swiper,
15380    extendParams,
15381    on
15382  }) {
15383    extendParams({
15384      controller: {
15385        control: undefined,
15386        inverse: false,
15387        by: 'slide' // or 'container'
15388      }
15389    });
15390
15391    swiper.controller = {
15392      control: undefined
15393    };
15394    function LinearSpline(x, y) {
15395      const binarySearch = function search() {
15396        let maxIndex;
15397        let minIndex;
15398        let guess;
15399        return (array, val) => {
15400          minIndex = -1;
15401          maxIndex = array.length;
15402          while (maxIndex - minIndex > 1) {
15403            guess = maxIndex + minIndex >> 1;
15404            if (array[guess] <= val) {
15405              minIndex = guess;
15406            } else {
15407              maxIndex = guess;
15408            }
15409          }
15410          return maxIndex;
15411        };
15412      }();
15413      this.x = x;
15414      this.y = y;
15415      this.lastIndex = x.length - 1;
15416      // Given an x value (x2), return the expected y2 value:
15417      // (x1,y1) is the known point before given value,
15418      // (x3,y3) is the known point after given value.
15419      let i1;
15420      let i3;
15421      this.interpolate = function interpolate(x2) {
15422        if (!x2) return 0;
15423
15424        // Get the indexes of x1 and x3 (the array indexes before and after given x2):
15425        i3 = binarySearch(this.x, x2);
15426        i1 = i3 - 1;
15427
15428        // We have our indexes i1 & i3, so we can calculate already:
15429        // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
15430        return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
15431      };
15432      return this;
15433    }
15434    function getInterpolateFunction(c) {
15435      swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);
15436    }
15437    function setTranslate(_t, byController) {
15438      const controlled = swiper.controller.control;
15439      let multiplier;
15440      let controlledTranslate;
15441      const Swiper = swiper.constructor;
15442      function setControlledTranslate(c) {
15443        if (c.destroyed) return;
15444
15445        // this will create an Interpolate function based on the snapGrids
15446        // x is the Grid of the scrolled scroller and y will be the controlled scroller
15447        // it makes sense to create this only once and recall it for the interpolation
15448        // the function does a lot of value caching for performance
15449        const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
15450        if (swiper.params.controller.by === 'slide') {
15451          getInterpolateFunction(c);
15452          // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
15453          // but it did not work out
15454          controlledTranslate = -swiper.controller.spline.interpolate(-translate);
15455        }
15456        if (!controlledTranslate || swiper.params.controller.by === 'container') {
15457          multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
15458          if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
15459            multiplier = 1;
15460          }
15461          controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
15462        }
15463        if (swiper.params.controller.inverse) {
15464          controlledTranslate = c.maxTranslate() - controlledTranslate;
15465        }
15466        c.updateProgress(controlledTranslate);
15467        c.setTranslate(controlledTranslate, swiper);
15468        c.updateActiveIndex();
15469        c.updateSlidesClasses();
15470      }
15471      if (Array.isArray(controlled)) {
15472        for (let i = 0; i < controlled.length; i += 1) {
15473          if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
15474            setControlledTranslate(controlled[i]);
15475          }
15476        }
15477      } else if (controlled instanceof Swiper && byController !== controlled) {
15478        setControlledTranslate(controlled);
15479      }
15480    }
15481    function setTransition(duration, byController) {
15482      const Swiper = swiper.constructor;
15483      const controlled = swiper.controller.control;
15484      let i;
15485      function setControlledTransition(c) {
15486        if (c.destroyed) return;
15487        c.setTransition(duration, swiper);
15488        if (duration !== 0) {
15489          c.transitionStart();
15490          if (c.params.autoHeight) {
15491            nextTick(() => {
15492              c.updateAutoHeight();
15493            });
15494          }
15495          elementTransitionEnd(c.wrapperEl, () => {
15496            if (!controlled) return;
15497            c.transitionEnd();
15498          });
15499        }
15500      }
15501      if (Array.isArray(controlled)) {
15502        for (i = 0; i < controlled.length; i += 1) {
15503          if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
15504            setControlledTransition(controlled[i]);
15505          }
15506        }
15507      } else if (controlled instanceof Swiper && byController !== controlled) {
15508        setControlledTransition(controlled);
15509      }
15510    }
15511    function removeSpline() {
15512      if (!swiper.controller.control) return;
15513      if (swiper.controller.spline) {
15514        swiper.controller.spline = undefined;
15515        delete swiper.controller.spline;
15516      }
15517    }
15518    on('beforeInit', () => {
15519      if (typeof window !== 'undefined' && (
15520      // eslint-disable-line
15521      typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) {
15522        const controlElements = typeof swiper.params.controller.control === 'string' ? [...document.querySelectorAll(swiper.params.controller.control)] : [swiper.params.controller.control];
15523        controlElements.forEach(controlElement => {
15524          if (!swiper.controller.control) swiper.controller.control = [];
15525          if (controlElement && controlElement.swiper) {
15526            swiper.controller.control.push(controlElement.swiper);
15527          } else if (controlElement) {
15528            const eventName = `${swiper.params.eventsPrefix}init`;
15529            const onControllerSwiper = e => {
15530              swiper.controller.control.push(e.detail[0]);
15531              swiper.update();
15532              controlElement.removeEventListener(eventName, onControllerSwiper);
15533            };
15534            controlElement.addEventListener(eventName, onControllerSwiper);
15535          }
15536        });
15537        return;
15538      }
15539      swiper.controller.control = swiper.params.controller.control;
15540    });
15541    on('update', () => {
15542      removeSpline();
15543    });
15544    on('resize', () => {
15545      removeSpline();
15546    });
15547    on('observerUpdate', () => {
15548      removeSpline();
15549    });
15550    on('setTranslate', (_s, translate, byController) => {
15551      if (!swiper.controller.control || swiper.controller.control.destroyed) return;
15552      swiper.controller.setTranslate(translate, byController);
15553    });
15554    on('setTransition', (_s, duration, byController) => {
15555      if (!swiper.controller.control || swiper.controller.control.destroyed) return;
15556      swiper.controller.setTransition(duration, byController);
15557    });
15558    Object.assign(swiper.controller, {
15559      setTranslate,
15560      setTransition
15561    });
15562  }
15563
15564  function A11y({
15565    swiper,
15566    extendParams,
15567    on
15568  }) {
15569    extendParams({
15570      a11y: {
15571        enabled: true,
15572        notificationClass: 'swiper-notification',
15573        prevSlideMessage: 'Previous slide',
15574        nextSlideMessage: 'Next slide',
15575        firstSlideMessage: 'This is the first slide',
15576        lastSlideMessage: 'This is the last slide',
15577        paginationBulletMessage: 'Go to slide {{index}}',
15578        slideLabelMessage: '{{index}} / {{slidesLength}}',
15579        containerMessage: null,
15580        containerRoleDescriptionMessage: null,
15581        containerRole: null,
15582        itemRoleDescriptionMessage: null,
15583        slideRole: 'group',
15584        id: null,
15585        scrollOnFocus: true,
15586        wrapperLiveRegion: true
15587      }
15588    });
15589    swiper.a11y = {
15590      clicked: false
15591    };
15592    let liveRegion = null;
15593    let preventFocusHandler;
15594    let focusTargetSlideEl;
15595    let visibilityChangedTimestamp = new Date().getTime();
15596    function notify(message) {
15597      const notification = liveRegion;
15598      if (notification.length === 0) return;
15599      setInnerHTML(notification, message);
15600    }
15601    function getRandomNumber(size = 16) {
15602      const randomChar = () => Math.round(16 * Math.random()).toString(16);
15603      return 'x'.repeat(size).replace(/x/g, randomChar);
15604    }
15605    function makeElFocusable(el) {
15606      el = makeElementsArray(el);
15607      el.forEach(subEl => {
15608        subEl.setAttribute('tabIndex', '0');
15609      });
15610    }
15611    function makeElNotFocusable(el) {
15612      el = makeElementsArray(el);
15613      el.forEach(subEl => {
15614        subEl.setAttribute('tabIndex', '-1');
15615      });
15616    }
15617    function addElRole(el, role) {
15618      el = makeElementsArray(el);
15619      el.forEach(subEl => {
15620        subEl.setAttribute('role', role);
15621      });
15622    }
15623    function addElRoleDescription(el, description) {
15624      el = makeElementsArray(el);
15625      el.forEach(subEl => {
15626        subEl.setAttribute('aria-roledescription', description);
15627      });
15628    }
15629    function addElControls(el, controls) {
15630      el = makeElementsArray(el);
15631      el.forEach(subEl => {
15632        subEl.setAttribute('aria-controls', controls);
15633      });
15634    }
15635    function addElLabel(el, label) {
15636      el = makeElementsArray(el);
15637      el.forEach(subEl => {
15638        subEl.setAttribute('aria-label', label);
15639      });
15640    }
15641    function addElId(el, id) {
15642      el = makeElementsArray(el);
15643      el.forEach(subEl => {
15644        subEl.setAttribute('id', id);
15645      });
15646    }
15647    function addElLive(el, live) {
15648      el = makeElementsArray(el);
15649      el.forEach(subEl => {
15650        subEl.setAttribute('aria-live', live);
15651      });
15652    }
15653    function disableEl(el) {
15654      el = makeElementsArray(el);
15655      el.forEach(subEl => {
15656        subEl.setAttribute('aria-disabled', true);
15657      });
15658    }
15659    function enableEl(el) {
15660      el = makeElementsArray(el);
15661      el.forEach(subEl => {
15662        subEl.setAttribute('aria-disabled', false);
15663      });
15664    }
15665    function onEnterOrSpaceKey(e) {
15666      if (e.keyCode !== 13 && e.keyCode !== 32) return;
15667      const params = swiper.params.a11y;
15668      const targetEl = e.target;
15669      if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
15670        if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
15671      }
15672      if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
15673        const prevEls = makeElementsArray(swiper.navigation.prevEl);
15674        const nextEls = makeElementsArray(swiper.navigation.nextEl);
15675        if (nextEls.includes(targetEl)) {
15676          if (!(swiper.isEnd && !swiper.params.loop)) {
15677            swiper.slideNext();
15678          }
15679          if (swiper.isEnd) {
15680            notify(params.lastSlideMessage);
15681          } else {
15682            notify(params.nextSlideMessage);
15683          }
15684        }
15685        if (prevEls.includes(targetEl)) {
15686          if (!(swiper.isBeginning && !swiper.params.loop)) {
15687            swiper.slidePrev();
15688          }
15689          if (swiper.isBeginning) {
15690            notify(params.firstSlideMessage);
15691          } else {
15692            notify(params.prevSlideMessage);
15693          }
15694        }
15695      }
15696      if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
15697        targetEl.click();
15698      }
15699    }
15700    function updateNavigation() {
15701      if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
15702      const {
15703        nextEl,
15704        prevEl
15705      } = swiper.navigation;
15706      if (prevEl) {
15707        if (swiper.isBeginning) {
15708          disableEl(prevEl);
15709          makeElNotFocusable(prevEl);
15710        } else {
15711          enableEl(prevEl);
15712          makeElFocusable(prevEl);
15713        }
15714      }
15715      if (nextEl) {
15716        if (swiper.isEnd) {
15717          disableEl(nextEl);
15718          makeElNotFocusable(nextEl);
15719        } else {
15720          enableEl(nextEl);
15721          makeElFocusable(nextEl);
15722        }
15723      }
15724    }
15725    function hasPagination() {
15726      return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
15727    }
15728    function hasClickablePagination() {
15729      return hasPagination() && swiper.params.pagination.clickable;
15730    }
15731    function updatePagination() {
15732      const params = swiper.params.a11y;
15733      if (!hasPagination()) return;
15734      swiper.pagination.bullets.forEach(bulletEl => {
15735        if (swiper.params.pagination.clickable) {
15736          makeElFocusable(bulletEl);
15737          if (!swiper.params.pagination.renderBullet) {
15738            addElRole(bulletEl, 'button');
15739            addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
15740          }
15741        }
15742        if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
15743          bulletEl.setAttribute('aria-current', 'true');
15744        } else {
15745          bulletEl.removeAttribute('aria-current');
15746        }
15747      });
15748    }
15749    const initNavEl = (el, wrapperId, message) => {
15750      makeElFocusable(el);
15751      if (el.tagName !== 'BUTTON') {
15752        addElRole(el, 'button');
15753        el.addEventListener('keydown', onEnterOrSpaceKey);
15754      }
15755      addElLabel(el, message);
15756      addElControls(el, wrapperId);
15757    };
15758    const handlePointerDown = e => {
15759      if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) {
15760        preventFocusHandler = true;
15761      }
15762      swiper.a11y.clicked = true;
15763    };
15764    const handlePointerUp = () => {
15765      preventFocusHandler = false;
15766      requestAnimationFrame(() => {
15767        requestAnimationFrame(() => {
15768          if (!swiper.destroyed) {
15769            swiper.a11y.clicked = false;
15770          }
15771        });
15772      });
15773    };
15774    const onVisibilityChange = e => {
15775      visibilityChangedTimestamp = new Date().getTime();
15776    };
15777    const handleFocus = e => {
15778      if (swiper.a11y.clicked || !swiper.params.a11y.scrollOnFocus) return;
15779      if (new Date().getTime() - visibilityChangedTimestamp < 100) return;
15780      const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
15781      if (!slideEl || !swiper.slides.includes(slideEl)) return;
15782      focusTargetSlideEl = slideEl;
15783      const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
15784      const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
15785      if (isActive || isVisible) return;
15786      if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
15787      if (swiper.isHorizontal()) {
15788        swiper.el.scrollLeft = 0;
15789      } else {
15790        swiper.el.scrollTop = 0;
15791      }
15792      requestAnimationFrame(() => {
15793        if (preventFocusHandler) return;
15794        if (swiper.params.loop) {
15795          swiper.slideToLoop(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index'))), 0);
15796        } else {
15797          swiper.slideTo(swiper.getSlideIndexWhenGrid(swiper.slides.indexOf(slideEl)), 0);
15798        }
15799        preventFocusHandler = false;
15800      });
15801    };
15802    const initSlides = () => {
15803      const params = swiper.params.a11y;
15804      if (params.itemRoleDescriptionMessage) {
15805        addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
15806      }
15807      if (params.slideRole) {
15808        addElRole(swiper.slides, params.slideRole);
15809      }
15810      const slidesLength = swiper.slides.length;
15811      if (params.slideLabelMessage) {
15812        swiper.slides.forEach((slideEl, index) => {
15813          const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
15814          const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
15815          addElLabel(slideEl, ariaLabelMessage);
15816        });
15817      }
15818    };
15819    const init = () => {
15820      const params = swiper.params.a11y;
15821      swiper.el.append(liveRegion);
15822
15823      // Container
15824      const containerEl = swiper.el;
15825      if (params.containerRoleDescriptionMessage) {
15826        addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
15827      }
15828      if (params.containerMessage) {
15829        addElLabel(containerEl, params.containerMessage);
15830      }
15831      if (params.containerRole) {
15832        addElRole(containerEl, params.containerRole);
15833      }
15834
15835      // Wrapper
15836      const wrapperEl = swiper.wrapperEl;
15837      const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
15838      addElId(wrapperEl, wrapperId);
15839      if (params.wrapperLiveRegion) {
15840        const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
15841        addElLive(wrapperEl, live);
15842      }
15843
15844      // Slide
15845      initSlides();
15846
15847      // Navigation
15848      let {
15849        nextEl,
15850        prevEl
15851      } = swiper.navigation ? swiper.navigation : {};
15852      nextEl = makeElementsArray(nextEl);
15853      prevEl = makeElementsArray(prevEl);
15854      if (nextEl) {
15855        nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage));
15856      }
15857      if (prevEl) {
15858        prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage));
15859      }
15860
15861      // Pagination
15862      if (hasClickablePagination()) {
15863        const paginationEl = makeElementsArray(swiper.pagination.el);
15864        paginationEl.forEach(el => {
15865          el.addEventListener('keydown', onEnterOrSpaceKey);
15866        });
15867      }
15868
15869      // Tab focus
15870      const document = getDocument();
15871      document.addEventListener('visibilitychange', onVisibilityChange);
15872      swiper.el.addEventListener('focus', handleFocus, true);
15873      swiper.el.addEventListener('focus', handleFocus, true);
15874      swiper.el.addEventListener('pointerdown', handlePointerDown, true);
15875      swiper.el.addEventListener('pointerup', handlePointerUp, true);
15876    };
15877    function destroy() {
15878      if (liveRegion) liveRegion.remove();
15879      let {
15880        nextEl,
15881        prevEl
15882      } = swiper.navigation ? swiper.navigation : {};
15883      nextEl = makeElementsArray(nextEl);
15884      prevEl = makeElementsArray(prevEl);
15885      if (nextEl) {
15886        nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
15887      }
15888      if (prevEl) {
15889        prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
15890      }
15891
15892      // Pagination
15893      if (hasClickablePagination()) {
15894        const paginationEl = makeElementsArray(swiper.pagination.el);
15895        paginationEl.forEach(el => {
15896          el.removeEventListener('keydown', onEnterOrSpaceKey);
15897        });
15898      }
15899      const document = getDocument();
15900      document.removeEventListener('visibilitychange', onVisibilityChange);
15901      // Tab focus
15902      if (swiper.el && typeof swiper.el !== 'string') {
15903        swiper.el.removeEventListener('focus', handleFocus, true);
15904        swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
15905        swiper.el.removeEventListener('pointerup', handlePointerUp, true);
15906      }
15907    }
15908    on('beforeInit', () => {
15909      liveRegion = createElement('span', swiper.params.a11y.notificationClass);
15910      liveRegion.setAttribute('aria-live', 'assertive');
15911      liveRegion.setAttribute('aria-atomic', 'true');
15912    });
15913    on('afterInit', () => {
15914      if (!swiper.params.a11y.enabled) return;
15915      init();
15916    });
15917    on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
15918      if (!swiper.params.a11y.enabled) return;
15919      initSlides();
15920    });
15921    on('fromEdge toEdge afterInit lock unlock', () => {
15922      if (!swiper.params.a11y.enabled) return;
15923      updateNavigation();
15924    });
15925    on('paginationUpdate', () => {
15926      if (!swiper.params.a11y.enabled) return;
15927      updatePagination();
15928    });
15929    on('destroy', () => {
15930      if (!swiper.params.a11y.enabled) return;
15931      destroy();
15932    });
15933  }
15934
15935  function History({
15936    swiper,
15937    extendParams,
15938    on
15939  }) {
15940    extendParams({
15941      history: {
15942        enabled: false,
15943        root: '',
15944        replaceState: false,
15945        key: 'slides',
15946        keepQuery: false
15947      }
15948    });
15949    let initialized = false;
15950    let paths = {};
15951    const slugify = text => {
15952      return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
15953    };
15954    const getPathValues = urlOverride => {
15955      const window = getWindow();
15956      let location;
15957      if (urlOverride) {
15958        location = new URL(urlOverride);
15959      } else {
15960        location = window.location;
15961      }
15962      const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
15963      const total = pathArray.length;
15964      const key = pathArray[total - 2];
15965      const value = pathArray[total - 1];
15966      return {
15967        key,
15968        value
15969      };
15970    };
15971    const setHistory = (key, index) => {
15972      const window = getWindow();
15973      if (!initialized || !swiper.params.history.enabled) return;
15974      let location;
15975      if (swiper.params.url) {
15976        location = new URL(swiper.params.url);
15977      } else {
15978        location = window.location;
15979      }
15980      const slide = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${index}"]`) : swiper.slides[index];
15981      let value = slugify(slide.getAttribute('data-history'));
15982      if (swiper.params.history.root.length > 0) {
15983        let root = swiper.params.history.root;
15984        if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
15985        value = `${root}/${key ? `${key}/` : ''}${value}`;
15986      } else if (!location.pathname.includes(key)) {
15987        value = `${key ? `${key}/` : ''}${value}`;
15988      }
15989      if (swiper.params.history.keepQuery) {
15990        value += location.search;
15991      }
15992      const currentState = window.history.state;
15993      if (currentState && currentState.value === value) {
15994        return;
15995      }
15996      if (swiper.params.history.replaceState) {
15997        window.history.replaceState({
15998          value
15999        }, null, value);
16000      } else {
16001        window.history.pushState({
16002          value
16003        }, null, value);
16004      }
16005    };
16006    const scrollToSlide = (speed, value, runCallbacks) => {
16007      if (value) {
16008        for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
16009          const slide = swiper.slides[i];
16010          const slideHistory = slugify(slide.getAttribute('data-history'));
16011          if (slideHistory === value) {
16012            const index = swiper.getSlideIndex(slide);
16013            swiper.slideTo(index, speed, runCallbacks);
16014          }
16015        }
16016      } else {
16017        swiper.slideTo(0, speed, runCallbacks);
16018      }
16019    };
16020    const setHistoryPopState = () => {
16021      paths = getPathValues(swiper.params.url);
16022      scrollToSlide(swiper.params.speed, paths.value, false);
16023    };
16024    const init = () => {
16025      const window = getWindow();
16026      if (!swiper.params.history) return;
16027      if (!window.history || !window.history.pushState) {
16028        swiper.params.history.enabled = false;
16029        swiper.params.hashNavigation.enabled = true;
16030        return;
16031      }
16032      initialized = true;
16033      paths = getPathValues(swiper.params.url);
16034      if (!paths.key && !paths.value) {
16035        if (!swiper.params.history.replaceState) {
16036          window.addEventListener('popstate', setHistoryPopState);
16037        }
16038        return;
16039      }
16040      scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
16041      if (!swiper.params.history.replaceState) {
16042        window.addEventListener('popstate', setHistoryPopState);
16043      }
16044    };
16045    const destroy = () => {
16046      const window = getWindow();
16047      if (!swiper.params.history.replaceState) {
16048        window.removeEventListener('popstate', setHistoryPopState);
16049      }
16050    };
16051    on('init', () => {
16052      if (swiper.params.history.enabled) {
16053        init();
16054      }
16055    });
16056    on('destroy', () => {
16057      if (swiper.params.history.enabled) {
16058        destroy();
16059      }
16060    });
16061    on('transitionEnd _freeModeNoMomentumRelease', () => {
16062      if (initialized) {
16063        setHistory(swiper.params.history.key, swiper.activeIndex);
16064      }
16065    });
16066    on('slideChange', () => {
16067      if (initialized && swiper.params.cssMode) {
16068        setHistory(swiper.params.history.key, swiper.activeIndex);
16069      }
16070    });
16071  }
16072
16073  function HashNavigation({
16074    swiper,
16075    extendParams,
16076    emit,
16077    on
16078  }) {
16079    let initialized = false;
16080    const document = getDocument();
16081    const window = getWindow();
16082    extendParams({
16083      hashNavigation: {
16084        enabled: false,
16085        replaceState: false,
16086        watchState: false,
16087        getSlideIndex(_s, hash) {
16088          if (swiper.virtual && swiper.params.virtual.enabled) {
16089            const slideWithHash = swiper.slides.find(slideEl => slideEl.getAttribute('data-hash') === hash);
16090            if (!slideWithHash) return 0;
16091            const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
16092            return index;
16093          }
16094          return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]);
16095        }
16096      }
16097    });
16098    const onHashChange = () => {
16099      emit('hashChange');
16100      const newHash = document.location.hash.replace('#', '');
16101      const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
16102      const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
16103      if (newHash !== activeSlideHash) {
16104        const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
16105        if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
16106        swiper.slideTo(newIndex);
16107      }
16108    };
16109    const setHash = () => {
16110      if (!initialized || !swiper.params.hashNavigation.enabled) return;
16111      const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
16112      const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : '';
16113      if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
16114        window.history.replaceState(null, null, `#${activeSlideHash}` || '');
16115        emit('hashSet');
16116      } else {
16117        document.location.hash = activeSlideHash || '';
16118        emit('hashSet');
16119      }
16120    };
16121    const init = () => {
16122      if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
16123      initialized = true;
16124      const hash = document.location.hash.replace('#', '');
16125      if (hash) {
16126        const speed = 0;
16127        const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
16128        swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
16129      }
16130      if (swiper.params.hashNavigation.watchState) {
16131        window.addEventListener('hashchange', onHashChange);
16132      }
16133    };
16134    const destroy = () => {
16135      if (swiper.params.hashNavigation.watchState) {
16136        window.removeEventListener('hashchange', onHashChange);
16137      }
16138    };
16139    on('init', () => {
16140      if (swiper.params.hashNavigation.enabled) {
16141        init();
16142      }
16143    });
16144    on('destroy', () => {
16145      if (swiper.params.hashNavigation.enabled) {
16146        destroy();
16147      }
16148    });
16149    on('transitionEnd _freeModeNoMomentumRelease', () => {
16150      if (initialized) {
16151        setHash();
16152      }
16153    });
16154    on('slideChange', () => {
16155      if (initialized && swiper.params.cssMode) {
16156        setHash();
16157      }
16158    });
16159  }
16160
16161  /* eslint no-underscore-dangle: "off" */
16162  /* eslint no-use-before-define: "off" */
16163  function Autoplay({
16164    swiper,
16165    extendParams,
16166    on,
16167    emit,
16168    params
16169  }) {
16170    swiper.autoplay = {
16171      running: false,
16172      paused: false,
16173      timeLeft: 0
16174    };
16175    extendParams({
16176      autoplay: {
16177        enabled: false,
16178        delay: 3000,
16179        waitForTransition: true,
16180        disableOnInteraction: false,
16181        stopOnLastSlide: false,
16182        reverseDirection: false,
16183        pauseOnMouseEnter: false
16184      }
16185    });
16186    let timeout;
16187    let raf;
16188    let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
16189    let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
16190    let autoplayTimeLeft;
16191    let autoplayStartTime = new Date().getTime();
16192    let wasPaused;
16193    let isTouched;
16194    let pausedByTouch;
16195    let touchStartTimeout;
16196    let slideChanged;
16197    let pausedByInteraction;
16198    let pausedByPointerEnter;
16199    function onTransitionEnd(e) {
16200      if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
16201      if (e.target !== swiper.wrapperEl) return;
16202      swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
16203      if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
16204        return;
16205      }
16206      resume();
16207    }
16208    const calcTimeLeft = () => {
16209      if (swiper.destroyed || !swiper.autoplay.running) return;
16210      if (swiper.autoplay.paused) {
16211        wasPaused = true;
16212      } else if (wasPaused) {
16213        autoplayDelayCurrent = autoplayTimeLeft;
16214        wasPaused = false;
16215      }
16216      const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
16217      swiper.autoplay.timeLeft = timeLeft;
16218      emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
16219      raf = requestAnimationFrame(() => {
16220        calcTimeLeft();
16221      });
16222    };
16223    const getSlideDelay = () => {
16224      let activeSlideEl;
16225      if (swiper.virtual && swiper.params.virtual.enabled) {
16226        activeSlideEl = swiper.slides.find(slideEl => slideEl.classList.contains('swiper-slide-active'));
16227      } else {
16228        activeSlideEl = swiper.slides[swiper.activeIndex];
16229      }
16230      if (!activeSlideEl) return undefined;
16231      const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
16232      return currentSlideDelay;
16233    };
16234    const run = delayForce => {
16235      if (swiper.destroyed || !swiper.autoplay.running) return;
16236      cancelAnimationFrame(raf);
16237      calcTimeLeft();
16238      let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
16239      autoplayDelayTotal = swiper.params.autoplay.delay;
16240      autoplayDelayCurrent = swiper.params.autoplay.delay;
16241      const currentSlideDelay = getSlideDelay();
16242      if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
16243        delay = currentSlideDelay;
16244        autoplayDelayTotal = currentSlideDelay;
16245        autoplayDelayCurrent = currentSlideDelay;
16246      }
16247      autoplayTimeLeft = delay;
16248      const speed = swiper.params.speed;
16249      const proceed = () => {
16250        if (!swiper || swiper.destroyed) return;
16251        if (swiper.params.autoplay.reverseDirection) {
16252          if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
16253            swiper.slidePrev(speed, true, true);
16254            emit('autoplay');
16255          } else if (!swiper.params.autoplay.stopOnLastSlide) {
16256            swiper.slideTo(swiper.slides.length - 1, speed, true, true);
16257            emit('autoplay');
16258          }
16259        } else {
16260          if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
16261            swiper.slideNext(speed, true, true);
16262            emit('autoplay');
16263          } else if (!swiper.params.autoplay.stopOnLastSlide) {
16264            swiper.slideTo(0, speed, true, true);
16265            emit('autoplay');
16266          }
16267        }
16268        if (swiper.params.cssMode) {
16269          autoplayStartTime = new Date().getTime();
16270          requestAnimationFrame(() => {
16271            run();
16272          });
16273        }
16274      };
16275      if (delay > 0) {
16276        clearTimeout(timeout);
16277        timeout = setTimeout(() => {
16278          proceed();
16279        }, delay);
16280      } else {
16281        requestAnimationFrame(() => {
16282          proceed();
16283        });
16284      }
16285
16286      // eslint-disable-next-line
16287      return delay;
16288    };
16289    const start = () => {
16290      autoplayStartTime = new Date().getTime();
16291      swiper.autoplay.running = true;
16292      run();
16293      emit('autoplayStart');
16294    };
16295    const stop = () => {
16296      swiper.autoplay.running = false;
16297      clearTimeout(timeout);
16298      cancelAnimationFrame(raf);
16299      emit('autoplayStop');
16300    };
16301    const pause = (internal, reset) => {
16302      if (swiper.destroyed || !swiper.autoplay.running) return;
16303      clearTimeout(timeout);
16304      if (!internal) {
16305        pausedByInteraction = true;
16306      }
16307      const proceed = () => {
16308        emit('autoplayPause');
16309        if (swiper.params.autoplay.waitForTransition) {
16310          swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
16311        } else {
16312          resume();
16313        }
16314      };
16315      swiper.autoplay.paused = true;
16316      if (reset) {
16317        if (slideChanged) {
16318          autoplayTimeLeft = swiper.params.autoplay.delay;
16319        }
16320        slideChanged = false;
16321        proceed();
16322        return;
16323      }
16324      const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
16325      autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
16326      if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
16327      if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
16328      proceed();
16329    };
16330    const resume = () => {
16331      if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
16332      autoplayStartTime = new Date().getTime();
16333      if (pausedByInteraction) {
16334        pausedByInteraction = false;
16335        run(autoplayTimeLeft);
16336      } else {
16337        run();
16338      }
16339      swiper.autoplay.paused = false;
16340      emit('autoplayResume');
16341    };
16342    const onVisibilityChange = () => {
16343      if (swiper.destroyed || !swiper.autoplay.running) return;
16344      const document = getDocument();
16345      if (document.visibilityState === 'hidden') {
16346        pausedByInteraction = true;
16347        pause(true);
16348      }
16349      if (document.visibilityState === 'visible') {
16350        resume();
16351      }
16352    };
16353    const onPointerEnter = e => {
16354      if (e.pointerType !== 'mouse') return;
16355      pausedByInteraction = true;
16356      pausedByPointerEnter = true;
16357      if (swiper.animating || swiper.autoplay.paused) return;
16358      pause(true);
16359    };
16360    const onPointerLeave = e => {
16361      if (e.pointerType !== 'mouse') return;
16362      pausedByPointerEnter = false;
16363      if (swiper.autoplay.paused) {
16364        resume();
16365      }
16366    };
16367    const attachMouseEvents = () => {
16368      if (swiper.params.autoplay.pauseOnMouseEnter) {
16369        swiper.el.addEventListener('pointerenter', onPointerEnter);
16370        swiper.el.addEventListener('pointerleave', onPointerLeave);
16371      }
16372    };
16373    const detachMouseEvents = () => {
16374      if (swiper.el && typeof swiper.el !== 'string') {
16375        swiper.el.removeEventListener('pointerenter', onPointerEnter);
16376        swiper.el.removeEventListener('pointerleave', onPointerLeave);
16377      }
16378    };
16379    const attachDocumentEvents = () => {
16380      const document = getDocument();
16381      document.addEventListener('visibilitychange', onVisibilityChange);
16382    };
16383    const detachDocumentEvents = () => {
16384      const document = getDocument();
16385      document.removeEventListener('visibilitychange', onVisibilityChange);
16386    };
16387    on('init', () => {
16388      if (swiper.params.autoplay.enabled) {
16389        attachMouseEvents();
16390        attachDocumentEvents();
16391        start();
16392      }
16393    });
16394    on('destroy', () => {
16395      detachMouseEvents();
16396      detachDocumentEvents();
16397      if (swiper.autoplay.running) {
16398        stop();
16399      }
16400    });
16401    on('_freeModeStaticRelease', () => {
16402      if (pausedByTouch || pausedByInteraction) {
16403        resume();
16404      }
16405    });
16406    on('_freeModeNoMomentumRelease', () => {
16407      if (!swiper.params.autoplay.disableOnInteraction) {
16408        pause(true, true);
16409      } else {
16410        stop();
16411      }
16412    });
16413    on('beforeTransitionStart', (_s, speed, internal) => {
16414      if (swiper.destroyed || !swiper.autoplay.running) return;
16415      if (internal || !swiper.params.autoplay.disableOnInteraction) {
16416        pause(true, true);
16417      } else {
16418        stop();
16419      }
16420    });
16421    on('sliderFirstMove', () => {
16422      if (swiper.destroyed || !swiper.autoplay.running) return;
16423      if (swiper.params.autoplay.disableOnInteraction) {
16424        stop();
16425        return;
16426      }
16427      isTouched = true;
16428      pausedByTouch = false;
16429      pausedByInteraction = false;
16430      touchStartTimeout = setTimeout(() => {
16431        pausedByInteraction = true;
16432        pausedByTouch = true;
16433        pause(true);
16434      }, 200);
16435    });
16436    on('touchEnd', () => {
16437      if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
16438      clearTimeout(touchStartTimeout);
16439      clearTimeout(timeout);
16440      if (swiper.params.autoplay.disableOnInteraction) {
16441        pausedByTouch = false;
16442        isTouched = false;
16443        return;
16444      }
16445      if (pausedByTouch && swiper.params.cssMode) resume();
16446      pausedByTouch = false;
16447      isTouched = false;
16448    });
16449    on('slideChange', () => {
16450      if (swiper.destroyed || !swiper.autoplay.running) return;
16451      slideChanged = true;
16452    });
16453    Object.assign(swiper.autoplay, {
16454      start,
16455      stop,
16456      pause,
16457      resume
16458    });
16459  }
16460
16461  function Thumb({
16462    swiper,
16463    extendParams,
16464    on
16465  }) {
16466    extendParams({
16467      thumbs: {
16468        swiper: null,
16469        multipleActiveThumbs: true,
16470        autoScrollOffset: 0,
16471        slideThumbActiveClass: 'swiper-slide-thumb-active',
16472        thumbsContainerClass: 'swiper-thumbs'
16473      }
16474    });
16475    let initialized = false;
16476    let swiperCreated = false;
16477    swiper.thumbs = {
16478      swiper: null
16479    };
16480    function onThumbClick() {
16481      const thumbsSwiper = swiper.thumbs.swiper;
16482      if (!thumbsSwiper || thumbsSwiper.destroyed) return;
16483      const clickedIndex = thumbsSwiper.clickedIndex;
16484      const clickedSlide = thumbsSwiper.clickedSlide;
16485      if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
16486      if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
16487      let slideToIndex;
16488      if (thumbsSwiper.params.loop) {
16489        slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
16490      } else {
16491        slideToIndex = clickedIndex;
16492      }
16493      if (swiper.params.loop) {
16494        swiper.slideToLoop(slideToIndex);
16495      } else {
16496        swiper.slideTo(slideToIndex);
16497      }
16498    }
16499    function init() {
16500      const {
16501        thumbs: thumbsParams
16502      } = swiper.params;
16503      if (initialized) return false;
16504      initialized = true;
16505      const SwiperClass = swiper.constructor;
16506      if (thumbsParams.swiper instanceof SwiperClass) {
16507        if (thumbsParams.swiper.destroyed) {
16508          initialized = false;
16509          return false;
16510        }
16511        swiper.thumbs.swiper = thumbsParams.swiper;
16512        Object.assign(swiper.thumbs.swiper.originalParams, {
16513          watchSlidesProgress: true,
16514          slideToClickedSlide: false
16515        });
16516        Object.assign(swiper.thumbs.swiper.params, {
16517          watchSlidesProgress: true,
16518          slideToClickedSlide: false
16519        });
16520        swiper.thumbs.swiper.update();
16521      } else if (isObject(thumbsParams.swiper)) {
16522        const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
16523        Object.assign(thumbsSwiperParams, {
16524          watchSlidesProgress: true,
16525          slideToClickedSlide: false
16526        });
16527        swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
16528        swiperCreated = true;
16529      }
16530      swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
16531      swiper.thumbs.swiper.on('tap', onThumbClick);
16532      return true;
16533    }
16534    function update(initial) {
16535      const thumbsSwiper = swiper.thumbs.swiper;
16536      if (!thumbsSwiper || thumbsSwiper.destroyed) return;
16537      const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
16538
16539      // Activate thumbs
16540      let thumbsToActivate = 1;
16541      const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
16542      if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
16543        thumbsToActivate = swiper.params.slidesPerView;
16544      }
16545      if (!swiper.params.thumbs.multipleActiveThumbs) {
16546        thumbsToActivate = 1;
16547      }
16548      thumbsToActivate = Math.floor(thumbsToActivate);
16549      thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
16550      if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
16551        for (let i = 0; i < thumbsToActivate; i += 1) {
16552          elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
16553            slideEl.classList.add(thumbActiveClass);
16554          });
16555        }
16556      } else {
16557        for (let i = 0; i < thumbsToActivate; i += 1) {
16558          if (thumbsSwiper.slides[swiper.realIndex + i]) {
16559            thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
16560          }
16561        }
16562      }
16563      const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
16564      const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
16565      if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
16566        const currentThumbsIndex = thumbsSwiper.activeIndex;
16567        let newThumbsIndex;
16568        let direction;
16569        if (thumbsSwiper.params.loop) {
16570          const newThumbsSlide = thumbsSwiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`);
16571          newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
16572          direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
16573        } else {
16574          newThumbsIndex = swiper.realIndex;
16575          direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
16576        }
16577        if (useOffset) {
16578          newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
16579        }
16580        if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
16581          if (thumbsSwiper.params.centeredSlides) {
16582            if (newThumbsIndex > currentThumbsIndex) {
16583              newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
16584            } else {
16585              newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
16586            }
16587          } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ;
16588          thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
16589        }
16590      }
16591    }
16592    on('beforeInit', () => {
16593      const {
16594        thumbs
16595      } = swiper.params;
16596      if (!thumbs || !thumbs.swiper) return;
16597      if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
16598        const document = getDocument();
16599        const getThumbsElementAndInit = () => {
16600          const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
16601          if (thumbsElement && thumbsElement.swiper) {
16602            thumbs.swiper = thumbsElement.swiper;
16603            init();
16604            update(true);
16605          } else if (thumbsElement) {
16606            const eventName = `${swiper.params.eventsPrefix}init`;
16607            const onThumbsSwiper = e => {
16608              thumbs.swiper = e.detail[0];
16609              thumbsElement.removeEventListener(eventName, onThumbsSwiper);
16610              init();
16611              update(true);
16612              thumbs.swiper.update();
16613              swiper.update();
16614            };
16615            thumbsElement.addEventListener(eventName, onThumbsSwiper);
16616          }
16617          return thumbsElement;
16618        };
16619        const watchForThumbsToAppear = () => {
16620          if (swiper.destroyed) return;
16621          const thumbsElement = getThumbsElementAndInit();
16622          if (!thumbsElement) {
16623            requestAnimationFrame(watchForThumbsToAppear);
16624          }
16625        };
16626        requestAnimationFrame(watchForThumbsToAppear);
16627      } else {
16628        init();
16629        update(true);
16630      }
16631    });
16632    on('slideChange update resize observerUpdate', () => {
16633      update();
16634    });
16635    on('setTransition', (_s, duration) => {
16636      const thumbsSwiper = swiper.thumbs.swiper;
16637      if (!thumbsSwiper || thumbsSwiper.destroyed) return;
16638      thumbsSwiper.setTransition(duration);
16639    });
16640    on('beforeDestroy', () => {
16641      const thumbsSwiper = swiper.thumbs.swiper;
16642      if (!thumbsSwiper || thumbsSwiper.destroyed) return;
16643      if (swiperCreated) {
16644        thumbsSwiper.destroy();
16645      }
16646    });
16647    Object.assign(swiper.thumbs, {
16648      init,
16649      update
16650    });
16651  }
16652
16653  function freeMode({
16654    swiper,
16655    extendParams,
16656    emit,
16657    once
16658  }) {
16659    extendParams({
16660      freeMode: {
16661        enabled: false,
16662        momentum: true,
16663        momentumRatio: 1,
16664        momentumBounce: true,
16665        momentumBounceRatio: 1,
16666        momentumVelocityRatio: 1,
16667        sticky: false,
16668        minimumVelocity: 0.02
16669      }
16670    });
16671    function onTouchStart() {
16672      if (swiper.params.cssMode) return;
16673      const translate = swiper.getTranslate();
16674      swiper.setTranslate(translate);
16675      swiper.setTransition(0);
16676      swiper.touchEventsData.velocities.length = 0;
16677      swiper.freeMode.onTouchEnd({
16678        currentPos: swiper.rtl ? swiper.translate : -swiper.translate
16679      });
16680    }
16681    function onTouchMove() {
16682      if (swiper.params.cssMode) return;
16683      const {
16684        touchEventsData: data,
16685        touches
16686      } = swiper;
16687      // Velocity
16688      if (data.velocities.length === 0) {
16689        data.velocities.push({
16690          position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
16691          time: data.touchStartTime
16692        });
16693      }
16694      data.velocities.push({
16695        position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
16696        time: now()
16697      });
16698    }
16699    function onTouchEnd({
16700      currentPos
16701    }) {
16702      if (swiper.params.cssMode) return;
16703      const {
16704        params,
16705        wrapperEl,
16706        rtlTranslate: rtl,
16707        snapGrid,
16708        touchEventsData: data
16709      } = swiper;
16710      // Time diff
16711      const touchEndTime = now();
16712      const timeDiff = touchEndTime - data.touchStartTime;
16713      if (currentPos < -swiper.minTranslate()) {
16714        swiper.slideTo(swiper.activeIndex);
16715        return;
16716      }
16717      if (currentPos > -swiper.maxTranslate()) {
16718        if (swiper.slides.length < snapGrid.length) {
16719          swiper.slideTo(snapGrid.length - 1);
16720        } else {
16721          swiper.slideTo(swiper.slides.length - 1);
16722        }
16723        return;
16724      }
16725      if (params.freeMode.momentum) {
16726        if (data.velocities.length > 1) {
16727          const lastMoveEvent = data.velocities.pop();
16728          const velocityEvent = data.velocities.pop();
16729          const distance = lastMoveEvent.position - velocityEvent.position;
16730          const time = lastMoveEvent.time - velocityEvent.time;
16731          swiper.velocity = distance / time;
16732          swiper.velocity /= 2;
16733          if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
16734            swiper.velocity = 0;
16735          }
16736          // this implies that the user stopped moving a finger then released.
16737          // There would be no events with distance zero, so the last event is stale.
16738          if (time > 150 || now() - lastMoveEvent.time > 300) {
16739            swiper.velocity = 0;
16740          }
16741        } else {
16742          swiper.velocity = 0;
16743        }
16744        swiper.velocity *= params.freeMode.momentumVelocityRatio;
16745        data.velocities.length = 0;
16746        let momentumDuration = 1000 * params.freeMode.momentumRatio;
16747        const momentumDistance = swiper.velocity * momentumDuration;
16748        let newPosition = swiper.translate + momentumDistance;
16749        if (rtl) newPosition = -newPosition;
16750        let doBounce = false;
16751        let afterBouncePosition;
16752        const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
16753        let needsLoopFix;
16754        if (newPosition < swiper.maxTranslate()) {
16755          if (params.freeMode.momentumBounce) {
16756            if (newPosition + swiper.maxTranslate() < -bounceAmount) {
16757              newPosition = swiper.maxTranslate() - bounceAmount;
16758            }
16759            afterBouncePosition = swiper.maxTranslate();
16760            doBounce = true;
16761            data.allowMomentumBounce = true;
16762          } else {
16763            newPosition = swiper.maxTranslate();
16764          }
16765          if (params.loop && params.centeredSlides) needsLoopFix = true;
16766        } else if (newPosition > swiper.minTranslate()) {
16767          if (params.freeMode.momentumBounce) {
16768            if (newPosition - swiper.minTranslate() > bounceAmount) {
16769              newPosition = swiper.minTranslate() + bounceAmount;
16770            }
16771            afterBouncePosition = swiper.minTranslate();
16772            doBounce = true;
16773            data.allowMomentumBounce = true;
16774          } else {
16775            newPosition = swiper.minTranslate();
16776          }
16777          if (params.loop && params.centeredSlides) needsLoopFix = true;
16778        } else if (params.freeMode.sticky) {
16779          let nextSlide;
16780          for (let j = 0; j < snapGrid.length; j += 1) {
16781            if (snapGrid[j] > -newPosition) {
16782              nextSlide = j;
16783              break;
16784            }
16785          }
16786          if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
16787            newPosition = snapGrid[nextSlide];
16788          } else {
16789            newPosition = snapGrid[nextSlide - 1];
16790          }
16791          newPosition = -newPosition;
16792        }
16793        if (needsLoopFix) {
16794          once('transitionEnd', () => {
16795            swiper.loopFix();
16796          });
16797        }
16798        // Fix duration
16799        if (swiper.velocity !== 0) {
16800          if (rtl) {
16801            momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
16802          } else {
16803            momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
16804          }
16805          if (params.freeMode.sticky) {
16806            // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
16807            // event, then durations can be 20+ seconds to slide one (or zero!) slides.
16808            // It's easy to see this when simulating touch with mouse events. To fix this,
16809            // limit single-slide swipes to the default slide duration. This also has the
16810            // nice side effect of matching slide speed if the user stopped moving before
16811            // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
16812            // For faster swipes, also apply limits (albeit higher ones).
16813            const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
16814            const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
16815            if (moveDistance < currentSlideSize) {
16816              momentumDuration = params.speed;
16817            } else if (moveDistance < 2 * currentSlideSize) {
16818              momentumDuration = params.speed * 1.5;
16819            } else {
16820              momentumDuration = params.speed * 2.5;
16821            }
16822          }
16823        } else if (params.freeMode.sticky) {
16824          swiper.slideToClosest();
16825          return;
16826        }
16827        if (params.freeMode.momentumBounce && doBounce) {
16828          swiper.updateProgress(afterBouncePosition);
16829          swiper.setTransition(momentumDuration);
16830          swiper.setTranslate(newPosition);
16831          swiper.transitionStart(true, swiper.swipeDirection);
16832          swiper.animating = true;
16833          elementTransitionEnd(wrapperEl, () => {
16834            if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
16835            emit('momentumBounce');
16836            swiper.setTransition(params.speed);
16837            setTimeout(() => {
16838              swiper.setTranslate(afterBouncePosition);
16839              elementTransitionEnd(wrapperEl, () => {
16840                if (!swiper || swiper.destroyed) return;
16841                swiper.transitionEnd();
16842              });
16843            }, 0);
16844          });
16845        } else if (swiper.velocity) {
16846          emit('_freeModeNoMomentumRelease');
16847          swiper.updateProgress(newPosition);
16848          swiper.setTransition(momentumDuration);
16849          swiper.setTranslate(newPosition);
16850          swiper.transitionStart(true, swiper.swipeDirection);
16851          if (!swiper.animating) {
16852            swiper.animating = true;
16853            elementTransitionEnd(wrapperEl, () => {
16854              if (!swiper || swiper.destroyed) return;
16855              swiper.transitionEnd();
16856            });
16857          }
16858        } else {
16859          swiper.updateProgress(newPosition);
16860        }
16861        swiper.updateActiveIndex();
16862        swiper.updateSlidesClasses();
16863      } else if (params.freeMode.sticky) {
16864        swiper.slideToClosest();
16865        return;
16866      } else if (params.freeMode) {
16867        emit('_freeModeNoMomentumRelease');
16868      }
16869      if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
16870        emit('_freeModeStaticRelease');
16871        swiper.updateProgress();
16872        swiper.updateActiveIndex();
16873        swiper.updateSlidesClasses();
16874      }
16875    }
16876    Object.assign(swiper, {
16877      freeMode: {
16878        onTouchStart,
16879        onTouchMove,
16880        onTouchEnd
16881      }
16882    });
16883  }
16884
16885  function Grid({
16886    swiper,
16887    extendParams,
16888    on
16889  }) {
16890    extendParams({
16891      grid: {
16892        rows: 1,
16893        fill: 'column'
16894      }
16895    });
vendor: 1,326 bytes, lines 16896-16930
16896    let slidesNumberEvenToRows;
16897    let slidesPerRow;
16898    let numFullColumns;
16899    let wasMultiRow;
16900    const getSpaceBetween = () => {
16901      let spaceBetween = swiper.params.spaceBetween;
16902      if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
16903        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
16904      } else if (typeof spaceBetween === 'string') {
16905        spaceBetween = parseFloat(spaceBetween);
16906      }
16907      return spaceBetween;
16908    };
16909    const initSlides = slides => {
16910      const {
16911        slidesPerView
16912      } = swiper.params;
16913      const {
16914        rows,
16915        fill
16916      } = swiper.params.grid;
16917      const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
16918      numFullColumns = Math.floor(slidesLength / rows);
16919      if (Math.floor(slidesLength / rows) === slidesLength / rows) {
16920        slidesNumberEvenToRows = slidesLength;
16921      } else {
16922        slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
16923      }
16924      if (slidesPerView !== 'auto' && fill === 'row') {
16925        slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
16926      }
16927      slidesPerRow = slidesNumberEvenToRows / rows;
16928    };
16929    const unsetSlides = () => {
16930      if (swiper.slides) {
vendor: 38,075 bytes, lines 16931-17997
16931        swiper.slides.forEach(slide => {
16932          if (slide.swiperSlideGridSet) {
16933            slide.style.height = '';
16934            slide.style[swiper.getDirectionLabel('margin-top')] = '';
16935          }
16936        });
16937      }
16938    };
16939    const updateSlide = (i, slide, slides) => {
16940      const {
16941        slidesPerGroup
16942      } = swiper.params;
16943      const spaceBetween = getSpaceBetween();
16944      const {
16945        rows,
16946        fill
16947      } = swiper.params.grid;
16948      const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
16949      // Set slides order
16950      let newSlideOrderIndex;
16951      let column;
16952      let row;
16953      if (fill === 'row' && slidesPerGroup > 1) {
16954        const groupIndex = Math.floor(i / (slidesPerGroup * rows));
16955        const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
16956        const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
16957        row = Math.floor(slideIndexInGroup / columnsInGroup);
16958        column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
16959        newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;
16960        slide.style.order = newSlideOrderIndex;
16961      } else if (fill === 'column') {
16962        column = Math.floor(i / rows);
16963        row = i - column * rows;
16964        if (column > numFullColumns || column === numFullColumns && row === rows - 1) {
16965          row += 1;
16966          if (row >= rows) {
16967            row = 0;
16968            column += 1;
16969          }
16970        }
16971      } else {
16972        row = Math.floor(i / slidesPerRow);
16973        column = i - row * slidesPerRow;
16974      }
16975      slide.row = row;
16976      slide.column = column;
16977      slide.style.height = `calc((100% - ${(rows - 1) * spaceBetween}px) / ${rows})`;
16978      slide.style[swiper.getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
16979      slide.swiperSlideGridSet = true;
16980    };
16981    const updateWrapperSize = (slideSize, snapGrid) => {
16982      const {
16983        centeredSlides,
16984        roundLengths
16985      } = swiper.params;
16986      const spaceBetween = getSpaceBetween();
16987      const {
16988        rows
16989      } = swiper.params.grid;
16990      swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
16991      swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
16992      if (!swiper.params.cssMode) {
16993        swiper.wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
16994      }
16995      if (centeredSlides) {
16996        const newSlidesGrid = [];
16997        for (let i = 0; i < snapGrid.length; i += 1) {
16998          let slidesGridItem = snapGrid[i];
16999          if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
17000          if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
17001        }
17002        snapGrid.splice(0, snapGrid.length);
17003        snapGrid.push(...newSlidesGrid);
17004      }
17005    };
17006    const onInit = () => {
17007      wasMultiRow = swiper.params.grid && swiper.params.grid.rows > 1;
17008    };
17009    const onUpdate = () => {
17010      const {
17011        params,
17012        el
17013      } = swiper;
17014      const isMultiRow = params.grid && params.grid.rows > 1;
17015      if (wasMultiRow && !isMultiRow) {
17016        el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
17017        numFullColumns = 1;
17018        swiper.emitContainerClasses();
17019      } else if (!wasMultiRow && isMultiRow) {
17020        el.classList.add(`${params.containerModifierClass}grid`);
17021        if (params.grid.fill === 'column') {
17022          el.classList.add(`${params.containerModifierClass}grid-column`);
17023        }
17024        swiper.emitContainerClasses();
17025      }
17026      wasMultiRow = isMultiRow;
17027    };
17028    on('init', onInit);
17029    on('update', onUpdate);
17030    swiper.grid = {
17031      initSlides,
17032      unsetSlides,
17033      updateSlide,
17034      updateWrapperSize
17035    };
17036  }
17037
17038  function appendSlide(slides) {
17039    const swiper = this;
17040    const {
17041      params,
17042      slidesEl
17043    } = swiper;
17044    if (params.loop) {
17045      swiper.loopDestroy();
17046    }
17047    const appendElement = slideEl => {
17048      if (typeof slideEl === 'string') {
17049        const tempDOM = document.createElement('div');
17050        setInnerHTML(tempDOM, slideEl);
17051        slidesEl.append(tempDOM.children[0]);
17052        setInnerHTML(tempDOM, '');
17053      } else {
17054        slidesEl.append(slideEl);
17055      }
17056    };
17057    if (typeof slides === 'object' && 'length' in slides) {
17058      for (let i = 0; i < slides.length; i += 1) {
17059        if (slides[i]) appendElement(slides[i]);
17060      }
17061    } else {
17062      appendElement(slides);
17063    }
17064    swiper.recalcSlides();
17065    if (params.loop) {
17066      swiper.loopCreate();
17067    }
17068    if (!params.observer || swiper.isElement) {
17069      swiper.update();
17070    }
17071  }
17072
17073  function prependSlide(slides) {
17074    const swiper = this;
17075    const {
17076      params,
17077      activeIndex,
17078      slidesEl
17079    } = swiper;
17080    if (params.loop) {
17081      swiper.loopDestroy();
17082    }
17083    let newActiveIndex = activeIndex + 1;
17084    const prependElement = slideEl => {
17085      if (typeof slideEl === 'string') {
17086        const tempDOM = document.createElement('div');
17087        setInnerHTML(tempDOM, slideEl);
17088        slidesEl.prepend(tempDOM.children[0]);
17089        setInnerHTML(tempDOM, '');
17090      } else {
17091        slidesEl.prepend(slideEl);
17092      }
17093    };
17094    if (typeof slides === 'object' && 'length' in slides) {
17095      for (let i = 0; i < slides.length; i += 1) {
17096        if (slides[i]) prependElement(slides[i]);
17097      }
17098      newActiveIndex = activeIndex + slides.length;
17099    } else {
17100      prependElement(slides);
17101    }
17102    swiper.recalcSlides();
17103    if (params.loop) {
17104      swiper.loopCreate();
17105    }
17106    if (!params.observer || swiper.isElement) {
17107      swiper.update();
17108    }
17109    swiper.slideTo(newActiveIndex, 0, false);
17110  }
17111
17112  function addSlide(index, slides) {
17113    const swiper = this;
17114    const {
17115      params,
17116      activeIndex,
17117      slidesEl
17118    } = swiper;
17119    let activeIndexBuffer = activeIndex;
17120    if (params.loop) {
17121      activeIndexBuffer -= swiper.loopedSlides;
17122      swiper.loopDestroy();
17123      swiper.recalcSlides();
17124    }
17125    const baseLength = swiper.slides.length;
17126    if (index <= 0) {
17127      swiper.prependSlide(slides);
17128      return;
17129    }
17130    if (index >= baseLength) {
17131      swiper.appendSlide(slides);
17132      return;
17133    }
17134    let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
17135    const slidesBuffer = [];
17136    for (let i = baseLength - 1; i >= index; i -= 1) {
17137      const currentSlide = swiper.slides[i];
17138      currentSlide.remove();
17139      slidesBuffer.unshift(currentSlide);
17140    }
17141    if (typeof slides === 'object' && 'length' in slides) {
17142      for (let i = 0; i < slides.length; i += 1) {
17143        if (slides[i]) slidesEl.append(slides[i]);
17144      }
17145      newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
17146    } else {
17147      slidesEl.append(slides);
17148    }
17149    for (let i = 0; i < slidesBuffer.length; i += 1) {
17150      slidesEl.append(slidesBuffer[i]);
17151    }
17152    swiper.recalcSlides();
17153    if (params.loop) {
17154      swiper.loopCreate();
17155    }
17156    if (!params.observer || swiper.isElement) {
17157      swiper.update();
17158    }
17159    if (params.loop) {
17160      swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
17161    } else {
17162      swiper.slideTo(newActiveIndex, 0, false);
17163    }
17164  }
17165
17166  function removeSlide(slidesIndexes) {
17167    const swiper = this;
17168    const {
17169      params,
17170      activeIndex
17171    } = swiper;
17172    let activeIndexBuffer = activeIndex;
17173    if (params.loop) {
17174      activeIndexBuffer -= swiper.loopedSlides;
17175      swiper.loopDestroy();
17176    }
17177    let newActiveIndex = activeIndexBuffer;
17178    let indexToRemove;
17179    if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
17180      for (let i = 0; i < slidesIndexes.length; i += 1) {
17181        indexToRemove = slidesIndexes[i];
17182        if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
17183        if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
17184      }
17185      newActiveIndex = Math.max(newActiveIndex, 0);
17186    } else {
17187      indexToRemove = slidesIndexes;
17188      if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
17189      if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
17190      newActiveIndex = Math.max(newActiveIndex, 0);
17191    }
17192    swiper.recalcSlides();
17193    if (params.loop) {
17194      swiper.loopCreate();
17195    }
17196    if (!params.observer || swiper.isElement) {
17197      swiper.update();
17198    }
17199    if (params.loop) {
17200      swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
17201    } else {
17202      swiper.slideTo(newActiveIndex, 0, false);
17203    }
17204  }
17205
17206  function removeAllSlides() {
17207    const swiper = this;
17208    const slidesIndexes = [];
17209    for (let i = 0; i < swiper.slides.length; i += 1) {
17210      slidesIndexes.push(i);
17211    }
17212    swiper.removeSlide(slidesIndexes);
17213  }
17214
17215  function Manipulation({
17216    swiper
17217  }) {
17218    Object.assign(swiper, {
17219      appendSlide: appendSlide.bind(swiper),
17220      prependSlide: prependSlide.bind(swiper),
17221      addSlide: addSlide.bind(swiper),
17222      removeSlide: removeSlide.bind(swiper),
17223      removeAllSlides: removeAllSlides.bind(swiper)
17224    });
17225  }
17226
17227  function effectInit(params) {
17228    const {
17229      effect,
17230      swiper,
17231      on,
17232      setTranslate,
17233      setTransition,
17234      overwriteParams,
17235      perspective,
17236      recreateShadows,
17237      getEffectParams
17238    } = params;
17239    on('beforeInit', () => {
17240      if (swiper.params.effect !== effect) return;
17241      swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
17242      if (perspective && perspective()) {
17243        swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
17244      }
17245      const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
17246      Object.assign(swiper.params, overwriteParamsResult);
17247      Object.assign(swiper.originalParams, overwriteParamsResult);
17248    });
17249    on('setTranslate _virtualUpdated', () => {
17250      if (swiper.params.effect !== effect) return;
17251      setTranslate();
17252    });
17253    on('setTransition', (_s, duration) => {
17254      if (swiper.params.effect !== effect) return;
17255      setTransition(duration);
17256    });
17257    on('transitionEnd', () => {
17258      if (swiper.params.effect !== effect) return;
17259      if (recreateShadows) {
17260        if (!getEffectParams || !getEffectParams().slideShadows) return;
17261        // remove shadows
17262        swiper.slides.forEach(slideEl => {
17263          slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => shadowEl.remove());
17264        });
17265        // create new one
17266        recreateShadows();
17267      }
17268    });
17269    let requireUpdateOnVirtual;
17270    on('virtualUpdate', () => {
17271      if (swiper.params.effect !== effect) return;
17272      if (!swiper.slides.length) {
17273        requireUpdateOnVirtual = true;
17274      }
17275      requestAnimationFrame(() => {
17276        if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {
17277          setTranslate();
17278          requireUpdateOnVirtual = false;
17279        }
17280      });
17281    });
17282  }
17283
17284  function effectTarget(effectParams, slideEl) {
17285    const transformEl = getSlideTransformEl(slideEl);
17286    if (transformEl !== slideEl) {
17287      transformEl.style.backfaceVisibility = 'hidden';
17288      transformEl.style['-webkit-backface-visibility'] = 'hidden';
17289    }
17290    return transformEl;
17291  }
17292
17293  function effectVirtualTransitionEnd({
17294    swiper,
17295    duration,
17296    transformElements,
17297    allSlides
17298  }) {
17299    const {
17300      activeIndex
17301    } = swiper;
17302    const getSlide = el => {
17303      if (!el.parentElement) {
17304        // assume shadow root
17305        const slide = swiper.slides.find(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode);
17306        return slide;
17307      }
17308      return el.parentElement;
17309    };
17310    if (swiper.params.virtualTranslate && duration !== 0) {
17311      let eventTriggered = false;
17312      let transitionEndTarget;
17313      if (allSlides) {
17314        transitionEndTarget = transformElements;
17315      } else {
17316        transitionEndTarget = transformElements.filter(transformEl => {
17317          const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
17318          return swiper.getSlideIndex(el) === activeIndex;
17319        });
17320      }
17321      transitionEndTarget.forEach(el => {
17322        elementTransitionEnd(el, () => {
17323          if (eventTriggered) return;
17324          if (!swiper || swiper.destroyed) return;
17325          eventTriggered = true;
17326          swiper.animating = false;
17327          const evt = new window.CustomEvent('transitionend', {
17328            bubbles: true,
17329            cancelable: true
17330          });
17331          swiper.wrapperEl.dispatchEvent(evt);
17332        });
17333      });
17334    }
17335  }
17336
17337  function EffectFade({
17338    swiper,
17339    extendParams,
17340    on
17341  }) {
17342    extendParams({
17343      fadeEffect: {
17344        crossFade: false
17345      }
17346    });
17347    const setTranslate = () => {
17348      const {
17349        slides
17350      } = swiper;
17351      const params = swiper.params.fadeEffect;
17352      for (let i = 0; i < slides.length; i += 1) {
17353        const slideEl = swiper.slides[i];
17354        const offset = slideEl.swiperSlideOffset;
17355        let tx = -offset;
17356        if (!swiper.params.virtualTranslate) tx -= swiper.translate;
17357        let ty = 0;
17358        if (!swiper.isHorizontal()) {
17359          ty = tx;
17360          tx = 0;
17361        }
17362        const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
17363        const targetEl = effectTarget(params, slideEl);
17364        targetEl.style.opacity = slideOpacity;
17365        targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
17366      }
17367    };
17368    const setTransition = duration => {
17369      const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
17370      transformElements.forEach(el => {
17371        el.style.transitionDuration = `${duration}ms`;
17372      });
17373      effectVirtualTransitionEnd({
17374        swiper,
17375        duration,
17376        transformElements,
17377        allSlides: true
17378      });
17379    };
17380    effectInit({
17381      effect: 'fade',
17382      swiper,
17383      on,
17384      setTranslate,
17385      setTransition,
17386      overwriteParams: () => ({
17387        slidesPerView: 1,
17388        slidesPerGroup: 1,
17389        watchSlidesProgress: true,
17390        spaceBetween: 0,
17391        virtualTranslate: !swiper.params.cssMode
17392      })
17393    });
17394  }
17395
17396  function EffectCube({
17397    swiper,
17398    extendParams,
17399    on
17400  }) {
17401    extendParams({
17402      cubeEffect: {
17403        slideShadows: true,
17404        shadow: true,
17405        shadowOffset: 20,
17406        shadowScale: 0.94
17407      }
17408    });
17409    const createSlideShadows = (slideEl, progress, isHorizontal) => {
17410      let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
17411      let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
17412      if (!shadowBefore) {
17413        shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' '));
17414        slideEl.append(shadowBefore);
17415      }
17416      if (!shadowAfter) {
17417        shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' '));
17418        slideEl.append(shadowAfter);
17419      }
17420      if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
17421      if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
17422    };
17423    const recreateShadows = () => {
17424      // create new ones
17425      const isHorizontal = swiper.isHorizontal();
17426      swiper.slides.forEach(slideEl => {
17427        const progress = Math.max(Math.min(slideEl.progress, 1), -1);
17428        createSlideShadows(slideEl, progress, isHorizontal);
17429      });
17430    };
17431    const setTranslate = () => {
17432      const {
17433        el,
17434        wrapperEl,
17435        slides,
17436        width: swiperWidth,
17437        height: swiperHeight,
17438        rtlTranslate: rtl,
17439        size: swiperSize,
17440        browser
17441      } = swiper;
17442      const r = getRotateFix(swiper);
17443      const params = swiper.params.cubeEffect;
17444      const isHorizontal = swiper.isHorizontal();
17445      const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
17446      let wrapperRotate = 0;
17447      let cubeShadowEl;
17448      if (params.shadow) {
17449        if (isHorizontal) {
17450          cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow');
17451          if (!cubeShadowEl) {
17452            cubeShadowEl = createElement('div', 'swiper-cube-shadow');
17453            swiper.wrapperEl.append(cubeShadowEl);
17454          }
17455          cubeShadowEl.style.height = `${swiperWidth}px`;
17456        } else {
17457          cubeShadowEl = el.querySelector('.swiper-cube-shadow');
17458          if (!cubeShadowEl) {
17459            cubeShadowEl = createElement('div', 'swiper-cube-shadow');
17460            el.append(cubeShadowEl);
17461          }
17462        }
17463      }
17464      for (let i = 0; i < slides.length; i += 1) {
17465        const slideEl = slides[i];
17466        let slideIndex = i;
17467        if (isVirtual) {
17468          slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
17469        }
17470        let slideAngle = slideIndex * 90;
17471        let round = Math.floor(slideAngle / 360);
17472        if (rtl) {
17473          slideAngle = -slideAngle;
17474          round = Math.floor(-slideAngle / 360);
17475        }
17476        const progress = Math.max(Math.min(slideEl.progress, 1), -1);
17477        let tx = 0;
17478        let ty = 0;
17479        let tz = 0;
17480        if (slideIndex % 4 === 0) {
17481          tx = -round * 4 * swiperSize;
17482          tz = 0;
17483        } else if ((slideIndex - 1) % 4 === 0) {
17484          tx = 0;
17485          tz = -round * 4 * swiperSize;
17486        } else if ((slideIndex - 2) % 4 === 0) {
17487          tx = swiperSize + round * 4 * swiperSize;
17488          tz = swiperSize;
17489        } else if ((slideIndex - 3) % 4 === 0) {
17490          tx = -swiperSize;
17491          tz = 3 * swiperSize + swiperSize * 4 * round;
17492        }
17493        if (rtl) {
17494          tx = -tx;
17495        }
17496        if (!isHorizontal) {
17497          ty = tx;
17498          tx = 0;
17499        }
17500        const transform = `rotateX(${r(isHorizontal ? 0 : -slideAngle)}deg) rotateY(${r(isHorizontal ? slideAngle : 0)}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
17501        if (progress <= 1 && progress > -1) {
17502          wrapperRotate = slideIndex * 90 + progress * 90;
17503          if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
17504        }
17505        slideEl.style.transform = transform;
17506        if (params.slideShadows) {
17507          createSlideShadows(slideEl, progress, isHorizontal);
17508        }
17509      }
17510      wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
17511      wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
17512      if (params.shadow) {
17513        if (isHorizontal) {
17514          cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(89.99deg) rotateZ(0deg) scale(${params.shadowScale})`;
17515        } else {
17516          const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
17517          const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
17518          const scale1 = params.shadowScale;
17519          const scale2 = params.shadowScale / multiplier;
17520          const offset = params.shadowOffset;
17521          cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-89.99deg)`;
17522        }
17523      }
17524      const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
17525      wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${r(swiper.isHorizontal() ? 0 : wrapperRotate)}deg) rotateY(${r(swiper.isHorizontal() ? -wrapperRotate : 0)}deg)`;
17526      wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
17527    };
17528    const setTransition = duration => {
17529      const {
17530        el,
17531        slides
17532      } = swiper;
17533      slides.forEach(slideEl => {
17534        slideEl.style.transitionDuration = `${duration}ms`;
17535        slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => {
17536          subEl.style.transitionDuration = `${duration}ms`;
17537        });
17538      });
17539      if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
17540        const shadowEl = el.querySelector('.swiper-cube-shadow');
17541        if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
17542      }
17543    };
17544    effectInit({
17545      effect: 'cube',
17546      swiper,
17547      on,
17548      setTranslate,
17549      setTransition,
17550      recreateShadows,
17551      getEffectParams: () => swiper.params.cubeEffect,
17552      perspective: () => true,
17553      overwriteParams: () => ({
17554        slidesPerView: 1,
17555        slidesPerGroup: 1,
17556        watchSlidesProgress: true,
17557        resistanceRatio: 0,
17558        spaceBetween: 0,
17559        centeredSlides: false,
17560        virtualTranslate: true
17561      })
17562    });
17563  }
17564
17565  function createShadow(suffix, slideEl, side) {
17566    const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`;
17567    const shadowContainer = getSlideTransformEl(slideEl);
17568    let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`);
17569    if (!shadowEl) {
17570      shadowEl = createElement('div', shadowClass.split(' '));
17571      shadowContainer.append(shadowEl);
17572    }
17573    return shadowEl;
17574  }
17575
17576  function EffectFlip({
17577    swiper,
17578    extendParams,
17579    on
17580  }) {
17581    extendParams({
17582      flipEffect: {
17583        slideShadows: true,
17584        limitRotation: true
17585      }
17586    });
17587    const createSlideShadows = (slideEl, progress) => {
17588      let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
17589      let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
17590      if (!shadowBefore) {
17591        shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top');
17592      }
17593      if (!shadowAfter) {
17594        shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
17595      }
17596      if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
17597      if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
17598    };
17599    const recreateShadows = () => {
17600      // Set shadows
17601      swiper.params.flipEffect;
17602      swiper.slides.forEach(slideEl => {
17603        let progress = slideEl.progress;
17604        if (swiper.params.flipEffect.limitRotation) {
17605          progress = Math.max(Math.min(slideEl.progress, 1), -1);
17606        }
17607        createSlideShadows(slideEl, progress);
17608      });
17609    };
17610    const setTranslate = () => {
17611      const {
17612        slides,
17613        rtlTranslate: rtl
17614      } = swiper;
17615      const params = swiper.params.flipEffect;
17616      const rotateFix = getRotateFix(swiper);
17617      for (let i = 0; i < slides.length; i += 1) {
17618        const slideEl = slides[i];
17619        let progress = slideEl.progress;
17620        if (swiper.params.flipEffect.limitRotation) {
17621          progress = Math.max(Math.min(slideEl.progress, 1), -1);
17622        }
17623        const offset = slideEl.swiperSlideOffset;
17624        const rotate = -180 * progress;
17625        let rotateY = rotate;
17626        let rotateX = 0;
17627        let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
17628        let ty = 0;
17629        if (!swiper.isHorizontal()) {
17630          ty = tx;
17631          tx = 0;
17632          rotateX = -rotateY;
17633          rotateY = 0;
17634        } else if (rtl) {
17635          rotateY = -rotateY;
17636        }
17637        slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
17638        if (params.slideShadows) {
17639          createSlideShadows(slideEl, progress);
17640        }
17641        const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateFix(rotateX)}deg) rotateY(${rotateFix(rotateY)}deg)`;
17642        const targetEl = effectTarget(params, slideEl);
17643        targetEl.style.transform = transform;
17644      }
17645    };
17646    const setTransition = duration => {
17647      const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
17648      transformElements.forEach(el => {
17649        el.style.transitionDuration = `${duration}ms`;
17650        el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
17651          shadowEl.style.transitionDuration = `${duration}ms`;
17652        });
17653      });
17654      effectVirtualTransitionEnd({
17655        swiper,
17656        duration,
17657        transformElements
17658      });
17659    };
17660    effectInit({
17661      effect: 'flip',
17662      swiper,
17663      on,
17664      setTranslate,
17665      setTransition,
17666      recreateShadows,
17667      getEffectParams: () => swiper.params.flipEffect,
17668      perspective: () => true,
17669      overwriteParams: () => ({
17670        slidesPerView: 1,
17671        slidesPerGroup: 1,
17672        watchSlidesProgress: true,
17673        spaceBetween: 0,
17674        virtualTranslate: !swiper.params.cssMode
17675      })
17676    });
17677  }
17678
17679  function EffectCoverflow({
17680    swiper,
17681    extendParams,
17682    on
17683  }) {
17684    extendParams({
17685      coverflowEffect: {
17686        rotate: 50,
17687        stretch: 0,
17688        depth: 100,
17689        scale: 1,
17690        modifier: 1,
17691        slideShadows: true
17692      }
17693    });
17694    const setTranslate = () => {
17695      const {
17696        width: swiperWidth,
17697        height: swiperHeight,
17698        slides,
17699        slidesSizesGrid
17700      } = swiper;
17701      const params = swiper.params.coverflowEffect;
17702      const isHorizontal = swiper.isHorizontal();
17703      const transform = swiper.translate;
17704      const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
17705      const rotate = isHorizontal ? params.rotate : -params.rotate;
17706      const translate = params.depth;
17707      const r = getRotateFix(swiper);
17708      // Each slide offset from center
17709      for (let i = 0, length = slides.length; i < length; i += 1) {
17710        const slideEl = slides[i];
17711        const slideSize = slidesSizesGrid[i];
17712        const slideOffset = slideEl.swiperSlideOffset;
17713        const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
17714        const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
17715        let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
17716        let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
17717        // var rotateZ = 0
17718        let translateZ = -translate * Math.abs(offsetMultiplier);
17719        let stretch = params.stretch;
17720        // Allow percentage to make a relative stretch for responsive sliders
17721        if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
17722          stretch = parseFloat(params.stretch) / 100 * slideSize;
17723        }
17724        let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
17725        let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
17726        let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
17727
17728        // Fix for ultra small values
17729        if (Math.abs(translateX) < 0.001) translateX = 0;
17730        if (Math.abs(translateY) < 0.001) translateY = 0;
17731        if (Math.abs(translateZ) < 0.001) translateZ = 0;
17732        if (Math.abs(rotateY) < 0.001) rotateY = 0;
17733        if (Math.abs(rotateX) < 0.001) rotateX = 0;
17734        if (Math.abs(scale) < 0.001) scale = 0;
17735        const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px)  rotateX(${r(rotateX)}deg) rotateY(${r(rotateY)}deg) scale(${scale})`;
17736        const targetEl = effectTarget(params, slideEl);
17737        targetEl.style.transform = slideTransform;
17738        slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
17739        if (params.slideShadows) {
17740          // Set shadows
17741          let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
17742          let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
17743          if (!shadowBeforeEl) {
17744            shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top');
17745          }
17746          if (!shadowAfterEl) {
17747            shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom');
17748          }
17749          if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
17750          if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
17751        }
17752      }
17753    };
17754    const setTransition = duration => {
17755      const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
17756      transformElements.forEach(el => {
17757        el.style.transitionDuration = `${duration}ms`;
17758        el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
17759          shadowEl.style.transitionDuration = `${duration}ms`;
17760        });
17761      });
17762    };
17763    effectInit({
17764      effect: 'coverflow',
17765      swiper,
17766      on,
17767      setTranslate,
17768      setTransition,
17769      perspective: () => true,
17770      overwriteParams: () => ({
17771        watchSlidesProgress: true
17772      })
17773    });
17774  }
17775
17776  function EffectCreative({
17777    swiper,
17778    extendParams,
17779    on
17780  }) {
17781    extendParams({
17782      creativeEffect: {
17783        limitProgress: 1,
17784        shadowPerProgress: false,
17785        progressMultiplier: 1,
17786        perspective: true,
17787        prev: {
17788          translate: [0, 0, 0],
17789          rotate: [0, 0, 0],
17790          opacity: 1,
17791          scale: 1
17792        },
17793        next: {
17794          translate: [0, 0, 0],
17795          rotate: [0, 0, 0],
17796          opacity: 1,
17797          scale: 1
17798        }
17799      }
17800    });
17801    const getTranslateValue = value => {
17802      if (typeof value === 'string') return value;
17803      return `${value}px`;
17804    };
17805    const setTranslate = () => {
17806      const {
17807        slides,
17808        wrapperEl,
17809        slidesSizesGrid
17810      } = swiper;
17811      const params = swiper.params.creativeEffect;
17812      const {
17813        progressMultiplier: multiplier
17814      } = params;
17815      const isCenteredSlides = swiper.params.centeredSlides;
17816      const rotateFix = getRotateFix(swiper);
17817      if (isCenteredSlides) {
17818        const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
17819        wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
17820      }
17821      for (let i = 0; i < slides.length; i += 1) {
17822        const slideEl = slides[i];
17823        const slideProgress = slideEl.progress;
17824        const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
17825        let originalProgress = progress;
17826        if (!isCenteredSlides) {
17827          originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
17828        }
17829        const offset = slideEl.swiperSlideOffset;
17830        const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
17831        const r = [0, 0, 0];
17832        let custom = false;
17833        if (!swiper.isHorizontal()) {
17834          t[1] = t[0];
17835          t[0] = 0;
17836        }
17837        let data = {
17838          translate: [0, 0, 0],
17839          rotate: [0, 0, 0],
17840          scale: 1,
17841          opacity: 1
17842        };
17843        if (progress < 0) {
17844          data = params.next;
17845          custom = true;
17846        } else if (progress > 0) {
17847          data = params.prev;
17848          custom = true;
17849        }
17850        // set translate
17851        t.forEach((value, index) => {
17852          t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
17853        });
17854        // set rotates
17855        r.forEach((value, index) => {
17856          let val = data.rotate[index] * Math.abs(progress * multiplier);
17857          r[index] = val;
17858        });
17859        slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
17860        const translateString = t.join(', ');
17861        const rotateString = `rotateX(${rotateFix(r[0])}deg) rotateY(${rotateFix(r[1])}deg) rotateZ(${rotateFix(r[2])}deg)`;
17862        const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
17863        const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
17864        const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
17865
17866        // Set shadows
17867        if (custom && data.shadow || !custom) {
17868          let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
17869          if (!shadowEl && data.shadow) {
17870            shadowEl = createShadow('creative', slideEl);
17871          }
17872          if (shadowEl) {
17873            const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
17874            shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
17875          }
17876        }
17877        const targetEl = effectTarget(params, slideEl);
17878        targetEl.style.transform = transform;
17879        targetEl.style.opacity = opacityString;
17880        if (data.origin) {
17881          targetEl.style.transformOrigin = data.origin;
17882        }
17883      }
17884    };
17885    const setTransition = duration => {
17886      const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
17887      transformElements.forEach(el => {
17888        el.style.transitionDuration = `${duration}ms`;
17889        el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
17890          shadowEl.style.transitionDuration = `${duration}ms`;
17891        });
17892      });
17893      effectVirtualTransitionEnd({
17894        swiper,
17895        duration,
17896        transformElements,
17897        allSlides: true
17898      });
17899    };
17900    effectInit({
17901      effect: 'creative',
17902      swiper,
17903      on,
17904      setTranslate,
17905      setTransition,
17906      perspective: () => swiper.params.creativeEffect.perspective,
17907      overwriteParams: () => ({
17908        watchSlidesProgress: true,
17909        virtualTranslate: !swiper.params.cssMode
17910      })
17911    });
17912  }
17913
17914  function EffectCards({
17915    swiper,
17916    extendParams,
17917    on
17918  }) {
17919    extendParams({
17920      cardsEffect: {
17921        slideShadows: true,
17922        rotate: true,
17923        perSlideRotate: 2,
17924        perSlideOffset: 8
17925      }
17926    });
17927    const setTranslate = () => {
17928      const {
17929        slides,
17930        activeIndex,
17931        rtlTranslate: rtl
17932      } = swiper;
17933      const params = swiper.params.cardsEffect;
17934      const {
17935        startTranslate,
17936        isTouched
17937      } = swiper.touchEventsData;
17938      const currentTranslate = rtl ? -swiper.translate : swiper.translate;
17939      for (let i = 0; i < slides.length; i += 1) {
17940        const slideEl = slides[i];
17941        const slideProgress = slideEl.progress;
17942        const progress = Math.min(Math.max(slideProgress, -4), 4);
17943        let offset = slideEl.swiperSlideOffset;
17944        if (swiper.params.centeredSlides && !swiper.params.cssMode) {
17945          swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
17946        }
17947        if (swiper.params.centeredSlides && swiper.params.cssMode) {
17948          offset -= slides[0].swiperSlideOffset;
17949        }
17950        let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
17951        let tY = 0;
17952        const tZ = -100 * Math.abs(progress);
17953        let scale = 1;
17954        let rotate = -params.perSlideRotate * progress;
17955        let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
17956        const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
17957        const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;
17958        const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;
17959        if (isSwipeToNext || isSwipeToPrev) {
17960          const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
17961          rotate += -28 * progress * subProgress;
17962          scale += -0.5 * subProgress;
17963          tXAdd += 96 * subProgress;
17964          tY = `${(params.rotate || swiper.isHorizontal() ? -25 : 0) * subProgress * Math.abs(progress)}%`;
17965        }
17966        if (progress < 0) {
17967          // next
17968          tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
17969        } else if (progress > 0) {
17970          // prev
17971          tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
17972        } else {
17973          tX = `${tX}px`;
17974        }
17975        if (!swiper.isHorizontal()) {
17976          const prevY = tY;
17977          tY = tX;
17978          tX = prevY;
17979        }
17980        const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
17981
17982        /* eslint-disable */
17983        const transform = `
17984        translate3d(${tX}, ${tY}, ${tZ}px)
17985        rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg)
17986        scale(${scaleString})
17987      `;
17988        /* eslint-enable */
17989
17990        if (params.slideShadows) {
17991          // Set shadows
17992          let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
17993          if (!shadowEl) {
17994            shadowEl = createShadow('cards', slideEl);
17995          }
17996          if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
17997        }
17998        slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
17999        const targetEl = effectTarget(params, slideEl);
18000        targetEl.style.transform = transform;
18001      }
18002    };
18003    const setTransition = duration => {
18004      const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
18005      transformElements.forEach(el => {
18006        el.style.transitionDuration = `${duration}ms`;
18007        el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
18008          shadowEl.style.transitionDuration = `${duration}ms`;
18009        });
18010      });
18011      effectVirtualTransitionEnd({
18012        swiper,
18013        duration,
18014        transformElements
18015      });
18016    };
18017    effectInit({
18018      effect: 'cards',
18019      swiper,
18020      on,
18021      setTranslate,
18022      setTransition,
18023      perspective: () => true,
18024      overwriteParams: () => ({
18025        _loopSwapReset: false,
18026        watchSlidesProgress: true,
18027        loopAdditionalSlides: swiper.params.cardsEffect.rotate ? 3 : 2,
18028        centeredSlides: true,
18029        virtualTranslate: !swiper.params.cssMode
18030      })
18031    });
18032  }
18033
18034  /**
18035   * Swiper 12.0.3
18036   * Most modern mobile touch slider and framework with hardware accelerated transitions
18037   * https://swiperjs.com
18038   *
18039   * Copyright 2014-2025 Vladimir Kharlampidi
18040   *
18041   * Released under the MIT License
18042   *
18043   * Released on: October 21, 2025
18044   */
18045
18046
18047  // Swiper Class
18048  const modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards];
18049  Swiper.use(modules);
18050
18051  return Swiper;
18052
18053})();
18054
18055(function () {
18056
18057  const hasGalleryBodyClass = !!(document.body && (
18058    document.body.classList.contains('Gallery') ||
18059    document.body.classList.contains('Body--Gallery') ||
18060    document.body.classList.contains('BodyGallery')
18061  ));
18062
18063  const galleries = document.querySelectorAll('.MediaGallery, .MediaGalleryFullWidth');
18064  if (!galleries.length) {
18065    return;
18066  }
18067  const adIds = [];
18068  const adSlots = new Map();
18069
18070  /*
18071   * Konstanten-Dokumentation
18072   *
18073   * Layout/Rendering:
18074   * - AD_VERTICAL_OFFSET_PERCENT: Vertikaler Offset zur Positionierung des Ads im Ad-Slide.
18075   * - DEFAULT_INITIAL_SLIDE_HEIGHT_PX: Fallback-Start-Minimalhoehe fuer Slider/Slides.
18076   * - DEFAULT_SLIDER_CONTAINER_MIN_HEIGHT_PX: Standard-Minimalhoehe fuer normale Galerien.
18077   * - DEFAULT_FULLWIDTH_SLIDER_CONTAINER_MIN_HEIGHT_PX: Standard-Minimalhoehe fuer Fullwidth-Galerien.
18078   * - AUTO_HEIGHT_TOLERANCE_PX: Toleranz, ab der eine AutoHeight-Neuberechnung noetig ist.
18079   *
18080   * Debug/Beobachtbarkeit:
18081   * - DEBUG_EVENT_LIMIT: Maximale Anzahl gespeicherter Debug-Events im Ringpuffer.
18082   * - EXTERNAL_SLOT_HISTORY_LIMIT: Maximale Anzahl Historieneintraege je externem Slot.
18083   *
18084   * Refresh-Regeln (intern/extern):
18085   * - MIN_REFRESH_INTERVAL_MS: Untergrenze fuer konfigurierbares Refresh-Intervall (>= 30s).
18086   * - DEFAULT_REFRESH_INTERVAL_MS: Default-Refresh-Intervall fuer zeitgesteuerte Pruefungen.
18087   * - DEFAULT_MIN_VIEWABLE_MS: Mindestdauer, die ein Slot sichtbar sein muss.
18088   * - DEFAULT_USER_IDLE_TIMEOUT_MS: Inaktivitaetsgrenze; danach wird Refresh pausiert.
18089   * - DEFAULT_ELIGIBILITY_CACHE_TTL_MS: Cache-Lebensdauer fuer Eligibility-Abfragen.
18090   * - SLOT_VIEWPORT_THRESHOLD: Sichtbarkeits-Schwelle fuer internen Gallery-Slot (0..1).
18091   * - EXTERNAL_SLOT_VIEWPORT_THRESHOLD: Sichtbarkeits-Schwelle fuer externe Slots (0..1).
18092   * - EXTERNAL_REFRESH_COOLDOWN_MS: Mindestabstand zwischen externen Refreshes (ausser adPos-Trigger).
18093   *
18094   * Externe Slots:
18095   * - EXTERNAL_REFRESH_SLOT_IDS: IDs der externen Werbeflaechen, die mitrefreshen sollen.
18096   *
18097   * Display/Targeting-Orchestrierung:
18098   * - REQUIRED_PAGE_TARGETING_KEYS: Muss-Targeting-Keys vor display(), sonst Warteschleife/Fallback.
18099   * - MAX_DISPLAY_WAIT_ATTEMPTS: Maximale Anzahl Warteversuche auf Targeting.
18100   * - DISPLAY_WAIT_INTERVAL_MS: Intervall zwischen den Warteversuchen.
18101   *
18102   * Debug-Helfer (window.*):
18103   * - __galleryDebug: Aktiviert Konsolen-Logs der Galerie-Debugmeldungen.
18104   * - __galleryDebugVisualRefresh: Visuelle Marker an externen Slots (Request/Render).
18105   * - __galleryExternalRefreshForceNewCorrelator: Erzwingt externen Refresh mit changeCorrelator=true.
18106   * - __galleryExternalSlotViewportThreshold: Optionaler Viewport-Threshold (0..1) fuer externe Slots.
18107   * - __galleryDebugPing(): Kurzer Lebenszeichen-Check (Galleries/Slots/pubadsReady).
18108   * - __galleryDebugEvents(): Liefert den aktuellen Event-Puffer als Array.
18109   * - __galleryDebugDumpEvents(): Schreibt kompletten Event-Puffer als Snapshot ins Log.
18110   * - __galleryDebugDumpAdFlow(): Loggt gefilterten Ad-Flow ohne Thumb/Virtual-Tracking-Rauschen.
18111   * - __galleryDebugDump(): Snapshot zu adIds, Slot-States und registrierten GPT-Slots.
18112   * - __galleryDebugRefresh(): Trigger fuer manuellen Refresh der internen Gallery-Slots.
18113   * - __galleryDebugTargetingDump(): Dump der aktuellen Slot-Targeting-Informationen.
18114   * - __galleryDebugExternalStats(): Snapshot inkl. Historie fuer externe Slots.
18115   */
18116
18117  const AD_VERTICAL_OFFSET_PERCENT = 0;
18118  const DEFAULT_INITIAL_SLIDE_HEIGHT_PX = 0;
18119  const DEFAULT_SLIDER_CONTAINER_MIN_HEIGHT_PX = 540;
18120  const DEFAULT_FULLWIDTH_SLIDER_CONTAINER_MIN_HEIGHT_PX = 940;
18121  const AUTO_HEIGHT_TOLERANCE_PX = 6;
18122  const slotTargetingState = new WeakMap();
18123  const debugEventBuffer = [];
18124  const DEBUG_EVENT_LIMIT = 250;
18125  const REQUIRED_PAGE_TARGETING_KEYS = ['kw_page_url'];
18126  const MAX_DISPLAY_WAIT_ATTEMPTS = 20;
18127  const DISPLAY_WAIT_INTERVAL_MS = 120;
18128  const MIN_REFRESH_INTERVAL_MS = 30000;
18129  const DEFAULT_REFRESH_INTERVAL_MS = 30000;
18130  const DEFAULT_MIN_VIEWABLE_MS = 3000;
18131  const DEFAULT_USER_IDLE_TIMEOUT_MS = 20000;
18132  const DEFAULT_ELIGIBILITY_CACHE_TTL_MS = 120000;
18133  const SLOT_VIEWPORT_THRESHOLD = 0.5;
18134  const EXTERNAL_SLOT_VIEWPORT_THRESHOLD = 0.2;
18135  const EXTERNAL_REFRESH_SLOT_IDS = [
18136    'renderSlot_Billboard',
18137    'renderSlot_Skyscraper-links',
18138    'renderSlot_Skyscraper-rechts',
18139  ];
18140  const EXTERNAL_REFRESH_COOLDOWN_MS = 1000;
18141  const EXTERNAL_SLOT_HISTORY_LIMIT = 20;
18142  const ACTIVE_AD_FALLBACK_RETRY_MS = 450;
18143  const AD_SLIDE_REENTRY_GUARD_MS = 900;
18144  let lastExternalRefreshTs = Date.now();
18145  let externalRefreshCount = 0;
18146
18147  function createExternalSlotStatsBucket() {
18148    return {
18149      refreshCallTriggered: 0,
18150      slotRequested: 0,
18151      slotResponseReceived: 0,
18152      slotRenderEnded: 0,
18153      lastRenderLineItemId: null,
18154      lastRenderCreativeId: null,
18155      lastRenderTs: null,
18156      history: [],
18157    };
18158  }
18159
18160  const externalSlotDebugStats = {
18161    totals: {
18162      refreshCallTriggered: 0,
18163      slotRequested: 0,
18164      slotResponseReceived: 0,
18165      slotRenderEnded: 0,
18166    },
18167    bySlot: EXTERNAL_REFRESH_SLOT_IDS.reduce(function (acc, slotId) {
18168      acc[slotId] = createExternalSlotStatsBucket();
18169      return acc;
18170    }, {}),
18171  };
18172
18173  function ensureExternalSlotStats(slotId) {
18174    if (!externalSlotDebugStats.bySlot[slotId]) {
18175      externalSlotDebugStats.bySlot[slotId] = createExternalSlotStatsBucket();
18176    }
18177    return externalSlotDebugStats.bySlot[slotId];
18178  }
18179
18180  function pushExternalSlotHistory(slotId, eventType, payload) {
18181    if (!slotId || !eventType) {
18182      return;
18183    }
18184
18185    const slotStats = ensureExternalSlotStats(slotId);
18186    slotStats.history.push(Object.assign({
18187      ts: new Date().toISOString(),
18188      event: eventType,
18189    }, payload || {}));
18190
18191    if (slotStats.history.length > EXTERNAL_SLOT_HISTORY_LIMIT) {
18192      slotStats.history.shift();
18193    }
18194  }
18195
18196  function flashExternalSlotDebugMarker(slotId, phase) {
18197    if (typeof window === 'undefined' || !window.__galleryDebugVisualRefresh) {
18198      return;
18199    }
18200
18201    const slotElement = document.getElementById(slotId);
18202    if (!slotElement) {
18203      return;
18204    }
18205
18206    const isRenderPhase = phase === 'render';
18207    const borderColor = isRenderPhase ? '#2e7d32' : '#c62828';
18208    const shadowColor = isRenderPhase ? 'rgba(46, 125, 50, 0.82)' : 'rgba(198, 40, 40, 0.72)';
18209    const holdMs = isRenderPhase ? 700 : 260;
18210    const transitionMs = isRenderPhase ? 180 : 120;
18211
18212    slotElement.__galleryDebugMarkerToken = (slotElement.__galleryDebugMarkerToken || 0) + 1;
18213    const markerToken = slotElement.__galleryDebugMarkerToken;
18214
18215    slotElement.style.transition = 'box-shadow ' + transitionMs + 'ms ease-out, outline-color ' + transitionMs + 'ms ease-out';
18216    slotElement.style.outline = '3px solid ' + borderColor;
18217    slotElement.style.boxShadow = '0 0 0 4px ' + shadowColor;
18218
18219    window.setTimeout(function () {
18220      if (!slotElement || !slotElement.style) {
18221        return;
18222      }
18223      if (slotElement.__galleryDebugMarkerToken !== markerToken) {
18224        return;
18225      }
18226      slotElement.style.outline = '';
18227      slotElement.style.boxShadow = '';
18228    }, holdMs);
18229  }
18230
18231  function incrementExternalSlotStat(slotId, key) {
18232    if (!slotId || !key) {
18233      return;
18234    }
18235
18236    if (externalSlotDebugStats.totals[key] === undefined) {
18237      externalSlotDebugStats.totals[key] = 0;
18238    }
18239    externalSlotDebugStats.totals[key] += 1;
18240
18241    const slotStats = ensureExternalSlotStats(slotId);
18242
18243    if (slotStats[key] === undefined) {
18244      slotStats[key] = 0;
18245    }
18246    slotStats[key] += 1;
18247  }
18248
18249  function parsePositiveInt(value, fallback) {
18250    const parsed = parseInt(value, 10);
18251    return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
18252  }
18253
18254  function getRefreshRuntimeConfig() {
18255    const cfg = (typeof window !== 'undefined' && window.__galleryAdRefreshConfig && typeof window.__galleryAdRefreshConfig === 'object')
18256      ? window.__galleryAdRefreshConfig
18257      : {};
18258
18259    const refreshIntervalMs = Math.max(
18260      MIN_REFRESH_INTERVAL_MS,
18261      parsePositiveInt(cfg.refreshIntervalMs, DEFAULT_REFRESH_INTERVAL_MS)
18262    );
18263
18264    return {
18265      refreshIntervalMs: refreshIntervalMs,
18266      minViewableMs: parsePositiveInt(cfg.minViewableMs, DEFAULT_MIN_VIEWABLE_MS),
18267      userIdleTimeoutMs: parsePositiveInt(cfg.userIdleTimeoutMs, DEFAULT_USER_IDLE_TIMEOUT_MS),
18268      eligibilityCacheTtlMs: parsePositiveInt(cfg.eligibilityCacheTtlMs, DEFAULT_ELIGIBILITY_CACHE_TTL_MS),
18269      refreshCheckIntervalMs: parsePositiveInt(cfg.refreshCheckIntervalMs, 1000),
18270      strictDifferentLineItem: cfg.strictDifferentLineItem !== false,
18271    };
18272  }
18273
18274  const refreshRuntimeConfig = getRefreshRuntimeConfig();
18275  let lastUserActivityTs = Date.now();
18276  let hasExplicitUserInteraction = false;
18277
18278  function markUserActivity() {
18279    lastUserActivityTs = Date.now();
18280  }
18281
18282  function isUserRecentlyActive() {
18283    return (Date.now() - lastUserActivityTs) <= refreshRuntimeConfig.userIdleTimeoutMs;
18284  }
18285
18286  function isDocumentVisible() {
18287    if (typeof document === 'undefined') {
18288      return true;
18289    }
18290    if (typeof document.visibilityState === 'string') {
18291      return document.visibilityState === 'visible';
18292    }
18293    return true;
18294  }
18295
18296  if (typeof window !== 'undefined') {
18297    ['pointerdown', 'pointermove', 'keydown', 'scroll', 'touchstart', 'wheel', 'focus'].forEach(function (eventName) {
18298      window.addEventListener(eventName, markUserActivity, { passive: true });
18299    });
18300    ['pointerdown', 'keydown', 'touchstart', 'wheel', 'mousedown', 'click'].forEach(function (eventName) {
18301      window.addEventListener(eventName, function () {
18302        hasExplicitUserInteraction = true;
18303      }, { passive: true });
18304    });
18305    document.addEventListener('visibilitychange', function () {
18306      if (isDocumentVisible()) {
18307        markUserActivity();
18308      }
18309    });
18310  }
18311
18312  function debugAdLog(message, meta) {
18313    debugEventBuffer.push({
18314      ts: new Date().toISOString(),
18315      message: message,
18316      meta: meta || {},
18317    });
18318    if (debugEventBuffer.length > DEBUG_EVENT_LIMIT) {
18319      debugEventBuffer.shift();
18320    }
18321
18322    const isGalleryDebugEnabled = typeof window !== 'undefined' && !!window.__galleryDebug;
18323    if (!isGalleryDebugEnabled || !window.console) {
18324      return;
18325    }
18326
18327    if (typeof window.console.log === 'function') {
18328      window.console.log('[GalleryAds] ' + message, meta || '');
18329      return;
18330    }
18331
18332    if (typeof window.console.info === 'function') {
18333      window.console.info('[GalleryAds] ' + message, meta || '');
18334    }
18335  }
18336
18337  function applySlotConfigTargeting(slotObj, targeting) {
18338    if (!slotObj || !targeting || typeof targeting !== 'object') {
18339      return;
18340    }
18341
18342    const previousTargeting = slotTargetingState.get(slotObj) || {};
18343    const mergedTargeting = Object.assign({}, previousTargeting, targeting);
18344    slotTargetingState.set(slotObj, mergedTargeting);
18345
18346    if (typeof slotObj.setConfig === 'function') {
18347      slotObj.setConfig({ targeting: mergedTargeting });
18348      return;
18349    }
18350
18351    if (typeof slotObj.setTargeting !== 'function') {
18352      return;
18353    }
18354
18355    Object.keys(targeting).forEach(function (key) {
18356      slotObj.setTargeting(key, targeting[key]);
18357    });
18358  }
18359
18360  function getStoredSlotTargetingSnapshot(slotObj) {
18361    const stored = slotTargetingState.get(slotObj) || {};
18362    return Object.assign({}, stored);
18363  }
18364
18365  function normalizeTargetingSnapshot(rawTargeting) {
18366    if (!rawTargeting || typeof rawTargeting !== 'object') {
18367      return {};
18368    }
18369
18370    function collectPrimitiveTargetingValues(inputValue, collector) {
18371      if (inputValue === null || typeof inputValue === 'undefined') {
18372        return;
18373      }
18374
18375      if (Array.isArray(inputValue)) {
18376        inputValue.forEach(function (entry) {
18377          collectPrimitiveTargetingValues(entry, collector);
18378        });
18379        return;
18380      }
18381
18382      if (typeof inputValue === 'object') {
18383        // GPT kann je nach API-Variante Objektstrukturen liefern (z. B. mit `value`).
18384        if (Object.prototype.hasOwnProperty.call(inputValue, 'value')) {
18385          collectPrimitiveTargetingValues(inputValue.value, collector);
18386          return;
18387        }
18388        return;
18389      }
18390
18391      if (typeof inputValue === 'function') {
18392        return;
18393      }
18394
18395      const normalized = String(inputValue);
18396      if (normalized.length > 0) {
18397        collector[normalized] = true;
18398      }
18399    }
18400
18401    function setNormalizedValue(target, key, value) {
18402      if (!key || typeof key !== 'string') {
18403        return;
18404      }
18405
18406      const valuesCollector = {};
18407      collectPrimitiveTargetingValues(value, valuesCollector);
18408      const normalizedValues = Object.keys(valuesCollector);
18409      if (normalizedValues.length === 0) {
18410        return;
18411      }
18412
18413      target[key] = normalizedValues;
18414    }
18415
18416    const normalized = {};
18417
18418    // GPT `getConfig('targeting')` kann als `{ targeting: {...} }` zurückkommen.
18419    if (
18420      Object.prototype.hasOwnProperty.call(rawTargeting, 'targeting') &&
18421      rawTargeting.targeting &&
18422      typeof rawTargeting.targeting === 'object' &&
18423      !Array.isArray(rawTargeting.targeting)
18424    ) {
18425      Object.keys(rawTargeting.targeting).forEach(function (nestedKey) {
18426        setNormalizedValue(normalized, nestedKey, rawTargeting.targeting[nestedKey]);
18427      });
18428      return normalized;
18429    }
18430
18431    Object.keys(rawTargeting).forEach(function (key) {
18432      setNormalizedValue(normalized, key, rawTargeting[key]);
18433    });
18434
18435    return normalized;
18436  }
18437
18438  function getSlotTargetingSnapshot(slotObj) {
18439    if (!slotObj) {
18440      return {};
18441    }
18442
18443    if (typeof slotObj.getConfig === 'function') {
18444      return normalizeTargetingSnapshot(slotObj.getConfig('targeting'));
18445    }
18446
18447    if (typeof slotObj.getTargetingKeys !== 'function' || typeof slotObj.getTargeting !== 'function') {
18448      return {};
18449    }
18450
18451    const targeting = {};
18452    slotObj.getTargetingKeys().forEach(function (key) {
18453      targeting[key] = slotObj.getTargeting(key);
18454    });
18455
18456    return normalizeTargetingSnapshot(targeting);
18457  }
18458
18459  function getPageTargetingSnapshot() {
18460    if (typeof googletag === 'undefined') {
18461      return {};
18462    }
18463
18464    if (typeof googletag.getConfig === 'function') {
18465      return normalizeTargetingSnapshot(googletag.getConfig('targeting'));
18466    }
18467
18468    if (!googletag.pubads || typeof googletag.pubads !== 'function') {
18469      return {};
18470    }
18471
18472    const pubads = googletag.pubads();
18473    if (!pubads || typeof pubads.getTargetingKeys !== 'function' || typeof pubads.getTargeting !== 'function') {
18474      return {};
18475    }
18476
18477    const pageTargeting = {};
18478    pubads.getTargetingKeys().forEach(function (key) {
18479      pageTargeting[key] = pubads.getTargeting(key);
18480    });
18481
18482    return normalizeTargetingSnapshot(pageTargeting);
18483  }
18484
18485  function getGalleryAdDatasetSnapshot(gallery) {
18486    if (!gallery || !gallery.dataset) {
18487      return {};
18488    }
18489
18490    const adGamIdRaw = typeof gallery.dataset.ad_gam_id === 'string' ? gallery.dataset.ad_gam_id : '';
18491    return {
18492      galleryId: gallery.id || null,
18493      adPosRaw: typeof gallery.dataset.adpos === 'string' ? gallery.dataset.adpos : null,
18494      adTargetingRaw: typeof gallery.dataset.ad_targeting === 'string' ? gallery.dataset.ad_targeting : null,
18495      hasAdGamId: adGamIdRaw.length > 0,
18496      adGamIdPreview: adGamIdRaw.slice(0, 180),
18497    };
18498  }
18499
18500  function mirrorPageTargetingToSlot(slotObj, keys) {
18501    if (!slotObj) {
18502      return;
18503    }
18504
18505    const pageTargeting = getPageTargetingSnapshot();
18506    const targetKeys = Array.isArray(keys) && keys.length > 0 ? keys : Object.keys(pageTargeting);
18507    const mirrored = {};
18508
18509    targetKeys.forEach(function (key) {
18510      const values = pageTargeting[key];
18511      if (!Array.isArray(values) || values.length === 0) {
18512        return;
18513      }
18514
18515      const normalized = values.filter(function (v) {
18516        return v !== null && typeof v !== 'undefined' && String(v).length > 0;
18517      }).map(function (v) {
18518        return String(v);
18519      });
18520
18521      if (normalized.length === 1) {
18522        mirrored[key] = normalized[0];
18523        return;
18524      }
18525
18526      if (normalized.length > 1) {
18527        mirrored[key] = normalized;
18528      }
18529    });
18530
18531    const mirroredKeys = Object.keys(mirrored);
18532    if (mirroredKeys.length === 0) {
18533      debugAdLog('Kein Page-Targeting zum Spiegeln vorhanden', {
18534        requestedKeys: targetKeys,
18535        availablePageKeys: Object.keys(pageTargeting),
18536      });
18537      return;
18538    }
18539
18540    applySlotConfigTargeting(slotObj, mirrored);
18541    debugAdLog('Page-Targeting auf Slot gespiegelt', {
18542      keys: mirroredKeys,
18543      values: mirrored,
18544    });
18545  }
18546
18547  function hasAllRequiredPageTargeting(keys) {
18548    if (!Array.isArray(keys) || keys.length === 0) {
18549      return true;
18550    }
18551
18552    const pageTargeting = getPageTargetingSnapshot();
18553    return keys.every(function (key) {
18554      const values = pageTargeting[key];
18555      return Array.isArray(values) && values.length > 0;
18556    });
18557  }
18558
18559  if (typeof window !== 'undefined') {
18560    window.__galleryDebugPing = function () {
18561      debugAdLog('Debug-Ping', {
18562        galleries: galleries.length,
18563        adIds: adIds.length,
18564        slots: adSlots.size,
18565        pubadsReady: !!googletag.pubadsReady,
18566      });
18567    };
18568
18569    window.__galleryDebugEvents = function () {
18570      return debugEventBuffer.slice();
18571    };
18572
18573    window.__galleryDebugDumpEvents = function () {
18574      debugAdLog('Debug-Eventbuffer Snapshot', {
18575        count: debugEventBuffer.length,
18576        events: debugEventBuffer.slice(),
18577      });
18578    };
18579
18580    window.__galleryDebugDumpAdFlow = function () {
18581      const adFlowEvents = debugEventBuffer.filter(function (entry) {
18582        return entry.message.indexOf('ThumbTrace') === -1 && entry.message.indexOf('Virtual-Tracking') === -1;
18583      });
18584
18585      debugAdLog('Debug-Ad-Flow Snapshot', {
18586        count: adFlowEvents.length,
18587        events: adFlowEvents,
18588      });
18589
18590      return adFlowEvents;
18591    };
18592  }
18593
18594  function normalizeTargetingValueForSlot(value) {
18595    if (value === null || typeof value === 'undefined') {
18596      return null;
18597    }
18598
18599    if (Array.isArray(value)) {
18600      const normalizedList = value.filter(function (v) {
18601        const valueType = typeof v;
18602        return v !== null && valueType !== 'undefined' && valueType !== 'object' && valueType !== 'function' && String(v).length > 0;
18603      }).map(function (v) {
18604        return String(v);
18605      });
18606
18607      return normalizedList.length > 0 ? normalizedList : null;
18608    }
18609
18610    const valueType = typeof value;
18611    if (valueType === 'object' || valueType === 'function') {
18612      return null;
18613    }
18614
18615    const normalizedValue = String(value);
18616    return normalizedValue.length > 0 ? normalizedValue : null;
18617  }
18618
18619  function applySlotTargeting(slotObj, adData) {
18620    if (!slotObj || (typeof slotObj.setConfig !== 'function' && typeof slotObj.setTargeting !== 'function') || !adData) {
18621      return;
18622    }
18623
18624    const targetingSources = [
18625      { name: 'targeting', data: adData.targeting },
18626      { name: 'gam_config.targeting', data: adData.gam_config && adData.gam_config.targeting },
18627    ];
18628
18629    const mergedTargeting = {};
18630    const sourceInfo = [];
18631    const droppedEntries = [];
18632
18633    targetingSources.forEach(function (source) {
18634      const targeting = source.data;
18635      if (!targeting || typeof targeting !== 'object') {
18636        sourceInfo.push({ source: source.name, present: false, keys: [] });
18637        return;
18638      }
18639
18640      const sourceKeys = Object.keys(targeting);
18641      sourceInfo.push({ source: source.name, present: sourceKeys.length > 0, keys: sourceKeys });
18642
18643      sourceKeys.forEach(function (key) {
18644        const value = targeting[key];
18645        const normalizedValue = normalizeTargetingValueForSlot(value);
18646        if (normalizedValue === null) {
18647          droppedEntries.push({
18648            key: key,
18649            source: source.name,
18650            type: Array.isArray(value) ? 'array' : typeof value,
18651          });
18652          return;
18653        }
18654
18655        mergedTargeting[key] = normalizedValue;
18656      });
18657    });
18658
18659    const appliedKeys = Object.keys(mergedTargeting);
18660    if (appliedKeys.length > 0) {
18661      applySlotConfigTargeting(slotObj, mergedTargeting);
18662    }
18663
18664    debugAdLog('Slot-Targeting ausgewertet', {
18665      path: adData.path || null,
18666      sourceInfo: sourceInfo,
18667      appliedKeys: appliedKeys,
18668      droppedEntries: droppedEntries,
18669    });
18670  }
18671
18672  function applyGalleryDatasetTargeting(slotObj, gallery) {
18673    if (!slotObj || (typeof slotObj.setConfig !== 'function' && typeof slotObj.setTargeting !== 'function') || !gallery || !gallery.dataset) {
18674      return;
18675    }
18676
18677    const adTargetingValue = typeof gallery.dataset.ad_targeting === 'string'
18678      ? gallery.dataset.ad_targeting.trim()
18679      : '';
18680
18681    if (!adTargetingValue) {
18682      return;
18683    }
18684
18685    applySlotConfigTargeting(slotObj, { kw: adTargetingValue });
18686
18687    debugAdLog('Gallery data-ad_targeting gesetzt', {
18688      galleryId: gallery.id || null,
18689      key: 'kw',
18690      value: adTargetingValue,
18691    });
18692  }
18693
18694  googletag.cmd.push(function () {
18695
18696    function getReferenceSlideHeight(gallery, targetAdSlide) {
18697      if (!gallery) {
18698        return 0;
18699      }
18700
18701      if (gallery.__lastImageSlideHeight && gallery.__lastImageSlideHeight > 0) {
18702        return gallery.__lastImageSlideHeight;
18703      }
18704
18705      const sliderContainer = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
18706      if (!sliderContainer) {
18707        return 0;
18708      }
18709
18710      const normalSlides = Array.from(sliderContainer.children).filter(function (slide) {
18711        return !slide.classList.contains('ad-slide');
18712      });
18713
18714      if (!normalSlides.length) {
18715        return targetAdSlide ? targetAdSlide.clientHeight : 0;
18716      }
18717
18718      const activeNormalSlide = normalSlides.find(function (slide) {
18719        return slide.classList.contains('swiper-slide-active');
18720      });
18721
18722      if (activeNormalSlide && activeNormalSlide.clientHeight > 0) {
18723        return activeNormalSlide.clientHeight;
18724      }
18725
18726      const maxHeight = normalSlides.reduce(function (acc, slide) {
18727        return Math.max(acc, slide.clientHeight || 0);
18728      }, 0);
18729
18730      return maxHeight;
18731    }
18732
18733    function rememberCurrentImageSlideHeight(gallery, swiperInstance) {
18734      if (!gallery || !swiperInstance || !swiperInstance.slides || typeof swiperInstance.activeIndex !== 'number') {
18735        return;
18736      }
18737
18738      const activeSlide = swiperInstance.slides[swiperInstance.activeIndex];
18739      if (!activeSlide || activeSlide.classList.contains('ad-slide')) {
18740        return;
18741      }
18742
18743      const measuredHeight = Math.max(
18744        activeSlide.offsetHeight || 0,
18745        activeSlide.scrollHeight || 0,
18746        Math.ceil(activeSlide.getBoundingClientRect ? activeSlide.getBoundingClientRect().height : 0)
18747      );
18748
18749      if (measuredHeight > 0) {
18750        gallery.__lastImageSlideHeight = measuredHeight;
18751      }
18752    }
18753
18754    function centerAdIframes(adContainer, targetAdSlide) {
18755      if (!adContainer) {
18756        return;
18757      }
18758
18759      let gallery = adContainer.closest('.MediaGallery, .MediaGalleryFullWidth');
18760      if (targetAdSlide) {
18761        gallery = targetAdSlide.closest('.MediaGallery, .MediaGalleryFullWidth');
18762      }
18763
18764      if (targetAdSlide) {
18765        // Kein Fremdwert von Bild-Slides erzwingen: Ad-Slide soll sich am Ad-Inhalt orientieren.
18766        targetAdSlide.style.minHeight = '0';
18767        targetAdSlide.style.height = 'auto';
18768
18769        targetAdSlide.style.display = 'flex';
18770        targetAdSlide.style.justifyContent = 'center';
18771        targetAdSlide.style.alignItems = 'center';
18772      }
18773
18774      adContainer.style.width = '100%';
18775      adContainer.style.height = '100%';
18776      adContainer.style.display = 'flex';
18777      adContainer.style.justifyContent = 'center';
18778      adContainer.style.alignItems = 'center';
18779      adContainer.style.textAlign = 'center';
18780      adContainer.style.minHeight = '0';
18781      adContainer.style.transform = 'translateY(' + AD_VERTICAL_OFFSET_PERCENT + '%)';
18782
18783      adContainer.querySelectorAll('iframe').forEach(function (iframe) {
18784        iframe.style.display = 'block';
18785        iframe.style.marginLeft = 'auto';
18786        iframe.style.marginRight = 'auto';
18787      });
18788
18789      if (targetAdSlide) {
18790        const firstIframe = adContainer.querySelector('iframe');
18791        const measuredHeight = firstIframe ? firstIframe.offsetHeight : adContainer.scrollHeight;
18792        const referenceHeight = getReferenceSlideHeight(gallery, targetAdSlide);
18793        const minHeight = Math.max(measuredHeight || 0, referenceHeight || 0
18793);
18794        if (minHeight > 0) {
18795          // Ensure vertical centering has enough available slide height.
18796          targetAdSlide.style.minHeight = minHeight + 'px';
18797        }
18798      }
18799
18800      if (!adContainer.__galleryAdObserver) {
18801        const observer = new MutationObserver(function () {
18802          adContainer.querySelectorAll('iframe').forEach(function (iframe) {
18803            iframe.style.display = 'block';
18804            iframe.style.marginLeft = 'auto';
18805            iframe.style.marginRight = 'auto';
18806          });
18807        });
18808
18809        observer.observe(adContainer, { childList: true, subtree: true });
18810        adContainer.__galleryAdObserver = observer;
18811      }
18812    }
18813
18814
18815    function removeAllAdMarkup(gallery) {
18816      const adElements = gallery.querySelectorAll('.ad-thumb, .ad-slide');
18817      adElements.forEach(function (el) {
18818        el.remove();
18819      });
18820
18821      debugAdLog('Ad-Markup entfernt', {
18822        galleryId: gallery.id || null,
18823        removedNodes: adElements.length,
18824      });
18825    }
18826
18827    function injectAdMarkup(slotInfo) {
18828      let adsAdded = 0;
18829      let insertedSlides = 0;
18830      const originalSlides = Array.from(slotInfo.mainWrapper.children).filter(function (slide) {
18831        return !slide.classList.contains('ad-slide');
18832      });
18833
18834      originalSlides.forEach(function (slide, index) {
18835        if ((index + 1) % slotInfo.adPos === 0) {
18836          const adSlide = document.createElement('div');
18837          adSlide.className = 'swiper-slide ad-slide MediaGallery_sliderImage';
18838          adSlide.style.height = 'auto';
18839          const insertAt = index + adsAdded + 1;
18840          slotInfo.mainWrapper.insertBefore(adSlide, slotInfo.mainWrapper.children[insertAt] || null);
18841          adsAdded++;
18842          insertedSlides++;
18843        }
18844      });
18845
18846      debugAdLog('Ad-Markup eingefuegt', {
18847        adId: slotInfo.adId,
18848        galleryId: slotInfo.gallery.id || null,
18849        insertedSlides: insertedSlides,
18850        insertedThumbs: 0,
18851      });
18852    }
18853
18854    function getImageIndexFromMainIndex(mainSlides, mainIndex) {
18855      let imageIndex = -1;
18856      for (let i = 0; i <= mainIndex; i++) {
18857        if (mainSlides[i] && !mainSlides[i].classList.contains('ad-slide')) {
18858          imageIndex++;
18859        }
18860      }
18861      return imageIndex;
18862    }
18863
18864    function getMainIndexFromImageIndex(mainSlides, imageIndex) {
18865      let currentImageIndex = -1;
18866      for (let i = 0; i < mainSlides.length; i++) {
18867        if (!mainSlides[i].classList.contains('ad-slide')) {
18868          currentImageIndex++;
18869          if (currentImageIndex === imageIndex) {
18870            return i;
18871          }
18872        }
18873      }
18874      return -1;
18875    }
18876
18877    function getThumbActiveClassIndex(gallery) {
18878      if (!gallery || !gallery.tSwiper || !gallery.tSwiper.slides) {
18879        return -1;
18880      }
18881
18882      for (let i = 0; i < gallery.tSwiper.slides.length; i++) {
18883        if (gallery.tSwiper.slides[i].classList.contains('swiper-slide-thumb-active')) {
18884          return i;
18885        }
18886      }
18887
18888      return -1;
18889    }
18890
18891    function traceThumbSync(gallery, stage, extra) {
18892      if (typeof window === 'undefined' || !window.__galleryDebug) {
18893        return;
18894      }
18895
18896      const mainSwiper = gallery && gallery.mSwiper;
18897      const mainActiveIndex = mainSwiper && typeof mainSwiper.activeIndex === 'number' ? mainSwiper.activeIndex : -1;
18898      const mainSlides = mainSwiper && mainSwiper.slides ? mainSwiper.slides : null;
18899      const imageIndex = mainSlides && mainActiveIndex >= 0 ? getImageIndexFromMainIndex(mainSlides, mainActiveIndex) : -1;
18900      const activeSlide = mainSlides && mainActiveIndex >= 0 ? mainSlides[mainActiveIndex] : null;
18901
18902      debugAdLog('ThumbTrace ' + stage, Object.assign({
18903        galleryId: gallery && gallery.id ? gallery.id : null,
18904        mainActiveIndex: mainActiveIndex,
18905        imageIndex: imageIndex,
18906        mainIsAd: !!(activeSlide && activeSlide.classList.contains('ad-slide')),
18907        thumbSwiperActiveIndex: gallery && gallery.tSwiper && typeof gallery.tSwiper.activeIndex === 'number' ? gallery.tSwiper.activeIndex : -1,
18908        thumbActiveClassIndex: getThumbActiveClassIndex(gallery),
18909        thumbSyncToken: gallery && gallery.__thumbSyncToken ? gallery.__thumbSyncToken : 0,
18910      }, extra || {}));
18911    }
18912
18913    function updateActiveThumbState(gallery, imageIndex) {
18914      if (!gallery || !gallery.tSwiper || !gallery.tSwiper.slides) {
18915        return;
18916      }
18917
18918      Array.from(gallery.tSwiper.slides).forEach(function (slide, idx) {
18919        const isActive = idx === imageIndex;
18920
18921        // Beide Klassen konsistent pflegen, da Theme-Styling auf swiper-slide-active basiert.
18922        slide.classList.toggle('swiper-slide-thumb-active', isActive);
18923        slide.classList.toggle('swiper-slide-active', isActive);
18924      });
18925
18926      traceThumbSync(gallery, 'updateActiveThumbState', { targetImageIndex: imageIndex });
18927    }
18928
18929    function clearActiveThumbState(gallery) {
18930      if (!gallery || !gallery.tSwiper || !gallery.tSwiper.slides) {
18931        return;
18932      }
18933
18934      Array.from(gallery.tSwiper.slides).forEach(function (slide) {
18935        slide.classList.remove('swiper-slide-thumb-active');
18936        slide.classList.remove('swiper-slide-active');
18937      });
18938
18939      traceThumbSync(gallery, 'clearActiveThumbState');
18940    }
18941
18942    function syncThumbSwiperToImageIndex(gallery, imageIndex) {
18943      if (!gallery || !gallery.tSwiper || typeof gallery.tSwiper.slideTo !== 'function') {
18944        return;
18945      }
18946
18947      if (!Number.isInteger(imageIndex) || imageIndex < 0) {
18948        return;
18949      }
18950
18951      traceThumbSync(gallery, 'syncThumbSwiperToImageIndex:start', { targetImageIndex: imageIndex });
18952
18953      // Ohne Animation synchronisieren, damit nach Ad-Slides kein Versatz entsteht.
18954      gallery.tSwiper.slideTo(imageIndex, 0);
18955      updateActiveThumbState(gallery, imageIndex);
18956
18957      // Schutz gegen stale RAF-Updates: nur der neueste Sync darf nachlaufen.
18958      gallery.__thumbSyncToken = (gallery.__thumbSyncToken || 0) + 1;
18959      const syncToken = gallery.__thumbSyncToken;
18960
18961      // Zweiter Tick: manche Swiper-Zustaende laufen nach dem ersten slideTo noch nach.
18962      if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
18963        window.requestAnimationFrame(function () {
18964          if (gallery.__thumbSyncToken !== syncToken) {
18965            traceThumbSync(gallery, 'syncThumbSwiperToImageIndex:raf-skip-stale', { targetImageIndex: imageIndex, syncToken: syncToken });
18966            return;
18967          }
18968
18969          gallery.tSwiper.slideTo(imageIndex, 0);
18970          updateActiveThumbState(gallery, imageIndex);
18971          traceThumbSync(gallery, 'syncThumbSwiperToImageIndex:raf-apply', { targetImageIndex: imageIndex, syncToken: syncToken });
18972        });
18973      }
18974
18975      traceThumbSync(gallery, 'syncThumbSwiperToImageIndex:end', { targetImageIndex: imageIndex, syncToken: syncToken });
18976    }
18977
18978    function syncThumbStateWithMainSwiper(gallery) {
18979      if (!gallery || !gallery.mSwiper || !gallery.tSwiper || !gallery.mSwiper.slides || typeof gallery.mSwiper.activeIndex !== 'number') {
18980        return;
18981      }
18982
18983      traceThumbSync(gallery, 'syncThumbStateWithMainSwiper:start');
18984
18985      const activeSlide = gallery.mSwiper.slides[gallery.mSwiper.activeIndex];
18986      if (!activeSlide) {
18987        return;
18988      }
18989
18990      if (activeSlide.classList.contains('ad-slide')) {
18991        clearActiveThumbState(gallery);
18992        traceThumbSync(gallery, 'syncThumbStateWithMainSwiper:active-ad');
18993        return;
18994      }
18995
18996      const imageIndex = getImageIndexFromMainIndex(gallery.mSwiper.slides, gallery.mSwiper.activeIndex);
18997      if (imageIndex >= 0) {
18998        updateActiveThumbState(gallery, imageIndex);
18999        syncThumbSwiperToImageIndex(gallery, imageIndex);
19000        traceThumbSync(gallery, 'syncThumbStateWithMainSwiper:active-image', { targetImageIndex: imageIndex });
19001      }
19002    }
19003
19004    function setGalleryAdNavigationState(gallery, activeSlide) {
19005      if (!gallery || !gallery.classList) {
19006        return;
19007      }
19008
19009      const isAdActive = !!(activeSlide && activeSlide.classList.contains('ad-slide'));
19010      gallery.classList.toggle('is-ad-active', isAdActive);
19011
19012      const overlays = gallery.querySelectorAll('.MediaGallery_slideLeft, .MediaGallery_slideRight, .MediaGalleryFullWidth_slideLeft, .MediaGalleryFullWidth_slideRight');
19013      if (!overlays.length) {
19014        return;
19015      }
19016
19017      overlays.forEach(function (overlayEl) {
19018        if (isAdActive) {
19019          // Schmale Rand-Klickzonen nur fuer Ad-Slides: Mitte bleibt fuer Ad-Klicks frei.
19020          overlayEl.style.width = '8%';
19021          overlayEl.style.pointerEvents = 'auto';
19022          return;
19023        }
19024
19025        // Fuer normale Bild-Slides wieder das CSS-Layout verwenden.
19026        overlayEl.style.width = '';
19027        overlayEl.style.pointerEvents = '';
19028      });
19029    }
19030
19031    function getActiveSlideHeight(swiperInstance) {
19032      if (!swiperInstance || !swiperInstance.slides || typeof swiperInstance.activeIndex !== 'number') {
19033        return 0;
19034      }
19035
19036      const activeSlide = swiperInstance.slides[swiperInstance.activeIndex];
19037      if (!activeSlide) {
19038        return 0;
19039      }
19040
19041      return Math.max(
19042        activeSlide.offsetHeight || 0,
19043        activeSlide.scrollHeight || 0,
19044        Math.ceil(activeSlide.getBoundingClientRect ? activeSlide.getBoundingClientRect().height : 0)
19045      );
19046    }
19047
19048    function shouldUpdateAutoHeight(gallery, swiperInstance, forceUpdate) {
19049      if (forceUpdate) {
19050        return true;
19051      }
19052
19053      const activeSlide = swiperInstance && swiperInstance.slides && typeof swiperInstance.activeIndex === 'number'
19054        ? swiperInstance.slides[swiperInstance.activeIndex]
19055        : null;
19056
19057      // Keep the previous image height while an ad slide is active to avoid small page jumps.
19058      if (activeSlide && activeSlide.classList.contains('ad-slide')) {
19059        return false;
19060      }
19061
19062      const activeSlideHeight = getActiveSlideHeight(swiperInstance);
19063      if (activeSlideHeight <= 0) {
19064        return false;
19065      }
19066
19067      // Solange die initiale Hoehe aktiv ist, nur updaten wenn sie sichtbar nicht passt.
19068      if (gallery && gallery.__initialSlideHeightActive) {
19069        const initialHeight = getInitialSlideHeightPx(gallery);
19070        if (initialHeight <= 0) {
19071          return true;
19072        }
19073        return Math.abs(activeSlideHeight - initialHeight) > AUTO_HEIGHT_TOLERANCE_PX;
19074      }
19075
19076      const wrapperHeight = swiperInstance && swiperInstance.wrapperEl ? swiperInstance.wrapperEl.offsetHeight : 0;
19077      if (wrapperHeight <= 0) {
19078        return true;
19079      }
19080
19081      return Math.abs(activeSlideHeight - wrapperHeight) > AUTO_HEIGHT_TOLERANCE_PX;
19082    }
19083
19084    function refreshSwiperAutoHeight(swiperInstance, gallery, forceUpdate) {
19085      if (!swiperInstance || typeof swiperInstance.updateAutoHeight !== 'function') {
19086        return;
19087      }
19088
19089      if (!shouldUpdateAutoHeight(gallery, swiperInstance, !!forceUpdate)) {
19090        return;
19091      }
19092
19093      swiperInstance.updateAutoHeight();
19094
19095      // Zweiter Tick fuer sichere Hoehen-Neuberechnung nach Reflow/Render.
19096      if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
19097        window.requestAnimationFrame(function () {
19098          if (shouldUpdateAutoHeight(gallery, swiperInstance, !!forceUpdate)) {
19099            swiperInstance.updateAutoHeight();
19100          }
19101        });
19102      }
19103    }
19104
19105    // Optional data attributes:
19106    // - data-initial-slide-height
19107    // - data-slider-container-min-height
19108    // Numeric values are interpreted as px, missing/invalid/'auto' fall back to auto behavior.
19109    function getInitialSlideHeightPx(gallery) {
19110      if (!gallery || !gallery.dataset) {
19111        return DEFAULT_INITIAL_SLIDE_HEIGHT_PX;
19112      }
19113
19114      const fromData = parseInt(gallery.dataset.initialSlideHeight, 10);
19115      return Number.isFinite(fromData) && fromData > 0 ? fromData : DEFAULT_INITIAL_SLIDE_HEIGHT_PX;
19116    }
19117
19118    function isFullWidthGallery(gallery) {
19119      return !!(gallery && gallery.classList && gallery.classList.contains('MediaGalleryFullWidth'));
19120    }
19121
19122    function getSliderContainerMinHeightPx(gallery) {
19123      if (!gallery || !gallery.dataset) {
19124        return DEFAULT_SLIDER_CONTAINER_MIN_HEIGHT_PX;
19125      }
19126
19127      const fromData = parseInt(gallery.dataset.sliderContainerMinHeight, 10);
19128      if (Number.isFinite(fromData) && fromData > 0) {
19129        return fromData;
19130      }
19131
19132      if (isFullWidthGallery(gallery)) {
19133        return DEFAULT_FULLWIDTH_SLIDER_CONTAINER_MIN_HEIGHT_PX;
19134      }
19135
19136      const sliderEl = gallery.querySelector('.MediaGallery_slider');
19137      const sliderWidth = sliderEl ? sliderEl.clientWidth : 0;
19138
19139      if (sliderWidth > 0) {
19140        // Adaptive Untergrenze fuer eingebettete, schmale Galerien (z. B. Artikelspalte).
19141        const adaptiveHeight = Math.round(sliderWidth * 0.62);
19142        return Math.max(220, Math.min(DEFAULT_SLIDER_CONTAINER_MIN_HEIGHT_PX, adaptiveHeight));
19143      }
19144
19145      return DEFAULT_SLIDER_CONTAINER_MIN_HEIGHT_PX;
19146    }
19147
19148    function toMinHeightCssValue(heightPx) {
19149      return Number.isFinite(heightPx) && heightPx > 0 ? heightPx + 'px' : 'auto';
19150    }
19151
19152    function applyInitialSlideHeight(gallery) {
19153      if (!gallery) {
19154        return;
19155      }
19156
19157      const slider = gallery.querySelector('.MediaGallery_slider, .MediaGalleryFullWidth_slider');
19158      const wrapper = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
19159      const initialHeight = getInitialSlideHeightPx(gallery);
19160
19161      if (slider) {
19162        slider.style.minHeight = toMinHeightCssValue(initialHeight);
19163      }
19164
19165      if (wrapper) {
19166        wrapper.style.minHeight = toMinHeightCssValue(initialHeight);
19167      }
19168
19169      gallery.__initialSlideHeightActive = true;
19170    }
19171
19172    function clearInitialSlideHeightIfReady(gallery, swiperInstance) {
19173      if (!gallery || !gallery.__initialSlideHeightActive) {
19174        return;
19175      }
19176
19177      if (!swiperInstance || !swiperInstance.wrapperEl || swiperInstance.wrapperEl.offsetHeight <= 0) {
19178        return;
19179      }
19180
19181      const slider = gallery.querySelector('.MediaGallery_slider, .MediaGalleryFullWidth_slider');
19182      const wrapper = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
19183
19184      if (slider) {
19185        slider.style.minHeight = '0';
19186      }
19187
19188      if (wrapper) {
19189        wrapper.style.minHeight = toMinHeightCssValue(getSliderContainerMinHeightPx(gallery));
19190      }
19191
19192      gallery.__initialSlideHeightActive = false;
19193    }
19194
19195    function normalizeGallerySlideHeights(gallery) {
19196      if (!gallery) {
19197        return;
19198      }
19199
19200      const slider = gallery.querySelector('.MediaGallery_slider, .MediaGalleryFullWidth_slider');
19201      const wrapper = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
19202
19203      if (slider) {
19204        slider.style.height = 'auto';
19205        if (!gallery.__initialSlideHeightActive) {
19206          slider.style.minHeight = '0';
19207        }
19208      }
19209
19210      if (!wrapper) {
19211        return;
19212      }
19213
19214      wrapper.style.height = 'auto';
19215      if (!gallery.__initialSlideHeightActive) {
19216        wrapper.style.minHeight = toMinHeightCssValue(getSliderContainerMinHeightPx(gallery));
19217      }
19218
19219      Array.from(wrapper.children).forEach(function (slide) {
19220        slide.style.height = 'auto';
19221      });
19222    }
19223
19224    function bindImageLoadAutoHeight(gallery) {
19225      if (!gallery) {
19226        return;
19227      }
19228
19229      gallery.querySelectorAll('.MediaGallery_sliderImage img, .MediaGalleryFullWidth_sliderImage img').forEach(function (img) {
19230        if (img.complete) {
19231          return;
19232        }
19233
19234        img.addEventListener('load', function () {
19235          refreshSwiperAutoHeight(gallery.mSwiper, gallery);
19236          clearInitialSlideHeightIfReady(gallery, gallery.mSwiper);
19237          scheduleDescriptionThumbOverlapCheck(gallery);
19238        }, { once: true });
19239      });
19240    }
19241
19242    function refreshActiveAdSlot(gallery, activeSlide) {
19243      if (!gallery || !activeSlide || !activeSlide.classList.contains('ad-slide')) {
19244        return;
19245      }
19246
19247      traceThumbSync(gallery, 'refreshActiveAdSlot:start');
19248
19249      const adDiv = gallery.querySelector('.ad-container');
19250      if (!adDiv || !adDiv.children[0]) {
19251        debugAdLog('Interner Gallery-Slot nicht refreshbar (ad-container fehlt)', {
19252          galleryId: gallery.id || null,
19253        });
19254        return;
19255      }
19256
19257      if (adDiv.parentNode !== activeSlide) {
19258        activeSlide.appendChild(adDiv);
19259      }
19260
19261      centerAdIframes(adDiv, activeSlide);
19262
19263      const slots = googletag.pubads().getSlots();
19264      const slotElementId = adDiv.children[0].id;
19265      const currentSlot = slots.find(function (s) {
19266        return s.getSlotElementId() === slotElementId;
19267      });
19268
19269      if (!currentSlot) {
19270        debugAdLog('Interner Gallery-Slot nicht refreshbar (Slotobjekt fehlt)', {
19271          galleryId: gallery.id || null,
19272          slotElementId: slotElementId,
19273        });
19274        return;
19275      }
19276
19277      const activeSlotInfo = adSlots.get(slotElementId);
19278      if (activeSlotInfo) {
19279        activeSlotInfo.targetAdSlide = activeSlide;
19280        const refreshState = getOrCreateRefreshState(activeSlotInfo);
19281        const nowTs = Date.now();
19282        if (refreshState.lastHandledAdSlideElement === activeSlide && (nowTs - refreshState.lastHandledAdSlideTs) < AD_SLIDE_REENTRY_GUARD_MS) {
19283          traceThumbSync(gallery, 'refreshActiveAdSlot:dedup-skip', { slotElementId: slotElementId });
19284          return;
19285        }
19286        refreshState.lastHandledAdSlideElement = activeSlide;
19287        refreshState.lastHandledAdSlideTs = nowTs;
19288        refreshState.lastAdSlideActivationTs = nowTs;
19289        refreshState.fallbackRefreshDone = false;
19290        if (refreshState.activeSlideFallbackTimerId) {
19291          window.clearTimeout(refreshState.activeSlideFallbackTimerId);
19292          refreshState.activeSlideFallbackTimerId = null;
19293        }
19294
19295        maybeRefreshSlot(activeSlotInfo, 'slideChangeTransitionEnd').catch(function (err) {
19296          debugAdLog('Refresh bei aktivem Ad-Slide fehlgeschlagen', {
19297            adId: activeSlotInfo.adId,
19298            message: err && err.message ? err.message : String(err),
19299          });
19300        });
19301
19302        if (hasExplicitUserInteraction) {
19303          const activationTs = refreshState.lastAdSlideActivationTs;
19304          refreshState.activeSlideFallbackTimerId = window.setTimeout(function () {
19305            refreshState.activeSlideFallbackTimerId = null;
19306
19307            if (!hasExplicitUserInteraction || !activeSlide.isConnected || !activeSlide.classList.contains('swiper-slide-active')) {
19308              return;
19309            }
19310            if (activeSlotInfo.targetAdSlide !== activeSlide || refreshState.pending || refreshState.fallbackRefreshDone) {
19311              return;
19312            }
19313
19314            const iframe = adDiv.querySelector('iframe');
19315            const hasNoVisibleIframe = !iframe || iframe.offsetWidth < 10 || iframe.offsetHeight < 10;
19316            const noRefreshSinceActivation = refreshState.lastRefreshTs < activationTs;
19317            if (!hasNoVisibleIframe && !noRefreshSinceActivation) {
19318              return;
19319            }
19320
19321            refreshState.fallbackRefreshDone = true;
19322            maybeRefreshSlot(activeSlotInfo, 'activeSlideFallback', { ignoreInterval: true }).catch(function (err) {
19323              debugAdLog('Fallback-Refresh bei aktivem Ad-Slide fehlgeschlagen', {
19324                adId: activeSlotInfo.adId,
19325                message: err && err.message ? err.message : String(err),
19326              });
19327            });
19328          }, ACTIVE_AD_FALLBACK_RETRY_MS);
19329        }
19330      }
19331
19332      traceThumbSync(gallery, 'refreshActiveAdSlot:evaluated', { slotElementId: slotElementId });
19333    }
19334
19335    function maybeRefreshExternalSlotsByAdPos(gallery, mainSwiper) {
19336      if (!gallery || !mainSwiper || !mainSwiper.slides || typeof mainSwiper.activeIndex !== 'number') {
19337        return;
19338      }
19339
19340      const adPos = parseInt(gallery.dataset.adpos, 10);
19341      if (!adPos || adPos < 1) {
19342        return;
19343      }
19344
19345      const imageIndex = getImageIndexFromMainIndex(mainSwiper.slides, mainSwiper.activeIndex);
19346      if (imageIndex < 0) {
19347        return;
19348      }
19349
19350      const imageCount = imageIndex + 1;
19351      const stepCount = mainSwiper.activeIndex + 1;
19352      const triggerEvery = adPos + 1;
19353
19354      // Wenn der User zurueckblaettert, Trigger-Freigabe fuer bereits erreichte Positionen zuruecksetzen.
19355      const lastSeenStepCount = Number.isInteger(gallery.__lastExternalRefreshSeenStepCount)
19356        ? gallery.__lastExternalRefreshSeenStepCount
19357        : null;
19358      if (lastSeenStepCount !== null && stepCount < lastSeenStepCount) {
19359        gallery.__lastExternalRefreshTriggerStepCount = null;
19360      }
19361      gallery.__lastExternalRefreshSeenStepCount = stepCount;
19362
19363      if ((stepCount % triggerEvery) !== 0) {
19364        return;
19365      }
19366
19367      // Pro Slide-Position nur ein Trigger, bis wieder unter diese Position zurueckgeblaettert wurde.
19368      if (gallery.__lastExternalRefreshTriggerStepCount === stepCount) {
19369        return;
19370      }
19371
19372      const triggerMarker = stepCount + ':' + mainSwiper.activeIndex;
19373
19374      debugAdLog('Externer Refresh via adPos-Trigger', {
19375        galleryId: gallery.id || null,
19376        adPos: adPos,
19377        triggerEvery: triggerEvery,
19378        imageCount: imageCount,
19379        mainActiveIndex: mainSwiper.activeIndex,
19380      });
19381
19382      const refreshExecuted = refreshExternalGalleryRelatedSlots('adPosTransition', {
19383        galleryId: gallery.id || null,
19384        imageCount: imageCount,
19385        stepCount: stepCount,
19386        mainActiveIndex: mainSwiper.activeIndex,
19387        triggerEvery: triggerEvery,
19388        triggerMarker: triggerMarker,
19389      });
19390      if (refreshExecuted) {
19391        gallery.__lastExternalRefreshTriggerStepCount = stepCount;
19392      }
19393    }
19394
19395    function applySliderContainerMinHeight(gallery) {
19396      if (!gallery) {
19397        return;
19398      }
19399
19400      const wrapper = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
19401      if (!wrapper) {
19402        return;
19403      }
19404
19405      wrapper.style.minHeight = toMinHeightCssValue(getSliderContainerMinHeightPx(gallery));
19406    }
19407
19408    function forceThumbnailContainerFullWidth(gallery) {
19409      if (!gallery) {
19410        return;
19411      }
19412
19413      const thumbWrapper = gallery.querySelector('.MediaGallery_thumbnailContainer');
19414      if (!thumbWrapper) {
19415        return;
19416      }
19417
19418      // Override legacy theme offsets (left: ~45%) via inline styles.
19419      thumbWrapper.style.left = '0';
19420      thumbWrapper.style.width = '100%';
19421      thumbWrapper.style.maxWidth = '100%';
19422      thumbWrapper.style.position = 'relative';
19423    }
19424
19425    function getActiveDescriptionElement(gallery) {
19426      if (!gallery) {
19427        return null;
19428      }
19429
19430      return gallery.querySelector(
19431        '.MediaGallery_sliderImage.swiper-slide-active .MediaGallery_imageDescription, ' +
19432        '.MediaGalleryFullWidth_sliderImage.swiper-slide-active .MediaGallery_imageDescription, ' +
19433        '.MediaGallery_imageDescription'
19434      );
19435    }
19436
19437    function preventDescriptionThumbOverlap(gallery) {
19438      if (!gallery) {
19439        return;
19440      }
19441
19442      const thumbsEl = gallery.querySelector('.MediaGallery_thumbnails');
19443      if (!thumbsEl) {
19444        return;
19445      }
19446
19447      const descriptionEl = getActiveDescriptionElement(gallery);
19448      if (!descriptionEl) {
19449        thumbsEl.style.marginTop = '';
19450        return;
19451      }
19452
19453      // Erst resetten, damit wiederholte Messungen keine Offsets aufaddieren.
19454      thumbsEl.style.marginTop = '';
19455
19456      const descriptionRect = descriptionEl.getBoundingClientRect();
19457      const thumbsRect = thumbsEl.getBoundingClientRect();
19458      const overlapPx = Math.ceil(descriptionRect.bottom - thumbsRect.top);
19459
19460      if (overlapPx > 0) {
19461        // Kleiner Puffer, damit Border/Line-Height nicht am Thumb klebt.
19462        thumbsEl.style.marginTop = (overlapPx + 8) + 'px';
19463      }
19464    }
19465
19466    function scheduleDescriptionThumbOverlapCheck(gallery) {
19467      if (!gallery) {
19468        return;
19469      }
19470
19471      if (gallery.__descThumbOverlapRaf && typeof window !== 'undefined' && typeof window.cancelAnimationFrame === 'function') {
19472        window.cancelAnimationFrame(gallery.__descThumbOverlapRaf);
19473      }
19474
19475      if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
19476        gallery.__descThumbOverlapRaf = window.requestAnimationFrame(function () {
19477          preventDescriptionThumbOverlap(gallery);
19478          gallery.__descThumbOverlapRaf = null;
19479        });
19480        return;
19481      }
19482
19483      preventDescriptionThumbOverlap(gallery);
19484    }
19485
19486    function bindDescriptionThumbOverlapGuard(gallery) {
19487      if (!gallery || gallery.__descThumbOverlapResizeBound) {
19488        return;
19489      }
19490
19491      if (typeof window !== 'undefined') {
19492        window.addEventListener('resize', function () {
19493          scheduleDescriptionThumbOverlapCheck(gallery);
19494        });
19495      }
19496
19497      gallery.__descThumbOverlapResizeBound = true;
19498    }
19499
19500    function buildTrackingUrl(gallery, activeSlide, activeIndex) {
19501      const baseUrl = (gallery && gallery.dataset && gallery.dataset.url) || (window.location.pathname + window.location.search);
19502      const hashFromSlide = activeSlide && activeSlide.getAttribute('data-hash');
19503      const hash = hashFromSlide || ('slide-' + (activeIndex + 1));
19504      return baseUrl.split('#')[0] + '#' + hash;
19505    }
19506
19507    function safeTrackerCall(label, fn) {
19508      try {
19509        fn();
19510      } catch (err) {
19511        debugAdLog('Tracking-Fehler in ' + label, {
19512          message: err && err.message ? err.message : String(err),
19513        });
19514      }
19515    }
19516
19517    function triggerVirtualPageTracking(gallery, activeSlide, activeIndex) {
19518      if (!gallery || !activeSlide) {
19519        return;
19520      }
19521
19522      // Ads nicht als virtuelle Seiten tracken, um externe Tracker-Fehler zu vermeiden.
19523      if (activeSlide.classList.contains('ad-slide')) {
19524        return;
19525      }
19526
19527      const url = buildTrackingUrl(gallery, activeSlide, activeIndex);
19528      const gtitle = (gallery && gallery.dataset && gallery.dataset.title) || document.title || '';
19529      const galId = (gallery && gallery.id) || null;
19530
19531      if (typeof window.dfv_iom_rpl === 'function') {
19532        safeTrackerCall('window.dfv_iom_rpl', function () {
19533          window.dfv_iom_rpl();
19534        });
19535      } else if (typeof dfv_iom_rpl === 'function') {
19536        safeTrackerCall('dfv_iom_rpl', function () {
19537          dfv_iom_rpl();
19538        });
19539      }
19540
19541      if (typeof window.dfv_ga_vpageview === 'function') {
19542        safeTrackerCall('window.dfv_ga_vpageview', function () {
19543          window.dfv_ga_vpageview(url, gtitle);
19544        });
19545      }
19546
19547      if (typeof window.sp_track_virtual_page_view === 'function') {
19548        safeTrackerCall('window.sp_track_virtual_page_view', function () {
19549          window.sp_track_virtual_page_view(galId, url, gtitle);
19550        });
19551      }
19552
19553      debugAdLog('Virtual-Tracking ausgeloest', {
19554        galId: galId,
19555        url: url,
19556        title: gtitle,
19557        mainIndex: activeIndex,
19558        isAd: !!(activeSlide && activeSlide.classList.contains('ad-slide')),
19559      });
19560    }
19561
19562    const refreshEligibilityCache = new Map();
19563
19564    function getRegisteredSlotById(slotId) {
19565      const slots = googletag.pubads().getSlots();
19566      return slots.find(function (slot) {
19567        return slot.getSlotElementId() === slotId;
19568      }) || null;
19569    }
19570
19571    function getVisibleRatio(element) {
19572      if (!element || typeof element.getBoundingClientRect !== 'function') {
19573        return 0;
19574      }
19575      const rect = element.getBoundingClientRect();
19576      if (!rect.width || !rect.height) {
19577        return 0;
19578      }
19579
19580      const viewportWidth = window.innerWidth || document.documentElement.clientWidth || 0;
19581      const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
19582      if (!viewportWidth || !viewportHeight) {
19583        return 0;
19584      }
19585
19586      const intersectionWidth = Math.max(0, Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0));
19587      const intersectionHeight = Math.max(0, Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0));
19588      const intersectionArea = intersectionWidth * intersectionHeight;
19589      const area = rect.width * rect.height;
19590      return area > 0 ? (intersectionArea / area) : 0;
19591    }
19592
19593    function isSlotInViewport(slotInfo) {
19594      if (!slotInfo || !slotInfo.gallery) {
19595        return false;
19596      }
19597      const galleryRatio = getVisibleRatio(slotInfo.gallery);
19598      if (galleryRatio < SLOT_VIEWPORT_THRESHOLD) {
19599        return false;
19600      }
19601
19602      const adContainer = slotInfo.gallery.querySelector('.ad-container');
19603      if (!adContainer) {
19604        return false;
19605      }
19606
19607      return getVisibleRatio(adContainer) >= SLOT_VIEWPORT_THRESHOLD;
19608    }
19609
19610    function getExternalSlotViewportThreshold() {
19611      if (typeof window === 'undefined') {
19612        return EXTERNAL_SLOT_VIEWPORT_THRESHOLD;
19613      }
19614
19615      const raw = Number(window.__galleryExternalSlotViewportThreshold);
19616      if (!Number.isFinite(raw)) {
19617        return EXTERNAL_SLOT_VIEWPORT_THRESHOLD;
19618      }
19619
19620      return Math.max(0, Math.min(1, raw));
19621    }
19622
19623    function isExternalSlotInViewport(slotId) {
19624      if (!slotId) {
19625        return false;
19626      }
19627
19628      const slotElement = document.getElementById(slotId);
19629      if (!slotElement) {
19630        return false;
19631      }
19632
19633      const visibleRatio = getVisibleRatio(slotElement);
19634      const threshold = getExternalSlotViewportThreshold();
19635      return visibleRatio >= threshold;
19636    }
19637
19638    function isExternalSlotRefreshEligible(slotId) {
19639      if (!slotId || typeof window === 'undefined') {
19640        return false;
19641      }
19642
19643      const eligibilityMap = window.__galleryAdRefreshEligibilityByAdUnitId;
19644      if (!eligibilityMap || typeof eligibilityMap !== 'object') {
19645        return false;
19646      }
19647
19648      const slotName = slotId.replace(/^renderSlot_/, '');
19649      const candidates = [slotName, slotId];
19650      for (let i = 0; i < candidates.length; i++) {
19651        const key = candidates[i];
19652        if (Object.prototype.hasOwnProperty.call(eligibilityMap, key)) {
19653          return eligibilityMap[key] === true;
19654        }
19655      }
19656
19657      return false;
19658    }
19659
19660    function getOrCreateRefreshState(slotInfo) {
19661      if (!slotInfo.refreshState) {
19662        slotInfo.refreshState = {
19663          renderedLineItemId: null,
19664          previousRenderedLineItemId: null,
19665          viewableSinceTs: 0,
19666          lastRefreshTs: Date.now(),
19667          pending: false,
19668          lastRefreshReason: null,
19669          refreshCount: 0,
19670          lastAdSlideActivationTs: 0,
19671          fallbackRefreshDone: false,
19672          activeSlideFallbackTimerId: null,
19673          lastHandledAdSlideElement: null,
19674          lastHandledAdSlideTs: 0,
19675        };
19676      }
19677      return slotInfo.refreshState;
19678    }
19679
19680    function resolveEligibilityFromAdData(slotInfo) {
19681      if (!slotInfo || !slotInfo.adData) {
19682        return null;
19683      }
19684
19685      if (typeof slotInfo.adData.refreshEligible === 'boolean') {
19686        return slotInfo.adData.refreshEligible;
19687      }
19688
19689      if (typeof slotInfo.adData.lineItemCount === 'number') {
19690        return slotInfo.adData.lineItemCount > 1;
19691      }
19692
19693      return null;
19694    }
19695
19696    function resolveEligibilityFromWindow(path, adUnitId) {
19697      if (typeof window === 'undefined') {
19698        return null;
19699      }
19700
19701      if (adUnitId && window.__galleryAdRefreshEligibilityByAdUnitId && typeof window.__galleryAdRefreshEligibilityByAdUnitId === 'object') {
19702        const mappedByAdUnit = window.__galleryAdRefreshEligibilityByAdUnitId[String(adUnitId)];
19703        if (typeof mappedByAdUnit === 'boolean') {
19704          return mappedByAdUnit;
19705        }
19706      }
19707
19708      if (!path) {
19709        return null;
19710      }
19711
19712      const rawMap = window.__galleryAdRefreshEligibilityByPath;
19713      if (!rawMap || typeof rawMap !== 'object') {
19714        return null;
19715      }
19716
19717      const value = rawMap[path];
19718      if (typeof value === 'boolean') {
19719        return value;
19720      }
19721      if (value && typeof value === 'object' && typeof value.refreshEligible === 'boolean') {
19722        return value.refreshEligible;
19723      }
19724
19725      return null;
19726    }
19727
19728    async function resolveSlotRefreshEligibility(slotInfo, slotObj) {
19729      const slotPath = slotObj && typeof slotObj.getAdUnitPath === 'function' ? slotObj.getAdUnitPath() : null;
19730      if (!slotPath) {
19731        return false;
19732      }
19733
19734      const nowTs = Date.now();
19735      const cached = refreshEligibilityCache.get(slotPath);
19736      if (cached && (nowTs - cached.ts) <= refreshRuntimeConfig.eligibilityCacheTtlMs) {
19737        return cached.value;
19738      }
19739
19740      let eligible = resolveEligibilityFromAdData(slotInfo);
19741      const slotAdUnitId = slotInfo && slotInfo.adData ? String(slotInfo.adData.adUnitId || '') : '';
19742      if (eligible === null) {
19743        eligible = resolveEligibilityFromWindow(slotPath, slotAdUnitId);
19744      }
19745
19746      if (eligible === null && typeof window !== 'undefined' && typeof window.__galleryAdRefreshEligibilityProvider === 'function') {
19747        try {
19748          const providerResult = await window.__galleryAdRefreshEligibilityProvider(slotPath);
19749          if (typeof providerResult === 'boolean') {
19750            eligible = providerResult;
19751          } else if (providerResult && typeof providerResult === 'object' && typeof providerResult.refreshEligible === 'boolean') {
19752            eligible = providerResult.refreshEligible;
19753          }
19754        } catch (err) {
19755          debugAdLog('Eligibility-Provider Fehler', {
19756            slotPath: slotPath,
19757            message: err && err.message ? err.message : String(err),
19758          });
19759        }
19760      }
19761
19762      if (eligible === null) {
19763        // Falls keine Datenquelle vorhanden ist, defensiv keinen Refresh ausfuehren.
19764        eligible = false;
19765      }
19766
19767      refreshEligibilityCache.set(slotPath, { value: !!eligible, ts: nowTs });
19768      return !!eligible;
19769    }
19770
19771    async function maybeRefreshSlot(slotInfo, reason, options) {
19772      if (!slotInfo || !slotInfo.injected) {
19773        return;
19774      }
19775
19776      // Legacy-Verhalten: Gallery-Slot nur beim Wechsel auf einen Ad-Slide refreshen.
19777      if (reason !== 'slideChangeTransitionEnd' && reason !== 'activeSlideFallback') {
19778        return;
19779      }
19780
19781      const refreshOptions = options || {};
19782      const refreshState = getOrCreateRefreshState(slotInfo);
19783      if (refreshState.pending) {
19784        return;
19785      }
19786
19787      const nowTs = Date.now();
19788      const ignoreInterval = !!refreshOptions.ignoreInterval;
19789      const intervalNotReached = (nowTs - refreshState.lastRefreshTs) < refreshRuntimeConfig.refreshIntervalMs;
19790      const canBypassInitialDelay = refreshState.refreshCount === 0 && hasExplicitUserInteraction;
19791      if (!ignoreInterval && intervalNotReached && !canBypassInitialDelay) {
19792        return;
19793      }
19794
19795      const slotObj = getRegisteredSlotById(slotInfo.adId);
19796      if (!slotObj) {
19797        return;
19798      }
19799
19800      refreshState.pending = true;
19801      refreshState.lastRefreshReason = reason;
19802      refreshState.lastRefreshTs = nowTs;
19803      refreshState.refreshCount += 1;
19804
19805      googletag.pubads().refresh([slotObj]);
19806      debugAdLog('Slot-Refresh ausgeloest', {
19807        adId: slotInfo.adId,
19808        reason: refreshState.lastRefreshReason,
19809        slotPath: typeof slotObj.getAdUnitPath === 'function' ? slotObj.getAdUnitPath() : null,
19810      });
19811    }
19812
19813    function evaluateAllSlotRefreshes(reason) {
19814      adSlots.forEach(function (slotInfo) {
19815        maybeRefreshSlot(slotInfo, reason).catch(function (err) {
19816          debugAdLog('Refresh-Pruefung fehlgeschlagen', {
19817            adId: slotInfo && slotInfo.adId ? slotInfo.adId : null,
19818            reason: reason,
19819            message: err && err.message ? err.message : String(err),
19820          });
19821        });
19822      });
19823    }
19824
19825    function refreshExternalGalleryRelatedSlots(reason, meta) {
19826      // Billboard/Skyscraper-Refreshes nur auf Gallerydetail-Seiten
19827      if (!hasGalleryBodyClass) {
19828        return false;
19829      }
19830
19831      const nowTs = Date.now();
19832      const elapsedSinceLastRefreshMs = nowTs - lastExternalRefreshTs;
19833      const isAdPosTransition = reason === 'adPosTransition';
19834      const canBypassInitialDelay = externalRefreshCount === 0 && hasExplicitUserInteraction;
19835      if (!isAdPosTransition && !canBypassInitialDelay && elapsedSinceLastRefreshMs < refreshRuntimeConfig.refreshIntervalMs) {
19836        debugAdLog('Externer Slot-Refresh wegen Initial-Intervall gesperrt', {
19837          reason: reason || null,
19838          elapsedSinceLastRefreshMs: elapsedSinceLastRefreshMs,
19839          minIntervalMs: refreshRuntimeConfig.refreshIntervalMs,
19840          externalRefreshCount: externalRefreshCount,
19841          hasExplicitUserInteraction: hasExplicitUserInteraction,
19842        });
19843        return false;
19844      }
19845
19846      const shouldApplyCooldown = reason !== 'adPosTransition';
19847      const forceNewCorrelator = typeof window !== 'undefined' && !!window.__galleryExternalRefreshForceNewCorrelator;
19848      if (shouldApplyCooldown && (nowTs - lastExternalRefreshTs) < EXTERNAL_REFRESH_COOLDOWN_MS) {
19849        debugAdLog('Externer Slot-Refresh wegen Cooldown uebersprungen', {
19850          reason: reason || null,
19851          cooldownMs: EXTERNAL_REFRESH_COOLDOWN_MS,
19852        });
19853        return false;
19854      }
19855
19856      if (typeof window === 'undefined' || typeof window.refreshAdSlot !== 'function') {
19857        debugAdLog('Externer Slot-Refresh nicht verfuegbar', {
19858          reason: reason || null,
19859          hasWindow: typeof window !== 'undefined',
19860          hasRefreshFn: typeof window !== 'undefined' && typeof window.refreshAdSlot === 'function',
19861        });
19862        return false;
19863      }
19864
19865      const attempted = [];
19866      let refreshedCount = 0;
19867      EXTERNAL_REFRESH_SLOT_IDS.forEach(function (slotId) {
19868        const slotObj = window.gamSlots && window.gamSlots[slotId] ? window.gamSlots[slotId] : null;
19869        const eligibilityAllowed = isExternalSlotRefreshEligible(slotId);
19870        const canRefresh = !!(slotObj && slotObj.allowRefresh && eligibilityAllowed);
19871         const inViewport = canRefresh ? isExternalSlotInViewport(slotId) : false;
19872         const visibleRatio = canRefresh ? getVisibleRatio(document.getElementById(slotId)) : 0;
19873
19874         attempted.push({
19875           slotId: slotId,
19876           hasSlot: !!slotObj,
19877           refreshEligible: eligibilityAllowed,
19878           allowRefresh: canRefresh,
19879           inViewport: inViewport,
19880           visibleRatio: Number(visibleRatio.toFixed(3)),
19881         });
19882
19883         if (!canRefresh || !inViewport) {
19884           if (!eligibilityAllowed) {
19885             pushExternalSlotHistory(slotId, 'refreshSkippedEligibilityFalse', {
19886               reason: reason || null,
19887               meta: meta || null,
19888             });
19889           } else if (canRefresh && !inViewport) {
19890             pushExternalSlotHistory(slotId, 'refreshSkippedNotInViewport', {
19891               reason: reason || null,
19892               visibleRatio: Number(visibleRatio.toFixed(3)),
19893               threshold: getExternalSlotViewportThreshold(),
19894               meta: meta || null,
19895             });
19896           }
19897           return;
19898         }
19899
19900         if (forceNewCorrelator && typeof googletag !== 'undefined' && googletag.pubads && typeof googletag.pubads === 'function') {
19901           googletag.pubads().refresh([slotObj], { changeCorrelator: true });
19902         } else {
19903           window.refreshAdSlot(slotId);
19904         }
19905         incrementExternalSlotStat(slotId, 'refreshCallTriggered');
19906         flashExternalSlotDebugMarker(slotId, 'request');
19907         pushExternalSlotHistory(slotId, 'refreshCallTriggered', {
19908           reason: reason || null,
19909           forceNewCorrelator: forceNewCorrelator,
19910           meta: meta || null,
19911         });
19912         refreshedCount += 1;
19913       });
19914
19915       if (refreshedCount < 1) {
19916         debugAdLog('Externer Slot-Refresh ohne refreshbare Slots uebersprungen', {
19917           reason: reason || null,
19918           attempted: attempted,
19919         });
19920         return false;
19921       }
19922
19923       lastExternalRefreshTs = nowTs;
19924       externalRefreshCount += 1;
19925       debugAdLog('Externer Slot-Refresh ausgefuehrt', {
19926         reason: reason || null,
19927         forceNewCorrelator: forceNewCorrelator,
19928         refreshedCount: refreshedCount,
19929         attempted: attempted,
19930       });
19931       return true;
19932     }
19933
19934     function maybeRefreshExternalSlotsByInterval() {
19935       const nowTs = Date.now();
19936       const elapsedSinceLastRefreshMs = nowTs - lastExternalRefreshTs;
19937
19938       if (elapsedSinceLastRefreshMs < refreshRuntimeConfig.refreshIntervalMs) {
19939         return;
19940       }
19941
19942       if (!isDocumentVisible()) {
19943         debugAdLog('Externer Intervall-Refresh ausgesetzt (Dokument nicht sichtbar)', {
19944           elapsedSinceLastRefreshMs: elapsedSinceLastRefreshMs,
19945           minIntervalMs: refreshRuntimeConfig.refreshIntervalMs,
19946         });
19947         return;
19948       }
19949
19950       if (!isUserRecentlyActive()) {
19951         debugAdLog('Externer Intervall-Refresh ausgesetzt (Nutzer inaktiv)', {
19952           elapsedSinceLastRefreshMs: elapsedSinceLastRefreshMs,
19953           minIntervalMs: refreshRuntimeConfig.refreshIntervalMs,
19954           userIdleTimeoutMs: refreshRuntimeConfig.userIdleTimeoutMs,
19955           inactiveForMs: nowTs - lastUserActivityTs,
19956         });
19957         return;
19958       }
19959
19960       refreshExternalGalleryRelatedSlots('autoInterval', {
19961         elapsedSinceLastRefreshMs: elapsedSinceLastRefreshMs,
19962         minIntervalMs: refreshRuntimeConfig.refreshIntervalMs,
19963       });
19964     }
19965
19966     function isExternalGalleryRelatedSlotId(slotId) {
19967       return EXTERNAL_REFRESH_SLOT_IDS.indexOf(slotId) !== -1;
19968     }
19969
19970     function logExternalSlotEvent(eventName, event) {
19971       if (!event || !event.slot || typeof event.slot.getSlotElementId !== 'function') {
19972         return;
19973       }
19974
19975       const slotId = event.slot.getSlotElementId();
19976       if (!isExternalGalleryRelatedSlotId(slotId)) {
19977         return;
19978       }
19979
19980       debugAdLog(eventName + ' (External)', {
19981         slotId: slotId,
19982         path: typeof event.slot.getAdUnitPath === 'function' ? event.slot.getAdUnitPath() : null,
19983         isEmpty: typeof event.isEmpty === 'boolean' ? event.isEmpty : null,
19984         size: event.size || null,
19985         lineItemId: typeof event.lineItemId === 'number' ? event.lineItemId : null,
19986         creativeId: typeof event.creativeId === 'number' ? event.creativeId : null,
19987       });
19988
19989       if (eventName === 'slotRequested') {
19990         incrementExternalSlotStat(slotId, 'slotRequested');
19991         pushExternalSlotHistory(slotId, 'slotRequested', {
19992           path: typeof event.slot.getAdUnitPath === 'function' ? event.slot.getAdUnitPath() : null,
19993         });
19994       } else if (eventName === 'slotResponseReceived') {
19995         incrementExternalSlotStat(slotId, 'slotResponseReceived');
19996         pushExternalSlotHistory(slotId, 'slotResponseReceived', {
19997           path: typeof event.slot.getAdUnitPath === 'function' ? event.slot.getAdUnitPath() : null,
19998         });
19999       } else if (eventName === 'slotRenderEnded') {
20000         incrementExternalSlotStat(slotId, 'slotRenderEnded');
20001         flashExternalSlotDebugMarker(slotId, 'render');
20002         const slotStats = ensureExternalSlotStats(slotId);
20003         slotStats.lastRenderLineItemId = typeof event.lineItemId === 'number' ? event.lineItemId : null;
20004         slotStats.lastRenderCreativeId = typeof event.creativeId === 'number' ? event.creativeId : null;
20005         slotStats.lastRenderTs = new Date().toISOString();
20006         pushExternalSlotHistory(slotId, 'slotRenderEnded', {
20007           isEmpty: typeof event.isEmpty === 'boolean' ? event.isEmpty : null,
20008           size: event.size || null,
20009           lineItemId: typeof event.lineItemId === 'number' ? event.lineItemId : null,
20010           creativeId: typeof event.creativeId === 'number' ? event.creativeId : null,
20011         });
20012       }
20013     }
20014
20015     googletag.pubads().addEventListener('slotRenderEnded', function(event) {
20016       const slotId = event.slot.getSlotElementId();
20017       const slotInfo = adSlots.get(slotId);
20018       if (!slotInfo) {
20019         logExternalSlotEvent('slotRenderEnded', event);
20020         return;
20021       }
20022
20023       debugAdLog('slotRenderEnded empfangen', {
20024         slotId: slotId,
20025         isEmpty: !!event.isEmpty,
20026         size: event.size || null,
20027         lineItemId: typeof event.lineItemId === 'number' ? event.lineItemId : null,
20028         creativeId: typeof event.creativeId === 'number' ? event.creativeId : null,
20029       });
20030
20031       const gallery = slotInfo.gallery;
20032       const refreshState = getOrCreateRefreshState(slotInfo);
20033       refreshState.pending = false;
20034       if (refreshState.activeSlideFallbackTimerId) {
20035         window.clearTimeout(refreshState.activeSlideFallbackTimerId);
20036         refreshState.activeSlideFallbackTimerId = null;
20037       }
20038       refreshState.previousRenderedLineItemId = refreshState.renderedLineItemId;
20039       refreshState.renderedLineItemId = typeof event.lineItemId === 'number' ? String(event.lineItemId) : null;
20040       if (!gallery) {
20041         return;
20042       }
20043
20044       if (event.isEmpty) {
20045         if (!slotInfo.injected) {
20046           debugAdLog('Leerer Initial-Slot, Ad-Markup wird nicht eingefuegt', {
20047             adId: slotInfo.adId,
20048             galleryId: gallery.id || null,
20049           });
20050         } else {
20051           debugAdLog('Leerer Refresh-Slot, Ad-Markup bleibt erhalten', {
20052             adId: slotInfo.adId,
20053             galleryId: gallery.id || null,
20054           });
20055         }
20056         if (gallery.mSwiper && typeof gallery.mSwiper.update === 'function') {
20057           gallery.mSwiper.update();
20058         }
20059         if (gallery.tSwiper && typeof gallery.tSwiper.update === 'function') {
20060           gallery.tSwiper.update();
20061         }
20062         scheduleDescriptionThumbOverlapCheck(gallery);
20063         return;
20064       }
20065
20066       let hasInjectedAdMarkup = false;
20067       if (!slotInfo.injected) {
20068         injectAdMarkup(slotInfo);
20069         slotInfo.injected = true;
20070         hasInjectedAdMarkup = true;
20071       }
20072
20073       normalizeGallerySlideHeights(gallery);
20074
20075       const adContainer = gallery.querySelector('#renderSlot-' + slotId);
20076       const targetAdSlide = slotInfo.targetAdSlide && slotInfo.targetAdSlide.isConnected
20077         ? slotInfo.targetAdSlide
20078         : slotInfo.mainWrapper.querySelector('.ad-slide');
20079
20080       if (adContainer && targetAdSlide && adContainer.parentNode !== targetAdSlide) {
20081         targetAdSlide.appendChild(adContainer);
20082         debugAdLog('Ad-Container in aktiven Ad-Slide verschoben', {
20083           adId: slotInfo.adId,
20084           galleryId: gallery.id || null,
20085         });
20086       }
20087
20088       centerAdIframes(adContainer, targetAdSlide);
20089
20090       if (isSlotInViewport(slotInfo) && !refreshState.viewableSinceTs) {
20091         refreshState.viewableSinceTs = Date.now();
20092       }
20093
20094       refreshSwiperAutoHeight(gallery.mSwiper, gallery);
20095
20096       if (hasInjectedAdMarkup && gallery.mSwiper && typeof gallery.mSwiper.update === 'function') {
20097         gallery.mSwiper.update();
20098       }
20099       if (hasInjectedAdMarkup && gallery.tSwiper && typeof gallery.tSwiper.update === 'function') {
20100         gallery.tSwiper.update();
20101       }
20102
20103       syncThumbStateWithMainSwiper(gallery);
20104       traceThumbSync(gallery, 'slotRenderEnded:after-sync', { slotId: slotId, isEmpty: !!event.isEmpty });
20105       scheduleDescriptionThumbOverlapCheck(gallery);
20106       evaluateAllSlotRefreshes('slotRenderEnded');
20107     });
20108
20109     googletag.pubads().addEventListener('slotRequested', function (event) {
20110       const slotId = event.slot.getSlotElementId();
20111       if (!adSlots.has(slotId)) {
20112         logExternalSlotEvent('slotRequested', event);
20113         return;
20114       }
20115
20116       debugAdLog('slotRequested (Gallery)', {
20117         slotId: slotId,
20118         path: typeof event.slot.getAdUnitPath === 'function' ? event.slot.getAdUnitPath() : null,
20119         slotTargetingFromCode: getStoredSlotTargetingSnapshot(event.slot),
20120         slotTargetingFromGpt: getSlotTargetingSnapshot(event.slot),
20121         pageTargeting: getPageTargetingSnapshot(),
20122       });
20123     });
20124
20125     googletag.pubads().addEventListener('slotResponseReceived', function (event) {
20126       const slotId = event.slot.getSlotElementId();
20127       if (!adSlots.has(slotId)) {
20128         logExternalSlotEvent('slotResponseReceived', event);
20129         return;
20130       }
20131
20132       debugAdLog('slotResponseReceived (Gallery)', {
20133         slotId: slotId,
20134         path: typeof event.slot.getAdUnitPath === 'function' ? event.slot.getAdUnitPath() : null,
20135       });
20136     });
20137
20138     googletag.pubads().addEventListener('impressionViewable', function (event) {
20139       const slotId = event.slot.getSlotElementId();
20140       const slotInfo = adSlots.get(slotId);
20141       if (!slotInfo) {
20142         return;
20143       }
20144
20145       const refreshState = getOrCreateRefreshState(slotInfo);
20146       if (!refreshState.viewableSinceTs) {
20147         refreshState.viewableSinceTs = Date.now();
20148       }
20149
20150       debugAdLog('impressionViewable empfangen', {
20151         slotId: slotId,
20152       });
20153
20154       evaluateAllSlotRefreshes('impressionViewable');
20155     });
20156
20157     galleries.forEach((gallery, wIndex) => {
20158       debugAdLog('Gallery-Ad-Konfiguration erkannt', getGalleryAdDatasetSnapshot(gallery));
20159
20160       const adPos = parseInt(gallery.dataset.adpos, 10);
20161       let adData = {};
20162
20163       if (!adPos || adPos < 1) {
20164         debugAdLog('Gallery ohne gueltige adPos uebersprungen', {
20165           galleryId: gallery.id || null,
20166           adPos: gallery.dataset.adpos,
20167         });
20168         return;
20169       }
20170
20171       try {
20172         adData = JSON.parse(gallery.dataset.ad_gam_id);
20173       } catch (e) {
20174         debugAdLog('Gallery mit ungueltiger ad_gam_id uebersprungen', {
20175           galleryId: gallery.id || null,
20176         });
20177         return;
20178       }
20179       if(!adData.path || !adData.sizes || adData.path.length < 1){
20180         debugAdLog('Gallery ohne vollstaendige Ad-Daten uebersprungen', {
20181           galleryId: gallery.id || null,
20182         });
20183         return;
20184       }
20185
20186
20187       const adId = `ad-id-${wIndex}`;
20188
20189       const mainWrapper = gallery.querySelector('.MediaGallery_sliderContainer, .MediaGalleryFullWidth_sliderContainer');
20190       if (!mainWrapper) {
20191         debugAdLog('Gallery ohne Slider-Container uebersprungen', {
20192           galleryId: gallery.id || null,
20193         });
20194         return;
20195       }
20196
20197       if (Math.floor(mainWrapper.children.length / adPos) < 1) {
20198         debugAdLog('Gallery hat zu wenige Slides fuer Ad-Position', {
20199           galleryId: gallery.id || null,
20200           slideCount: mainWrapper.children.length,
20201           adPos: adPos,
20202         });
20203         return;
20204       }
20205
20206       adIds.push(adId);
20207       const definedSlot = googletag.defineSlot(adData.path, adData.sizes, adId);
20208       if (!definedSlot) {
20209         debugAdLog('defineSlot lieferte kein Slot-Objekt, Gallery-Ad wird uebersprungen', {
20210           adId: adId,
20211           galleryId: gallery.id || null,
20212           path: adData.path || null,
20213           sizes: adData.sizes || null,
20214         });
20215         adIds.pop();
20216         return;
20217       }
20218
20219       const slotObj = definedSlot.addService(googletag.pubads());
20220       applySlotTargeting(slotObj, adData);
20221       mirrorPageTargetingToSlot(slotObj);
20222       applyGalleryDatasetTargeting(slotObj, gallery);
20223
20224       const mainThumbWrapper = gallery.querySelector('.MediaGallery_thumbnailContainer');
20225
20226       const staging = document.createElement('div');
20227       // GPT/Creatives koennen in display:none sporadisch nicht sauber initialisieren.
20228       // Deshalb offscreen parken statt komplett aus dem Render-Tree zu nehmen.
20229       staging.style.position = 'absolute';
20230       staging.style.left = '-10000px';
20231       staging.style.top = '0';
20232       staging.style.width = '1px';
20233       staging.style.height = '1px';
20234       staging.style.overflow = 'hidden';
20235       staging.style.pointerEvents = 'none';
20236       staging.innerHTML = `<div class="ad-container Ad" id="renderSlot-${adId}"><div id="${adId}"></div></div>`;
20237       gallery.appendChild(staging);
20238
20239       adSlots.set(adId, {
20240         adId: adId,
20241         gallery: gallery,
20242         adData: adData,
20243         mainWrapper: mainWrapper,
20244         mainThumbWrapper: mainThumbWrapper,
20245         adPos: adPos,
20246         staging: staging,
20247         injected: false,
20248         targetAdSlide: null,
20249         refreshState: {
20250           renderedLineItemId: null,
20251           previousRenderedLineItemId: null,
20252           viewableSinceTs: 0,
20253           lastRefreshTs: Date.now(),
20254           pending: false,
20255           lastRefreshReason: null,
20256           refreshCount: 0,
20257           lastAdSlideActivationTs: 0,
20258           fallbackRefreshDone: false,
20259           activeSlideFallbackTimerId: null,
20260           lastHandledAdSlideElement: null,
20261           lastHandledAdSlideTs: 0,
20262         },
20263       });
20264
20265       debugAdLog('Ad-Slot fuer Gallery registriert', {
20266         adId: adId,
20267         galleryId: gallery.id || null,
20268         adPos: adPos,
20269         slotTargetingFromCode: getStoredSlotTargetingSnapshot(slotObj),
20270         pageTargetingAtRegister: getPageTargetingSnapshot(),
20271       });
20272     });
20273
20274     function displayGallerySlots(waitAttempt) {
20275       const attempt = typeof waitAttempt === 'number' ? waitAttempt : 0;
20276       if (displayGallerySlots.executed) {
20277         return;
20278       }
20279
20280       if (!hasAllRequiredPageTargeting(REQUIRED_PAGE_TARGETING_KEYS) && attempt < MAX_DISPLAY_WAIT_ATTEMPTS) {
20281         debugAdLog('Display wartet auf required page-targeting', {
20282           attempt: attempt,
20283           maxAttempts: MAX_DISPLAY_WAIT_ATTEMPTS,
20284           requiredKeys: REQUIRED_PAGE_TARGETING_KEYS,
20285           pageTargetingNow: getPageTargetingSnapshot(),
20286         });
20287         window.setTimeout(function () {
20288           displayGallerySlots(attempt + 1);
20289         }
20289, DISPLAY_WAIT_INTERVAL_MS);
20290         return;
20291       }
20292
20293       if (!hasAllRequiredPageTargeting(REQUIRED_PAGE_TARGETING_KEYS) && attempt >= MAX_DISPLAY_WAIT_ATTEMPTS) {
20294         debugAdLog('Display-Fallback ohne vollstaendiges page-targeting', {
20295           attempts: attempt,
20296           requiredKeys: REQUIRED_PAGE_TARGETING_KEYS,
20297           pageTargetingNow: getPageTargetingSnapshot(),
20298         });
20299       }
20300
20301       displayGallerySlots.executed = true;
20302       adIds.forEach(function (id) {
20303         const slots = googletag.pubads().getSlots();
20304         const slot = slots.find(function (s) {
20305           return s.getSlotElementId() === id;
20306         });
20307
20308         if (slot) {
20309           mirrorPageTargetingToSlot(slot);
20310         }
20311
20312         debugAdLog('display() wird aufgerufen', {
20313           adId: id,
20314           hasSlotObject: !!slot,
20315           path: slot && typeof slot.getAdUnitPath === 'function' ? slot.getAdUnitPath() : null,
20316           slotTargetingFromCode: slot ? getStoredSlotTargetingSnapshot(slot) : {},
20317           pageTargetingBeforeDisplay: getPageTargetingSnapshot(),
20318         });
20319
20320         googletag.display(id);
20321
20322         debugAdLog('display() aufgerufen', {
20323           adId: id,
20324         });
20325       });
20326       debugAdLog('Gallery-Slots wurden ausgeloest', { count: adIds.length });
20327     }
20328
20329     if (typeof window !== 'undefined') {
20330       window.__galleryDebugDump = function () {
20331         const slotStates = [];
20332         adSlots.forEach(function (slotInfo, adId) {
20333           slotStates.push({
20334             adId: adId,
20335             injected: !!slotInfo.injected,
20336             hasTargetSlide: !!slotInfo.targetAdSlide,
20337             hasStaging: !!slotInfo.staging,
20338             adPos: slotInfo.adPos,
20339           });
20340         });
20341
20342         debugAdLog('Debug-Dump', {
20343           adIds: adIds.slice(),
20344           slotStates: slotStates,
20345           pubadsReady: !!googletag.pubadsReady,
20346           registeredSlots: googletag.pubads().getSlots().map(function (s) {
20347             return s.getSlotElementId();
20348           }),
20349         });
20350       };
20351
20352       window.__galleryDebugRefresh = function () {
20353         const refreshed = [];
20354         const slots = googletag.pubads().getSlots();
20355
20356         adIds.forEach(function (adId) {
20357           const slot = slots.find(function (s) {
20358             return s.getSlotElementId() === adId;
20359           });
20360           if (slot) {
20361             googletag.pubads().refresh([slot]);
20362             refreshed.push(adId);
20363           }
20364         });
20365
20366         debugAdLog('Debug-Refresh ausgefuehrt', {
20367           refreshedSlots: refreshed,
20368           requestedSlots: adIds.slice(),
20369         });
20370       };
20371
20372       window.__galleryDebugTargetingDump = function () {
20373         const slots = googletag.pubads().getSlots();
20374
20375         adIds.forEach(function (adId) {
20376           const slot = slots.find(function (s) {
20377             return s.getSlotElementId() === adId;
20378           });
20379
20380           if (!slot) {
20381             debugAdLog('Targeting-Dump: Slot nicht gefunden', { adId: adId });
20382             return;
20383           }
20384
20385           const targeting = getSlotTargetingSnapshot(slot);
20386           const keys = Object.keys(targeting);
20387
20388           debugAdLog('Targeting-Dump', {
20389             adId: adId,
20390             keys: keys,
20391             targeting: targeting,
20392           });
20393         });
20394       };
20395
20396       window.__galleryDebugExternalStats = function () {
20397         const snapshot = JSON.parse(JSON.stringify(externalSlotDebugStats));
20398         debugAdLog('External-Slot-Debug-Stats', snapshot);
20399         return snapshot;
20400       };
20401     }
20402
20403     if (googletag.pubadsReady) {
20404       debugAdLog('pubads bereits aktiv, display direkt', {});
20405       displayGallerySlots(0);
20406     } else if (document.readyState === 'loading') {
20407       document.addEventListener('DOMContentLoaded', function () {
20408         googletag.cmd.push(function () {
20409           debugAdLog('display nach DOMContentLoaded ausgefuehrt', {});
20410           displayGallerySlots(0);
20411         });
20412       }, { once: true });
20413     } else {
20414       googletag.cmd.push(function () {
20415         debugAdLog('display nach spaeterem GPT-Init ausgefuehrt', {});
20416         displayGallerySlots(0);
20417       });
20418     }
20419
20420     if (typeof window !== 'undefined' && adSlots.size > 0) {
20421       window.setInterval(function () {
20422         evaluateAllSlotRefreshes('interval');
20423         maybeRefreshExternalSlotsByInterval();
20424       }, refreshRuntimeConfig.refreshCheckIntervalMs);
20425     }
20426
20427
20428     galleries.forEach(function (gallery) {
20429       const thumbnailsEl = gallery.querySelector('.MediaGallery_thumbnails');
20430       const sliderEl = gallery.querySelector('.MediaGallery_slider, .MediaGalleryFullWidth_slider');
20431       const paginationEl = gallery.querySelector('.swiper-pagination');
20432
20433       forceThumbnailContainerFullWidth(gallery);
20434       bindDescriptionThumbOverlapGuard(gallery);
20435
20436       if (paginationEl) {
20437         paginationEl.style.display = 'none';
20438       }
20439
20440       if (!sliderEl) {
20441         return;
20442       }
20443
20444       if (thumbnailsEl) {
20445         gallery.tSwiper = new Swiper(thumbnailsEl, {
20446           slidesPerView: 'auto',
20447           centeredSlides: false,
20448           centeredSlidesBounds: false,
20449           centerInsufficientSlides: false,
20450           slideToClickedSlide: true,
20451           watchSlidesProgress: true,
20452           observer: true,
20453           observeParents: true,
20454           spaceBetween: 10
20455         });
20456
20457         gallery.tSwiper.on('tap', function () {
20458           if (!gallery.mSwiper || typeof this.clickedIndex !== 'number') {
20459             return;
20460           }
20461
20462           const clickedImageIndex = this.clickedIndex;
20463           const targetMainIndex = getMainIndexFromImageIndex(gallery.mSwiper.slides, clickedImageIndex);
20464           if (targetMainIndex >= 0) {
20465             const currentMainIndex = gallery.mSwiper.activeIndex;
20466             const currentImageIndex = getImageIndexFromMainIndex(gallery.mSwiper.slides, currentMainIndex);
20467             const adBeforeTargetMainIndex = targetMainIndex > 0 && gallery.mSwiper.slides[targetMainIndex - 1] && gallery.mSwiper.slides[targetMainIndex - 1].classList.contains('ad-slide')
20468               ? targetMainIndex - 1
20469               : -1;
20470             const adAfterTargetMainIndex = gallery.mSwiper.slides[targetMainIndex + 1] && gallery.mSwiper.slides[targetMainIndex + 1].classList.contains('ad-slide')
20471               ? targetMainIndex + 1
20472               : -1;
20473             const isForwardNavigation = clickedImageIndex > currentImageIndex;
20474             const isBackwardNavigation = clickedImageIndex < currentImageIndex;
20475
20476             if (isForwardNavigation && adBeforeTargetMainIndex >= 0 && currentMainIndex < adBeforeTargetMainIndex) {
20477               gallery.mSwiper.slideTo(adBeforeTargetMainIndex);
20478               return;
20479             }
20480
20481             if (isBackwardNavigation && adAfterTargetMainIndex >= 0 && currentMainIndex > adAfterTargetMainIndex) {
20482               gallery.mSwiper.slideTo(adAfterTargetMainIndex);
20483               return;
20484             }
20485
20486             gallery.mSwiper.slideTo(targetMainIndex);
20487             traceThumbSync(gallery, 'thumbTap:slideTo', { clickedImageIndex: clickedImageIndex, targetMainIndex: targetMainIndex });
20488           }
20489         });
20490       } else {
20491         gallery.tSwiper = null;
20492       }
20493
20494       const mainSwiperConfig = {
20495         loop: false,
20496         slidesPerView: 1,
20497         autoHeight: true,
20498         pagination: {
20499           el: '.swiper-pagination',
20500           clickable: true,
20501           centered: true,
20502         },
20503         navigation: {
20504           nextEl: '.swiper-button-next',
20505           prevEl: '.swiper-button-prev',
20506           addIcons: false
20507         },
20508         keyboard: {
20509           enabled: true,
20510           onlyInViewport: true,
20511         },
20512         centeredSlides: true,
20513         centeredSlidesBounds: true,
20514         observer: true,
20515         observeParents: true,
20516         observeSlideChildren: true,
20517         on: {
20518           init: function () {
20519             normalizeGallerySlideHeights(gallery);
20520             refreshSwiperAutoHeight(this, gallery);
20521             clearInitialSlideHeightIfReady(gallery, this);
20522             rememberCurrentImageSlideHeight(gallery, this);
20523             setGalleryAdNavigationState(gallery, this.slides && typeof this.activeIndex === 'number' ? this.slides[this.activeIndex] : null);
20524             scheduleDescriptionThumbOverlapCheck(gallery);
20525           },
20526           slideChange: function() {
20527             const activeIndex = this.activeIndex;
20528             const activeSlide = this.slides[this.activeIndex];
20529             if (!activeSlide) {
20530               return;
20531             }
20532
20533             setGalleryAdNavigationState(gallery, activeSlide);
20534
20535             traceThumbSync(gallery, 'slideChange:start');
20536
20537             refreshSwiperAutoHeight(this, gallery);
20538             clearInitialSlideHeightIfReady(gallery, this);
20539
20540             triggerVirtualPageTracking(gallery, activeSlide, activeIndex);
20541
20542             if (gallery.tSwiper && activeSlide && !activeSlide.classList.contains('ad-slide')) {
20543               rememberCurrentImageSlideHeight(gallery, this);
20544               const imageIndex = getImageIndexFromMainIndex(this.slides, this.activeIndex);
20545               if (imageIndex >= 0) {
20546                 updateActiveThumbState(gallery, imageIndex);
20547                 syncThumbSwiperToImageIndex(gallery, imageIndex);
20548                 traceThumbSync(gallery, 'slideChangeTransitionEnd:image-slide', { targetImageIndex: imageIndex });
20549               }
20550             }
20551
20552             maybeRefreshExternalSlotsByAdPos(gallery, this);
20553             refreshActiveAdSlot(gallery, activeSlide);
20554             traceThumbSync(gallery, 'slideChangeTransitionEnd:end');
20555             scheduleDescriptionThumbOverlapCheck(gallery);
20556           }
20557         }
20558       };
20559
20560       applyInitialSlideHeight(gallery);
20561       applySliderContainerMinHeight(gallery);
20562
20563       gallery.mSwiper = new Swiper(sliderEl, mainSwiperConfig);
20564
20565       setGalleryAdNavigationState(
20566         gallery,
20567         gallery.mSwiper && gallery.mSwiper.slides && typeof gallery.mSwiper.activeIndex === 'number'
20568           ? gallery.mSwiper.slides[gallery.mSwiper.activeIndex]
20569           : null
20570       );
20571
20572       normalizeGallerySlideHeights(gallery);
20573       bindImageLoadAutoHeight(gallery);
20574
20575       refreshSwiperAutoHeight(gallery.mSwiper, gallery);
20576       clearInitialSlideHeightIfReady(gallery, gallery.mSwiper);
20577       scheduleDescriptionThumbOverlapCheck(gallery);
20578
20579       if (gallery.tSwiper && gallery.mSwiper && gallery.mSwiper.slides && typeof gallery.mSwiper.activeIndex === 'number') {
20580         rememberCurrentImageSlideHeight(gallery, gallery.mSwiper);
20581         const initialImageIndex = getImageIndexFromMainIndex(gallery.mSwiper.slides, gallery.mSwiper.activeIndex);
20582         if (initialImageIndex >= 0) {
20583           updateActiveThumbState(gallery, initialImageIndex);
20584         }
20585       }
20586     });
20587
20588   });
20589})();
20590

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.