1/******/ (() => { // webpackBootstrap 2/******/ var __webpack_modules__ = ({ 3
4/***/ "./assets/scripts/main.js": 5/*!********************************!*\ 6 !*** ./assets/scripts/main.js ***! 7 \********************************/ 8/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 9 10"use strict"; 11__webpack_require__.r(__webpack_exports__); 12/* harmony import */ var magnific_popup__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! magnific-popup */ "./node_modules/magnific-popup/dist/jquery.magnific-popup.js"); 13/* harmony import */ var magnific_popup__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(magnific_popup__WEBPACK_IMPORTED_MODULE_0__); 14/* harmony import */ var owl_carousel_dist_assets_owl_carousel_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! owl.carousel/dist/assets/owl.carousel.css */ "./node_modules/owl.carousel/dist/assets/owl.carousel.css"); 15/* harmony import */ var owl_carousel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! owl.carousel */ "./node_modules/owl.carousel/dist/owl.carousel.js"); 16/* harmony import */ var owl_carousel__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(owl_carousel__WEBPACK_IMPORTED_MODULE_2__); 17/* harmony import */ var jquery_nicescroll__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! jquery.nicescroll */ "./node_modules/jquery.nicescroll/jquery.nicescroll.js"); 18/* harmony import */ var jquery_nicescroll__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(jquery_nicescroll__WEBPACK_IMPORTED_MODULE_3__); 19/* harmony import */ var _components_quote_slider_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../components/quote-slider/index */ "./components/quote-slider/index.js"); 20/* harmony import */ var _components_quote_slider_index__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_components_quote_slider_index__WEBPACK_IMPORTED_MODULE_4__); 21/* harmony import */ var _components_copy_index__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../components/copy/index */ "./components/copy/index.js"); 22/* harmony import */ var _components_copy_index__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_components_copy_index__WEBPACK_IMPORTED_MODULE_5__); 23/* harmony import */ var _components_copy_video_index__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../components/copy-video/index */ "./components/copy-video/index.js"); 24/* harmony import */ var _components_copy_video_index__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_components_copy_video_index__WEBPACK_IMPORTED_MODULE_6__); 25/* harmony import */ var _components_buttons_index__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../components/buttons/index */ "./components/buttons/index.js"); 26/* harmony import */ var _components_buttons_index__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_components_buttons_index__WEBPACK_IMPORTED_MODULE_7__); 27/* harmony import */ var _components_button_download_index__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../components/button-download/index */ "./components/button-download/index.js"); 28/* harmony import */ var _components_button_download_index__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_components_button_download_index__WEBPACK_IMPORTED_MODULE_8__); 29/* harmony import */ var _components_resource_index__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../components/resource/index */ "./components/resource/index.js"); 30/* harmony import */ var _components_resource_index__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_components_resource_index__WEBPACK_IMPORTED_MODULE_9__); 31 32jQuery(function ($) { 33 34 let currentPage = 1; 35 36 $(".stl-pagination-btn").on("click", function () { 37 currentPage++; 38 let btn = $(this); 39 let btnText = btn.text(); 40 41 $.ajax({ 42 url: '/wp-admin/admin-ajax.php', 43 data: { 44 action: 'stl_load_more', 45 paged: currentPage, 46 post_type: btn.data('post-type'), 47 post_cat: btn.data('category'), 48 posts_per_page: btn.data('posts-per-page'), 49 }, 50 type: "POST", 51 beforeSend: function () { 52 btn.text("Loading..."); 53 }, 54 success: function (data) { 55 if (data) { 56 btn.text(btnText).parent().prev().append(data); 57 } else { 58 btn.hide(); // If no data, hide the button 59 } 60 }, 61 }); 62 });
63 64 $(".stl-navigation-block-item.active").on("click", function () { 65 $(".stl-navigation-block-row").toggleClass("active"); 66 }); 67}); 68 69 70 71 72 73 74/***/ }), 75
76/***/ "./components/button-download/index.js": 77/*!*********************************************!*\ 78 !*** ./components/button-download/index.js ***! 79 \*********************************************/ 80/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 81 82/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 83function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 84 85function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 86 87function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 88 89var downloadButton = /*#__PURE__*/function () { 90 function downloadButton(element) { 91 _classCallCheck(this, downloadButton); 92 93 this.$element = $(element); 94 this.$button = this.$element.find('.btn--download'); 95 this.init(); 96 } 97 98 _createClass(downloadButton, [{ 99 key: "init", 100 value: function init() { 101 this.$button.on("click", function (e) { 102 e.preventDefault(); 103 var $dl = $(e.currentTarget); 104 var i = $dl.find(".download-text").html(); 105 $dl.find(".download-text").html("Fetching..."); 106 $.ajax({
107 type: 'POST', 108 url: my_ajax_object.ajax_url, 109 dataType: 'html', 110 data: { 111 action: 'pdf_file_url_download', 112 download_url: $dl.attr('href') 113 }, 114 success: function success(res) { 115 $dl.find(".download-text").html(i); 116 117 if (res != 'not_eligible') { 118 window.location.href = res; 119 } else { 120 alert('You do not have permission to download this file!'); 121 } 122 }, 123 error: function error() { 124 $dl.find(".download-text").html(i); 125 alert('You do not have permission to download this file!'); 126 } 127 }); 128 }); 129 } 130 }]); 131 132 return downloadButton; 133}(); 134 135$('[data-button-download]').each(function (index, element) { 136 return new downloadButton(element); 137}); 138 139/***/ }), 140
141/***/ "./components/buttons/index.js": 142/*!*************************************!*\ 143 !*** ./components/buttons/index.js ***! 144 \*************************************/ 145/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 146 147/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 148function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 149 150function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 151 152function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 153 154var buttons = /*#__PURE__*/function () { 155 function buttons(element) { 156 _classCallCheck(this, buttons); 157 158 this.$element = $(element); 159 this.$scrollLink = $(element).find('.buttons__btn'); 160 this.init(); 161 } 162 163 _createClass(buttons, [{ 164 key: "init", 165 value: function init() { 166 this.$scrollLink.click(function () { 167 var linkId = $(this).attr('href'); 168 $('html, body').animate({ 169 scrollTop: $(linkId).offset().top 170 }, 1000); 171 }); 172 } 173 }]); 174 175 return buttons; 176}(); 177 178$('[data-buttons]').each(function (index, element) { 179 return new buttons(element); 180}); 181 182/***/ }), 183
184/***/ "./components/copy-video/index.js": 185/*!****************************************!*\ 186 !*** ./components/copy-video/index.js ***! 187 \****************************************/ 188/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 189 190/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 191function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 192 193function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 194 195function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 196 197var copyVideo = /*#__PURE__*/function () { 198 function copyVideo(element) { 199 _classCallCheck(this, copyVideo); 200 201 this.$element = $(element); 202 this.$play = $(element).find('.et_pb_video_play'); 203 this.$overlay = $(element).find('.et_pb_video_overlay'); 204 this.$video = $(element).find('.et_pb_video_box-video'); 205 this.init(); 206 } 207 208 _createClass(copyVideo, [{ 209 key: "init", 210 value: function init() { 211 var _this = this; 212 213 this.$play.click(function (e) { 214 e.preventDefault(); 215 216 _this.$overlay.hide(); 217 218 _this.$video.get(0).play(); 219 }); 220 } 221 }]); 222 223 return copyVideo; 224}(); 225 226$('[data-copy-video]').each(function (index, element) { 227 return new copyVideo(element); 228}); 229 230/***/ }), 231
232/***/ "./components/copy/index.js": 233/*!**********************************!*\ 234 !*** ./components/copy/index.js ***! 235 \**********************************/ 236/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 237 238/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 239/* provided dependency */ var jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 240function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 241 242function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 243 244function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 245 246var copy = /*#__PURE__*/function () { 247 function copy(element) { 248 _classCallCheck(this, copy); 249 250 this.$element = $(element); 251 this.$accordian = $(element).find('.copy__accordian-title'); 252 this.$tab = $(element).find('.tab'); 253 this.$tabCont = $(element).find('.tab-content'); 254 this.$slider = this.$element.find('.what-customers__slider'); 255 this.$h2 = this.$element.find('.o-wrapper .o-layout h2'); 256 this.$popUp = this.$element.find('.cta-banner__btn'); 257 this.init(); 258 } 259 260 _createClass(copy, [{ 261 key: "init", 262 value: function init() { 263 var _this = this; 264 265 this.$popUp.magnificPopup({ 266 type: 'inline', 267 preloader: false, 268 focus: '#name', 269 // When elemened is focused, some mobile browsers in some cases zoom in 270 // It looks not nice, so we disable it: 271 callbacks: { 272 beforeOpen: function beforeOpen() { 273 if ($(window).width() < 700) { 274 this.st.focus = false; 275 } else { 276 this.st.focus = '#name'; 277 } 278 } 279 } 280 }); 281 this.$h2.each(function () { 282 if (jQuery(this).css('text-align') == 'center') { 283 jQuery(this).addClass('center-text'); 284 } 285 }); 286 this.$tab.click(function (e) { 287 e.preventDefault(); 288 289 if (!$(e.currentTarget).hasClass('active')) { 290 var tabId = $(e.currentTarget).attr('href'); 291 292 _this.$tab.removeClass('active'); 293 294 $(e.currentTarget).addClass('active'); 295 296 _this.$tabCont.removeClass('active'); 297 298 $(tabId).addClass('active'); 299 } 300 }); 301 this.$slider.owlCarousel({ 302 margin: 10, 303 autoplay: false, 304 items: 1, 305 smartSpeed: 500, 306 loop: true, 307 dots: true, 308 pagination: true, 309 nav: true, 310 responcive: { 311 768: { 312 items: 1 313 }, 314 992: { 315 items: 1 316 } 317 } 318 }); 319 this.$accordian.click(function (e) { 320 if (!$(e.currentTarget).hasClass('active')) { 321 var activeLength = $(e.currentTarget).closest('.copy__accordian').find('.active').length; 322 323 if (activeLength > 0) { 324 $(e.currentTarget).closest('.copy__accordian').find('.active').next().slideUp(); 325 $(e.currentTarget).closest('.copy__accordian').find('.active').removeClass('active'); 326 } 327 328 $(e.currentTarget).addClass('active'); 329 $(e.currentTarget).next('.copy__accordian-desc').slideDown(); 330 } else { 331 $(e.currentTarget).removeClass('active'); 332 $(e.currentTarget).next('.copy__accordian-desc').slideUp(); 333 } 334 }); 335 } 336 }]); 337 338 return copy; 339}(); 340 341$('[data-copy]').each(function (index, element) { 342 return new copy(element); 343}); 344 345/***/ }), 346
347/***/ "./components/quote-slider/index.js": 348/*!******************************************!*\ 349 !*** ./components/quote-slider/index.js ***! 350 \******************************************/ 351/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 352 353/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 354function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 355 356function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 357 358function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 359 360var quoteSlider = /*#__PURE__*/function () { 361 function quoteSlider(element) { 362 _classCallCheck(this, quoteSlider); 363 364 this.$element = $(element); 365 this.$slider = this.$element.find('.quote-slider__slider'); 366 this.$slide = this.$element.find('.quote-slider__slider-content'); 367 this.init(); 368 } 369 370 _createClass(quoteSlider, [{ 371 key: "init", 372 value: function init() { 373 if (this.$slide.length > 1) { 374 this.$slider.owlCarousel({ 375 loop: true, 376 margin: 0, 377 responsiveClass: true, 378 nav: true, 379 dots: true, 380 navText: ['<i class="fa fa-angle-left" aria-hidden="true"></i>', '<i class="fa fa-angle-right" aria-hidden="true"></i>'], 381 responsive: { 382 0: { 383 items: 1, 384 nav: true 385 }, 386 575: { 387 items: 1, 388 nav: true 389 }, 390 768: { 391 items: 1, 392 nav: true 393 }, 394 992: { 395 items: 1, 396 nav: true 397 } 398 } 399 }); 400 } else { 401 this.$element.addClass('no-slider'); 402 } 403 } 404 }]); 405 406 return quoteSlider; 407}(); 408 409$('[data-quote-slider]').each(function (index, element) { 410 return new quoteSlider(element); 411}); 412 413/***/ }), 414
415/***/ "./components/resource/index.js": 416/*!**************************************!*\ 417 !*** ./components/resource/index.js ***! 418 \**************************************/ 419/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 420 421/* provided dependency */ var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 422// import 'jquery.nicescroll'; 423$(function () { 424 $('[data-clear-content_type]').click(function (e) { 425 e.preventDefault(); 426 $('[name="post_type[]"]').each(function (index, el) { 427 $(this).prop('checked', false); 428 }); 429 loadPostsWithAjax(false); 430 }); 431 $('[data-clear-topics]').click(function (e) { 432 e.preventDefault(); 433 $('[name="topics[]"]').each(function (index, el) { 434 $(this).prop('checked', false); 435 }); 436 loadPostsWithAjax(false); 437 }); 438 $('[data-clear-search]').click(function (e) { 439 e.preventDefault(); 440 $('[name="s"]').val(''); 441 $('[data-clear-search]').hide(); 442 loadPostsWithAjax(false); 443 }); 444 $('[data-load-more]').click(function (e) { 445 e.preventDefault(); 446 var paged = $('[name="paged"]').val(); 447 $('[name="paged"]').val(parseInt(paged) + 1); 448 loadPostsWithAjax(true); 449 }); 450 $('.resource .resource__title').click(function (e) { 451 e.preventDefault(); 452 var winW = $(window).width(); 453 454 if (winW < 768) { 455 if ($(this).hasClass('active')) { 456 $(this).removeClass('active').parent().children('.resource__form').slideUp(); 457 } else { 458 $(this).addClass('active').parent().children('.resource__form').slideDown(); 459 } 460 } 461 }); 462}); 463$('#search_value').keyup(function (e) { 464 if ($('#search_value').val() == '') { 465 $('[data-clear-search]').hide(); 466 } else { 467 $('[data-clear-search]').show(); 468 } 469}); 470$('[name="post_type[]"], [name="topics[]"]').click(function (e) { 471 loadPostsWithAjax(false); 472}); 473$('#resource__form').submit(function (e) { 474 e.preventDefault(); 475 loadPostsWithAjax(false); 476}); 477 478function loadPostsWithAjax(loadmore) { 479 if (!loadmore) { 480 $('[name="paged"]').val(1); 481 } 482 483 var formdata = $('#resource__form').serialize(); 484 $.ajax({ 485 url: my_ajax_object.ajax_url, 486 data: formdata, 487 dataType: "json", 488 type: "post", 489 success: function success(data) { 490 if (!data.load_more) { 491 $('[data-load-more]').hide(); 492 } else { 493 $('[data-load-more]').show(); 494 } 495 496 if (loadmore) { 497 $('#resources_content').append(data.html); 498 } else { 499 $('#resources_content').html(''); 500 $('#resources_content').html(data.html); 501 var winW = $(window).width(); 502 503 if (winW < 768) { 504 $('.resource .resource__title').removeClass('active').parent().children('.resource__form').slideUp(); 505 } 506 } 507 } 508 }); 509} 510 511/***/ }), 512 513/***/ "./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[2]!./node_modules/owl.carousel/dist/assets/owl.carousel.css": 514/*!**************************************************************************************************************************************************************************************************************************!*\ 515 !*** ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[2]!./node_modules/owl.carousel/dist/assets/owl.carousel.css ***! 516 \**************************************************************************************************************************************************************************************************************************/ 517/***/ ((module, __webpack_exports__, __webpack_require__) => { 518 519"use strict"; 520__webpack_require__.r(__webpack_exports__); 521/* harmony export */ __webpack_require__.d(__webpack_exports__, { 522/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 523/* harmony export */ }); 524/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); 525/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__); 526// Imports 527 528var ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]}); 529// Module
530___CSS_LOADER_EXPORT___.push([module.id, "/**\n * Owl Carousel v2.3.4\n * Copyright 2013-2018 David Deutsch\n * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE\n */\n/*\n * Owl Carousel - Core\n */\n.owl-carousel {\n display: none;\n width: 100%;\n -webkit-tap-highlight-color: transparent;\n /* position relative and z-index fix webkit rendering fonts issue */\n position: relative;\n z-index: 1; }\n .owl-carousel .owl-stage {\n position: relative;\n touch-action: manipulation;\n -moz-backface-visibility: hidden;\n /* fix firefox animation glitch */ }\n .owl-carousel .owl-stage:after {\n content: \".\";\n display: block;\n clear: both;\n visibility: hidden;\n line-height: 0;\n height: 0; }\n .owl-carousel .owl-stage-outer {\n position: relative;\n overflow: hidden;\n /* fix for flashing background */\n -webkit-transform: translate3d(0px, 0px, 0px); }\n .owl-carousel .owl-wrapper,\n .owl-carousel .owl-item {\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n -ms-backface-visibility: hidden;\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n -ms-transform: translate3d(0, 0, 0); }\n .owl-carousel .owl-item {\n position: relative;\n min-height: 1px;\n float: left;\n -webkit-backface-visibility: hidden;\n -webkit-tap-highlight-color: transparent;\n -webkit-touch-callout: none; }\n .owl-carousel .owl-item img {\n display: block;\n width: 100%; }\n .owl-carousel .owl-nav.disabled,\n .owl-carousel .owl-dots.disabled {\n display: none; }\n .owl-carousel .owl-nav .owl-prev,\n .owl-carousel .owl-nav .owl-next,\n .owl-carousel .owl-dot {\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none; }\n .owl-carousel .owl-nav button.owl-prev,\n .owl-carousel .owl-nav button.owl-next,\n .owl-carousel button.owl-dot {\n background: none;\n color: inherit;\n border: none;\n padding: 0 !important;\n font: inherit; }\n .owl-carousel.owl-loaded {\n display: block; }\n .owl-carousel.owl-loading {\n opacity: 0;\n display: block; }\n .owl-carousel.owl-hidden {\n opacity: 0; }\n .owl-carousel.owl-refresh .owl-item {\n visibility: hidden; }\n .owl-carousel.owl-drag .owl-item {\n touch-action: pan-y;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none; }\n .owl-carousel.owl-grab {\n cursor: move;\n cursor: -webkit-grab;\n cursor: grab; }\n .owl-carousel.owl-rtl {\n direction: rtl; }\n .owl-carousel.owl-rtl .owl-item {\n float: right; }\n\n/* No Js */\n.no-js .owl-carousel {\n display: block; }\n\n/*\n * Owl Carousel - Animate Plugin\n */\n.owl-carousel .animated {\n -webkit-animation-duration: 1000ms;\n animation-duration: 1000ms;\n -webkit-animation-fill-mode: both;\n animation-fill-mode: both; }\n\n.owl-carousel .owl-animated-in {\n z-index: 0; }\n\n.owl-carousel .owl-animated-out {\n z-index: 1; }\n\n.owl-carousel .fadeOut {\n -webkit-animation-name: fadeOut;\n animation-name: fadeOut; }\n\n@-webkit-keyframes fadeOut {\n 0% {\n opacity: 1; }\n 100% {\n opacity: 0; } }\n\n@keyframes fadeOut {\n 0% {\n opacity: 1; }\n 100% {\n opacity: 0; } }\n\n/*\n * \tOwl Carousel - Auto Height Plugin\n */\n.owl-height {\n transition: height 500ms ease-in-out; }\n\n/*\n * \tOwl Carousel - Lazy Load Plugin\n */\n.owl-carousel .owl-item {\n /**\n\t\t\tThis is introduced due to a bug in IE11 where lazy loading combined with autoheight plugin causes a wrong\n\t\t\tcalculation of the height of the owl-item that breaks page layouts\n\t\t */ }\n .owl-carousel .owl-item .owl-lazy {\n opacity: 0;\n transition: opacity 400ms ease; }\n .owl-carousel .owl-item .owl-lazy[src^=\"\"], .owl-carousel .owl-item .owl-lazy:not([src]) {\n max-height: 0; }\n .owl-carousel .owl-item img.owl-lazy {\n transform-style: preserve-3d; }\n\n/*\n * \tOwl Carousel - Video Plugin\n */\n.owl-carousel .owl-video-wrapper {\n position: relative;\n height: 100%;\n background: #000; }\n\n.owl-carousel .owl-video-play-icon {\n position: absolute;\n height: 80px;\n width: 80px;\n left: 50%;\n top: 50%;\n margin-left: -40px;\n margin-top: -40px;\n background: url(\"owl.video.play.png\") no-repeat;\n cursor: pointer;\n z-index: 1;\n -webkit-backface-visibility: hidden;\n transition: transform 100ms ease; }\n\n.owl-carousel .owl-video-play-icon:hover {\n transform: scale(1.3, 1.3); }\n\n.owl-carousel .owl-video-playing .owl-video-tn,\n.owl-carousel .owl-video-playing .owl-video-play-icon {\n display: none; }\n\n.owl-carousel .owl-video-tn {\n opacity: 0;\n height: 100%;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: contain;\n transition: opacity 400ms ease; }\n\n.owl-carousel .owl-video-frame {\n position: relative;\n z-index: 1;\n height: 100%;\n width: 100%; }\n", ""]);
531// Exports 532/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); 533 534 535/***/ }), 536
vendor: 1,948 bytes, lines 537-612
537/***/ "./node_modules/css-loader/dist/runtime/api.js": 538/*!*****************************************************!*\ 539 !*** ./node_modules/css-loader/dist/runtime/api.js ***! 540 \*****************************************************/ 541/***/ ((module) => { 542 543"use strict"; 544 545 546/* 547 MIT License http://www.opensource.org/licenses/mit-license.php 548 Author Tobias Koppers @sokra 549*/ 550// css base code, injected by the css-loader 551// eslint-disable-next-line func-names 552module.exports = function (cssWithMappingToString) { 553 var list = []; // return the list of modules as css string 554 555 list.toString = function toString() { 556 return this.map(function (item) { 557 var content = cssWithMappingToString(item); 558 559 if (item[2]) { 560 return "@media ".concat(item[2], " {").concat(content, "}"); 561 } 562 563 return content; 564 }).join(""); 565 }; // import a list of modules into the list 566 // eslint-disable-next-line func-names 567 568 569 list.i = function (modules, mediaQuery, dedupe) { 570 if (typeof modules === "string") { 571 // eslint-disable-next-line no-param-reassign 572 modules = [[null, modules, ""]]; 573 } 574 575 var alreadyImportedModules = {}; 576 577 if (dedupe) { 578 for (var i = 0; i < this.length; i++) { 579 // eslint-disable-next-line prefer-destructuring 580 var id = this[i][0]; 581 582 if (id != null) { 583 alreadyImportedModules[id] = true; 584 } 585 } 586 } 587 588 for (var _i = 0; _i < modules.length; _i++) { 589 var item = [].concat(modules[_i]); 590 591 if (dedupe && alreadyImportedModules[item[0]]) { 592 // eslint-disable-next-line no-continue 593 continue; 594 } 595 596 if (mediaQuery) { 597 if (!item[2]) { 598 item[2] = mediaQuery; 599 } else { 600 item[2] = "".concat(mediaQuery, " and ").concat(item[2]); 601 } 602 } 603 604 list.push(item); 605 } 606 }; 607 608 return list; 609}; 610 611/***/ }), 612
vendor: 124,318 bytes, lines 613-4338
613/***/ "./node_modules/jquery.nicescroll/jquery.nicescroll.js": 614/*!*************************************************************!*\ 615 !*** ./node_modules/jquery.nicescroll/jquery.nicescroll.js ***! 616 \*************************************************************/ 617/***/ ((module, exports, __webpack_require__) => { 618 619var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* jquery.nicescroll 620-- version 3.7.6 621-- copyright 2017-07-19 InuYaksa*2017 622-- licensed under the MIT 623-- 624-- https://nicescroll.areaaperta.com/ 625-- https://github.com/inuyaksa/jquery.nicescroll 626-- 627*/ 628 629/* jshint expr: true */ 630 631(function (factory) { 632 if (true) { 633 // AMD. Register as anonymous module. 634 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 635 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 636 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 637 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 638 } else {} 639}(function (jQuery) { 640 641 "use strict"; 642 643 // globals 644 var domfocus = false, 645 mousefocus = false, 646 tabindexcounter = 0, 647 ascrailcounter = 2000, 648 globalmaxzindex = 0; 649 650 var $ = jQuery, // sandbox 651 _doc = document, 652 _win = window, 653 $window = $(_win); 654 655 var delegatevents = []; 656 657 // http://stackoverflow.com/questions/2161159/get-script-path 658 function getScriptPath() { 659 var scripts = _doc.currentScript || (function () { var s = _doc.getElementsByTagName('script'); return (s.length) ? s[s.length - 1] : false; })(); 660 var path = scripts ? scripts.src.split('?')[0] : ''; 661 return (path.split('/').length > 0) ? path.split('/').slice(0, -1).join('/') + '/' : ''; 662 } 663 664 // based on code by Paul Irish https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ 665 var setAnimationFrame = _win.requestAnimationFrame || _win.webkitRequestAnimationFrame || _win.mozRequestAnimationFrame || false; 666 var clearAnimationFrame = _win.cancelAnimationFrame || _win.webkitCancelAnimationFrame || _win.mozCancelAnimationFrame || false; 667 668 if (!setAnimationFrame) { 669 var anilasttime = 0; 670 setAnimationFrame = function (callback, element) { 671 var currTime = new Date().getTime(); 672 var timeToCall = Math.max(0, 16 - (currTime - anilasttime)); 673 var id = _win.setTimeout(function () { callback(currTime + timeToCall); }, 674 timeToCall); 675 anilasttime = currTime + timeToCall; 676 return id; 677 }; 678 clearAnimationFrame = function (id) { 679 _win.clearTimeout(id); 680 }; 681 } else { 682 if (!_win.cancelAnimationFrame) clearAnimationFrame = function (id) { }; 683 } 684 685 var ClsMutationObserver = _win.MutationObserver || _win.WebKitMutationObserver || false; 686 687 var now = Date.now || function () { return new Date().getTime(); }; 688 689 var _globaloptions = { 690 zindex: "auto", 691 cursoropacitymin: 0, 692 cursoropacitymax: 1, 693 cursorcolor: "#424242", 694 cursorwidth: "6px", 695 cursorborder: "1px solid #fff", 696 cursorborderradius: "5px", 697 scrollspeed: 40, 698 mousescrollstep: 9 * 3, 699 touchbehavior: false, // deprecated 700 emulatetouch: false, // replacing touchbehavior 701 hwacceleration: true, 702 usetransition: true, 703 boxzoom: false, 704 dblclickzoom: true, 705 gesturezoom: true, 706 grabcursorenabled: true, 707 autohidemode: true, 708 background: "", 709 iframeautoresize: true, 710 cursorminheight: 32, 711 preservenativescrolling: true, 712 railoffset: false, 713 railhoffset: false, 714 bouncescroll: true, 715 spacebarenabled: true, 716 railpadding: { 717 top: 0, 718 right: 0, 719 left: 0, 720 bottom: 0 721 }, 722 disableoutline: true, 723 horizrailenabled: true, 724 railalign: "right", 725 railvalign: "bottom", 726 enabletranslate3d: true, 727 enablemousewheel: true, 728 enablekeyboard: true, 729 smoothscroll: true, 730 sensitiverail: true, 731 enablemouselockapi: true, 732 // cursormaxheight:false, 733 cursorfixedheight: false, 734 directionlockdeadzone: 6, 735 hidecursordelay: 400, 736 nativeparentscrolling: true, 737 enablescrollonselection: true, 738 overflowx: true, 739 overflowy: true, 740 cursordragspeed: 0.3, 741 rtlmode: "auto", 742 cursordragontouch: false, 743 oneaxismousemode: "auto", 744 scriptpath: getScriptPath(), 745 preventmultitouchscrolling: true, 746 disablemutationobserver: false, 747 enableobserver: true, 748 scrollbarid: false 749 }; 750 751 var browserdetected = false; 752 753 var getBrowserDetection = function () { 754 755 if (browserdetected) return browserdetected; 756 757 var _el = _doc.createElement('DIV'), 758 _style = _el.style, 759 _agent = navigator.userAgent, 760 _platform = navigator.platform, 761 d = {}; 762 763 d.haspointerlock = "pointerLockElement" in _doc || "webkitPointerLockElement" in _doc || "mozPointerLockElement" in _doc; 764 765 d.isopera = ("opera" in _win); // 12- 766 d.isopera12 = (d.isopera && ("getUserMedia" in navigator)); 767 d.isoperamini = (Object.prototype.toString.call(_win.operamini) === "[object OperaMini]"); 768 769 d.isie = (("all" in _doc) && ("attachEvent" in _el) && !d.isopera); //IE10- 770 d.isieold = (d.isie && !("msInterpolationMode" in _style)); // IE6 and older 771 d.isie7 = d.isie && !d.isieold && (!("documentMode" in _doc) || (_doc.documentMode === 7)); 772 d.isie8 = d.isie && ("documentMode" in _doc) && (_doc.documentMode === 8); 773 d.isie9 = d.isie && ("performance" in _win) && (_doc.documentMode === 9); 774 d.isie10 = d.isie && ("performance" in _win) && (_doc.documentMode === 10); 775 d.isie11 = ("msRequestFullscreen" in _el) && (_doc.documentMode >= 11); // IE11+ 776 777 d.ismsedge = ("msCredentials" in _win); // MS Edge 14+ 778 779 d.ismozilla = ("MozAppearance" in _style); 780 781 d.iswebkit = !d.ismsedge && ("WebkitAppearance" in _style); 782 783 d.ischrome = d.iswebkit && ("chrome" in _win); 784 d.ischrome38 = (d.ischrome && ("touchAction" in _style)); // behavior changed in touch emulation 785 d.ischrome22 = (!d.ischrome38) && (d.ischrome && d.haspointerlock); 786 d.ischrome26 = (!d.ischrome38) && (d.ischrome && ("transition" in _style)); // issue with transform detection (maintain prefix) 787 788 d.cantouch = ("ontouchstart" in _doc.documentElement) || ("ontouchstart" in _win); // with detection for Chrome Touch Emulation 789 d.hasw3ctouch = (_win.PointerEvent || false) && ((navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)); //IE11 pointer events, following W3C Pointer Events spec 790 d.hasmstouch = (!d.hasw3ctouch) && (_win.MSPointerEvent || false); // IE10 pointer events 791 792 d.ismac = /^mac$/i.test(_platform); 793 794 d.isios = d.cantouch && /iphone|ipad|ipod/i.test(_platform); 795 d.isios4 = d.isios && !("seal" in Object); 796 d.isios7 = d.isios && ("webkitHidden" in _doc); //iOS 7+ 797 d.isios8 = d.isios && ("hidden" in _doc); //iOS 8+ 798 d.isios10 = d.isios && _win.Proxy; //iOS 10+ 799 800 d.isandroid = (/android/i.test(_agent)); 801 802 d.haseventlistener = ("addEventListener" in _el); 803 804 d.trstyle = false; 805 d.hastransform = false; 806 d.hastranslate3d = false; 807 d.transitionstyle = false; 808 d.hastransition = false; 809 d.transitionend = false; 810 811 d.trstyle = "transform"; 812 d.hastransform = ("transform" in _style) || (function () { 813 var check = ['msTransform', 'webkitTransform', 'MozTransform', 'OTransform']; 814 for (var a = 0, c = check.length; a < c; a++) { 815 if (_style[check[a]] !== undefined) { 816 d.trstyle = check[a]; 817 break; 818 } 819 } 820 d.hastransform = (!!d.trstyle); 821 })(); 822 823 if (d.hastransform) { 824 _style[d.trstyle] = "translate3d(1px,2px,3px)"; 825 d.hastranslate3d = /translate3d/.test(_style[d.trstyle]); 826 } 827 828 d.transitionstyle = "transition"; 829 d.prefixstyle = ''; 830 d.transitionend = "transitionend"; 831 832 d.hastransition = ("transition" in _style) || (function () { 833 834 d.transitionend = false; 835 var check = ['webkitTransition', 'msTransition', 'MozTransition', 'OTransition', 'OTransition', 'KhtmlTransition']; 836 var prefix = ['-webkit-', '-ms-', '-moz-', '-o-', '-o', '-khtml-']; 837 var evs = ['webkitTransitionEnd', 'msTransitionEnd', 'transitionend', 'otransitionend', 'oTransitionEnd', 'KhtmlTransitionEnd']; 838 for (var a = 0, c = check.length; a < c; a++) { 839 if (check[a] in _style) { 840 d.transitionstyle = check[a]; 841 d.prefixstyle = prefix[a]; 842 d.transitionend = evs[a]; 843 break; 844 } 845 } 846 if (d.ischrome26) d.prefixstyle = prefix[1]; // always use prefix 847 848 d.hastransition = (d.transitionstyle); 849 850 })(); 851 852 function detectCursorGrab() { 853 var lst = ['grab', '-webkit-grab', '-moz-grab']; 854 if ((d.ischrome && !d.ischrome38) || d.isie) lst = []; // force setting for IE returns false positive and chrome cursor bug 855 for (var a = 0, l = lst.length; a < l; a++) { 856 var p = lst[a]; 857 _style.cursor = p; 858 if (_style.cursor == p) return p; 859 } 860 return 'url(https://cdnjs.cloudflare.com/ajax/libs/slider-pro/1.3.0/css/images/openhand.cur),n-resize'; // thanks to https://cdnjs.com/ for the openhand cursor! 861 } 862 d.cursorgrabvalue = detectCursorGrab(); 863 864 d.hasmousecapture = ("setCapture" in _el); 865 866 d.hasMutationObserver = (ClsMutationObserver !== false); 867 868 _el = null; //memory released 869 870 browserdetected = d; 871 872 return d; 873 }; 874 875 var NiceScrollClass = function (myopt, me) { 876 877 var self = this; 878 879 this.version = '3.7.6'; 880 this.name = 'nicescroll'; 881 882 this.me = me; 883 884 var $body = $("body"); 885 886 var opt = this.opt = { 887 doc: $body, 888 win: false 889 }; 890 891 $.extend(opt, _globaloptions); // clone opts 892 893 // Options for internal use 894 opt.snapbackspeed = 80; 895 896 if (myopt || false) { 897 for (var a in opt) { 898 if (myopt[a] !== undefined) opt[a] = myopt[a]; 899 } 900 } 901 902 if (opt.disablemutationobserver) ClsMutationObserver = false; 903 904 this.doc = opt.doc; 905 this.iddoc = (this.doc && this.doc[0]) ? this.doc[0].id || '' : ''; 906 this.ispage = /^BODY|HTML/.test((opt.win) ? opt.win[0].nodeName : this.doc[0].nodeName); 907 this.haswrapper = (opt.win !== false); 908 this.win = opt.win || (this.ispage ? $window : this.doc); 909 this.docscroll = (this.ispage && !this.haswrapper) ? $window : this.win; 910 this.body = $body; 911 this.viewport = false; 912 913 this.isfixed = false; 914 915 this.iframe = false; 916 this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME')); 917 918 this.istextarea = (this.win[0].nodeName == 'TEXTAREA'); 919 920 this.forcescreen = false; //force to use screen position on events 921 922 this.canshowonmouseevent = (opt.autohidemode != "scroll"); 923 924 // Events jump table 925 this.onmousedown = false; 926 this.onmouseup = false; 927 this.onmousemove = false; 928 this.onmousewheel = false; 929 this.onkeypress = false; 930 this.ongesturezoom = false; 931 this.onclick = false; 932 933 // Nicescroll custom events 934 this.onscrollstart = false; 935 this.onscrollend = false; 936 this.onscrollcancel = false; 937 938 this.onzoomin = false; 939 this.onzoomout = false; 940 941 // Let's start! 942 this.view = false; 943 this.page = false; 944 945 this.scroll = { 946 x: 0, 947 y: 0 948 }; 949 this.scrollratio = { 950 x: 0, 951 y: 0 952 }; 953 this.cursorheight = 20; 954 this.scrollvaluemax = 0; 955 956 // http://dev.w3.org/csswg/css-writing-modes-3/#logical-to-physical 957 // http://dev.w3.org/csswg/css-writing-modes-3/#svg-writing-mode 958 if (opt.rtlmode == "auto") { 959 var target = this.win[0] == _win ? this.body : this.win; 960 var writingMode = target.css("writing-mode") || target.css("-webkit-writing-mode") || target.css("-ms-writing-mode") || target.css("-moz-writing-mode"); 961 962 if (writingMode == "horizontal-tb" || writingMode == "lr-tb" || writingMode === "") { 963 this.isrtlmode = (target.css("direction") == "rtl"); 964 this.isvertical = false; 965 } else { 966 this.isrtlmode = (writingMode == "vertical-rl" || writingMode == "tb" || writingMode == "tb-rl" || writingMode == "rl-tb"); 967 this.isvertical = (writingMode == "vertical-rl" || writingMode == "tb" || writingMode == "tb-rl"); 968 } 969 } else { 970 this.isrtlmode = (opt.rtlmode === true); 971 this.isvertical = false; 972 } 973 // this.checkrtlmode = false; 974 975 this.scrollrunning = false; 976 977 this.scrollmom = false; 978 979 this.observer = false; // observer div changes 980 this.observerremover = false; // observer on parent for remove detection 981 this.observerbody = false; // observer on body for position change 982 983 if (opt.scrollbarid !== false) { 984 this.id = opt.scrollbarid; 985 } else { 986 do { 987 this.id = "ascrail" + (ascrailcounter++); 988 } while (_doc.getElementById(this.id)); 989 } 990 991 this.rail = false; 992 this.cursor = false; 993 this.cursorfreezed = false; 994 this.selectiondrag = false; 995 996 this.zoom = false; 997 this.zoomactive = false; 998 999 this.hasfocus = false; 1000 this.hasmousefocus = false; 1001 1002 //this.visibility = true; 1003 this.railslocked = false; // locked by resize 1004 this.locked = false; // prevent lost of locked status sets by user 1005 this.hidden = false; // rails always hidden 1006 this.cursoractive = true; // user can interact with cursors 1007 1008 this.wheelprevented = false; //prevent mousewheel event 1009 1010 this.overflowx = opt.overflowx; 1011 this.overflowy = opt.overflowy; 1012 1013 this.nativescrollingarea = false; 1014 this.checkarea = 0; 1015 1016 this.events = []; // event list for unbind 1017 1018 this.saved = {}; // style saved 1019 1020 this.delaylist = {}; 1021 this.synclist = {}; 1022 1023 this.lastdeltax = 0; 1024 this.lastdeltay = 0; 1025 1026 this.detected = getBrowserDetection(); 1027 1028 var cap = $.extend({}, this.detected); 1029 1030 this.canhwscroll = (cap.hastransform && opt.hwacceleration); 1031 this.ishwscroll = (this.canhwscroll && self.haswrapper); 1032 1033 if (!this.isrtlmode) { 1034 this.hasreversehr = false; 1035 } else if (this.isvertical) { // RTL mode with reverse horizontal axis 1036 this.hasreversehr = !(cap.iswebkit || cap.isie || cap.isie11); 1037 } else { 1038 this.hasreversehr = !(cap.iswebkit || (cap.isie && !cap.isie10 && !cap.isie11)); 1039 } 1040 1041 this.istouchcapable = false; // desktop devices with touch screen support 1042 1043 //## Check WebKit-based desktop with touch support 1044 //## + Firefox 18 nightly build (desktop) false positive (or desktop with touch support) 1045 1046 if (!cap.cantouch && (cap.hasw3ctouch || cap.hasmstouch)) { // desktop device with multiple input 1047 this.istouchcapable = true; 1048 } else if (cap.cantouch && !cap.isios && !cap.isandroid && (cap.iswebkit || cap.ismozilla)) { 1049 this.istouchcapable = true; 1050 } 1051 1052 //## disable MouseLock API on user request 1053 if (!opt.enablemouselockapi) { 1054 cap.hasmousecapture = false; 1055 cap.haspointerlock = false; 1056 } 1057 1058 this.debounced = function (name, fn, tm) { 1059 if (!self) return; 1060 var dd = self.delaylist[name] || false; 1061 if (!dd) { 1062 self.delaylist[name] = { 1063 h: setAnimationFrame(function () { 1064 self.delaylist[name].fn.call(self); 1065 self.delaylist[name] = false; 1066 }, tm) 1067 }; 1068 fn.call(self); 1069 } 1070 self.delaylist[name].fn = fn; 1071 }; 1072 1073 1074 this.synched = function (name, fn) { 1075 if (self.synclist[name]) self.synclist[name] = fn; 1076 else { 1077 self.synclist[name] = fn; 1078 setAnimationFrame(function () { 1079 if (!self) return; 1080 self.synclist[name] && self.synclist[name].call(self); 1081 self.synclist[name] = null; 1082 }); 1083 } 1084 }; 1085 1086 this.unsynched = function (name) { 1087 if (self.synclist[name]) self.synclist[name] = false; 1088 }; 1089 1090 this.css = function (el, pars) { // save & set 1091 for (var n in pars) { 1092 self.saved.css.push([el, n, el.css(n)]); 1093 el.css(n, pars[n]); 1094 } 1095 }; 1096 1097 this.scrollTop = function (val) { 1098 return (val === undefined) ? self.getScrollTop() : self.setScrollTop(val); 1099 }; 1100 1101 this.scrollLeft = function (val) { 1102 return (val === undefined) ? self.getScrollLeft() : self.setScrollLeft(val); 1103 }; 1104 1105 // derived by by Dan Pupius www.pupius.net 1106 var BezierClass = function (st, ed, spd, p1, p2, p3, p4) { 1107 1108 this.st = st; 1109 this.ed = ed; 1110 this.spd = spd; 1111 1112 this.p1 = p1 || 0; 1113 this.p2 = p2 || 1; 1114 this.p3 = p3 || 0; 1115 this.p4 = p4 || 1; 1116 1117 this.ts = now(); 1118 this.df = ed - st; 1119 }; 1120 BezierClass.prototype = { 1121 B2: function (t) { 1122 return 3 * (1 - t) * (1 - t) * t; 1123 }, 1124 B3: function (t) { 1125 return 3 * (1 - t) * t * t; 1126 }, 1127 B4: function (t) { 1128 return t * t * t; 1129 }, 1130 getPos: function () { 1131 return (now() - this.ts) / this.spd; 1132 }, 1133 getNow: function () { 1134 var pc = (now() - this.ts) / this.spd; 1135 var bz = this.B2(pc) + this.B3(pc) + this.B4(pc); 1136 return (pc >= 1) ? this.ed : this.st + (this.df * bz) | 0; 1137 }, 1138 update: function (ed, spd) { 1139 this.st = this.getNow(); 1140 this.ed = ed; 1141 this.spd = spd; 1142 this.ts = now(); 1143 this.df = this.ed - this.st; 1144 return this; 1145 } 1146 }; 1147 1148 //derived from http://stackoverflow.com/questions/11236090/ 1149 function getMatrixValues() { 1150 var tr = self.doc.css(cap.trstyle); 1151 if (tr && (tr.substr(0, 6) == "matrix")) { 1152 return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g, '').split(/, +/); 1153 } 1154 return false; 1155 } 1156 1157 if (this.ishwscroll) { // hw accelerated scroll 1158 1159 this.doc.translate = { 1160 x: 0, 1161 y: 0, 1162 tx: "0px", 1163 ty: "0px" 1164 }; 1165 1166 //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/ 1167 if (cap.hastranslate3d && cap.isios) this.doc.css("-webkit-backface-visibility", "hidden"); // prevent flickering http://stackoverflow.com/questions/3461441/ 1168 1169 this.getScrollTop = function (last) { 1170 if (!last) { 1171 var mtx = getMatrixValues(); 1172 if (mtx) return (mtx.length == 16) ? -mtx[13] : -mtx[5]; //matrix3d 16 on IE10 1173 if (self.timerscroll && self.timerscroll.bz) return self.timerscroll.bz.getNow(); 1174 } 1175 return self.doc.translate.y; 1176 }; 1177 1178 this.getScrollLeft = function (last) { 1179 if (!last) { 1180 var mtx = getMatrixValues(); 1181 if (mtx) return (mtx.length == 16) ? -mtx[12] : -mtx[4]; //matrix3d 16 on IE10 1182 if (self.timerscroll && self.timerscroll.bh) return self.timerscroll.bh.getNow(); 1183 } 1184 return self.doc.translate.x; 1185 }; 1186 1187 this.notifyScrollEvent = function (el) { 1188 var e = _doc.createEvent("UIEvents"); 1189 e.initUIEvent("scroll", false, false, _win, 1); 1190 e.niceevent = true; 1191 el.dispatchEvent(e); 1192 }; 1193 1194 var cxscrollleft = (this.isrtlmode) ? 1 : -1; 1195 1196 if (cap.hastranslate3d && opt.enabletranslate3d) { 1197 this.setScrollTop = function (val, silent) { 1198 self.doc.translate.y = val; 1199 self.doc.translate.ty = (val * -1) + "px"; 1200 self.doc.css(cap.trstyle, "translate3d(" + self.doc.translate.tx + "," + self.doc.translate.ty + ",0)"); 1201 if (!silent) self.notifyScrollEvent(self.win[0]); 1202 }; 1203 this.setScrollLeft = function (val, silent) { 1204 self.doc.translate.x = val; 1205 self.doc.translate.tx = (val * cxscrollleft) + "px"; 1206 self.doc.css(cap.trstyle, "translate3d(" + self.doc.translate.tx + "," + self.doc.translate.ty + ",0)"); 1207 if (!silent) self.notifyScrollEvent(self.win[0]); 1208 }; 1209 } else { 1210 this.setScrollTop = function (val, silent) { 1211 self.doc.translate.y = val; 1212 self.doc.translate.ty = (val * -1) + "px"; 1213 self.doc.css(cap.trstyle, "translate(" + self.doc.translate.tx + "," + self.doc.translate.ty + ")"); 1214 if (!silent) self.notifyScrollEvent(self.win[0]); 1215 }; 1216 this.setScrollLeft = function (val, silent) { 1217 self.doc.translate.x = val; 1218 self.doc.translate.tx = (val * cxscrollleft) + "px"; 1219 self.doc.css(cap.trstyle, "translate(" + self.doc.translate.tx + "," + self.doc.translate.ty + ")"); 1220 if (!silent) self.notifyScrollEvent(self.win[0]); 1221 }; 1222 } 1223 } else { // native scroll 1224 1225 this.getScrollTop = function () { 1226 return self.docscroll.scrollTop(); 1227 }; 1228 this.setScrollTop = function (val) { 1229 self.docscroll.scrollTop(val); 1230 }; 1231 1232 this.getScrollLeft = function () { 1233 var val; 1234 if (!self.hasreversehr) { 1235 val = self.docscroll.scrollLeft(); 1236 } else if (self.detected.ismozilla) { 1237 val = self.page.maxw - Math.abs(self.docscroll.scrollLeft()); 1238 } else { 1239 val = self.page.maxw - self.docscroll.scrollLeft(); 1240 } 1241 return val; 1242 }; 1243 this.setScrollLeft = function (val) { 1244 return setTimeout(function () { 1245 if (!self) return; 1246 if (self.hasreversehr) { 1247 if (self.detected.ismozilla) { 1248 val = -(self.page.maxw - val); 1249 } else { 1250 val = self.page.maxw - val; 1251 } 1252 } 1253 return self.docscroll.scrollLeft(val); 1254 }, 1); 1255 }; 1256 } 1257 1258 this.getTarget = function (e) { 1259 if (!e) return false; 1260 if (e.target) return e.target; 1261 if (e.srcElement) return e.srcElement; 1262 return false; 1263 }; 1264 1265 this.hasParent = function (e, id) { 1266 if (!e) return false; 1267 var el = e.target || e.srcElement || e || false; 1268 while (el && el.id != id) { 1269 el = el.parentNode || false; 1270 } 1271 return (el !== false); 1272 }; 1273 1274 function getZIndex() { 1275 var dom = self.win; 1276 if ("zIndex" in dom) return dom.zIndex(); // use jQuery UI method when available 1277 while (dom.length > 0) { 1278 if (dom[0].nodeType == 9) return false; 1279 var zi = dom.css('zIndex'); 1280 if (!isNaN(zi) && zi !== 0) return parseInt(zi); 1281 dom = dom.parent(); 1282 } 1283 return false; 1284 } 1285 1286 //inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie 1287 var _convertBorderWidth = { 1288 "thin": 1, 1289 "medium": 3, 1290 "thick": 5 1291 }; 1292 1293 function getWidthToPixel(dom, prop, chkheight) { 1294 var wd = dom.css(prop); 1295 var px = parseFloat(wd); 1296 if (isNaN(px)) { 1297 px = _convertBorderWidth[wd] || 0; 1298 var brd = (px == 3) ? ((chkheight) ? (self.win.outerHeight() - self.win.innerHeight()) : (self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS 1299 if (self.isie8 && px) px += 1; 1300 return (brd) ? px : 0; 1301 } 1302 return px; 1303 } 1304 1305 this.getDocumentScrollOffset = function () { 1306 return { 1307 top: _win.pageYOffset || _doc.documentElement.scrollTop, 1308 left: _win.pageXOffset || _doc.documentElement.scrollLeft 1309 }; 1310 }; 1311 1312 this.getOffset = function () { 1313 if (self.isfixed) { 1314 var ofs = self.win.offset(); // fix Chrome auto issue (when right/bottom props only) 1315 var scrl = self.getDocumentScrollOffset(); 1316 ofs.top -= scrl.top; 1317 ofs.left -= scrl.left; 1318 return ofs; 1319 } 1320 var ww = self.win.offset(); 1321 if (!self.viewport) return ww; 1322 var vp = self.viewport.offset(); 1323 return { 1324 top: ww.top - vp.top, 1325 left: ww.left - vp.left 1326 }; 1327 }; 1328 1329 this.updateScrollBar = function (len) { 1330 var pos, off; 1331 if (self.ishwscroll) { 1332 self.rail.css({ 1333 height: self.win.innerHeight() - (opt.railpadding.top + opt.railpadding.bottom) 1334 }); 1335 if (self.railh) self.railh.css({ 1336 width: self.win.innerWidth() - (opt.railpadding.left + opt.railpadding.right) 1337 }); 1338 } else { 1339 var wpos = self.getOffset(); 1340 pos = { 1341 top: wpos.top, 1342 left: wpos.left - (opt.railpadding.left + opt.railpadding.right) 1343 }; 1344 pos.top += getWidthToPixel(self.win, 'border-top-width', true); 1345 pos.left += (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win, 'border-right-width') - self.rail.width : getWidthToPixel(self.win, 'border-left-width'); 1346 1347 off = opt.railoffset; 1348 if (off) { 1349 if (off.top) pos.top += off.top; 1350 if (off.left) pos.left += off.left; 1351 } 1352 1353 if (!self.railslocked) self.rail.css({ 1354 top: pos.top, 1355 left: pos.left, 1356 height: ((len) ? len.h : self.win.innerHeight()) - (opt.railpadding.top + opt.railpadding.bottom) 1357 }); 1358 1359 if (self.zoom) { 1360 self.zoom.css({ 1361 top: pos.top + 1, 1362 left: (self.rail.align == 1) ? pos.left - 20 : pos.left + self.rail.width + 4 1363 }); 1364 } 1365 1366 if (self.railh && !self.railslocked) { 1367 pos = { 1368 top: wpos.top, 1369 left: wpos.left 1370 }; 1371 off = opt.railhoffset; 1372 if (off) { 1373 if (off.top) pos.top += off.top; 1374 if (off.left) pos.left += off.left; 1375 } 1376 var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win, 'border-top-width', true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win, 'border-top-width', true); 1377 var x = pos.left + getWidthToPixel(self.win, 'border-left-width'); 1378 self.railh.css({ 1379 top: y - (opt.railpadding.top + opt.railpadding.bottom), 1380 left: x, 1381 width: self.railh.width 1382 }); 1383 } 1384 1385 } 1386 }; 1387 1388 this.doRailClick = function (e, dbl, hr) { 1389 var fn, pg, cur, pos; 1390 1391 if (self.railslocked) return; 1392 1393 self.cancelEvent(e); 1394 1395 if (!("pageY" in e)) { 1396 e.pageX = e.clientX + _doc.documentElement.scrollLeft; 1397 e.pageY = e.clientY + _doc.documentElement.scrollTop; 1398 } 1399 1400 if (dbl) { 1401 fn = (hr) ? self.doScrollLeft : self.doScrollTop; 1402 cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth / 2)) * self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight / 2)) * self.scrollratio.y); 1403 self.unsynched("relativexy"); 1404 fn(cur|0); 1405 } else { 1406 fn = (hr) ? self.doScrollLeftBy : self.doScrollBy; 1407 cur = (hr) ? self.scroll.x : self.scroll.y; 1408 pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top; 1409 pg = (hr) ? self.view.w : self.view.h; 1410 fn((cur >= pos) ? pg : -pg); 1411 } 1412 1413 }; 1414 1415 self.newscrolly = self.newscrollx = 0; 1416 1417 self.hasanimationframe = ("requestAnimationFrame" in _win); 1418 self.hascancelanimationframe = ("cancelAnimationFrame" in _win); 1419 1420 self.hasborderbox = false; 1421 1422 this.init = function () { 1423 1424 self.saved.css = []; 1425 1426 if (cap.isoperamini) return true; // SORRY, DO NOT WORK! 1427 if (cap.isandroid && !("hidden" in _doc)) return true; // Android 3- SORRY, DO NOT WORK! 1428 1429 opt.emulatetouch = opt.emulatetouch || opt.touchbehavior; // mantain compatibility with "touchbehavior" 1430 1431 self.hasborderbox = _win.getComputedStyle && (_win.getComputedStyle(_doc.body)['box-sizing'] === "border-box"); 1432 1433 var _scrollyhidden = { 'overflow-y': 'hidden' }; 1434 if (cap.isie11 || cap.isie10) _scrollyhidden['-ms-overflow-style'] = 'none'; // IE 10 & 11 is always a world apart! 1435 1436 if (self.ishwscroll) { 1437 this.doc.css(cap.transitionstyle, cap.prefixstyle + 'transform 0ms ease-out'); 1438 if (cap.transitionend) self.bind(self.doc, cap.transitionend, self.onScrollTransitionEnd, false); //I have got to do something usefull!! 1439 } 1440 1441 self.zindex = "auto"; 1442 if (!self.ispage && opt.zindex == "auto") { 1443 self.zindex = getZIndex() || "auto"; 1444 } else { 1445 self.zindex = opt.zindex; 1446 } 1447 1448 if (!self.ispage && self.zindex != "auto" && self.zindex > globalmaxzindex) { 1449 globalmaxzindex = self.zindex; 1450 } 1451 1452 if (self.isie && self.zindex === 0 && opt.zindex == "auto") { // fix IE auto == 0 1453 self.zindex = "auto"; 1454 } 1455 1456 if (!self.ispage || !cap.isieold) { 1457 1458 var cont = self.docscroll; 1459 if (self.ispage) cont = (self.haswrapper) ? self.win : self.doc; 1460 1461 self.css(cont, _scrollyhidden); 1462 1463 if (self.ispage && (cap.isie11 || cap.isie)) { // IE 7-11 1464 self.css($("html"), _scrollyhidden); 1465 } 1466 1467 if (cap.isios && !self.ispage && !self.haswrapper) self.css($body, { 1468 "-webkit-overflow-scrolling": "touch" 1469 }); //force hw acceleration 1470 1471 var cursor = $(_doc.createElement('div')); 1472 cursor.css({ 1473 position: "relative", 1474 top: 0, 1475 "float": "right", 1476 width: opt.cursorwidth, 1477 height: 0, 1478 'background-color': opt.cursorcolor, 1479 border: opt.cursorborder, 1480 'background-clip': 'padding-box', 1481 '-webkit-border-radius': opt.cursorborderradius, 1482 '-moz-border-radius': opt.cursorborderradius, 1483 'border-radius': opt.cursorborderradius 1484 }); 1485 1486 cursor.addClass('nicescroll-cursors'); 1487 1488 self.cursor = cursor; 1489 1490 var rail = $(_doc.createElement('div')); 1491 rail.attr('id', self.id); 1492 rail.addClass('nicescroll-rails nicescroll-rails-vr'); 1493 1494 var v, a, kp = ["left", "right", "top", "bottom"]; //** 1495 for (var n in kp) { 1496 a = kp[n]; 1497 v = opt.railpadding[a] || 0; 1498 v && rail.css("padding-" + a, v + "px"); 1499 } 1500 1501 rail.append(cursor); 1502 1503 rail.width = Math.max(parseFloat(opt.cursorwidth), cursor.outerWidth()); 1504 rail.css({ 1505 width: rail.width + "px", 1506 zIndex: self.zindex, 1507 background: opt.background, 1508 cursor: "default" 1509 }); 1510 1511 rail.visibility = true; 1512 rail.scrollable = true; 1513 1514 rail.align = (opt.railalign == "left") ? 0 : 1; 1515 1516 self.rail = rail; 1517 1518 self.rail.drag = false; 1519 1520 var zoom = false; 1521 if (opt.boxzoom && !self.ispage && !cap.isieold) { 1522 zoom = _doc.createElement('div'); 1523 1524 self.bind(zoom, "click", self.doZoom); 1525 self.bind(zoom, "mouseenter", function () { 1526 self.zoom.css('opacity', opt.cursoropacitymax); 1527 }); 1528 self.bind(zoom, "mouseleave", function () { 1529 self.zoom.css('opacity', opt.cursoropacitymin); 1530 }); 1531 1532 self.zoom = $(zoom); 1533 self.zoom.css({ 1534 cursor: "pointer", 1535 zIndex: self.zindex, 1536 backgroundImage: 'url(' + opt.scriptpath + 'zoomico.png)', 1537 height: 18, 1538 width: 18, 1539 backgroundPosition: '0 0' 1540 }); 1541 if (opt.dblclickzoom) self.bind(self.win, "dblclick", self.doZoom); 1542 if (cap.cantouch && opt.gesturezoom) { 1543 self.ongesturezoom = function (e) { 1544 if (e.scale > 1.5) self.doZoomIn(e); 1545 if (e.scale < 0.8) self.doZoomOut(e); 1546 return self.cancelEvent(e); 1547 }; 1548 self.bind(self.win, "gestureend", self.ongesturezoom); 1549 } 1550 } 1551 1552 // init HORIZ 1553 1554 self.railh = false; 1555 var railh; 1556 1557 if (opt.horizrailenabled) { 1558 1559 self.css(cont, { 1560 overflowX: 'hidden' 1561 }); 1562 1563 cursor = $(_doc.createElement('div')); 1564 cursor.css({ 1565 position: "absolute", 1566 top: 0, 1567 height: opt.cursorwidth, 1568 width: 0, 1569 backgroundColor: opt.cursorcolor, 1570 border: opt.cursorborder, 1571 backgroundClip: 'padding-box', 1572 '-webkit-border-radius': opt.cursorborderradius, 1573 '-moz-border-radius': opt.cursorborderradius, 1574 'border-radius': opt.cursorborderradius 1575 }); 1576 1577 if (cap.isieold) cursor.css('overflow', 'hidden'); //IE6 horiz scrollbar issue 1578 1579 cursor.addClass('nicescroll-cursors'); 1580 1581 self.cursorh = cursor; 1582 1583 railh = $(_doc.createElement('div')); 1584 railh.attr('id', self.id + '-hr'); 1585 railh.addClass('nicescroll-rails nicescroll-rails-hr'); 1586 railh.height = Math.max(parseFloat(opt.cursorwidth), cursor.outerHeight()); 1587 railh.css({ 1588 height: railh.height + "px", 1589 'zIndex': self.zindex, 1590 "background": opt.background 1591 }); 1592 1593 railh.append(cursor); 1594 1595 railh.visibility = true; 1596 railh.scrollable = true; 1597 1598 railh.align = (opt.railvalign == "top") ? 0 : 1; 1599 1600 self.railh = railh; 1601 1602 self.railh.drag = false; 1603 1604 } 1605 1606 if (self.ispage) { 1607 1608 rail.css({ 1609 position: "fixed", 1610 top: 0, 1611 height: "100%" 1612 }); 1613 1614 rail.css((rail.align) ? { right: 0 } : { left: 0 }); 1615 1616 self.body.append(rail); 1617 if (self.railh) { 1618 railh.css({ 1619 position: "fixed", 1620 left: 0, 1621 width: "100%" 1622 }); 1623 1624 railh.css((railh.align) ? { bottom: 0 } : { top: 0 }); 1625 1626 self.body.append(railh); 1627 } 1628 } else { 1629 if (self.ishwscroll) { 1630 if (self.win.css('position') == 'static') self.css(self.win, { 'position': 'relative' }); 1631 var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win; 1632 $(bd).scrollTop(0).scrollLeft(0); // fix rail position if content already scrolled 1633 if (self.zoom) { 1634 self.zoom.css({ 1635 position: "absolute", 1636 top: 1, 1637 right: 0, 1638 "margin-right": rail.width + 4 1639 }); 1640 bd.append(self.zoom); 1641 } 1642 rail.css({ 1643 position: "absolute", 1644 top: 0 1645 }); 1646 rail.css((rail.align) ? { right: 0 } : { left: 0 }); 1647 bd.append(rail); 1648 if (railh) { 1649 railh.css({ 1650 position: "absolute", 1651 left: 0, 1652 bottom: 0 1653 }); 1654 railh.css((railh.align) ? { bottom: 0 } : { top: 0 }); 1655 bd.append(railh); 1656 } 1657 } else { 1658 self.isfixed = (self.win.css("position") == "fixed"); 1659 var rlpos = (self.isfixed) ? "fixed" : "absolute"; 1660 1661 if (!self.isfixed) self.viewport = self.getViewport(self.win[0]); 1662 if (self.viewport) { 1663 self.body = self.viewport; 1664 if (!(/fixed|absolute/.test(self.viewport.css("position")))) self.css(self.viewport, { 1665 "position": "relative" 1666 }); 1667 } 1668 1669 rail.css({ 1670 position: rlpos 1671 }); 1672 if (self.zoom) self.zoom.css({ 1673 position: rlpos 1674 }); 1675 self.updateScrollBar(); 1676 self.body.append(rail); 1677 if (self.zoom) self.body.append(self.zoom); 1678 if (self.railh) { 1679 railh.css({ 1680 position: rlpos 1681 }); 1682 self.body.append(railh); 1683 } 1684 } 1685 1686 if (cap.isios) self.css(self.win, { 1687 '-webkit-tap-highlight-color': 'rgba(0,0,0,0)', 1688 '-webkit-touch-callout': 'none' 1689 }); // prevent grey layer on click 1690 1691 if (opt.disableoutline) { 1692 if (cap.isie) self.win.attr("hideFocus", "true"); // IE, prevent dotted rectangle on focused div 1693 if (cap.iswebkit) self.win.css('outline', 'none'); // Webkit outline 1694 } 1695 1696 } 1697 1698 if (opt.autohidemode === false) { 1699 self.autohidedom = false; 1700 self.rail.css({ 1701 opacity: opt.cursoropacitymax 1702 }); 1703 if (self.railh) self.railh.css({ 1704 opacity: opt.cursoropacitymax 1705 }); 1706 } else if ((opt.autohidemode === true) || (opt.autohidemode === "leave")) { 1707 self.autohidedom = $().add(self.rail); 1708 if (cap.isie8) self.autohidedom = self.autohidedom.add(self.cursor); 1709 if (self.railh) self.autohidedom = self.autohidedom.add(self.railh); 1710 if (self.railh && cap.isie8) self.autohidedom = self.autohidedom.add(self.cursorh); 1711 } else if (opt.autohidemode == "scroll") { 1712 self.autohidedom = $().add(self.rail); 1713 if (self.railh) self.autohidedom = self.autohidedom.add(self.railh); 1714 } else if (opt.autohidemode == "cursor") { 1715 self.autohidedom = $().add(self.cursor); 1716 if (self.railh) self.autohidedom = self.autohidedom.add(self.cursorh); 1717 } else if (opt.autohidemode == "hidden") { 1718 self.autohidedom = false; 1719 self.hide(); 1720 self.railslocked = false; 1721 } 1722 1723 if (cap.cantouch || self.istouchcapable || opt.emulatetouch || cap.hasmstouch) { 1724 1725 self.scrollmom = new ScrollMomentumClass2D(self); 1726 1727 var delayedclick = null; 1728 1729 self.ontouchstart = function (e) { 1730 1731 if (self.locked) return false; 1732 1733 //if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1734 if (e.pointerType && (e.pointerType === 'mouse' || e.pointerType === e.MSPOINTER_TYPE_MOUSE)) return false; // need test on surface!! 1735 1736 self.hasmoving = false; 1737 1738 if (self.scrollmom.timer) { 1739 self.triggerScrollEnd(); 1740 self.scrollmom.stop(); 1741 } 1742 1743 if (!self.railslocked) { 1744 var tg = self.getTarget(e); 1745 1746 if (tg) { 1747 var skp = (/INPUT/i.test(tg.nodeName)) && (/range/i.test(tg.type)); 1748 if (skp) return self.stopPropagation(e); 1749 } 1750 1751 var ismouse = (e.type === "mousedown"); 1752 1753 if (!("clientX" in e) && ("changedTouches" in e)) { 1754 e.clientX = e.changedTouches[0].clientX; 1755 e.clientY = e.changedTouches[0].clientY; 1756 } 1757 1758 if (self.forcescreen) { 1759 var le = e; 1760 e = { 1761 "original": (e.original) ? e.original : e 1762 }; 1763 e.clientX = le.screenX; 1764 e.clientY = le.screenY; 1765 } 1766 1767 self.rail.drag = { 1768 x: e.clientX, 1769 y: e.clientY, 1770 sx: self.scroll.x, 1771 sy: self.scroll.y, 1772 st: self.getScrollTop(), 1773 sl: self.getScrollLeft(), 1774 pt: 2, 1775 dl: false, 1776 tg: tg 1777 }; 1778 1779 if (self.ispage || !opt.directionlockdeadzone) { 1780 1781 self.rail.drag.dl = "f"; 1782 1783 } else { 1784 1785 var view = { 1786 w: $window.width(), 1787 h: $window.height() 1788 }; 1789 1790 var page = self.getContentSize(); 1791 1792 var maxh = page.h - view.h; 1793 var maxw = page.w - view.w; 1794 1795 if (self.rail.scrollable && !self.railh.scrollable) self.rail.drag.ck = (maxh > 0) ? "v" : false; 1796 else if (!self.rail.scrollable && self.railh.scrollable) self.rail.drag.ck = (maxw > 0) ? "h" : false; 1797 else self.rail.drag.ck = false; 1798 1799 } 1800 1801 if (opt.emulatetouch && self.isiframe && cap.isie) { 1802 var wp = self.win.position(); 1803 self.rail.drag.x += wp.left; 1804 self.rail.drag.y += wp.top; 1805 } 1806 1807 self.hasmoving = false; 1808 self.lastmouseup = false; 1809 self.scrollmom.reset(e.clientX, e.clientY); 1810 1811 if (tg&&ismouse) { 1812 1813 var ip = /INPUT|SELECT|BUTTON|TEXTAREA/i.test(tg.nodeName); 1814 if (!ip) { 1815 if (cap.hasmousecapture) tg.setCapture(); 1816 if (opt.emulatetouch) { 1817 if (tg.onclick && !(tg._onclick || false)) { // intercept DOM0 onclick event 1818 tg._onclick = tg.onclick; 1819 tg.onclick = function (e) { 1820 if (self.hasmoving) return false; 1821 tg._onclick.call(this, e); 1822 }; 1823 } 1824 return self.cancelEvent(e); 1825 } 1826 return self.stopPropagation(e); 1827 } 1828 1829 if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) { 1830 self.preventclick = { 1831 "tg": tg, 1832 "click": false 1833 }; 1834 } 1835 1836 } 1837 } 1838 1839 }; 1840 1841 self.ontouchend = function (e) { 1842 1843 if (!self.rail.drag) return true; 1844 1845 if (self.rail.drag.pt == 2) { 1846 //if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1847 if (e.pointerType && (e.pointerType === 'mouse' || e.pointerType === e.MSPOINTER_TYPE_MOUSE)) return false; 1848 1849 self.rail.drag = false; 1850 1851 var ismouse = (e.type === "mouseup"); 1852 1853 if (self.hasmoving) { 1854 self.scrollmom.doMomentum(); 1855 self.lastmouseup = true; 1856 self.hideCursor(); 1857 if (cap.hasmousecapture) _doc.releaseCapture(); 1858 if (ismouse) return self.cancelEvent(e); 1859 } 1860 1861 } 1862 else if (self.rail.drag.pt == 1) { 1863 return self.onmouseup(e); 1864 } 1865 1866 }; 1867 1868 var moveneedoffset = (opt.emulatetouch && self.isiframe && !cap.hasmousecapture); 1869 1870 var locktollerance = opt.directionlockdeadzone * 0.3 | 0; 1871 1872 self.ontouchmove = function (e, byiframe) { 1873 1874 if (!self.rail.drag) return true; 1875 1876 if (e.targetTouches && opt.preventmultitouchscrolling) { 1877 if (e.targetTouches.length > 1) return true; // multitouch 1878 } 1879 1880 //if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1881 if (e.pointerType && (e.pointerType === 'mouse' || e.pointerType === e.MSPOINTER_TYPE_MOUSE)) return true; 1882 1883 if (self.rail.drag.pt == 2) { 1884 1885 if (("changedTouches" in e)) { 1886 e.clientX = e.changedTouches[0].clientX; 1887 e.clientY = e.changedTouches[0].clientY; 1888 } 1889 1890 var ofy, ofx; 1891 ofx = ofy = 0; 1892 1893 if (moveneedoffset && !byiframe) { 1894 var wp = self.win.position(); 1895 ofx = -wp.left; 1896 ofy = -wp.top; 1897 } 1898 1899 var fy = e.clientY + ofy; 1900 var my = (fy - self.rail.drag.y); 1901 var fx = e.clientX + ofx; 1902 var mx = (fx - self.rail.drag.x); 1903 1904 var ny = self.rail.drag.st - my; 1905 1906 if (self.ishwscroll && opt.bouncescroll) { 1907 if (ny < 0) { 1908 ny = Math.round(ny / 2); 1909 } else if (ny > self.page.maxh) { 1910 ny = self.page.maxh + Math.round((ny - self.page.maxh) / 2); 1911 } 1912 } else { 1913 if (ny < 0) { 1914 ny = 0; 1915 fy = 0; 1916 } 1917 else if (ny > self.page.maxh) { 1918 ny = self.page.maxh; 1919 fy = 0; 1920 } 1921 if (fy === 0 && !self.hasmoving) { 1922 if (!self.ispage) self.rail.drag = false; 1923 return true; 1924 } 1925 } 1926 1927 var nx = self.getScrollLeft(); 1928 1929 if (self.railh && self.railh.scrollable) { 1930 nx = (self.isrtlmode) ? mx - self.rail.drag.sl : self.rail.drag.sl - mx; 1931 1932 if (self.ishwscroll && opt.bouncescroll) { 1933 if (nx < 0) { 1934 nx = Math.round(nx / 2); 1935 } else if (nx > self.page.maxw) { 1936 nx = self.page.maxw + Math.round((nx - self.page.maxw) / 2); 1937 } 1938 } else { 1939 if (nx < 0) { 1940 nx = 0; 1941 fx = 0; 1942 } 1943 if (nx > self.page.maxw) { 1944 nx = self.page.maxw; 1945 fx = 0; 1946 } 1947 } 1948 1949 } 1950 1951 1952 if (!self.hasmoving) { 1953 1954 if (self.rail.drag.y === e.clientY && self.rail.drag.x === e.clientX) return self.cancelEvent(e); // prevent first useless move event 1955 1956 var ay = Math.abs(my); 1957 var ax = Math.abs(mx); 1958 var dz = opt.directionlockdeadzone; 1959 1960 if (!self.rail.drag.ck) { 1961 if (ay > dz && ax > dz) self.rail.drag.dl = "f"; 1962 else if (ay > dz) self.rail.drag.dl = (ax > locktollerance) ? "f" : "v"; 1963 else if (ax > dz) self.rail.drag.dl = (ay > locktollerance) ? "f" : "h"; 1964 } 1965 else if (self.rail.drag.ck == "v") { 1966 if (ax > dz && ay <= locktollerance) { 1967 self.rail.drag = false; 1968 } 1969 else if (ay > dz) self.rail.drag.dl = "v"; 1970 1971 } 1972 else if (self.rail.drag.ck == "h") { 1973 1974 if (ay > dz && ax <= locktollerance) { 1975 self.rail.drag = false; 1976 } 1977 else if (ax > dz) self.rail.drag.dl = "h"; 1978 1979 } 1980 1981 if (!self.rail.drag.dl) return self.cancelEvent(e); 1982 1983 self.triggerScrollStart(e.clientX, e.clientY, 0, 0, 0); 1984 self.hasmoving = true; 1985 } 1986 1987 if (self.preventclick && !self.preventclick.click) { 1988 self.preventclick.click = self.preventclick.tg.onclick || false; 1989 self.preventclick.tg.onclick = self.onpreventclick; 1990 } 1991 1992 if (self.rail.drag.dl) { 1993 if (self.rail.drag.dl == "v") nx = self.rail.drag.sl; 1994 else if (self.rail.drag.dl == "h") ny = self.rail.drag.st; 1995 } 1996 1997 self.synched("touchmove", function () { 1998 if (self.rail.drag && (self.rail.drag.pt == 2)) { 1999 if (self.prepareTransition) self.resetTransition(); 2000 if (self.rail.scrollable) self.setScrollTop(ny); 2001 self.scrollmom.update(fx, fy); 2002 if (self.railh && self.railh.scrollable) { 2003 self.setScrollLeft(nx); 2004 self.showCursor(ny, nx); 2005 } else { 2006 self.showCursor(ny); 2007 } 2008 if (cap.isie10) _doc.selection.clear(); 2009 } 2010 }); 2011 2012 return self.cancelEvent(e); 2013 2014 } 2015 else if (self.rail.drag.pt == 1) { // drag on cursor 2016 return self.onmousemove(e); 2017 } 2018 2019 }; 2020 2021 self.ontouchstartCursor = function (e, hronly) { 2022 if (self.rail.drag && self.rail.drag.pt != 3) return; 2023 if (self.locked) return self.cancelEvent(e); 2024 self.cancelScroll(); 2025 self.rail.drag = { 2026 x: e.touches[0].clientX, 2027 y: e.touches[0].clientY, 2028 sx: self.scroll.x, 2029 sy: self.scroll.y, 2030 pt: 3, 2031 hr: (!!hronly) 2032 }; 2033 var tg = self.getTarget(e); 2034 if (!self.ispage && cap.hasmousecapture) tg.setCapture(); 2035 if (self.isiframe && !cap.hasmousecapture) { 2036 self.saved.csspointerevents = self.doc.css("pointer-events"); 2037 self.css(self.doc, { "pointer-events": "none" }); 2038 } 2039 return self.cancelEvent(e); 2040 }; 2041 2042 self.ontouchendCursor = function (e) { 2043 if (self.rail.drag) { 2044 if (cap.hasmousecapture) _doc.releaseCapture(); 2045 if (self.isiframe && !cap.hasmousecapture) self.doc.css("pointer-events", self.saved.csspointerevents); 2046 if (self.rail.drag.pt != 3) return; 2047 self.rail.drag = false; 2048 return self.cancelEvent(e); 2049 } 2050 }; 2051 2052 self.ontouchmoveCursor = function (e) { 2053 if (self.rail.drag) { 2054 if (self.rail.drag.pt != 3) return; 2055 2056 self.cursorfreezed = true; 2057 2058 if (self.rail.drag.hr) { 2059 self.scroll.x = self.rail.drag.sx + (e.touches[0].clientX - self.rail.drag.x); 2060 if (self.scroll.x < 0) self.scroll.x = 0; 2061 var mw = self.scrollvaluemaxw; 2062 if (self.scroll.x > mw) self.scroll.x = mw; 2063 } else { 2064 self.scroll.y = self.rail.drag.sy + (e.touches[0].clientY - self.rail.drag.y); 2065 if (self.scroll.y < 0) self.scroll.y = 0; 2066 var my = self.scrollvaluemax; 2067 if (self.scroll.y > my) self.scroll.y = my; 2068 } 2069 2070 self.synched('touchmove', function () { 2071 if (self.rail.drag && (self.rail.drag.pt == 3)) { 2072 self.showCursor(); 2073 if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x * self.scrollratio.x), opt.cursordragspeed); 2074 else self.doScrollTop(Math.round(self.scroll.y * self.scrollratio.y), opt.cursordragspeed); 2075 } 2076 }); 2077 2078 return self.cancelEvent(e); 2079 } 2080 2081 }; 2082 2083 } 2084 2085 self.onmousedown = function (e, hronly) { 2086 if (self.rail.drag && self.rail.drag.pt != 1) return; 2087 if (self.railslocked) return self.cancelEvent(e); 2088 self.cancelScroll(); 2089 self.rail.drag = { 2090 x: e.clientX, 2091 y: e.clientY, 2092 sx: self.scroll.x, 2093 sy: self.scroll.y, 2094 pt: 1, 2095 hr: hronly || false 2096 }; 2097 var tg = self.getTarget(e); 2098 2099 if (cap.hasmousecapture) tg.setCapture(); 2100 if (self.isiframe && !cap.hasmousecapture) { 2101 self.saved.csspointerevents = self.doc.css("pointer-events"); 2102 self.css(self.doc, { 2103 "pointer-events": "none" 2104 }); 2105 } 2106 self.hasmoving = false; 2107 return self.cancelEvent(e); 2108 }; 2109 2110 self.onmouseup = function (e) { 2111 if (self.rail.drag) { 2112 if (self.rail.drag.pt != 1) return true; 2113 2114 if (cap.hasmousecapture) _doc.releaseCapture(); 2115 if (self.isiframe && !cap.hasmousecapture) self.doc.css("pointer-events", self.saved.csspointerevents); 2116 self.rail.drag = false; 2117 self.cursorfreezed = false; 2118 if (self.hasmoving) self.triggerScrollEnd(); 2119 return self.cancelEvent(e); 2120 } 2121 }; 2122 2123 self.onmousemove = function (e) { 2124 if (self.rail.drag) { 2125 if (self.rail.drag.pt !== 1) return; 2126 2127 if (cap.ischrome && e.which === 0) return self.onmouseup(e); 2128 2129 self.cursorfreezed = true; 2130 2131 if (!self.hasmoving) self.triggerScrollStart(e.clientX, e.clientY, 0, 0, 0); 2132 2133 self.hasmoving = true; 2134 2135 if (self.rail.drag.hr) { 2136 self.scroll.x = self.rail.drag.sx + (e.clientX - self.rail.drag.x); 2137 if (self.scroll.x < 0) self.scroll.x = 0; 2138 var mw = self.scrollvaluemaxw; 2139 if (self.scroll.x > mw) self.scroll.x = mw; 2140 } else { 2141 self.scroll.y = self.rail.drag.sy + (e.clientY - self.rail.drag.y); 2142 if (self.scroll.y < 0) self.scroll.y = 0; 2143 var my = self.scrollvaluemax; 2144 if (self.scroll.y > my) self.scroll.y = my; 2145 } 2146 2147 self.synched('mousemove', function () { 2148 2149 if (self.cursorfreezed) { 2150 self.showCursor(); 2151 2152 if (self.rail.drag.hr) { 2153 self.scrollLeft(Math.round(self.scroll.x * self.scrollratio.x)); 2154 } else { 2155 self.scrollTop(Math.round(self.scroll.y * self.scrollratio.y)); 2156 } 2157 2158 } 2159 }); 2160 2161 return self.cancelEvent(e); 2162 } 2163 else { 2164 self.checkarea = 0; 2165 } 2166 }; 2167 2168 if (cap.cantouch || opt.emulatetouch) { 2169 2170 self.onpreventclick = function (e) { 2171 if (self.preventclick) { 2172 self.preventclick.tg.onclick = self.preventclick.click; 2173 self.preventclick = false; 2174 return self.cancelEvent(e); 2175 } 2176 }; 2177 2178 self.onclick = (cap.isios) ? false : function (e) { // it needs to check IE11 ??? 2179 if (self.lastmouseup) { 2180 self.lastmouseup = false; 2181 return self.cancelEvent(e); 2182 } else { 2183 return true; 2184 } 2185 }; 2186 2187 if (opt.grabcursorenabled && cap.cursorgrabvalue) { 2188 self.css((self.ispage) ? self.doc : self.win, { 2189 'cursor': cap.cursorgrabvalue 2190 }); 2191 self.css(self.rail, { 2192 'cursor': cap.cursorgrabvalue 2193 }); 2194 } 2195 2196 } else { 2197 2198 var checkSelectionScroll = function (e) { 2199 if (!self.selectiondrag) return; 2200 2201 if (e) { 2202 var ww = self.win.outerHeight(); 2203 var df = (e.pageY - self.selectiondrag.top); 2204 if (df > 0 && df < ww) df = 0; 2205 if (df >= ww) df -= ww; 2206 self.selectiondrag.df = df; 2207 } 2208 if (self.selectiondrag.df === 0) return; 2209 2210 var rt = -(self.selectiondrag.df*2/6)|0; 2211 self.doScrollBy(rt); 2212 2213 self.debounced("doselectionscroll", function () { 2214 checkSelectionScroll(); 2215 }, 50); 2216 }; 2217 2218 if ("getSelection" in _doc) { // A grade - Major browsers 2219 self.hasTextSelected = function () { 2220 return (_doc.getSelection().rangeCount > 0); 2221 }; 2222 } else if ("selection" in _doc) { //IE9- 2223 self.hasTextSelected = function () { 2224 return (_doc.selection.type != "None"); 2225 }; 2226 } else { 2227 self.hasTextSelected = function () { // no support 2228 return false; 2229 }; 2230 } 2231 2232 self.onselectionstart = function (e) { 2233 // More testing - severe chrome issues 2234 /* 2235 if (!self.haswrapper&&(e.which&&e.which==2)) { // fool browser to manage middle button scrolling 2236 self.win.css({'overflow':'auto'}); 2237 setTimeout(function(){ 2238 self.win.css({'overflow':'hidden'}); 2239 },10); 2240 return true; 2241 } 2242 */ 2243 if (self.ispage) return; 2244 self.selectiondrag = self.win.offset(); 2245 }; 2246 2247 self.onselectionend = function (e) { 2248 self.selectiondrag = false; 2249 }; 2250 self.onselectiondrag = function (e) { 2251 if (!self.selectiondrag) return; 2252 if (self.hasTextSelected()) self.debounced("selectionscroll", function () { 2253 checkSelectionScroll(e); 2254 }, 250); 2255 }; 2256 } 2257 2258 if (cap.hasw3ctouch) { //IE11+ 2259 self.css((self.ispage) ? $("html") : self.win, { 'touch-action': 'none' }); 2260 self.css(self.rail, { 2261 'touch-action': 'none' 2262 }); 2263 self.css(self.cursor, { 2264 'touch-action': 'none' 2265 }); 2266 self.bind(self.win, "pointerdown", self.ontouchstart); 2267 self.bind(_doc, "pointerup", self.ontouchend); 2268 self.delegate(_doc, "pointermove", self.ontouchmove); 2269 } else if (cap.hasmstouch) { //IE10 2270 self.css((self.ispage) ? $("html") : self.win, { '-ms-touch-action': 'none' }); 2271 self.css(self.rail, { 2272 '-ms-touch-action': 'none' 2273 }); 2274 self.css(self.cursor, { 2275 '-ms-touch-action': 'none' 2276 }); 2277 self.bind(self.win, "MSPointerDown", self.ontouchstart); 2278 self.bind(_doc, "MSPointerUp", self.ontouchend); 2279 self.delegate(_doc, "MSPointerMove", self.ontouchmove); 2280 self.bind(self.cursor, "MSGestureHold", function (e) { 2281 e.preventDefault(); 2282 }); 2283 self.bind(self.cursor, "contextmenu", function (e) { 2284 e.preventDefault(); 2285 }); 2286 } else if (cap.cantouch) { // smartphones/touch devices 2287 self.bind(self.win, "touchstart", self.ontouchstart, false, true); 2288 self.bind(_doc, "touchend", self.ontouchend, false, true); 2289 self.bind(_doc, "touchcancel", self.ontouchend, false, true); 2290 self.delegate(_doc, "touchmove", self.ontouchmove, false, true); 2291 } 2292 2293 if (opt.emulatetouch) { 2294 self.bind(self.win, "mousedown", self.ontouchstart, false, true); 2295 self.bind(_doc, "mouseup", self.ontouchend, false, true); 2296 self.bind(_doc, "mousemove", self.ontouchmove, false, true); 2297 } 2298 2299 if (opt.cursordragontouch || (!cap.cantouch && !opt.emulatetouch)) { 2300 2301 self.rail.css({ 2302 cursor: "default" 2303 }); 2304 self.railh && self.railh.css({ 2305 cursor: "default" 2306 }); 2307 2308 self.jqbind(self.rail, "mouseenter", function () { 2309 if (!self.ispage && !self.win.is(":visible")) return false; 2310 if (self.canshowonmouseevent) self.showCursor(); 2311 self.rail.active = true; 2312 }); 2313 self.jqbind(self.rail, "mouseleave", function () { 2314 self.rail.active = false; 2315 if (!self.rail.drag) self.hideCursor(); 2316 }); 2317 2318 if (opt.sensitiverail) { 2319 self.bind(self.rail, "click", function (e) { 2320 self.doRailClick(e, false, false); 2321 }); 2322 self.bind(self.rail, "dblclick", function (e) { 2323 self.doRailClick(e, true, false); 2324 }); 2325 self.bind(self.cursor, "click", function (e) { 2326 self.cancelEvent(e); 2327 }); 2328 self.bind(self.cursor, "dblclick", function (e) { 2329 self.cancelEvent(e); 2330 }); 2331 } 2332 2333 if (self.railh) { 2334 self.jqbind(self.railh, "mouseenter", function () { 2335 if (!self.ispage && !self.win.is(":visible")) return false; 2336 if (self.canshowonmouseevent) self.showCursor(); 2337 self.rail.active = true; 2338 }); 2339 self.jqbind(self.railh, "mouseleave", function () { 2340 self.rail.active = false; 2341 if (!self.rail.drag) self.hideCursor(); 2342 }); 2343 2344 if (opt.sensitiverail) { 2345 self.bind(self.railh, "click", function (e) { 2346 self.doRailClick(e, false, true); 2347 }); 2348 self.bind(self.railh, "dblclick", function (e) { 2349 self.doRailClick(e, true, true); 2350 }); 2351 self.bind(self.cursorh, "click", function (e) { 2352 self.cancelEvent(e); 2353 }); 2354 self.bind(self.cursorh, "dblclick", function (e) { 2355 self.cancelEvent(e); 2356 }); 2357 } 2358 2359 } 2360 2361 } 2362 2363 if (opt.cursordragontouch && (this.istouchcapable || cap.cantouch)) { 2364 self.bind(self.cursor, "touchstart", self.ontouchstartCursor); 2365 self.bind(self.cursor, "touchmove", self.ontouchmoveCursor); 2366 self.bind(self.cursor, "touchend", self.ontouchendCursor); 2367 self.cursorh && self.bind(self.cursorh, "touchstart", function (e) { 2368 self.ontouchstartCursor(e, true); 2369 }); 2370 self.cursorh && self.bind(self.cursorh, "touchmove", self.ontouchmoveCursor); 2371 self.cursorh && self.bind(self.cursorh, "touchend", self.ontouchendCursor); 2372 } 2373 2374// if (!cap.cantouch && !opt.emulatetouch) { 2375 if (!opt.emulatetouch && !cap.isandroid && !cap.isios) { 2376 2377 self.bind((cap.hasmousecapture) ? self.win : _doc, "mouseup", self.onmouseup); 2378 self.bind(_doc, "mousemove", self.onmousemove); 2379 if (self.onclick) self.bind(_doc, "click", self.onclick); 2380 2381 self.bind(self.cursor, "mousedown", self.onmousedown); 2382 self.bind(self.cursor, "mouseup", self.onmouseup); 2383 2384 if (self.railh) { 2385 self.bind(self.cursorh, "mousedown", function (e) { 2386 self.onmousedown(e, true); 2387 }); 2388 self.bind(self.cursorh, "mouseup", self.onmouseup); 2389 } 2390 2391 if (!self.ispage && opt.enablescrollonselection) { 2392 self.bind(self.win[0], "mousedown", self.onselectionstart); 2393 self.bind(_doc, "mouseup", self.onselectionend); 2394 self.bind(self.cursor, "mouseup", self.onselectionend); 2395 if (self.cursorh) self.bind(self.cursorh, "mouseup", self.onselectionend); 2396 self.bind(_doc, "mousemove", self.onselectiondrag); 2397 } 2398 2399 if (self.zoom) { 2400 self.jqbind(self.zoom, "mouseenter", function () { 2401 if (self.canshowonmouseevent) self.showCursor(); 2402 self.rail.active = true; 2403 }); 2404 self.jqbind(self.zoom, "mouseleave", function () { 2405 self.rail.active = false; 2406 if (!self.rail.drag) self.hideCursor(); 2407 }); 2408 } 2409 2410 } else { 2411 2412 self.bind((cap.hasmousecapture) ? self.win : _doc, "mouseup", self.ontouchend); 2413 if (self.onclick) self.bind(_doc, "click", self.onclick); 2414 2415 if (opt.cursordragontouch) { 2416 self.bind(self.cursor, "mousedown", self.onmousedown); 2417 self.bind(self.cursor, "mouseup", self.onmouseup); 2418 self.cursorh && self.bind(self.cursorh, "mousedown", function (e) { 2419 self.onmousedown(e, true); 2420 }); 2421 self.cursorh && self.bind(self.cursorh, "mouseup", self.onmouseup); 2422 } else { 2423 self.bind(self.rail, "mousedown", function (e) { e.preventDefault(); }); // prevent text selection 2424 self.railh && self.bind(self.railh, "mousedown", function (e) { e.preventDefault(); }); 2425 } 2426 2427 } 2428 2429 2430 if (opt.enablemousewheel) { 2431 if (!self.isiframe) self.mousewheel((cap.isie && self.ispage) ? _doc : self.win, self.onmousewheel); 2432 self.mousewheel(self.rail, self.onmousewheel); 2433 if (self.railh) self.mousewheel(self.railh, self.onmousewheelhr); 2434 } 2435 2436 if (!self.ispage && !cap.cantouch && !(/HTML|^BODY/.test(self.win[0].nodeName))) { 2437 if (!self.win.attr("tabindex")) self.win.attr({ 2438 "tabindex": ++tabindexcounter 2439 }); 2440 2441 self.bind(self.win, "focus", function (e) { // better using native events 2442 domfocus = (self.getTarget(e)).id || self.getTarget(e) || false; 2443 self.hasfocus = true; 2444 if (self.canshowonmouseevent) self.noticeCursor(); 2445 }); 2446 self.bind(self.win, "blur", function (e) { // * 2447 domfocus = false; 2448 self.hasfocus = false; 2449 }); 2450 2451 self.bind(self.win, "mouseenter", function (e) { // * 2452 mousefocus = (self.getTarget(e)).id || self.getTarget(e) || false; 2453 self.hasmousefocus = true; 2454 if (self.canshowonmouseevent) self.noticeCursor(); 2455 }); 2456 self.bind(self.win, "mouseleave", function (e) { // * 2457 mousefocus = false; 2458 self.hasmousefocus = false; 2459 if (!self.rail.drag) self.hideCursor(); 2460 }); 2461 2462 } 2463 2464 2465 //Thanks to http://www.quirksmode.org !! 2466 self.onkeypress = function (e) { 2467 if (self.railslocked && self.page.maxh === 0) return true; 2468 2469 e = e || _win.event; 2470 var tg = self.getTarget(e); 2471 if (tg && /INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) { 2472 var tp = tg.getAttribute('type') || tg.type || false; 2473 if ((!tp) || !(/submit|button|cancel/i.tp)) return true; 2474 } 2475 2476 if ($(tg).attr('contenteditable')) return true; 2477 2478 if (self.hasfocus || (self.hasmousefocus && !domfocus) || (self.ispage && !domfocus && !mousefocus)) { 2479 var key = e.keyCode; 2480 2481 if (self.railslocked && key != 27) return self.cancelEvent(e); 2482 2483 var ctrl = e.ctrlKey || false; 2484 var shift = e.shiftKey || false; 2485 2486 var ret = false; 2487 switch (key) { 2488 case 38: 2489 case 63233: //safari 2490 self.doScrollBy(24 * 3); 2491 ret = true; 2492 break; 2493 case 40: 2494 case 63235: //safari 2495 self.doScrollBy(-24 * 3); 2496 ret = true; 2497 break; 2498 case 37: 2499 case 63232: //safari 2500 if (self.railh) { 2501 (ctrl) ? self.doScrollLeft(0) : self.doScrollLeftBy(24 * 3); 2502 ret = true; 2503 } 2504 break; 2505 case 39: 2506 case 63234: //safari 2507 if (self.railh) { 2508 (ctrl) ? self.doScrollLeft(self.page.maxw) : self.doScrollLeftBy(-24 * 3); 2509 ret = true; 2510 } 2511 break; 2512 case 33: 2513 case 63276: // safari 2514 self.doScrollBy(self.view.h); 2515 ret = true; 2516 break; 2517 case 34: 2518 case 63277: // safari 2519 self.doScrollBy(-self.view.h); 2520 ret = true; 2521 break; 2522 case 36: 2523 case 63273: // safari 2524 (self.railh && ctrl) ? self.doScrollPos(0, 0) : self.doScrollTo(0); 2525 ret = true; 2526 break; 2527 case 35: 2528 case 63275: // safari 2529 (self.railh && ctrl) ? self.doScrollPos(self.page.maxw, self.page.maxh) : self.doScrollTo(self.page.maxh); 2530 ret = true; 2531 break; 2532 case 32: 2533 if (opt.spacebarenabled) { 2534 (shift) ? self.doScrollBy(self.view.h) : self.doScrollBy(-self.view.h); 2535 ret = true; 2536 } 2537 break; 2538 case 27: // ESC 2539 if (self.zoomactive) { 2540 self.doZoom(); 2541 ret = true; 2542 } 2543 break; 2544 } 2545 if (ret) return self.cancelEvent(e); 2546 } 2547 }; 2548 2549 if (opt.enablekeyboard) self.bind(_doc, (cap.isopera && !cap.isopera12) ? "keypress" : "keydown", self.onkeypress); 2550 2551 self.bind(_doc, "keydown", function (e) { 2552 var ctrl = e.ctrlKey || false; 2553 if (ctrl) self.wheelprevented = true; 2554 }); 2555 self.bind(_doc, "keyup", function (e) { 2556 var ctrl = e.ctrlKey || false; 2557 if (!ctrl) self.wheelprevented = false; 2558 }); 2559 self.bind(_win, "blur", function (e) { 2560 self.wheelprevented = false; 2561 }); 2562 2563 self.bind(_win, 'resize', self.onscreenresize); 2564 self.bind(_win, 'orientationchange', self.onscreenresize); 2565 2566 self.bind(_win, "load", self.lazyResize); 2567 2568 if (cap.ischrome && !self.ispage && !self.haswrapper) { //chrome void scrollbar bug - it persists in version 26 2569 var tmp = self.win.attr("style"); 2570 var ww = parseFloat(self.win.css("width")) + 1; 2571 self.win.css('width', ww); 2572 self.synched("chromefix", function () { 2573 self.win.attr("style", tmp); 2574 }); 2575 } 2576 2577 2578 // Trying a cross-browser implementation - good luck! 2579 2580 self.onAttributeChange = function (e) { 2581 self.lazyResize(self.isieold ? 250 : 30); 2582 }; 2583 2584 if (opt.enableobserver) { 2585 2586 if ((!self.isie11) && (ClsMutationObserver !== false)) { // IE11 crashes #568 2587 self.observerbody = new ClsMutationObserver(function (mutations) { 2588 mutations.forEach(function (mut) { 2589 if (mut.type == "attributes") { 2590 return ($body.hasClass("modal-open") && $body.hasClass("modal-dialog") && !$.contains($('.modal-dialog')[0], self.doc[0])) ? self.hide() : self.show(); // Support for Bootstrap modal; Added check if the nice scroll element is inside a modal 2591 } 2592 }); 2593 if (self.me.clientWidth != self.page.width || self.me.clientHeight != self.page.height) return self.lazyResize(30); 2594 }); 2595 self.observerbody.observe(_doc.body, { 2596 childList: true, 2597 subtree: true, 2598 characterData: false, 2599 attributes: true, 2600 attributeFilter: ['class'] 2601 }); 2602 } 2603 2604 if (!self.ispage && !self.haswrapper) { 2605 2606 var _dom = self.win[0]; 2607 2608 // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content 2609 if (ClsMutationObserver !== false) { 2610 self.observer = new ClsMutationObserver(function (mutations) { 2611 mutations.forEach(self.onAttributeChange); 2612 }); 2613 self.observer.observe(_dom, { 2614 childList: true, 2615 characterData: false, 2616 attributes: true, 2617 subtree: false 2618 }); 2619 self.observerremover = new ClsMutationObserver(function (mutations) { 2620 mutations.forEach(function (mo) { 2621 if (mo.removedNodes.length > 0) { 2622 for (var dd in mo.removedNodes) { 2623 if (!!self && (mo.removedNodes[dd] === _dom)) return self.remove(); 2624 } 2625 } 2626 }); 2627 }); 2628 self.observerremover.observe(_dom.parentNode, { 2629 childList: true, 2630 characterData: false, 2631 attributes: false, 2632 subtree: false 2633 }); 2634 } else { 2635 self.bind(_dom, (cap.isie && !cap.isie9) ? "propertychange" : "DOMAttrModified", self.onAttributeChange); 2636 if (cap.isie9) _dom.attachEvent("onpropertychange", self.onAttributeChange); //IE9 DOMAttrModified bug 2637 self.bind(_dom, "DOMNodeRemoved", function (e) { 2638 if (e.target === _dom) self.remove(); 2639 }); 2640 } 2641 } 2642 2643 } 2644 2645 // 2646 2647 if (!self.ispage && opt.boxzoom) self.bind(_win, "resize", self.resizeZoom); 2648 if (self.istextarea) { 2649 self.bind(self.win, "keydown", self.lazyResize); 2650 self.bind(self.win, "mouseup", self.lazyResize); 2651 } 2652 2653 self.lazyResize(30); 2654 2655 } 2656 2657 if (this.doc[0].nodeName == 'IFRAME') { 2658 var oniframeload = function () { 2659 self.iframexd = false; 2660 var doc; 2661 try { 2662 doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow._doc; 2663 var a = doc.domain; 2664 } catch (e) { 2665 self.iframexd = true; 2666 doc = false; 2667 } 2668 2669 if (self.iframexd) { 2670 if ("console" in _win) console.log('NiceScroll error: policy restriced iframe'); 2671 return true; //cross-domain - I can't manage this 2672 } 2673 2674 self.forcescreen = true; 2675 2676 if (self.isiframe) { 2677 self.iframe = { 2678 "doc": $(doc), 2679 "html": self.doc.contents().find('html')[0], 2680 "body": self.doc.contents().find('body')[0] 2681 }; 2682 self.getContentSize = function () { 2683 return { 2684 w: Math.max(self.iframe.html.scrollWidth, self.iframe.body.scrollWidth), 2685 h: Math.max(self.iframe.html.scrollHeight, self.iframe.body.scrollHeight) 2686 }; 2687 }; 2688 self.docscroll = $(self.iframe.body); 2689 } 2690 2691 if (!cap.isios && opt.iframeautoresize && !self.isiframe) { 2692 self.win.scrollTop(0); // reset position 2693 self.doc.height(""); //reset height to fix browser bug 2694 var hh = Math.max(doc.getElementsByTagName('html')[0].scrollHeight, doc.body.scrollHeight); 2695 self.doc.height(hh); 2696 } 2697 self.lazyResize(30); 2698 2699 self.css($(self.iframe.body), _scrollyhidden); 2700 2701 if (cap.isios && self.haswrapper) { 2702 self.css($(doc.body), { 2703 '-webkit-transform': 'translate3d(0,0,0)' 2704 }); // avoid iFrame content clipping - thanks to http://blog.derraab.com/2012/04/02/avoid-iframe-content-clipping-with-css-transform-on-ios/ 2705 } 2706 2707 if ('contentWindow' in this) { 2708 self.bind(this.contentWindow, "scroll", self.onscroll); //IE8 & minor 2709 } else { 2710 self.bind(doc, "scroll", self.onscroll); 2711 } 2712 2713 if (opt.enablemousewheel) { 2714 self.mousewheel(doc, self.onmousewheel); 2715 } 2716 2717 if (opt.enablekeyboard) self.bind(doc, (cap.isopera) ? "keypress" : "keydown", self.onkeypress); 2718 2719 if (cap.cantouch) { 2720 self.bind(doc, "touchstart", self.ontouchstart); 2721 self.bind(doc, "touchmove", self.ontouchmove); 2722 } 2723 else if (opt.emulatetouch) { 2724 self.bind(doc, "mousedown", self.ontouchstart); 2725 self.bind(doc, "mousemove", function (e) { 2726 return self.ontouchmove(e, true); 2727 }); 2728 if (opt.grabcursorenabled && cap.cursorgrabvalue) self.css($(doc.body), { 2729 'cursor': cap.cursorgrabvalue 2730 }); 2731 } 2732 2733 self.bind(doc, "mouseup", self.ontouchend); 2734 2735 if (self.zoom) { 2736 if (opt.dblclickzoom) self.bind(doc, 'dblclick', self.doZoom); 2737 if (self.ongesturezoom) self.bind(doc, "gestureend", self.ongesturezoom); 2738 } 2739 }; 2740 2741 if (this.doc[0].readyState && this.doc[0].readyState === "complete") { 2742 setTimeout(function () { 2743 oniframeload.call(self.doc[0], false); 2744 }, 500); 2745 } 2746 self.bind(this.doc, "load", oniframeload); 2747 2748 } 2749 2750 }; 2751 2752 this.showCursor = function (py, px) { 2753 if (self.cursortimeout) { 2754 clearTimeout(self.cursortimeout); 2755 self.cursortimeout = 0; 2756 } 2757 if (!self.rail) return; 2758 if (self.autohidedom) { 2759 self.autohidedom.stop().css({ 2760 opacity: opt.cursoropacitymax 2761 }); 2762 self.cursoractive = true; 2763 } 2764 2765 if (!self.rail.drag || self.rail.drag.pt != 1) { 2766 if (py !== undefined && py !== false) { 2767 self.scroll.y = (py / self.scrollratio.y) | 0; 2768 } 2769 if (px !== undefined) { 2770 self.scroll.x = (px / self.scrollratio.x) | 0; 2771 } 2772 } 2773 2774 self.cursor.css({ 2775 height: self.cursorheight, 2776 top: self.scroll.y 2777 }); 2778 if (self.cursorh) { 2779 var lx = (self.hasreversehr) ? self.scrollvaluemaxw - self.scroll.x : self.scroll.x; 2780 self.cursorh.css({ 2781 width: self.cursorwidth, 2782 left: (!self.rail.align && self.rail.visibility) ? lx + self.rail.width : lx 2783 }); 2784 self.cursoractive = true; 2785 } 2786 2787 if (self.zoom) self.zoom.stop().css({ 2788 opacity: opt.cursoropacitymax 2789 }); 2790 }; 2791 2792 this.hideCursor = function (tm) { 2793 if (self.cursortimeout) return; 2794 if (!self.rail) return; 2795 if (!self.autohidedom) return; 2796 2797 if (self.hasmousefocus && opt.autohidemode === "leave") return; 2798 self.cursortimeout = setTimeout(function () { 2799 if (!self.rail.active || !self.showonmouseevent) { 2800 self.autohidedom.stop().animate({ 2801 opacity: opt.cursoropacitymin 2802 }); 2803 if (self.zoom) self.zoom.stop().animate({ 2804 opacity: opt.cursoropacitymin 2805 }); 2806 self.cursoractive = false; 2807 } 2808 self.cursortimeout = 0; 2809 }, tm || opt.hidecursordelay); 2810 }; 2811 2812 this.noticeCursor = function (tm, py, px) { 2813 self.showCursor(py, px); 2814 if (!self.rail.active) self.hideCursor(tm); 2815 }; 2816 2817 this.getContentSize = 2818 (self.ispage) ? 2819 function () { 2820 return { 2821 w: Math.max(_doc.body.scrollWidth, _doc.documentElement.scrollWidth), 2822 h: Math.max(_doc.body.scrollHeight, _doc.documentElement.scrollHeight) 2823 }; 2824 } : (self.haswrapper) ? 2825 function () { 2826 return { 2827 w: self.doc[0].offsetWidth, 2828 h: self.doc[0].offsetHeight 2829 }; 2830 } : function () { 2831 return { 2832 w: self.docscroll[0].scrollWidth, 2833 h: self.docscroll[0].scrollHeight 2834 }; 2835 }; 2836 2837 this.onResize = function (e, page) { 2838 2839 if (!self || !self.win) return false; 2840 2841 var premaxh = self.page.maxh, 2842 premaxw = self.page.maxw, 2843 previewh = self.view.h, 2844 previeww = self.view.w; 2845 2846 self.view = { 2847 w: (self.ispage) ? self.win.width() : self.win[0].clientWidth, 2848 h: (self.ispage) ? self.win.height() : self.win[0].clientHeight 2849 }; 2850 2851 self.page = (page) ? page : self.getContentSize(); 2852 2853 self.page.maxh = Math.max(0, self.page.h - self.view.h); 2854 self.page.maxw = Math.max(0, self.page.w - self.view.w); 2855 2856 if ((self.page.maxh == premaxh) && (self.page.maxw == premaxw) && (self.view.w == previeww) && (self.view.h == previewh)) { 2857 // test position 2858 if (!self.ispage) { 2859 var pos = self.win.offset(); 2860 if (self.lastposition) { 2861 var lst = self.lastposition; 2862 if ((lst.top == pos.top) && (lst.left == pos.left)) return self; //nothing to do 2863 } 2864 self.lastposition = pos; 2865 } else { 2866 return self; //nothing to do 2867 } 2868 } 2869 2870 if (self.page.maxh === 0) { 2871 self.hideRail(); 2872 self.scrollvaluemax = 0; 2873 self.scroll.y = 0; 2874 self.scrollratio.y = 0; 2875 self.cursorheight = 0; 2876 self.setScrollTop(0); 2877 if (self.rail) self.rail.scrollable = false; 2878 } else { 2879 self.page.maxh -= (opt.railpadding.top + opt.railpadding.bottom); 2880 self.rail.scrollable = true; 2881 } 2882 2883 if (self.page.maxw === 0) { 2884 self.hideRailHr(); 2885 self.scrollvaluemaxw = 0; 2886 self.scroll.x = 0; 2887 self.scrollratio.x = 0; 2888 self.cursorwidth = 0; 2889 self.setScrollLeft(0); 2890 if (self.railh) { 2891 self.railh.scrollable = false; 2892 } 2893 } else { 2894 self.page.maxw -= (opt.railpadding.left + opt.railpadding.right); 2895 if (self.railh) self.railh.scrollable = (opt.horizrailenabled); 2896 } 2897 2898 self.railslocked = (self.locked) || ((self.page.maxh === 0) && (self.page.maxw === 0)); 2899 if (self.railslocked) { 2900 if (!self.ispage) self.updateScrollBar(self.view); 2901 return false; 2902 } 2903 2904 if (!self.hidden) { 2905 if (!self.rail.visibility) self.showRail(); 2906 if (self.railh && !self.railh.visibility) self.showRailHr(); 2907 } 2908 2909 if (self.istextarea && self.win.css('resize') && self.win.css('resize') != 'none') self.view.h -= 20; 2910 2911 self.cursorheight = Math.min(self.view.h, Math.round(self.view.h * (self.view.h / self.page.h))); 2912 self.cursorheight = (opt.cursorfixedheight) ? opt.cursorfixedheight : Math.max(opt.cursorminheight, self.cursorheight); 2913 2914 self.cursorwidth = Math.min(self.view.w, Math.round(self.view.w * (self.view.w / self.page.w))); 2915 self.cursorwidth = (opt.cursorfixedheight) ? opt.cursorfixedheight : Math.max(opt.cursorminheight, self.cursorwidth); 2916 2917 self.scrollvaluemax = self.view.h - self.cursorheight - (opt.railpadding.top + opt.railpadding.bottom); 2918 if (!self.hasborderbox) self.scrollvaluemax -= self.cursor[0].offsetHeight - self.cursor[0].clientHeight; 2919 2920 if (self.railh) { 2921 self.railh.width = (self.page.maxh > 0) ? (self.view.w - self.rail.width) : self.view.w; 2922 self.scrollvaluemaxw = self.railh.width - self.cursorwidth - (opt.railpadding.left + opt.railpadding.right); 2923 } 2924 2925 if (!self.ispage) self.updateScrollBar(self.view); 2926 2927 self.scrollratio = { 2928 x: (self.page.maxw / self.scrollvaluemaxw), 2929 y: (self.page.maxh / self.scrollvaluemax) 2930 }; 2931 2932 var sy = self.getScrollTop(); 2933 if (sy > self.page.maxh) { 2934 self.doScrollTop(self.page.maxh); 2935 } else { 2936 self.scroll.y = (self.getScrollTop() / self.scrollratio.y) | 0; 2937 self.scroll.x = (self.getScrollLeft() / self.scrollratio.x) | 0; 2938 if (self.cursoractive) self.noticeCursor(); 2939 } 2940 2941 if (self.scroll.y && (self.getScrollTop() === 0)) self.doScrollTo((self.scroll.y * self.scrollratio.y)|0); 2942 2943 return self; 2944 }; 2945 2946 this.resize = self.onResize; 2947 2948 var hlazyresize = 0; 2949 2950 this.onscreenresize = function(e) { 2951 clearTimeout(hlazyresize); 2952 2953 var hiderails = (!self.ispage && !self.haswrapper); 2954 if (hiderails) self.hideRails(); 2955 2956 hlazyresize = setTimeout(function () { 2957 if (self) { 2958 if (hiderails) self.showRails(); 2959 self.resize(); 2960 } 2961 hlazyresize=0; 2962 }, 120); 2963 }; 2964 2965 this.lazyResize = function (tm) { // event debounce 2966 2967 clearTimeout(hlazyresize); 2968 2969 tm = isNaN(tm) ? 240 : tm; 2970 2971 hlazyresize = setTimeout(function () { 2972 self && self.resize(); 2973 hlazyresize=0; 2974 }, tm); 2975 2976 return self; 2977 2978 }; 2979 2980 // derived by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel 2981 function _modernWheelEvent(dom, name, fn, bubble) { 2982 self._bind(dom, name, function (e) { 2983 e = e || _win.event; 2984 var event = { 2985 original: e, 2986 target: e.target || e.srcElement, 2987 type: "wheel", 2988 deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1, 2989 deltaX: 0, 2990 deltaZ: 0, 2991 preventDefault: function () { 2992 e.preventDefault ? e.preventDefault() : e.returnValue = false; 2993 return false; 2994 }, 2995 stopImmediatePropagation: function () { 2996 (e.stopImmediatePropagation) ? e.stopImmediatePropagation() : e.cancelBubble = true; 2997 } 2998 }; 2999 3000 if (name == "mousewheel") { 3001 e.wheelDeltaX && (event.deltaX = -1 / 40 * e.wheelDeltaX); 3002 e.wheelDeltaY && (event.deltaY = -1 / 40 * e.wheelDeltaY); 3003 !event.deltaY && !event.deltaX && (event.deltaY = -1 / 40 * e.wheelDelta); 3004 } else { 3005 event.deltaY = e.detail; 3006 } 3007 3008 return fn.call(dom, event); 3009 }, bubble); 3010 } 3011 3012 3013 3014 this.jqbind = function (dom, name, fn) { // use jquery bind for non-native events (mouseenter/mouseleave) 3015 self.events.push({ 3016 e: dom, 3017 n: name, 3018 f: fn, 3019 q: true 3020 }); 3021 $(dom).on(name, fn); 3022 }; 3023 3024 this.mousewheel = function (dom, fn, bubble) { // bind mousewheel 3025 var el = ("jquery" in dom) ? dom[0] : dom; 3026 if ("onwheel" in _doc.createElement("div")) { // Modern browsers support "wheel" 3027 self._bind(el, "wheel", fn, bubble || false); 3028 } else { 3029 var wname = (_doc.onmousewheel !== undefined) ? "mousewheel" : "DOMMouseScroll"; // older Webkit+IE support or older Firefox 3030 _modernWheelEvent(el, wname, fn, bubble || false); 3031 if (wname == "DOMMouseScroll") _modernWheelEvent(el, "MozMousePixelScroll", fn, bubble || false); // Firefox legacy 3032 } 3033 }; 3034 3035 var passiveSupported = false; 3036 3037 if (cap.haseventlistener) { // W3C standard event model 3038 3039 // thanks to https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener 3040 try { var options = Object.defineProperty({}, "passive", { get: function () { passiveSupported = !0; } }); _win.addEventListener("test", null, options); } catch (err) { } 3041 3042 this.stopPropagation = function (e) { 3043 if (!e) return false; 3044 e = (e.original) ? e.original : e; 3045 e.stopPropagation(); 3046 return false; 3047 }; 3048 3049 this.cancelEvent = function(e) { 3050 if (e.cancelable) e.preventDefault(); 3051 e.stopImmediatePropagation(); 3052 if (e.preventManipulation) e.preventManipulation(); // IE10+ 3053 return false; 3054 }; 3055 3056 } else { 3057 3058 // inspired from https://gist.github.com/jonathantneal/2415137 3059 3060 Event.prototype.preventDefault = function () { 3061 this.returnValue = false; 3062 }; 3063 3064 Event.prototype.stopPropagation = function () { 3065 this.cancelBubble = true; 3066 }; 3067 3068 _win.constructor.prototype.addEventListener = _doc.constructor.prototype.addEventListener = Element.prototype.addEventListener = function (type, listener, useCapture) { 3069 this.attachEvent("on" + type, listener); 3070 }; 3071 _win.constructor.prototype.removeEventListener = _doc.constructor.prototype.removeEventListener = Element.prototype.removeEventListener = function (type, listener, useCapture) { 3072 this.detachEvent("on" + type, listener); 3073 }; 3074 3075 // Thanks to http://www.switchonthecode.com !! 3076 this.cancelEvent = function (e) { 3077 e = e || _win.event; 3078 if (e) { 3079 e.cancelBubble = true; 3080 e.cancel = true; 3081 e.returnValue = false; 3082 } 3083 return false; 3084 }; 3085 3086 this.stopPropagation = function (e) { 3087 e = e || _win.event; 3088 if (e) e.cancelBubble = true; 3089 return false; 3090 }; 3091 3092 } 3093 3094 this.delegate = function (dom, name, fn, bubble, active) { 3095 3096 var de = delegatevents[name] || false; 3097 3098 if (!de) { 3099 3100 de = { 3101 a: [], 3102 l: [], 3103 f: function (e) { 3104 var lst = de.l, l = lst.length - 1; 3105 var r = false; 3106 for (var a = l; a >= 0; a--) { 3107 r = lst[a].call(e.target, e); 3108 if (r === false) return false; 3109 } 3110 return r; 3111 } 3112 }; 3113 3114 self.bind(dom, name, de.f, bubble, active); 3115 3116 delegatevents[name] = de; 3117 3118 } 3119 3120 if (self.ispage) { 3121 de.a = [self.id].concat(de.a); 3122 de.l = [fn].concat(de.l); 3123 } else { 3124 de.a.push(self.id); 3125 de.l.push(fn); 3126 } 3127 3128 }; 3129 3130 this.undelegate = function (dom, name, fn, bubble, active) { 3131 var de = delegatevents[name]||false; 3132 if (de&&de.l) { // quick fix #683 3133 for (var a=0,l=de.l.length;a<l;a++) { 3134 if (de.a[a] === self.id) { 3135 de.a.splice(a); 3136 de.l.splice(a); 3137 if (de.a.length===0) { 3138 self._unbind(dom,name,de.l.f); 3139 delegatevents[name] = null; 3140 } 3141 } 3142 } 3143 } 3144 }; 3145 3146 this.bind = function (dom, name, fn, bubble, active) { 3147 var el = ("jquery" in dom) ? dom[0] : dom; 3148 self._bind(el, name, fn, bubble || false, active || false); 3149 }; 3150 3151 this._bind = function (el, name, fn, bubble, active) { // primitive bind 3152 3153 self.events.push({ 3154 e: el, 3155 n: name, 3156 f: fn, 3157 b: bubble, 3158 q: false 3159 }); 3160 3161 (passiveSupported && active) ? el.addEventListener(name, fn, { passive: false, capture: bubble }) : el.addEventListener(name, fn, bubble || false); 3162 }; 3163 3164 this._unbind = function (el, name, fn, bub) { // primitive unbind 3165 if (delegatevents[name]) self.undelegate(el, name, fn, bub); 3166 else el.removeEventListener(name, fn, bub); 3167 }; 3168 3169 this.unbindAll = function () { 3170 for (var a = 0; a < self.events.length; a++) { 3171 var r = self.events[a]; 3172 (r.q) ? r.e.unbind(r.n, r.f) : self._unbind(r.e, r.n, r.f, r.b); 3173 } 3174 }; 3175 3176 this.showRails = function () { 3177 return self.showRail().showRailHr(); 3178 }; 3179 3180 this.showRail = function () { 3181 if ((self.page.maxh !== 0) && (self.ispage || self.win.css('display') != 'none')) { 3182 //self.visibility = true; 3183 self.rail.visibility = true; 3184 self.rail.css('display', 'block'); 3185 } 3186 return self; 3187 }; 3188 3189 this.showRailHr = function () { 3190 if (self.railh) { 3191 if ((self.page.maxw !== 0) && (self.ispage || self.win.css('display') != 'none')) { 3192 self.railh.visibility = true; 3193 self.railh.css('display', 'block'); 3194 } 3195 } 3196 return self; 3197 }; 3198 3199 this.hideRails = function () { 3200 return self.hideRail().hideRailHr(); 3201 }; 3202 3203 this.hideRail = function () { 3204 //self.visibility = false; 3205 self.rail.visibility = false; 3206 self.rail.css('display', 'none'); 3207 return self; 3208 }; 3209 3210 this.hideRailHr = function () { 3211 if (self.railh) { 3212 self.railh.visibility = false; 3213 self.railh.css('display', 'none'); 3214 } 3215 return self; 3216 }; 3217 3218 this.show = function () { 3219 self.hidden = false; 3220 self.railslocked = false; 3221 return self.showRails(); 3222 }; 3223 3224 this.hide = function () { 3225 self.hidden = true; 3226 self.railslocked = true; 3227 return self.hideRails(); 3228 }; 3229 3230 this.toggle = function () { 3231 return (self.hidden) ? self.show() : self.hide(); 3232 }; 3233 3234 this.remove = function () { 3235 self.stop(); 3236 if (self.cursortimeout) clearTimeout(self.cursortimeout); 3237 for (var n in self.delaylist) if (self.delaylist[n]) clearAnimationFrame(self.delaylist[n].h); 3238 self.doZoomOut(); 3239 self.unbindAll(); 3240 3241 if (cap.isie9) self.win[0].detachEvent("onpropertychange", self.onAttributeChange); //IE9 DOMAttrModified bug 3242 3243 if (self.observer !== false) self.observer.disconnect(); 3244 if (self.observerremover !== false) self.observerremover.disconnect(); 3245 if (self.observerbody !== false) self.observerbody.disconnect(); 3246 3247 self.events = null; 3248 3249 if (self.cursor) { 3250 self.cursor.remove(); 3251 } 3252 if (self.cursorh) { 3253 self.cursorh.remove(); 3254 } 3255 if (self.rail) { 3256 self.rail.remove(); 3257 } 3258 if (self.railh) { 3259 self.railh.remove(); 3260 } 3261 if (self.zoom) { 3262 self.zoom.remove(); 3263 } 3264 for (var a = 0; a < self.saved.css.length; a++) { 3265 var d = self.saved.css[a]; 3266 d[0].css(d[1], (d[2] === undefined) ? '' : d[2]); 3267 } 3268 self.saved = false; 3269 self.me.data('__nicescroll', ''); //erase all traces 3270 3271 // memory leak fixed by GianlucaGuarini - thanks a lot! 3272 // remove the current nicescroll from the $.nicescroll array & normalize array 3273 var lst = $.nicescroll; 3274 lst.each(function (i) { 3275 if (!this) return; 3276 if (this.id === self.id) { 3277 delete lst[i]; 3278 for (var b = ++i; b < lst.length; b++ , i++) lst[i] = lst[b]; 3279 lst.length--; 3280 if (lst.length) delete lst[lst.length]; 3281 } 3282 }); 3283 3284 for (var i in self) { 3285 self[i] = null; 3286 delete self[i]; 3287 } 3288 3289 self = null; 3290 3291 }; 3292 3293 this.scrollstart = function (fn) { 3294 this.onscrollstart = fn; 3295 return self; 3296 }; 3297 this.scrollend = function (fn) { 3298 this.onscrollend = fn; 3299 return self; 3300 }; 3301 this.scrollcancel = function (fn) { 3302 this.onscrollcancel = fn; 3303 return self; 3304 }; 3305 3306 this.zoomin = function (fn) { 3307 this.onzoomin = fn; 3308 return self; 3309 }; 3310 this.zoomout = function (fn) { 3311 this.onzoomout = fn; 3312 return self; 3313 }; 3314 3315 this.isScrollable = function (e) { 3316 var dom = (e.target) ? e.target : e; 3317 if (dom.nodeName == 'OPTION') return true; 3318 while (dom && (dom.nodeType == 1) && (dom !== this.me[0]) && !(/^BODY|HTML/.test(dom.nodeName))) { 3319 var dd = $(dom); 3320 var ov = dd.css('overflowY') || dd.css('overflowX') || dd.css('overflow') || ''; 3321 if (/scroll|auto/.test(ov)) return (dom.clientHeight != dom.scrollHeight); 3322 dom = (dom.parentNode) ? dom.parentNode : false; 3323 } 3324 return false; 3325 }; 3326 3327 this.getViewport = function (me) { 3328 var dom = (me && me.parentNode) ? me.parentNode : false; 3329 while (dom && (dom.nodeType == 1) && !(/^BODY|HTML/.test(dom.nodeName))) { 3330 var dd = $(dom); 3331 if (/fixed|absolute/.test(dd.css("position"))) return dd; 3332 var ov = dd.css('overflowY') || dd.css('overflowX') || dd.css('overflow') || ''; 3333 if ((/scroll|auto/.test(ov)) && (dom.clientHeight != dom.scrollHeight)) return dd; 3334 if (dd.getNiceScroll().length > 0) return dd; 3335 dom = (dom.parentNode) ? dom.parentNode : false; 3336 } 3337 return false; 3338 }; 3339 3340 this.triggerScrollStart = function (cx, cy, rx, ry, ms) { 3341 3342 if (self.onscrollstart) { 3343 var info = { 3344 type: "scrollstart", 3345 current: { 3346 x: cx, 3347 y: cy 3348 }, 3349 request: { 3350 x: rx, 3351 y: ry 3352 }, 3353 end: { 3354 x: self.newscrollx, 3355 y: self.newscrolly 3356 }, 3357 speed: ms 3358 }; 3359 self.onscrollstart.call(self, info); 3360 } 3361 3362 }; 3363 3364 this.triggerScrollEnd = function () { 3365 if (self.onscrollend) { 3366 3367 var px = self.getScrollLeft(); 3368 var py = self.getScrollTop(); 3369 3370 var info = { 3371 type: "scrollend", 3372 current: { 3373 x: px, 3374 y: py 3375 }, 3376 end: { 3377 x: px, 3378 y: py 3379 } 3380 }; 3381 3382 self.onscrollend.call(self, info); 3383 3384 } 3385 3386 }; 3387 3388 var scrolldiry = 0, scrolldirx = 0, scrolltmr = 0, scrollspd = 1; 3389 3390 function doScrollRelative(px, py, chkscroll, iswheel) { 3391 3392 if (!self.scrollrunning) { 3393 self.newscrolly = self.getScrollTop(); 3394 self.newscrollx = self.getScrollLeft(); 3395 scrolltmr = now(); 3396 } 3397 3398 var gap = (now() - scrolltmr); 3399 scrolltmr = now(); 3400 3401 if (gap > 350) { 3402 scrollspd = 1; 3403 } else { 3404 scrollspd += (2 - scrollspd) / 10; 3405 } 3406 3407 px = px * scrollspd | 0; 3408 py = py * scrollspd | 0; 3409 3410 if (px) { 3411 3412 if (iswheel) { // mouse-only 3413 if (px < 0) { // fix apple magic mouse swipe back/forward 3414 if (self.getScrollLeft() >= self.page.maxw) return true; 3415 } else { 3416 if (self.getScrollLeft() <= 0) return true; 3417 } 3418 } 3419 3420 var dx = px > 0 ? 1 : -1; 3421 3422 if (scrolldirx !== dx) { 3423 if (self.scrollmom) self.scrollmom.stop(); 3424 self.newscrollx = self.getScrollLeft(); 3425 scrolldirx = dx; 3426 } 3427 3428 self.lastdeltax -= px; 3429 3430 } 3431 3432 if (py) { 3433 3434 var chk = (function () { 3435 var top = self.getScrollTop(); 3436 if (py < 0) { 3437 if (top >= self.page.maxh) return true; 3438 } else { 3439 if (top <= 0) return true; 3440 } 3441 })(); 3442 3443 if (chk) { 3444 if (opt.nativeparentscrolling && chkscroll && !self.ispage && !self.zoomactive) return true; 3445 var ny = self.view.h >> 1; 3446 if (self.newscrolly < -ny) { self.newscrolly = -ny; py = -1; } 3447 else if (self.newscrolly > self.page.maxh + ny) { self.newscrolly = self.page.maxh + ny; py = 1; } 3448 else py = 0; 3449 } 3450 3451 var dy = py > 0 ? 1 : -1; 3452 3453 if (scrolldiry !== dy) { 3454 if (self.scrollmom) self.scrollmom.stop(); 3455 self.newscrolly = self.getScrollTop(); 3456 scrolldiry = dy; 3457 } 3458 3459 self.lastdeltay -= py; 3460 3461 } 3462 3463 if (py || px) { 3464 self.synched("relativexy", function () { 3465 3466 var dty = self.lastdeltay + self.newscrolly; 3467 self.lastdeltay = 0; 3468 3469 var dtx = self.lastdeltax + self.newscrollx; 3470 self.lastdeltax = 0; 3471 3472 if (!self.rail.drag) self.doScrollPos(dtx, dty); 3473 3474 }); 3475 } 3476 3477 } 3478 3479 var hasparentscrollingphase = false; 3480 3481 function execScrollWheel(e, hr, chkscroll) { 3482 var px, py; 3483 3484 if (!chkscroll && hasparentscrollingphase) return true; 3485 3486 if (e.deltaMode === 0) { // PIXEL 3487 px = -(e.deltaX * (opt.mousescrollstep / (18 * 3))) | 0; 3488 py = -(e.deltaY * (opt.mousescrollstep / (18 * 3))) | 0; 3489 } else if (e.deltaMode === 1) { // LINE 3490 px = -(e.deltaX * opt.mousescrollstep * 50 / 80) | 0; 3491 py = -(e.deltaY * opt.mousescrollstep * 50 / 80) | 0; 3492 } 3493 3494 if (hr && opt.oneaxismousemode && (px === 0) && py) { // classic vertical-only mousewheel + browser with x/y support 3495 px = py; 3496 py = 0; 3497 3498 if (chkscroll) { 3499 var hrend = (px < 0) ? (self.getScrollLeft() >= self.page.maxw) : (self.getScrollLeft() <= 0); 3500 if (hrend) { // preserve vertical scrolling 3501 py = px; 3502 px = 0; 3503 } 3504 } 3505 3506 } 3507 3508 // invert horizontal direction for rtl mode 3509 if (self.isrtlmode) px = -px; 3510 3511 var chk = doScrollRelative(px, py, chkscroll, true); 3512 3513 if (chk) { 3514 if (chkscroll) hasparentscrollingphase = true; 3515 } else { 3516 hasparentscrollingphase = false; 3517 e.stopImmediatePropagation(); 3518 return e.preventDefault(); 3519 } 3520 3521 } 3522 3523 this.onmousewheel = function (e) { 3524 if (self.wheelprevented||self.locked) return false; 3525 if (self.railslocked) { 3526 self.debounced("checkunlock", self.resize, 250); 3527 return false; 3528 } 3529 if (self.rail.drag) return self.cancelEvent(e); 3530 3531 if (opt.oneaxismousemode === "auto" && e.deltaX !== 0) opt.oneaxismousemode = false; // check two-axis mouse support (not very elegant) 3532 3533 if (opt.oneaxismousemode && e.deltaX === 0) { 3534 if (!self.rail.scrollable) { 3535 if (self.railh && self.railh.scrollable) { 3536 return self.onmousewheelhr(e); 3537 } else { 3538 return true; 3539 } 3540 } 3541 } 3542 3543 var nw = now(); 3544 var chk = false; 3545 if (opt.preservenativescrolling && ((self.checkarea + 600) < nw)) { 3546 self.nativescrollingarea = self.isScrollable(e); 3547 chk = true; 3548 } 3549 self.checkarea = nw; 3550 if (self.nativescrollingarea) return true; // this isn't my business 3551 var ret = execScrollWheel(e, false, chk); 3552 if (ret) self.checkarea = 0; 3553 return ret; 3554 }; 3555 3556 this.onmousewheelhr = function (e) { 3557 if (self.wheelprevented) return; 3558 if (self.railslocked || !self.railh.scrollable) return true; 3559 if (self.rail.drag) return self.cancelEvent(e); 3560 3561 var nw = now(); 3562 var chk = false; 3563 if (opt.preservenativescrolling && ((self.checkarea + 600) < nw)) { 3564 self.nativescrollingarea = self.isScrollable(e); 3565 chk = true; 3566 } 3567 self.checkarea = nw; 3568 if (self.nativescrollingarea) return true; // this is not my business 3569 if (self.railslocked) return self.cancelEvent(e); 3570 3571 return execScrollWheel(e, true, chk); 3572 }; 3573 3574 this.stop = function () { 3575 self.cancelScroll(); 3576 if (self.scrollmon) self.scrollmon.stop(); 3577 self.cursorfreezed = false; 3578 self.scroll.y = Math.round(self.getScrollTop() * (1 / self.scrollratio.y)); 3579 self.noticeCursor(); 3580 return self; 3581 }; 3582 3583 this.getTransitionSpeed = function (dif) { 3584 3585 return 80 + (dif / 72) * opt.scrollspeed |0; 3586 3587 }; 3588 3589 if (!opt.smoothscroll) { 3590 this.doScrollLeft = function (x, spd) { //direct 3591 var y = self.getScrollTop(); 3592 self.doScrollPos(x, y, spd); 3593 }; 3594 this.doScrollTop = function (y, spd) { //direct 3595 var x = self.getScrollLeft(); 3596 self.doScrollPos(x, y, spd); 3597 }; 3598 this.doScrollPos = function (x, y, spd) { //direct 3599 var nx = (x > self.page.maxw) ? self.page.maxw : x; 3600 if (nx < 0) nx = 0; 3601 var ny = (y > self.page.maxh) ? self.page.maxh : y; 3602 if (ny < 0) ny = 0; 3603 self.synched('scroll', function () { 3604 self.setScrollTop(ny); 3605 self.setScrollLeft(nx); 3606 }); 3607 }; 3608 this.cancelScroll = function () { }; // direct 3609 3610 } else if (self.ishwscroll && cap.hastransition && opt.usetransition && !!opt.smoothscroll) { 3611 3612 var lasttransitionstyle = ''; 3613 3614 this.resetTransition = function () { 3615 lasttransitionstyle = ''; 3616 self.doc.css(cap.prefixstyle + 'transition-duration', '0ms'); 3617 }; 3618 3619 this.prepareTransition = function (dif, istime) { 3620 var ex = (istime) ? dif : self.getTransitionSpeed(dif); 3621 var trans = ex + 'ms'; 3622 if (lasttransitionstyle !== trans) { 3623 lasttransitionstyle = trans; 3624 self.doc.css(cap.prefixstyle + 'transition-duration', trans); 3625 } 3626 return ex; 3627 }; 3628 3629 this.doScrollLeft = function (x, spd) { //trans 3630 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 3631 self.doScrollPos(x, y, spd); 3632 }; 3633 3634 this.doScrollTop = function (y, spd) { //trans 3635 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 3636 self.doScrollPos(x, y, spd); 3637 }; 3638 3639 this.cursorupdate = { 3640 running: false, 3641 start: function () { 3642 var m = this; 3643 3644 if (m.running) return; 3645 m.running = true; 3646 3647 var loop = function () { 3648 if (m.running) setAnimationFrame(loop); 3649 self.showCursor(self.getScrollTop(), self.getScrollLeft()); 3650 self.notifyScrollEvent(self.win[0]); 3651 }; 3652 3653 setAnimationFrame(loop); 3654 }, 3655 stop: function () { 3656 this.running = false; 3657 } 3658 }; 3659 3660 this.doScrollPos = function (x, y, spd) { //trans 3661 3662 var py = self.getScrollTop(); 3663 var px = self.getScrollLeft(); 3664 3665 if (((self.newscrolly - py) * (y - py) < 0) || ((self.newscrollx - px) * (x - px) < 0)) self.cancelScroll(); //inverted movement detection 3666 3667 if (!opt.bouncescroll) { 3668 if (y < 0) y = 0; 3669 else if (y > self.page.maxh) y = self.page.maxh; 3670 if (x < 0) x = 0; 3671 else if (x > self.page.maxw) x = self.page.maxw; 3672 } else { 3673 if (y < 0) y = y / 2 | 0; 3674 else if (y > self.page.maxh) y = self.page.maxh + (y - self.page.maxh) / 2 | 0; 3675 if (x < 0) x = x / 2 | 0; 3676 else if (x > self.page.maxw) x = self.page.maxw + (x - self.page.maxw) / 2 | 0; 3677 } 3678 3679 if (self.scrollrunning && x == self.newscrollx && y == self.newscrolly) return false; 3680 3681 self.newscrolly = y; 3682 self.newscrollx = x; 3683 3684 var top = self.getScrollTop(); 3685 var lft = self.getScrollLeft(); 3686 3687 var dst = {}; 3688 dst.x = x - lft; 3689 dst.y = y - top; 3690 3691 var dd = Math.sqrt((dst.x * dst.x) + (dst.y * dst.y)) | 0; 3692 3693 var ms = self.prepareTransition(dd); 3694 3695 if (!self.scrollrunning) { 3696 self.scrollrunning = true; 3697 self.triggerScrollStart(lft, top, x, y, ms); 3698 self.cursorupdate.start(); 3699 } 3700 3701 self.scrollendtrapped = true; 3702 3703 if (!cap.transitionend) { 3704 if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped); 3705 self.scrollendtrapped = setTimeout(self.onScrollTransitionEnd, ms); // simulate transitionend event 3706 } 3707 3708 self.setScrollTop(self.newscrolly); 3709 self.setScrollLeft(self.newscrollx); 3710 3711 }; 3712 3713 this.cancelScroll = function () { 3714 if (!self.scrollendtrapped) return true; 3715 var py = self.getScrollTop(); 3716 var px = self.getScrollLeft(); 3717 self.scrollrunning = false; 3718 if (!cap.transitionend) clearTimeout(cap.transitionend); 3719 self.scrollendtrapped = false; 3720 self.resetTransition(); 3721 self.setScrollTop(py); // fire event onscroll 3722 if (self.railh) self.setScrollLeft(px); 3723 if (self.timerscroll && self.timerscroll.tm) clearInterval(self.timerscroll.tm); 3724 self.timerscroll = false; 3725 3726 self.cursorfreezed = false; 3727 3728 self.cursorupdate.stop(); 3729 self.showCursor(py, px); 3730 return self; 3731 }; 3732 3733 this.onScrollTransitionEnd = function () { 3734 3735 if (!self.scrollendtrapped) return; 3736 3737 var py = self.getScrollTop(); 3738 var px = self.getScrollLeft(); 3739 3740 if (py < 0) py = 0; 3741 else if (py > self.page.maxh) py = self.page.maxh; 3742 if (px < 0) px = 0; 3743 else if (px > self.page.maxw) px = self.page.maxw; 3744 if ((py != self.newscrolly) || (px != self.newscrollx)) return self.doScrollPos(px, py, opt.snapbackspeed); 3745 3746 if (self.scrollrunning) self.triggerScrollEnd(); 3747 self.scrollrunning = false; 3748 3749 self.scrollendtrapped = false; 3750 self.resetTransition(); 3751 self.timerscroll = false; 3752 self.setScrollTop(py); // fire event onscroll 3753 if (self.railh) self.setScrollLeft(px); // fire event onscroll left 3754 3755 self.cursorupdate.stop(); 3756 self.noticeCursor(false, py, px); 3757 3758 self.cursorfreezed = false; 3759 3760 }; 3761 3762 } else { 3763 3764 this.doScrollLeft = function (x, spd) { //no-trans 3765 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 3766 self.doScrollPos(x, y, spd); 3767 }; 3768 3769 this.doScrollTop = function (y, spd) { //no-trans 3770 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 3771 self.doScrollPos(x, y, spd); 3772 }; 3773 3774 this.doScrollPos = function (x, y, spd) { //no-trans 3775 3776 var py = self.getScrollTop(); 3777 var px = self.getScrollLeft(); 3778 3779 if (((self.newscrolly - py) * (y - py) < 0) || ((self.newscrollx - px) * (x - px) < 0)) self.cancelScroll(); //inverted movement detection 3780 3781 var clipped = false; 3782 3783 if (!self.bouncescroll || !self.rail.visibility) { 3784 if (y < 0) { 3785 y = 0; 3786 clipped = true; 3787 } else if (y > self.page.maxh) { 3788 y = self.page.maxh; 3789 clipped = true; 3790 } 3791 } 3792 if (!self.bouncescroll || !self.railh.visibility) { 3793 if (x < 0) { 3794 x = 0; 3795 clipped = true; 3796 } else if (x > self.page.maxw) { 3797 x = self.page.maxw; 3798 clipped = true; 3799 } 3800 } 3801 3802 if (self.scrollrunning && (self.newscrolly === y) && (self.newscrollx === x)) return true; 3803 3804 self.newscrolly = y; 3805 self.newscrollx = x; 3806 3807 self.dst = {}; 3808 self.dst.x = x - px; 3809 self.dst.y = y - py; 3810 self.dst.px = px; 3811 self.dst.py = py; 3812 3813 var dd = Math.sqrt((self.dst.x * self.dst.x) + (self.dst.y * self.dst.y)) | 0; 3814 var ms = self.getTransitionSpeed(dd); 3815 3816 self.bzscroll = {}; 3817 3818 var p3 = (clipped) ? 1 : 0.58; 3819 self.bzscroll.x = new BezierClass(px, self.newscrollx, ms, 0, 0, p3, 1); 3820 self.bzscroll.y = new BezierClass(py, self.newscrolly, ms, 0, 0, p3, 1); 3821 3822 var loopid = now(); 3823 3824 var loop = function () { 3825 3826 if (!self.scrollrunning) return; 3827 var x = self.bzscroll.y.getPos(); 3828 3829 self.setScrollLeft(self.bzscroll.x.getNow()); 3830 self.setScrollTop(self.bzscroll.y.getNow()); 3831 3832 if (x <= 1) { 3833 self.timer = setAnimationFrame(loop); 3834 } else { 3835 self.scrollrunning = false; 3836 self.timer = 0; 3837 self.triggerScrollEnd(); 3838 } 3839 3840 }; 3841 3842 if (!self.scrollrunning) { 3843 self.triggerScrollStart(px, py, x, y, ms); 3844 self.scrollrunning = true; 3845 self.timer = setAnimationFrame(loop); 3846 } 3847 3848 }; 3849 3850 this.cancelScroll = function () { 3851 if (self.timer) clearAnimationFrame(self.timer); 3852 self.timer = 0; 3853 self.bzscroll = false; 3854 self.scrollrunning = false; 3855 return self; 3856 }; 3857 3858 } 3859 3860 this.doScrollBy = function (stp, relative) { 3861 doScrollRelative(0, stp); 3862 }; 3863 3864 this.doScrollLeftBy = function (stp, relative) { 3865 doScrollRelative(stp, 0); 3866 }; 3867 3868 this.doScrollTo = function (pos, relative) { 3869 var ny = (relative) ? Math.round(pos * self.scrollratio.y) : pos; 3870 if (ny < 0) ny = 0; 3871 else if (ny > self.page.maxh) ny = self.page.maxh; 3872 self.cursorfreezed = false; 3873 self.doScrollTop(pos); 3874 }; 3875 3876 this.checkContentSize = function () { 3877 var pg = self.getContentSize(); 3878 if ((pg.h != self.page.h) || (pg.w != self.page.w)) self.resize(false, pg); 3879 }; 3880 3881 self.onscroll = function (e) { 3882 if (self.rail.drag) return; 3883 if (!self.cursorfreezed) { 3884 self.synched('scroll', function () { 3885 self.scroll.y = Math.round(self.getScrollTop() / self.scrollratio.y); 3886 if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() / self.scrollratio.x); 3887 self.noticeCursor(); 3888 }); 3889 } 3890 }; 3891 self.bind(self.docscroll, "scroll", self.onscroll); 3892 3893 this.doZoomIn = function (e) { 3894 if (self.zoomactive) return; 3895 self.zoomactive = true; 3896 3897 self.zoomrestore = { 3898 style: {} 3899 }; 3900 var lst = ['position', 'top', 'left', 'zIndex', 'backgroundColor', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight']; 3901 var win = self.win[0].style; 3902 for (var a in lst) { 3903 var pp = lst[a]; 3904 self.zoomrestore.style[pp] = (win[pp] !== undefined) ? win[pp] : ''; 3905 } 3906 3907 self.zoomrestore.style.width = self.win.css('width'); 3908 self.zoomrestore.style.height = self.win.css('height'); 3909 3910 self.zoomrestore.padding = { 3911 w: self.win.outerWidth() - self.win.width(), 3912 h: self.win.outerHeight() - self.win.height() 3913 }; 3914 3915 if (cap.isios4) { 3916 self.zoomrestore.scrollTop = $window.scrollTop(); 3917 $window.scrollTop(0); 3918 } 3919 3920 self.win.css({ 3921 position: (cap.isios4) ? "absolute" : "fixed", 3922 top: 0, 3923 left: 0, 3924 zIndex: globalmaxzindex + 100, 3925 margin: 0 3926 }); 3927 var bkg = self.win.css("backgroundColor"); 3928 if ("" === bkg || /transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor", "#fff"); 3929 self.rail.css({ 3930 zIndex: globalmaxzindex + 101 3931 }); 3932 self.zoom.css({ 3933 zIndex: globalmaxzindex + 102 3934 }); 3935 self.zoom.css('backgroundPosition', '0 -18px'); 3936 self.resizeZoom(); 3937 3938 if (self.onzoomin) self.onzoomin.call(self); 3939 3940 return self.cancelEvent(e); 3941 }; 3942 3943 this.doZoomOut = function (e) { 3944 if (!self.zoomactive) return; 3945 self.zoomactive = false; 3946 3947 self.win.css("margin", ""); 3948 self.win.css(self.zoomrestore.style); 3949 3950 if (cap.isios4) { 3951 $window.scrollTop(self.zoomrestore.scrollTop); 3952 } 3953 3954 self.rail.css({ 3955 "z-index": self.zindex 3956 }); 3957 self.zoom.css({ 3958 "z-index": self.zindex 3959 }); 3960 self.zoomrestore = false; 3961 self.zoom.css('backgroundPosition', '0 0'); 3962 self.onResize(); 3963 3964 if (self.onzoomout) self.onzoomout.call(self); 3965 3966 return self.cancelEvent(e); 3967 }; 3968 3969 this.doZoom = function (e) { 3970 return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e); 3971 }; 3972 3973 this.resizeZoom = function () { 3974 if (!self.zoomactive) return; 3975 3976 var py = self.getScrollTop(); //preserve scrolling position 3977 self.win.css({ 3978 width: $window.width() - self.zoomrestore.padding.w + "px", 3979 height: $window.height() - self.zoomrestore.padding.h + "px" 3980 }); 3981 self.onResize(); 3982 3983 self.setScrollTop(Math.min(self.page.maxh, py)); 3984 }; 3985 3986 this.init(); 3987 3988 $.nicescroll.push(this); 3989 3990 }; 3991 3992 // Inspired by the work of Kin Blas 3993 // http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js 3994 var ScrollMomentumClass2D = function (nc) { 3995 var self = this; 3996 this.nc = nc; 3997 3998 this.lastx = 0; 3999 this.lasty = 0; 4000 this.speedx = 0; 4001 this.speedy = 0; 4002 this.lasttime = 0; 4003 this.steptime = 0; 4004 this.snapx = false; 4005 this.snapy = false; 4006 this.demulx = 0; 4007 this.demuly = 0; 4008 4009 this.lastscrollx = -1; 4010 this.lastscrolly = -1; 4011 4012 this.chkx = 0; 4013 this.chky = 0; 4014 4015 this.timer = 0; 4016 4017 this.reset = function (px, py) { 4018 self.stop(); 4019 self.steptime = 0; 4020 self.lasttime = now(); 4021 self.speedx = 0; 4022 self.speedy = 0; 4023 self.lastx = px; 4024 self.lasty = py; 4025 self.lastscrollx = -1; 4026 self.lastscrolly = -1; 4027 }; 4028 4029 this.update = function (px, py) { 4030 var tm = now(); 4031 self.steptime = tm - self.lasttime; 4032 self.lasttime = tm; 4033 var dy = py - self.lasty; 4034 var dx = px - self.lastx; 4035 var sy = self.nc.getScrollTop(); 4036 var sx = self.nc.getScrollLeft(); 4037 var newy = sy + dy; 4038 var newx = sx + dx; 4039 self.snapx = (newx < 0) || (newx > self.nc.page.maxw); 4040 self.snapy = (newy < 0) || (newy > self.nc.page.maxh); 4041 self.speedx = dx; 4042 self.speedy = dy; 4043 self.lastx = px; 4044 self.lasty = py; 4045 }; 4046 4047 this.stop = function () { 4048 self.nc.unsynched("domomentum2d"); 4049 if (self.timer) clearTimeout(self.timer); 4050 self.timer = 0; 4051 self.lastscrollx = -1; 4052 self.lastscrolly = -1; 4053 }; 4054 4055 this.doSnapy = function (nx, ny) { 4056 var snap = false; 4057 4058 if (ny < 0) { 4059 ny = 0; 4060 snap = true; 4061 } else if (ny > self.nc.page.maxh) { 4062 ny = self.nc.page.maxh; 4063 snap = true; 4064 } 4065 4066 if (nx < 0) { 4067 nx = 0; 4068 snap = true; 4069 } else if (nx > self.nc.page.maxw) { 4070 nx = self.nc.page.maxw; 4071 snap = true; 4072 } 4073 4074 (snap) ? self.nc.doScrollPos(nx, ny, self.nc.opt.snapbackspeed) : self.nc.triggerScrollEnd(); 4075 }; 4076 4077 this.doMomentum = function (gp) { 4078 var t = now(); 4079 var l = (gp) ? t + gp : self.lasttime; 4080 4081 var sl = self.nc.getScrollLeft(); 4082 var st = self.nc.getScrollTop(); 4083 4084 var pageh = self.nc.page.maxh; 4085 var pagew = self.nc.page.maxw; 4086 4087 self.speedx = (pagew > 0) ? Math.min(60, self.speedx) : 0; 4088 self.speedy = (pageh > 0) ? Math.min(60, self.speedy) : 0; 4089 4090 var chk = l && (t - l) <= 60; 4091 4092 if ((st < 0) || (st > pageh) || (sl < 0) || (sl > pagew)) chk = false; 4093 4094 var sy = (self.speedy && chk) ? self.speedy : false; 4095 var sx = (self.speedx && chk) ? self.speedx : false; 4096 4097 if (sy || sx) { 4098 var tm = Math.max(16, self.steptime); //timeout granularity 4099 4100 if (tm > 50) { // do smooth 4101 var xm = tm / 50; 4102 self.speedx *= xm; 4103 self.speedy *= xm; 4104 tm = 50; 4105 } 4106 4107 self.demulxy = 0; 4108 4109 self.lastscrollx = self.nc.getScrollLeft(); 4110 self.chkx = self.lastscrollx; 4111 self.lastscrolly = self.nc.getScrollTop(); 4112 self.chky = self.lastscrolly; 4113 4114 var nx = self.lastscrollx; 4115 var ny = self.lastscrolly; 4116 4117 var onscroll = function () { 4118 var df = ((now() - t) > 600) ? 0.04 : 0.02; 4119 4120 if (self.speedx) { 4121 nx = Math.floor(self.lastscrollx - (self.speedx * (1 - self.demulxy))); 4122 self.lastscrollx = nx; 4123 if ((nx < 0) || (nx > pagew)) df = 0.10; 4124 } 4125 4126 if (self.speedy) { 4127 ny = Math.floor(self.lastscrolly - (self.speedy * (1 - self.demulxy))); 4128 self.lastscrolly = ny; 4129 if ((ny < 0) || (ny > pageh)) df = 0.10; 4130 } 4131 4132 self.demulxy = Math.min(1, self.demulxy + df); 4133 4134 self.nc.synched("domomentum2d", function () { 4135 4136 if (self.speedx) { 4137 var scx = self.nc.getScrollLeft(); 4138 // if (scx != self.chkx) self.stop(); 4139 self.chkx = nx; 4140 self.nc.setScrollLeft(nx); 4141 } 4142 4143 if (self.speedy) { 4144 var scy = self.nc.getScrollTop(); 4145 // if (scy != self.chky) self.stop(); 4146 self.chky = ny; 4147 self.nc.setScrollTop(ny); 4148 } 4149 4150 if (!self.timer) { 4151 self.nc.hideCursor(); 4152 self.doSnapy(nx, ny); 4153 } 4154 4155 }); 4156 4157 if (self.demulxy < 1) { 4158 self.timer = setTimeout(onscroll, tm); 4159 } else { 4160 self.stop(); 4161 self.nc.hideCursor(); 4162 self.doSnapy(nx, ny); 4163 } 4164 }; 4165 4166 onscroll(); 4167 4168 } else { 4169 self.doSnapy(self.nc.getScrollLeft(), self.nc.getScrollTop()); 4170 } 4171 4172 }; 4173 4174 }; 4175 4176 4177 // override jQuery scrollTop 4178 var _scrollTop = jQuery.fn.scrollTop; // preserve original function 4179 4180 jQuery.cssHooks.pageYOffset = { 4181 get: function (elem, computed, extra) { 4182 var nice = $.data(elem, '__nicescroll') || false; 4183 return (nice && nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem); 4184 }, 4185 set: function (elem, value) { 4186 var nice = $.data(elem, '__nicescroll') || false; 4187 (nice && nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call(elem, value); 4188 return this; 4189 } 4190 }; 4191 4192 jQuery.fn.scrollTop = function (value) { 4193 if (value === undefined) { 4194 var nice = (this[0]) ? $.data(this[0], '__nicescroll') || false : false; 4195 return (nice && nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this); 4196 } else { 4197 return this.each(function () { 4198 var nice = $.data(this, '__nicescroll') || false; 4199 (nice && nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call($(this), value); 4200 }); 4201 } 4202 }; 4203 4204 // override jQuery scrollLeft 4205 var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function 4206 4207 $.cssHooks.pageXOffset = { 4208 get: function (elem, computed, extra) { 4209 var nice = $.data(elem, '__nicescroll') || false; 4210 return (nice && nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem); 4211 }, 4212 set: function (elem, value) { 4213 var nice = $.data(elem, '__nicescroll') || false; 4214 (nice && nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call(elem, value); 4215 return this; 4216 } 4217 }; 4218 4219 jQuery.fn.scrollLeft = function (value) { 4220 if (value === undefined) { 4221 var nice = (this[0]) ? $.data(this[0], '__nicescroll') || false : false; 4222 return (nice && nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this); 4223 } else { 4224 return this.each(function () { 4225 var nice = $.data(this, '__nicescroll') || false; 4226 (nice && nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call($(this), value); 4227 }); 4228 } 4229 }; 4230 4231 var NiceScrollArray = function (doms) { 4232 var self = this; 4233 this.length = 0; 4234 this.name = "nicescrollarray"; 4235 4236 this.each = function (fn) { 4237 $.each(self, fn); 4238 return self; 4239 }; 4240 4241 this.push = function (nice) { 4242 self[self.length] = nice; 4243 self.length++; 4244 }; 4245 4246 this.eq = function (idx) { 4247 return self[idx]; 4248 }; 4249 4250 if (doms) { 4251 for (var a = 0; a < doms.length; a++) { 4252 var nice = $.data(doms[a], '__nicescroll') || false; 4253 if (nice) { 4254 this[this.length] = nice; 4255 this.length++; 4256 } 4257 } 4258 } 4259 4260 return this; 4261 }; 4262 4263 function mplex(el, lst, fn) { 4264 for (var a = 0, l = lst.length; a < l; a++) fn(el, lst[a]); 4265 } 4266 mplex( 4267 NiceScrollArray.prototype, ['show', 'hide', 'toggle', 'onResize', 'resize', 'remove', 'stop', 'doScrollPos'], 4268 function (e, n) { 4269 e[n] = function () { 4270 var args = arguments; 4271 return this.each(function () { 4272 this[n].apply(this, args); 4273 }); 4274 }; 4275 } 4276 ); 4277 4278 jQuery.fn.getNiceScroll = function (index) { 4279 if (index === undefined) { 4280 return new NiceScrollArray(this); 4281 } else { 4282 return this[index] && $.data(this[index], '__nicescroll') || false; 4283 } 4284 }; 4285 4286 var pseudos = jQuery.expr.pseudos || jQuery.expr[':']; // jQuery 3 migration 4287 pseudos.nicescroll = function (a) { 4288 return $.data(a, '__nicescroll') !== undefined; 4289 }; 4290 4291 $.fn.niceScroll = function (wrapper, _opt) { 4292 if (_opt === undefined && typeof wrapper == "object" && !("jquery" in wrapper)) { 4293 _opt = wrapper; 4294 wrapper = false; 4295 } 4296 4297 var ret = new NiceScrollArray(); 4298 4299 this.each(function () { 4300 var $this = $(this); 4301 4302 var opt = $.extend({}, _opt); // cloning 4303 4304 if (wrapper || false) { 4305 var wrp = $(wrapper); 4306 opt.doc = (wrp.length > 1) ? $(wrapper, $this) : wrp; 4307 opt.win = $this; 4308 } 4309 var docundef = !("doc" in opt); 4310 if (!docundef && !("win" in opt)) opt.win = $this; 4311 4312 var nice = $this.data('__nicescroll') || false; 4313 if (!nice) { 4314 opt.doc = opt.doc || $this; 4315 nice = new NiceScrollClass(opt, $this); 4316 $this.data('__nicescroll', nice); 4317 } 4318 ret.push(nice); 4319 }); 4320 4321 return (ret.length === 1) ? ret[0] : ret; 4322 }; 4323 4324 _win.NiceScroll = { 4325 getjQuery: function () { 4326 return jQuery; 4327 } 4328 }; 4329 4330 if (!$.nicescroll) { 4331 $.nicescroll = new NiceScrollArray(); 4332 $.nicescroll.options = _globaloptions; 4333 } 4334 4335})); 4336 4337/***/ }), 4338
vendor: 299,913 bytes, lines 4339-15230
4339/***/ "./node_modules/jquery/dist/jquery.js": 4340/*!********************************************!*\ 4341 !*** ./node_modules/jquery/dist/jquery.js ***! 4342 \********************************************/ 4343/***/ (function(module, exports) { 4344 4345var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 4346 * jQuery JavaScript Library v3.6.0 4347 * https://jquery.com/ 4348 * 4349 * Includes Sizzle.js 4350 * https://sizzlejs.com/ 4351 * 4352 * Copyright OpenJS Foundation and other contributors 4353 * Released under the MIT license 4354 * https://jquery.org/license 4355 * 4356 * Date: 2021-03-02T17:08Z 4357 */ 4358( function( global, factory ) { 4359 4360 "use strict"; 4361 4362 if ( true && typeof module.exports === "object" ) { 4363 4364 // For CommonJS and CommonJS-like environments where a proper `window` 4365 // is present, execute the factory and get jQuery. 4366 // For environments that do not have a `window` with a `document` 4367 // (such as Node.js), expose a factory as module.exports. 4368 // This accentuates the need for the creation of a real `window`. 4369 // e.g. var jQuery = require("jquery")(window); 4370 // See ticket #14549 for more info. 4371 module.exports = global.document ? 4372 factory( global, true ) : 4373 function( w ) { 4374 if ( !w.document ) { 4375 throw new Error( "jQuery requires a window with a document" ); 4376 } 4377 return factory( w ); 4378 }; 4379 } else { 4380 factory( global ); 4381 } 4382 4383// Pass this if window is not defined yet 4384} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 4385 4386// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 4387// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 4388// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 4389// enough that all such attempts are guarded in a try block. 4390"use strict"; 4391 4392var arr = []; 4393 4394var getProto = Object.getPrototypeOf; 4395 4396var slice = arr.slice; 4397 4398var flat = arr.flat ? function( array ) { 4399 return arr.flat.call( array ); 4400} : function( array ) { 4401 return arr.concat.apply( [], array ); 4402}; 4403 4404 4405var push = arr.push; 4406 4407var indexOf = arr.indexOf; 4408 4409var class2type = {}; 4410 4411var toString = class2type.toString; 4412 4413var hasOwn = class2type.hasOwnProperty; 4414 4415var fnToString = hasOwn.toString; 4416 4417var ObjectFunctionString = fnToString.call( Object ); 4418 4419var support = {}; 4420 4421var isFunction = function isFunction( obj ) { 4422 4423 // Support: Chrome <=57, Firefox <=52 4424 // In some browsers, typeof returns "function" for HTML <object> elements 4425 // (i.e., `typeof document.createElement( "object" ) === "function"`). 4426 // We don't want to classify *any* DOM node as a function. 4427 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 4428 // Plus for old WebKit, typeof returns "function" for HTML collections 4429 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 4430 return typeof obj === "function" && typeof obj.nodeType !== "number" && 4431 typeof obj.item !== "function"; 4432 }; 4433 4434 4435var isWindow = function isWindow( obj ) { 4436 return obj != null && obj === obj.window; 4437 }; 4438 4439 4440var document = window.document; 4441 4442 4443 4444 var preservedScriptAttributes = { 4445 type: true, 4446 src: true, 4447 nonce: true, 4448 noModule: true 4449 }; 4450 4451 function DOMEval( code, node, doc ) { 4452 doc = doc || document; 4453 4454 var i, val, 4455 script = doc.createElement( "script" ); 4456 4457 script.text = code; 4458 if ( node ) { 4459 for ( i in preservedScriptAttributes ) { 4460 4461 // Support: Firefox 64+, Edge 18+ 4462 // Some browsers don't support the "nonce" property on scripts. 4463 // On the other hand, just using `getAttribute` is not enough as 4464 // the `nonce` attribute is reset to an empty string whenever it 4465 // becomes browsing-context connected. 4466 // See https://github.com/whatwg/html/issues/2369 4467 // See https://html.spec.whatwg.org/#nonce-attributes 4468 // The `node.getAttribute` check was added for the sake of 4469 // `jQuery.globalEval` so that it can fake a nonce-containing node 4470 // via an object. 4471 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 4472 if ( val ) { 4473 script.setAttribute( i, val ); 4474 } 4475 } 4476 } 4477 doc.head.appendChild( script ).parentNode.removeChild( script ); 4478 } 4479 4480 4481function toType( obj ) { 4482 if ( obj == null ) { 4483 return obj + ""; 4484 } 4485 4486 // Support: Android <=2.3 only (functionish RegExp) 4487 return typeof obj === "object" || typeof obj === "function" ? 4488 class2type[ toString.call( obj ) ] || "object" : 4489 typeof obj; 4490} 4491/* global Symbol */ 4492// Defining this global in .eslintrc.json would create a danger of using the global 4493// unguarded in another place, it seems safer to define global only for this module 4494 4495 4496 4497var 4498 version = "3.6.0", 4499 4500 // Define a local copy of jQuery 4501 jQuery = function( selector, context ) { 4502 4503 // The jQuery object is actually just the init constructor 'enhanced' 4504 // Need init if jQuery is called (just allow error to be thrown if not included) 4505 return new jQuery.fn.init( selector, context ); 4506 }; 4507 4508jQuery.fn = jQuery.prototype = { 4509 4510 // The current version of jQuery being used 4511 jquery: version, 4512 4513 constructor: jQuery, 4514 4515 // The default length of a jQuery object is 0 4516 length: 0, 4517 4518 toArray: function() { 4519 return slice.call( this ); 4520 }, 4521 4522 // Get the Nth element in the matched element set OR 4523 // Get the whole matched element set as a clean array 4524 get: function( num ) { 4525 4526 // Return all the elements in a clean array 4527 if ( num == null ) { 4528 return slice.call( this ); 4529 } 4530 4531 // Return just the one element from the set 4532 return num < 0 ? this[ num + this.length ] : this[ num ]; 4533 }, 4534 4535 // Take an array of elements and push it onto the stack 4536 // (returning the new matched element set) 4537 pushStack: function( elems ) { 4538 4539 // Build a new jQuery matched element set 4540 var ret = jQuery.merge( this.constructor(), elems ); 4541 4542 // Add the old object onto the stack (as a reference) 4543 ret.prevObject = this; 4544 4545 // Return the newly-formed element set 4546 return ret; 4547 }, 4548 4549 // Execute a callback for every element in the matched set. 4550 each: function( callback ) { 4551 return jQuery.each( this, callback ); 4552 }, 4553 4554 map: function( callback ) { 4555 return this.pushStack( jQuery.map( this, function( elem, i ) { 4556 return callback.call( elem, i, elem ); 4557 } ) ); 4558 }, 4559 4560 slice: function() { 4561 return this.pushStack( slice.apply( this, arguments ) ); 4562 }, 4563 4564 first: function() { 4565 return this.eq( 0 ); 4566 }, 4567 4568 last: function() { 4569 return this.eq( -1 ); 4570 }, 4571 4572 even: function() { 4573 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 4574 return ( i + 1 ) % 2; 4575 } ) ); 4576 }, 4577 4578 odd: function() { 4579 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 4580 return i % 2; 4581 } ) ); 4582 }, 4583 4584 eq: function( i ) { 4585 var len = this.length, 4586 j = +i + ( i < 0 ? len : 0 ); 4587 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 4588 }, 4589 4590 end: function() { 4591 return this.prevObject || this.constructor(); 4592 }, 4593 4594 // For internal use only. 4595 // Behaves like an Array's method, not like a jQuery method. 4596 push: push, 4597 sort: arr.sort, 4598 splice: arr.splice 4599}; 4600 4601jQuery.extend = jQuery.fn.extend = function() { 4602 var options, name, src, copy, copyIsArray, clone, 4603 target = arguments[ 0 ] || {}, 4604 i = 1, 4605 length = arguments.length, 4606 deep = false; 4607 4608 // Handle a deep copy situation 4609 if ( typeof target === "boolean" ) { 4610 deep = target; 4611 4612 // Skip the boolean and the target 4613 target = arguments[ i ] || {}; 4614 i++; 4615 } 4616 4617 // Handle case when target is a string or something (possible in deep copy) 4618 if ( typeof target !== "object" && !isFunction( target ) ) { 4619 target = {}; 4620 } 4621 4622 // Extend jQuery itself if only one argument is passed 4623 if ( i === length ) { 4624 target = this; 4625 i--; 4626 } 4627 4628 for ( ; i < length; i++ ) { 4629 4630 // Only deal with non-null/undefined values 4631 if ( ( options = arguments[ i ] ) != null ) { 4632 4633 // Extend the base object 4634 for ( name in options ) { 4635 copy = options[ name ]; 4636 4637 // Prevent Object.prototype pollution 4638 // Prevent never-ending loop 4639 if ( name === "__proto__" || target === copy ) { 4640 continue; 4641 } 4642 4643 // Recurse if we're merging plain objects or arrays 4644 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 4645 ( copyIsArray = Array.isArray( copy ) ) ) ) { 4646 src = target[ name ]; 4647 4648 // Ensure proper type for the source value 4649 if ( copyIsArray && !Array.isArray( src ) ) { 4650 clone = []; 4651 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 4652 clone = {}; 4653 } else { 4654 clone = src; 4655 } 4656 copyIsArray = false; 4657 4658 // Never move original objects, clone them 4659 target[ name ] = jQuery.extend( deep, clone, copy ); 4660 4661 // Don't bring in undefined values 4662 } else if ( copy !== undefined ) { 4663 target[ name ] = copy; 4664 } 4665 } 4666 } 4667 } 4668 4669 // Return the modified object 4670 return target; 4671}; 4672 4673jQuery.extend( { 4674 4675 // Unique for each copy of jQuery on the page 4676 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 4677 4678 // Assume jQuery is ready without the ready module 4679 isReady: true, 4680 4681 error: function( msg ) { 4682 throw new Error( msg ); 4683 }, 4684 4685 noop: function() {}, 4686 4687 isPlainObject: function( obj ) { 4688 var proto, Ctor; 4689 4690 // Detect obvious negatives 4691 // Use toString instead of jQuery.type to catch host objects 4692 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 4693 return false; 4694 } 4695 4696 proto = getProto( obj ); 4697 4698 // Objects with no prototype (e.g., `Object.create( null )`) are plain 4699 if ( !proto ) { 4700 return true; 4701 } 4702 4703 // Objects with prototype are plain iff they were constructed by a global Object function 4704 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 4705 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 4706 }, 4707 4708 isEmptyObject: function( obj ) { 4709 var name; 4710 4711 for ( name in obj ) { 4712 return false; 4713 } 4714 return true; 4715 }, 4716 4717 // Evaluates a script in a provided context; falls back to the global one 4718 // if not specified. 4719 globalEval: function( code, options, doc ) { 4720 DOMEval( code, { nonce: options && options.nonce }, doc ); 4721 }, 4722 4723 each: function( obj, callback ) { 4724 var length, i = 0; 4725 4726 if ( isArrayLike( obj ) ) { 4727 length = obj.length; 4728 for ( ; i < length; i++ ) { 4729 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 4730 break; 4731 } 4732 } 4733 } else { 4734 for ( i in obj ) { 4735 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 4736 break; 4737 } 4738 } 4739 } 4740 4741 return obj; 4742 }, 4743 4744 // results is for internal usage only 4745 makeArray: function( arr, results ) { 4746 var ret = results || []; 4747 4748 if ( arr != null ) { 4749 if ( isArrayLike( Object( arr ) ) ) { 4750 jQuery.merge( ret, 4751 typeof arr === "string" ? 4752 [ arr ] : arr 4753 ); 4754 } else { 4755 push.call( ret, arr ); 4756 } 4757 } 4758 4759 return ret; 4760 }, 4761 4762 inArray: function( elem, arr, i ) { 4763 return arr == null ? -1 : indexOf.call( arr, elem, i ); 4764 }, 4765 4766 // Support: Android <=4.0 only, PhantomJS 1 only 4767 // push.apply(_, arraylike) throws on ancient WebKit 4768 merge: function( first, second ) { 4769 var len = +second.length, 4770 j = 0, 4771 i = first.length; 4772 4773 for ( ; j < len; j++ ) { 4774 first[ i++ ] = second[ j ]; 4775 } 4776 4777 first.length = i; 4778 4779 return first; 4780 }, 4781 4782 grep: function( elems, callback, invert ) { 4783 var callbackInverse, 4784 matches = [], 4785 i = 0, 4786 length = elems.length, 4787 callbackExpect = !invert; 4788 4789 // Go through the array, only saving the items 4790 // that pass the validator function 4791 for ( ; i < length; i++ ) { 4792 callbackInverse = !callback( elems[ i ], i ); 4793 if ( callbackInverse !== callbackExpect ) { 4794 matches.push( elems[ i ] ); 4795 } 4796 } 4797 4798 return matches; 4799 }, 4800 4801 // arg is for internal usage only 4802 map: function( elems, callback, arg ) { 4803 var length, value, 4804 i = 0, 4805 ret = []; 4806 4807 // Go through the array, translating each of the items to their new values 4808 if ( isArrayLike( elems ) ) { 4809 length = elems.length; 4810 for ( ; i < length; i++ ) { 4811 value = callback( elems[ i ], i, arg ); 4812 4813 if ( value != null ) { 4814 ret.push( value ); 4815 } 4816 } 4817 4818 // Go through every key on the object, 4819 } else { 4820 for ( i in elems ) { 4821 value = callback( elems[ i ], i, arg ); 4822 4823 if ( value != null ) { 4824 ret.push( value ); 4825 } 4826 } 4827 } 4828 4829 // Flatten any nested arrays 4830 return flat( ret ); 4831 }, 4832 4833 // A global GUID counter for objects 4834 guid: 1, 4835 4836 // jQuery.support is not used in Core but other projects attach their 4837 // properties to it so it needs to exist. 4838 support: support 4839} ); 4840 4841if ( typeof Symbol === "function" ) { 4842 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 4843} 4844 4845// Populate the class2type map 4846jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 4847 function( _i, name ) { 4848 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 4849 } ); 4850 4851function isArrayLike( obj ) { 4852 4853 // Support: real iOS 8.2 only (not reproducible in simulator) 4854 // `in` check used to prevent JIT error (gh-2145) 4855 // hasOwn isn't used here due to false negatives 4856 // regarding Nodelist length in IE 4857 var length = !!obj && "length" in obj && obj.length, 4858 type = toType( obj ); 4859 4860 if ( isFunction( obj ) || isWindow( obj ) ) { 4861 return false; 4862 } 4863 4864 return type === "array" || length === 0 || 4865 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 4866} 4867var Sizzle = 4868/*! 4869 * Sizzle CSS Selector Engine v2.3.6 4870 * https://sizzlejs.com/ 4871 * 4872 * Copyright JS Foundation and other contributors 4873 * Released under the MIT license 4874 * https://js.foundation/ 4875 * 4876 * Date: 2021-02-16 4877 */ 4878( function( window ) { 4879var i, 4880 support, 4881 Expr, 4882 getText, 4883 isXML, 4884 tokenize, 4885 compile, 4886 select, 4887 outermostContext, 4888 sortInput, 4889 hasDuplicate, 4890 4891 // Local document vars 4892 setDocument, 4893 document, 4894 docElem, 4895 documentIsHTML, 4896 rbuggyQSA, 4897 rbuggyMatches, 4898 matches, 4899 contains, 4900 4901 // Instance-specific data 4902 expando = "sizzle" + 1 * new Date(), 4903 preferredDoc = window.document, 4904 dirruns = 0, 4905 done = 0, 4906 classCache = createCache(), 4907 tokenCache = createCache(), 4908 compilerCache = createCache(), 4909 nonnativeSelectorCache = createCache(), 4910 sortOrder = function( a, b ) { 4911 if ( a === b ) { 4912 hasDuplicate = true; 4913 } 4914 return 0; 4915 }, 4916 4917 // Instance methods 4918 hasOwn = ( {} ).hasOwnProperty, 4919 arr = [], 4920 pop = arr.pop, 4921 pushNative = arr.push, 4922 push = arr.push, 4923 slice = arr.slice, 4924 4925 // Use a stripped-down indexOf as it's faster than native 4926 // https://jsperf.com/thor-indexof-vs-for/5 4927 indexOf = function( list, elem ) { 4928 var i = 0, 4929 len = list.length; 4930 for ( ; i < len; i++ ) { 4931 if ( list[ i ] === elem ) { 4932 return i; 4933 } 4934 } 4935 return -1; 4936 }, 4937 4938 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + 4939 "ismap|loop|multiple|open|readonly|required|scoped", 4940 4941 // Regular expressions 4942 4943 // http://www.w3.org/TR/css3-selectors/#whitespace 4944 whitespace = "[\\x20\\t\\r\\n\\f]", 4945 4946 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 4947 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 4948 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 4949 4950 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 4951 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 4952 4953 // Operator (capture 2) 4954 "*([*^$|!~]?=)" + whitespace + 4955 4956 // "Attribute values must be CSS identifiers [capture 5] 4957 // or strings [capture 3 or capture 4]" 4958 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 4959 whitespace + "*\\]", 4960 4961 pseudos = ":(" + identifier + ")(?:\\((" + 4962 4963 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 4964 // 1. quoted (capture 3; capture 4 or capture 5) 4965 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 4966 4967 // 2. simple (capture 6) 4968 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 4969 4970 // 3. anything else (capture 2) 4971 ".*" + 4972 ")\\)|)", 4973 4974 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 4975 rwhitespace = new RegExp( whitespace + "+", "g" ), 4976 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 4977 whitespace + "+$", "g" ), 4978 4979 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 4980 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + 4981 "*" ), 4982 rdescend = new RegExp( whitespace + "|>" ), 4983 4984 rpseudo = new RegExp( pseudos ), 4985 ridentifier = new RegExp( "^" + identifier + "$" ), 4986 4987 matchExpr = { 4988 "ID": new RegExp( "^#(" + identifier + ")" ), 4989 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 4990 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 4991 "ATTR": new RegExp( "^" + attributes ), 4992 "PSEUDO": new RegExp( "^" + pseudos ), 4993 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 4994 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 4995 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 4996 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 4997 4998 // For use in libraries implementing .is() 4999 // We use this for POS matching in `select` 5000 "needsContext": new RegExp( "^" + whitespace + 5001 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 5002 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 5003 }, 5004 5005 rhtml = /HTML$/i, 5006 rinputs = /^(?:input|select|textarea|button)$/i, 5007 rheader = /^h\d$/i, 5008 5009 rnative = /^[^{]+\{\s*\[native \w/, 5010 5011 // Easily-parseable/retrievable ID or TAG or CLASS selectors 5012 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 5013 5014 rsibling = /[+~]/, 5015 5016 // CSS escapes 5017 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 5018 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), 5019 funescape = function( escape, nonHex ) { 5020 var high = "0x" + escape.slice( 1 ) - 0x10000; 5021 5022 return nonHex ? 5023 5024 // Strip the backslash prefix from a non-hex escape sequence 5025 nonHex : 5026 5027 // Replace a hexadecimal escape sequence with the encoded Unicode code point 5028 // Support: IE <=11+ 5029 // For values outside the Basic Multilingual Plane (BMP), manually construct a 5030 // surrogate pair 5031 high < 0 ? 5032 String.fromCharCode( high + 0x10000 ) : 5033 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 5034 }, 5035 5036 // CSS string/identifier serialization 5037 // https://drafts.csswg.org/cssom/#common-serializing-idioms 5038 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 5039 fcssescape = function( ch, asCodePoint ) { 5040 if ( asCodePoint ) { 5041 5042 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 5043 if ( ch === "\0" ) { 5044 return "\uFFFD"; 5045 } 5046 5047 // Control characters and (dependent upon position) numbers get escaped as code points 5048 return ch.slice( 0, -1 ) + "\\" + 5049 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 5050 } 5051 5052 // Other potentially-special ASCII characters get backslash-escaped 5053 return "\\" + ch; 5054 }, 5055 5056 // Used for iframes 5057 // See setDocument() 5058 // Removing the function wrapper causes a "Permission Denied" 5059 // error in IE 5060 unloadHandler = function() { 5061 setDocument(); 5062 }, 5063 5064 inDisabledFieldset = addCombinator( 5065 function( elem ) { 5066 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 5067 }, 5068 { dir: "parentNode", next: "legend" } 5069 ); 5070 5071// Optimize for push.apply( _, NodeList ) 5072try { 5073 push.apply( 5074 ( arr = slice.call( preferredDoc.childNodes ) ), 5075 preferredDoc.childNodes 5076 ); 5077 5078 // Support: Android<4.0 5079 // Detect silently failing push.apply 5080 // eslint-disable-next-line no-unused-expressions 5081 arr[ preferredDoc.childNodes.length ].nodeType; 5082} catch ( e ) { 5083 push = { apply: arr.length ? 5084 5085 // Leverage slice if possible 5086 function( target, els ) { 5087 pushNative.apply( target, slice.call( els ) ); 5088 } : 5089 5090 // Support: IE<9 5091 // Otherwise append directly 5092 function( target, els ) { 5093 var j = target.length, 5094 i = 0; 5095 5096 // Can't trust NodeList.length 5097 while ( ( target[ j++ ] = els[ i++ ] ) ) {} 5098 target.length = j - 1; 5099 } 5100 }; 5101} 5102 5103function Sizzle( selector, context, results, seed ) { 5104 var m, i, elem, nid, match, groups, newSelector, 5105 newContext = context && context.ownerDocument, 5106 5107 // nodeType defaults to 9, since context defaults to document 5108 nodeType = context ? context.nodeType : 9; 5109 5110 results = results || []; 5111 5112 // Return early from calls with invalid selector or context 5113 if ( typeof selector !== "string" || !selector || 5114 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 5115 5116 return results; 5117 } 5118 5119 // Try to shortcut find operations (as opposed to filters) in HTML documents 5120 if ( !seed ) { 5121 setDocument( context ); 5122 context = context || document; 5123 5124 if ( documentIsHTML ) { 5125 5126 // If the selector is sufficiently simple, try using a "get*By*" DOM method 5127 // (excepting DocumentFragment context, where the methods don't exist) 5128 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 5129 5130 // ID selector 5131 if ( ( m = match[ 1 ] ) ) { 5132 5133 // Document context 5134 if ( nodeType === 9 ) { 5135 if ( ( elem = context.getElementById( m ) ) ) { 5136 5137 // Support: IE, Opera, Webkit 5138 // TODO: identify versions 5139 // getElementById can match elements by name instead of ID 5140 if ( elem.id === m ) { 5141 results.push( elem ); 5142 return results; 5143 } 5144 } else { 5145 return results; 5146 } 5147 5148 // Element context 5149 } else { 5150 5151 // Support: IE, Opera, Webkit 5152 // TODO: identify versions 5153 // getElementById can match elements by name instead of ID 5154 if ( newContext && ( elem = newContext.getElementById( m ) ) && 5155 contains( context, elem ) && 5156 elem.id === m ) { 5157 5158 results.push( elem ); 5159 return results; 5160 } 5161 } 5162 5163 // Type selector 5164 } else if ( match[ 2 ] ) { 5165 push.apply( results, context.getElementsByTagName( selector ) ); 5166 return results; 5167 5168 // Class selector 5169 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && 5170 context.getElementsByClassName ) { 5171 5172 push.apply( results, context.getElementsByClassName( m ) ); 5173 return results; 5174 } 5175 } 5176 5177 // Take advantage of querySelectorAll 5178 if ( support.qsa && 5179 !nonnativeSelectorCache[ selector + " " ] && 5180 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && 5181 5182 // Support: IE 8 only 5183 // Exclude object elements 5184 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { 5185 5186 newSelector = selector; 5187 newContext = context; 5188 5189 // qSA considers elements outside a scoping root when evaluating child or 5190 // descendant combinators, which is not what we want. 5191 // In such cases, we work around the behavior by prefixing every selector in the 5192 // list with an ID selector referencing the scope context. 5193 // The technique has to be used as well when a leading combinator is used 5194 // as such selectors are not recognized by querySelectorAll. 5195 // Thanks to Andrew Dupont for this technique. 5196 if ( nodeType === 1 && 5197 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { 5198 5199 // Expand context for sibling selectors 5200 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 5201 context; 5202 5203 // We can use :scope instead of the ID hack if the browser 5204 // supports it & if we're not changing the context. 5205 if ( newContext !== context || !support.scope ) { 5206 5207 // Capture the context ID, setting it first if necessary 5208 if ( ( nid = context.getAttribute( "id" ) ) ) { 5209 nid = nid.replace( rcssescape, fcssescape ); 5210 } else { 5211 context.setAttribute( "id", ( nid = expando ) ); 5212 } 5213 } 5214 5215 // Prefix every selector in the list 5216 groups = tokenize( selector ); 5217 i = groups.length; 5218 while ( i-- ) { 5219 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 5220 toSelector( groups[ i ] ); 5221 } 5222 newSelector = groups.join( "," ); 5223 } 5224 5225 try { 5226 push.apply( results, 5227 newContext.querySelectorAll( newSelector ) 5228 ); 5229 return results; 5230 } catch ( qsaError ) { 5231 nonnativeSelectorCache( selector, true ); 5232 } finally { 5233 if ( nid === expando ) { 5234 context.removeAttribute( "id" ); 5235 } 5236 } 5237 } 5238 } 5239 } 5240 5241 // All others 5242 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 5243} 5244 5245/** 5246 * Create key-value caches of limited size 5247 * @returns {function(string, object)} Returns the Object data after storing it on itself with 5248 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 5249 * deleting the oldest entry 5250 */ 5251function createCache() { 5252 var keys = []; 5253 5254 function cache( key, value ) { 5255 5256 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 5257 if ( keys.push( key + " " ) > Expr.cacheLength ) { 5258 5259 // Only keep the most recent entries 5260 delete cache[ keys.shift() ]; 5261 } 5262 return ( cache[ key + " " ] = value ); 5263 } 5264 return cache; 5265} 5266 5267/** 5268 * Mark a function for special use by Sizzle 5269 * @param {Function} fn The function to mark 5270 */ 5271function markFunction( fn ) { 5272 fn[ expando ] = true; 5273 return fn; 5274} 5275 5276/** 5277 * Support testing using an element 5278 * @param {Function} fn Passed the created element and returns a boolean result 5279 */ 5280function assert( fn ) { 5281 var el = document.createElement( "fieldset" ); 5282 5283 try { 5284 return !!fn( el ); 5285 } catch ( e ) { 5286 return false; 5287 } finally { 5288 5289 // Remove from its parent by default 5290 if ( el.parentNode ) { 5291 el.parentNode.removeChild( el ); 5292 } 5293 5294 // release memory in IE 5295 el = null; 5296 } 5297} 5298 5299/** 5300 * Adds the same handler for all of the specified attrs 5301 * @param {String} attrs Pipe-separated list of attributes 5302 * @param {Function} handler The method that will be applied 5303 */ 5304function addHandle( attrs, handler ) { 5305 var arr = attrs.split( "|" ), 5306 i = arr.length; 5307 5308 while ( i-- ) { 5309 Expr.attrHandle[ arr[ i ] ] = handler; 5310 } 5311} 5312 5313/** 5314 * Checks document order of two siblings 5315 * @param {Element} a 5316 * @param {Element} b 5317 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 5318 */ 5319function siblingCheck( a, b ) { 5320 var cur = b && a, 5321 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 5322 a.sourceIndex - b.sourceIndex; 5323 5324 // Use IE sourceIndex if available on both nodes 5325 if ( diff ) { 5326 return diff; 5327 } 5328 5329 // Check if b follows a 5330 if ( cur ) { 5331 while ( ( cur = cur.nextSibling ) ) { 5332 if ( cur === b ) { 5333 return -1; 5334 } 5335 } 5336 } 5337 5338 return a ? 1 : -1; 5339} 5340 5341/** 5342 * Returns a function to use in pseudos for input types 5343 * @param {String} type 5344 */ 5345function createInputPseudo( type ) { 5346 return function( elem ) { 5347 var name = elem.nodeName.toLowerCase(); 5348 return name === "input" && elem.type === type; 5349 }; 5350} 5351 5352/** 5353 * Returns a function to use in pseudos for buttons 5354 * @param {String} type 5355 */ 5356function createButtonPseudo( type ) { 5357 return function( elem ) { 5358 var name = elem.nodeName.toLowerCase(); 5359 return ( name === "input" || name === "button" ) && elem.type === type; 5360 }; 5361} 5362 5363/** 5364 * Returns a function to use in pseudos for :enabled/:disabled 5365 * @param {Boolean} disabled true for :disabled; false for :enabled 5366 */ 5367function createDisabledPseudo( disabled ) { 5368 5369 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 5370 return function( elem ) { 5371 5372 // Only certain elements can match :enabled or :disabled 5373 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 5374 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 5375 if ( "form" in elem ) { 5376 5377 // Check for inherited disabledness on relevant non-disabled elements: 5378 // * listed form-associated elements in a disabled fieldset 5379 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 5380 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 5381 // * option elements in a disabled optgroup 5382 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 5383 // All such elements have a "form" property. 5384 if ( elem.parentNode && elem.disabled === false ) { 5385 5386 // Option elements defer to a parent optgroup if present 5387 if ( "label" in elem ) { 5388 if ( "label" in elem.parentNode ) { 5389 return elem.parentNode.disabled === disabled; 5390 } else { 5391 return elem.disabled === disabled; 5392 } 5393 } 5394 5395 // Support: IE 6 - 11 5396 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 5397 return elem.isDisabled === disabled || 5398 5399 // Where there is no isDisabled, check manually 5400 /* jshint -W018 */ 5401 elem.isDisabled !== !disabled && 5402 inDisabledFieldset( elem ) === disabled; 5403 } 5404 5405 return elem.disabled === disabled; 5406 5407 // Try to winnow out elements that can't be disabled before trusting the disabled property. 5408 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 5409 // even exist on them, let alone have a boolean value. 5410 } else if ( "label" in elem ) { 5411 return elem.disabled === disabled; 5412 } 5413 5414 // Remaining elements are neither :enabled nor :disabled 5415 return false; 5416 }; 5417} 5418 5419/** 5420 * Returns a function to use in pseudos for positionals 5421 * @param {Function} fn 5422 */ 5423function createPositionalPseudo( fn ) { 5424 return markFunction( function( argument ) { 5425 argument = +argument; 5426 return markFunction( function( seed, matches ) { 5427 var j, 5428 matchIndexes = fn( [], seed.length, argument ), 5429 i = matchIndexes.length; 5430 5431 // Match elements found at the specified indexes 5432 while ( i-- ) { 5433 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 5434 seed[ j ] = !( matches[ j ] = seed[ j ] ); 5435 } 5436 } 5437 } ); 5438 } ); 5439} 5440 5441/** 5442 * Checks a node for validity as a Sizzle context 5443 * @param {Element|Object=} context 5444 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 5445 */ 5446function testContext( context ) { 5447 return context && typeof context.getElementsByTagName !== "undefined" && context; 5448} 5449 5450// Expose support vars for convenience 5451support = Sizzle.support = {}; 5452 5453/** 5454 * Detects XML nodes 5455 * @param {Element|Object} elem An element or a document 5456 * @returns {Boolean} True iff elem is a non-HTML XML node 5457 */ 5458isXML = Sizzle.isXML = function( elem ) { 5459 var namespace = elem && elem.namespaceURI, 5460 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 5461 5462 // Support: IE <=8 5463 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 5464 // https://bugs.jquery.com/ticket/4833 5465 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 5466}; 5467 5468/** 5469 * Sets document-related variables once based on the current document 5470 * @param {Element|Object} [doc] An element or document object to use to set the document 5471 * @returns {Object} Returns the current document 5472 */ 5473setDocument = Sizzle.setDocument = function( node ) { 5474 var hasCompare, subWindow, 5475 doc = node ? node.ownerDocument || node : preferredDoc; 5476 5477 // Return early if doc is invalid or already selected 5478 // Support: IE 11+, Edge 17 - 18+ 5479 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5480 // two documents; shallow comparisons work. 5481 // eslint-disable-next-line eqeqeq 5482 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 5483 return document; 5484 } 5485 5486 // Update global variables 5487 document = doc; 5488 docElem = document.documentElement; 5489 documentIsHTML = !isXML( document ); 5490 5491 // Support: IE 9 - 11+, Edge 12 - 18+ 5492 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 5493 // Support: IE 11+, Edge 17 - 18+ 5494 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5495 // two documents; shallow comparisons work. 5496 // eslint-disable-next-line eqeqeq 5497 if ( preferredDoc != document && 5498 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 5499 5500 // Support: IE 11, Edge 5501 if ( subWindow.addEventListener ) { 5502 subWindow.addEventListener( "unload", unloadHandler, false ); 5503 5504 // Support: IE 9 - 10 only 5505 } else if ( subWindow.attachEvent ) { 5506 subWindow.attachEvent( "onunload", unloadHandler ); 5507 } 5508 } 5509 5510 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, 5511 // Safari 4 - 5 only, Opera <=11.6 - 12.x only 5512 // IE/Edge & older browsers don't support the :scope pseudo-class. 5513 // Support: Safari 6.0 only 5514 // Safari 6.0 supports :scope but it's an alias of :root there. 5515 support.scope = assert( function( el ) { 5516 docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); 5517 return typeof el.querySelectorAll !== "undefined" && 5518 !el.querySelectorAll( ":scope fieldset div" ).length; 5519 } ); 5520 5521 /* Attributes 5522 ---------------------------------------------------------------------- */ 5523 5524 // Support: IE<8 5525 // Verify that getAttribute really returns attributes and not properties 5526 // (excepting IE8 booleans) 5527 support.attributes = assert( function( el ) { 5528 el.className = "i"; 5529 return !el.getAttribute( "className" ); 5530 } ); 5531 5532 /* getElement(s)By* 5533 ---------------------------------------------------------------------- */ 5534 5535 // Check if getElementsByTagName("*") returns only elements 5536 support.getElementsByTagName = assert( function( el ) { 5537 el.appendChild( document.createComment( "" ) ); 5538 return !el.getElementsByTagName( "*" ).length; 5539 } ); 5540 5541 // Support: IE<9 5542 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 5543 5544 // Support: IE<10 5545 // Check if getElementById returns elements by name 5546 // The broken getElementById methods don't pick up programmatically-set names, 5547 // so use a roundabout getElementsByName test 5548 support.getById = assert( function( el ) { 5549 docElem.appendChild( el ).id = expando; 5550 return !document.getElementsByName || !document.getElementsByName( expando ).length; 5551 } ); 5552 5553 // ID filter and find 5554 if ( support.getById ) { 5555 Expr.filter[ "ID" ] = function( id ) { 5556 var attrId = id.replace( runescape, funescape ); 5557 return function( elem ) { 5558 return elem.getAttribute( "id" ) === attrId; 5559 }; 5560 }; 5561 Expr.find[ "ID" ] = function( id, context ) { 5562 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 5563 var elem = context.getElementById( id ); 5564 return elem ? [ elem ] : []; 5565 } 5566 }; 5567 } else { 5568 Expr.filter[ "ID" ] = function( id ) { 5569 var attrId = id.replace( runescape, funescape ); 5570 return function( elem ) { 5571 var node = typeof elem.getAttributeNode !== "undefined" && 5572 elem.getAttributeNode( "id" ); 5573 return node && node.value === attrId; 5574 }; 5575 }; 5576 5577 // Support: IE 6 - 7 only 5578 // getElementById is not reliable as a find shortcut 5579 Expr.find[ "ID" ] = function( id, context ) { 5580 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 5581 var node, i, elems, 5582 elem = context.getElementById( id ); 5583 5584 if ( elem ) { 5585 5586 // Verify the id attribute 5587 node = elem.getAttributeNode( "id" ); 5588 if ( node && node.value === id ) { 5589 return [ elem ]; 5590 } 5591 5592 // Fall back on getElementsByName 5593 elems = context.getElementsByName( id ); 5594 i = 0; 5595 while ( ( elem = elems[ i++ ] ) ) { 5596 node = elem.getAttributeNode( "id" ); 5597 if ( node && node.value === id ) { 5598 return [ elem ]; 5599 } 5600 } 5601 } 5602 5603 return []; 5604 } 5605 }; 5606 } 5607 5608 // Tag 5609 Expr.find[ "TAG" ] = support.getElementsByTagName ? 5610 function( tag, context ) { 5611 if ( typeof context.getElementsByTagName !== "undefined" ) { 5612 return context.getElementsByTagName( tag ); 5613 5614 // DocumentFragment nodes don't have gEBTN 5615 } else if ( support.qsa ) { 5616 return context.querySelectorAll( tag ); 5617 } 5618 } : 5619 5620 function( tag, context ) { 5621 var elem, 5622 tmp = [], 5623 i = 0, 5624 5625 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 5626 results = context.getElementsByTagName( tag ); 5627 5628 // Filter out possible comments 5629 if ( tag === "*" ) { 5630 while ( ( elem = results[ i++ ] ) ) { 5631 if ( elem.nodeType === 1 ) { 5632 tmp.push( elem ); 5633 } 5634 } 5635 5636 return tmp; 5637 } 5638 return results; 5639 }; 5640 5641 // Class 5642 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { 5643 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 5644 return context.getElementsByClassName( className ); 5645 } 5646 }; 5647 5648 /* QSA/matchesSelector 5649 ---------------------------------------------------------------------- */ 5650 5651 // QSA and matchesSelector support 5652 5653 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 5654 rbuggyMatches = []; 5655 5656 // qSa(:focus) reports false when true (Chrome 21) 5657 // We allow this because of a bug in IE8/9 that throws an error 5658 // whenever `document.activeElement` is accessed on an iframe 5659 // So, we allow :focus to pass through QSA all the time to avoid the IE error 5660 // See https://bugs.jquery.com/ticket/13378 5661 rbuggyQSA = []; 5662 5663 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { 5664 5665 // Build QSA regex 5666 // Regex strategy adopted from Diego Perini 5667 assert( function( el ) { 5668 5669 var input; 5670 5671 // Select is set to empty string on purpose 5672 // This is to test IE's treatment of not explicitly 5673 // setting a boolean content attribute, 5674 // since its presence should be enough 5675 // https://bugs.jquery.com/ticket/12359 5676 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 5677 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 5678 "<option selected=''></option></select>"; 5679 5680 // Support: IE8, Opera 11-12.16 5681 // Nothing should be selected when empty strings follow ^= or $= or *= 5682 // The test attribute must be unknown in Opera but "safe" for WinRT 5683 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 5684 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { 5685 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 5686 } 5687 5688 // Support: IE8 5689 // Boolean attributes and "value" are not treated correctly 5690 if ( !el.querySelectorAll( "[selected]" ).length ) { 5691 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 5692 } 5693 5694 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 5695 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 5696 rbuggyQSA.push( "~=" ); 5697 } 5698 5699 // Support: IE 11+, Edge 15 - 18+ 5700 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 5701 // Adding a temporary attribute to the document before the selection works 5702 // around the issue. 5703 // Interestingly, IE 10 & older don't seem to have the issue. 5704 input = document.createElement( "input" ); 5705 input.setAttribute( "name", "" ); 5706 el.appendChild( input ); 5707 if ( !el.querySelectorAll( "[name='']" ).length ) { 5708 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 5709 whitespace + "*(?:''|\"\")" ); 5710 } 5711 5712 // Webkit/Opera - :checked should return selected option elements 5713 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 5714 // IE8 throws error here and will not see later tests 5715 if ( !el.querySelectorAll( ":checked" ).length ) { 5716 rbuggyQSA.push( ":checked" ); 5717 } 5718 5719 // Support: Safari 8+, iOS 8+ 5720 // https://bugs.webkit.org/show_bug.cgi?id=136851 5721 // In-page `selector#id sibling-combinator selector` fails 5722 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 5723 rbuggyQSA.push( ".#.+[+~]" ); 5724 } 5725 5726 // Support: Firefox <=3.6 - 5 only 5727 // Old Firefox doesn't throw on a badly-escaped identifier. 5728 el.querySelectorAll( "\\\f" ); 5729 rbuggyQSA.push( "[\\r\\n\\f]" ); 5730 } ); 5731 5732 assert( function( el ) { 5733 el.innerHTML = "<a href='' disabled='disabled'></a>" + 5734 "<select disabled='disabled'><option/></select>"; 5735 5736 // Support: Windows 8 Native Apps 5737 // The type and name attributes are restricted during .innerHTML assignment 5738 var input = document.createElement( "input" ); 5739 input.setAttribute( "type", "hidden" ); 5740 el.appendChild( input ).setAttribute( "name", "D" ); 5741 5742 // Support: IE8 5743 // Enforce case-sensitivity of name attribute 5744 if ( el.querySelectorAll( "[name=d]" ).length ) { 5745 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 5746 } 5747 5748 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 5749 // IE8 throws error here and will not see later tests 5750 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { 5751 rbuggyQSA.push( ":enabled", ":disabled" ); 5752 } 5753 5754 // Support: IE9-11+ 5755 // IE's :disabled selector does not pick up the children of disabled fieldsets 5756 docElem.appendChild( el ).disabled = true; 5757 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 5758 rbuggyQSA.push( ":enabled", ":disabled" ); 5759 } 5760 5761 // Support: Opera 10 - 11 only 5762 // Opera 10-11 does not throw on post-comma invalid pseudos 5763 el.querySelectorAll( "*,:x" ); 5764 rbuggyQSA.push( ",.*:" ); 5765 } ); 5766 } 5767 5768 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || 5769 docElem.webkitMatchesSelector || 5770 docElem.mozMatchesSelector || 5771 docElem.oMatchesSelector || 5772 docElem.msMatchesSelector ) ) ) ) { 5773 5774 assert( function( el ) { 5775 5776 // Check to see if it's possible to do matchesSelector 5777 // on a disconnected node (IE 9) 5778 support.disconnectedMatch = matches.call( el, "*" ); 5779 5780 // This should fail with an exception 5781 // Gecko does not error, returns false instead 5782 matches.call( el, "[s!='']:x" ); 5783 rbuggyMatches.push( "!=", pseudos ); 5784 } ); 5785 } 5786 5787 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 5788 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); 5789 5790 /* Contains 5791 ---------------------------------------------------------------------- */ 5792 hasCompare = rnative.test( docElem.compareDocumentPosition ); 5793 5794 // Element contains another 5795 // Purposefully self-exclusive 5796 // As in, an element does not contain itself 5797 contains = hasCompare || rnative.test( docElem.contains ) ? 5798 function( a, b ) { 5799 var adown = a.nodeType === 9 ? a.documentElement : a, 5800 bup = b && b.parentNode; 5801 return a === bup || !!( bup && bup.nodeType === 1 && ( 5802 adown.contains ? 5803 adown.contains( bup ) : 5804 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 5805 ) ); 5806 } : 5807 function( a, b ) { 5808 if ( b ) { 5809 while ( ( b = b.parentNode ) ) { 5810 if ( b === a ) { 5811 return true; 5812 } 5813 } 5814 } 5815 return false; 5816 }; 5817 5818 /* Sorting 5819 ---------------------------------------------------------------------- */ 5820 5821 // Document order sorting 5822 sortOrder = hasCompare ? 5823 function( a, b ) { 5824 5825 // Flag for duplicate removal 5826 if ( a === b ) { 5827 hasDuplicate = true; 5828 return 0; 5829 } 5830 5831 // Sort on method existence if only one input has compareDocumentPosition 5832 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 5833 if ( compare ) { 5834 return compare; 5835 } 5836 5837 // Calculate position if both inputs belong to the same document 5838 // Support: IE 11+, Edge 17 - 18+ 5839 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5840 // two documents; shallow comparisons work. 5841 // eslint-disable-next-line eqeqeq 5842 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 5843 a.compareDocumentPosition( b ) : 5844 5845 // Otherwise we know they are disconnected 5846 1; 5847 5848 // Disconnected nodes 5849 if ( compare & 1 || 5850 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 5851 5852 // Choose the first element that is related to our preferred document 5853 // Support: IE 11+, Edge 17 - 18+ 5854 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5855 // two documents; shallow comparisons work. 5856 // eslint-disable-next-line eqeqeq 5857 if ( a == document || a.ownerDocument == preferredDoc && 5858 contains( preferredDoc, a ) ) { 5859 return -1; 5860 } 5861 5862 // Support: IE 11+, Edge 17 - 18+ 5863 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5864 // two documents; shallow comparisons work. 5865 // eslint-disable-next-line eqeqeq 5866 if ( b == document || b.ownerDocument == preferredDoc && 5867 contains( preferredDoc, b ) ) { 5868 return 1; 5869 } 5870 5871 // Maintain original order 5872 return sortInput ? 5873 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 5874 0; 5875 } 5876 5877 return compare & 4 ? -1 : 1; 5878 } : 5879 function( a, b ) { 5880 5881 // Exit early if the nodes are identical 5882 if ( a === b ) { 5883 hasDuplicate = true; 5884 return 0; 5885 } 5886 5887 var cur, 5888 i = 0, 5889 aup = a.parentNode, 5890 bup = b.parentNode, 5891 ap = [ a ], 5892 bp = [ b ]; 5893 5894 // Parentless nodes are either documents or disconnected 5895 if ( !aup || !bup ) { 5896 5897 // Support: IE 11+, Edge 17 - 18+ 5898 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5899 // two documents; shallow comparisons work. 5900 /* eslint-disable eqeqeq */ 5901 return a == document ? -1 : 5902 b == document ? 1 : 5903 /* eslint-enable eqeqeq */ 5904 aup ? -1 : 5905 bup ? 1 : 5906 sortInput ? 5907 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 5908 0; 5909 5910 // If the nodes are siblings, we can do a quick check 5911 } else if ( aup === bup ) { 5912 return siblingCheck( a, b ); 5913 } 5914 5915 // Otherwise we need full lists of their ancestors for comparison 5916 cur = a; 5917 while ( ( cur = cur.parentNode ) ) { 5918 ap.unshift( cur ); 5919 } 5920 cur = b; 5921 while ( ( cur = cur.parentNode ) ) { 5922 bp.unshift( cur ); 5923 } 5924 5925 // Walk down the tree looking for a discrepancy 5926 while ( ap[ i ] === bp[ i ] ) { 5927 i++; 5928 } 5929 5930 return i ? 5931 5932 // Do a sibling check if the nodes have a common ancestor 5933 siblingCheck( ap[ i ], bp[ i ] ) : 5934 5935 // Otherwise nodes in our document sort first 5936 // Support: IE 11+, Edge 17 - 18+ 5937 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5938 // two documents; shallow comparisons work. 5939 /* eslint-disable eqeqeq */ 5940 ap[ i ] == preferredDoc ? -1 : 5941 bp[ i ] == preferredDoc ? 1 : 5942 /* eslint-enable eqeqeq */ 5943 0; 5944 }; 5945 5946 return document; 5947}; 5948 5949Sizzle.matches = function( expr, elements ) { 5950 return Sizzle( expr, null, null, elements ); 5951}; 5952 5953Sizzle.matchesSelector = function( elem, expr ) { 5954 setDocument( elem ); 5955 5956 if ( support.matchesSelector && documentIsHTML && 5957 !nonnativeSelectorCache[ expr + " " ] && 5958 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 5959 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 5960 5961 try { 5962 var ret = matches.call( elem, expr ); 5963 5964 // IE 9's matchesSelector returns false on disconnected nodes 5965 if ( ret || support.disconnectedMatch || 5966 5967 // As well, disconnected nodes are said to be in a document 5968 // fragment in IE 9 5969 elem.document && elem.document.nodeType !== 11 ) { 5970 return ret; 5971 } 5972 } catch ( e ) { 5973 nonnativeSelectorCache( expr, true ); 5974 } 5975 } 5976 5977 return Sizzle( expr, document, null, [ elem ] ).length > 0; 5978}; 5979 5980Sizzle.contains = function( context, elem ) { 5981 5982 // Set document vars if needed 5983 // Support: IE 11+, Edge 17 - 18+ 5984 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5985 // two documents; shallow comparisons work. 5986 // eslint-disable-next-line eqeqeq 5987 if ( ( context.ownerDocument || context ) != document ) { 5988 setDocument( context ); 5989 } 5990 return contains( context, elem ); 5991}; 5992 5993Sizzle.attr = function( elem, name ) { 5994 5995 // Set document vars if needed 5996 // Support: IE 11+, Edge 17 - 18+ 5997 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 5998 // two documents; shallow comparisons work. 5999 // eslint-disable-next-line eqeqeq 6000 if ( ( elem.ownerDocument || elem ) != document ) { 6001 setDocument( elem ); 6002 } 6003 6004 var fn = Expr.attrHandle[ name.toLowerCase() ], 6005 6006 // Don't get fooled by Object.prototype properties (jQuery #13807) 6007 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 6008 fn( elem, name, !documentIsHTML ) : 6009 undefined; 6010 6011 return val !== undefined ? 6012 val : 6013 support.attributes || !documentIsHTML ? 6014 elem.getAttribute( name ) : 6015 ( val = elem.getAttributeNode( name ) ) && val.specified ? 6016 val.value : 6017 null; 6018}; 6019 6020Sizzle.escape = function( sel ) { 6021 return ( sel + "" ).replace( rcssescape, fcssescape ); 6022}; 6023 6024Sizzle.error = function( msg ) { 6025 throw new Error( "Syntax error, unrecognized expression: " + msg ); 6026}; 6027 6028/** 6029 * Document sorting and removing duplicates 6030 * @param {ArrayLike} results 6031 */ 6032Sizzle.uniqueSort = function( results ) { 6033 var elem, 6034 duplicates = [], 6035 j = 0, 6036 i = 0; 6037 6038 // Unless we *know* we can detect duplicates, assume their presence 6039 hasDuplicate = !support.detectDuplicates; 6040 sortInput = !support.sortStable && results.slice( 0 ); 6041 results.sort( sortOrder ); 6042 6043 if ( hasDuplicate ) { 6044 while ( ( elem = results[ i++ ] ) ) { 6045 if ( elem === results[ i ] ) { 6046 j = duplicates.push( i ); 6047 } 6048 } 6049 while ( j-- ) { 6050 results.splice( duplicates[ j ], 1 ); 6051 } 6052 } 6053 6054 // Clear input after sorting to release objects 6055 // See https://github.com/jquery/sizzle/pull/225 6056 sortInput = null; 6057 6058 return results; 6059}; 6060 6061/** 6062 * Utility function for retrieving the text value of an array of DOM nodes 6063 * @param {Array|Element} elem 6064 */ 6065getText = Sizzle.getText = function( elem ) { 6066 var node, 6067 ret = "", 6068 i = 0, 6069 nodeType = elem.nodeType; 6070 6071 if ( !nodeType ) { 6072 6073 // If no nodeType, this is expected to be an array 6074 while ( ( node = elem[ i++ ] ) ) { 6075 6076 // Do not traverse comment nodes 6077 ret += getText( node ); 6078 } 6079 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 6080 6081 // Use textContent for elements 6082 // innerText usage removed for consistency of new lines (jQuery #11153) 6083 if ( typeof elem.textContent === "string" ) { 6084 return elem.textContent; 6085 } else { 6086 6087 // Traverse its children 6088 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 6089 ret += getText( elem ); 6090 } 6091 } 6092 } else if ( nodeType === 3 || nodeType === 4 ) { 6093 return elem.nodeValue; 6094 } 6095 6096 // Do not include comment or processing instruction nodes 6097 6098 return ret; 6099}; 6100 6101Expr = Sizzle.selectors = { 6102 6103 // Can be adjusted by the user 6104 cacheLength: 50, 6105 6106 createPseudo: markFunction, 6107 6108 match: matchExpr, 6109 6110 attrHandle: {}, 6111 6112 find: {}, 6113 6114 relative: { 6115 ">": { dir: "parentNode", first: true }, 6116 " ": { dir: "parentNode" }, 6117 "+": { dir: "previousSibling", first: true }, 6118 "~": { dir: "previousSibling" } 6119 }, 6120 6121 preFilter: { 6122 "ATTR": function( match ) { 6123 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 6124 6125 // Move the given value to match[3] whether quoted or unquoted 6126 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || 6127 match[ 5 ] || "" ).replace( runescape, funescape ); 6128 6129 if ( match[ 2 ] === "~=" ) { 6130 match[ 3 ] = " " + match[ 3 ] + " "; 6131 } 6132 6133 return match.slice( 0, 4 ); 6134 }, 6135 6136 "CHILD": function( match ) { 6137 6138 /* matches from matchExpr["CHILD"] 6139 1 type (only|nth|...) 6140 2 what (child|of-type) 6141 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 6142 4 xn-component of xn+y argument ([+-]?\d*n|) 6143 5 sign of xn-component 6144 6 x of xn-component 6145 7 sign of y-component 6146 8 y of y-component 6147 */ 6148 match[ 1 ] = match[ 1 ].toLowerCase(); 6149 6150 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 6151 6152 // nth-* requires argument 6153 if ( !match[ 3 ] ) { 6154 Sizzle.error( match[ 0 ] ); 6155 } 6156 6157 // numeric x and y parameters for Expr.filter.CHILD 6158 // remember that false/true cast respectively to 0/1 6159 match[ 4 ] = +( match[ 4 ] ? 6160 match[ 5 ] + ( match[ 6 ] || 1 ) : 6161 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); 6162 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 6163 6164 // other types prohibit arguments 6165 } else if ( match[ 3 ] ) { 6166 Sizzle.error( match[ 0 ] ); 6167 } 6168 6169 return match; 6170 }, 6171 6172 "PSEUDO": function( match ) { 6173 var excess, 6174 unquoted = !match[ 6 ] && match[ 2 ]; 6175 6176 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { 6177 return null; 6178 } 6179 6180 // Accept quoted arguments as-is 6181 if ( match[ 3 ] ) { 6182 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 6183 6184 // Strip excess characters from unquoted arguments 6185 } else if ( unquoted && rpseudo.test( unquoted ) && 6186 6187 // Get excess from tokenize (recursively) 6188 ( excess = tokenize( unquoted, true ) ) && 6189 6190 // advance to the next closing parenthesis 6191 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 6192 6193 // excess is a negative index 6194 match[ 0 ] = match[ 0 ].slice( 0, excess ); 6195 match[ 2 ] = unquoted.slice( 0, excess ); 6196 } 6197 6198 // Return only captures needed by the pseudo filter method (type and argument) 6199 return match.slice( 0, 3 ); 6200 } 6201 }, 6202 6203 filter: { 6204 6205 "TAG": function( nodeNameSelector ) { 6206 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 6207 return nodeNameSelector === "*" ? 6208 function() { 6209 return true; 6210 } : 6211 function( elem ) { 6212 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 6213 }; 6214 }, 6215 6216 "CLASS": function( className ) { 6217 var pattern = classCache[ className + " " ]; 6218 6219 return pattern || 6220 ( pattern = new RegExp( "(^|" + whitespace + 6221 ")" + className + "(" + whitespace + "|$)" ) ) && classCache( 6222 className, function( elem ) { 6223 return pattern.test( 6224 typeof elem.className === "string" && elem.className || 6225 typeof elem.getAttribute !== "undefined" && 6226 elem.getAttribute( "class" ) || 6227 "" 6228 ); 6229 } ); 6230 }, 6231 6232 "ATTR": function( name, operator, check ) { 6233 return function( elem ) { 6234 var result = Sizzle.attr( elem, name ); 6235 6236 if ( result == null ) { 6237 return operator === "!="; 6238 } 6239 if ( !operator ) { 6240 return true; 6241 } 6242 6243 result += ""; 6244 6245 /* eslint-disable max-len */ 6246 6247 return operator === "=" ? result === check : 6248 operator === "!=" ? result !== check : 6249 operator === "^=" ? check && result.indexOf( check ) === 0 : 6250 operator === "*=" ? check && result.indexOf( check ) > -1 : 6251 operator === "$=" ? check && result.slice( -check.length ) === check : 6252 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 6253 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 6254 false; 6255 /* eslint-enable max-len */ 6256 6257 }; 6258 }, 6259 6260 "CHILD": function( type, what, _argument, first, last ) { 6261 var simple = type.slice( 0, 3 ) !== "nth", 6262 forward = type.slice( -4 ) !== "last", 6263 ofType = what === "of-type"; 6264 6265 return first === 1 && last === 0 ? 6266 6267 // Shortcut for :nth-*(n) 6268 function( elem ) { 6269 return !!elem.parentNode; 6270 } : 6271 6272 function( elem, _context, xml ) { 6273 var cache, uniqueCache, outerCache, node, nodeIndex, start, 6274 dir = simple !== forward ? "nextSibling" : "previousSibling", 6275 parent = elem.parentNode, 6276 name = ofType && elem.nodeName.toLowerCase(), 6277 useCache = !xml && !ofType, 6278 diff = false; 6279 6280 if ( parent ) { 6281 6282 // :(first|last|only)-(child|of-type) 6283 if ( simple ) { 6284 while ( dir ) { 6285 node = elem; 6286 while ( ( node = node[ dir ] ) ) { 6287 if ( ofType ? 6288 node.nodeName.toLowerCase() === name : 6289 node.nodeType === 1 ) { 6290 6291 return false; 6292 } 6293 } 6294 6295 // Reverse direction for :only-* (if we haven't yet done so) 6296 start = dir = type === "only" && !start && "nextSibling"; 6297 } 6298 return true; 6299 } 6300 6301 start = [ forward ? parent.firstChild : parent.lastChild ]; 6302 6303 // non-xml :nth-child(...) stores cache data on `parent` 6304 if ( forward && useCache ) { 6305 6306 // Seek `elem` from a previously-cached index 6307 6308 // ...in a gzip-friendly way 6309 node = parent; 6310 outerCache = node[ expando ] || ( node[ expando ] = {} ); 6311 6312 // Support: IE <9 only 6313 // Defend against cloned attroperties (jQuery gh-1709) 6314 uniqueCache = outerCache[ node.uniqueID ] || 6315 ( outerCache[ node.uniqueID ] = {} ); 6316 6317 cache = uniqueCache[ type ] || []; 6318 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 6319 diff = nodeIndex && cache[ 2 ]; 6320 node = nodeIndex && parent.childNodes[ nodeIndex ]; 6321 6322 while ( ( node = ++nodeIndex && node && node[ dir ] || 6323 6324 // Fallback to seeking `elem` from the start 6325 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 6326 6327 // When found, cache indexes on `parent` and break 6328 if ( node.nodeType === 1 && ++diff && node === elem ) { 6329 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 6330 break; 6331 } 6332 } 6333 6334 } else { 6335 6336 // Use previously-cached element index if available 6337 if ( useCache ) { 6338 6339 // ...in a gzip-friendly way 6340 node = elem; 6341 outerCache = node[ expando ] || ( node[ expando ] = {} ); 6342 6343 // Support: IE <9 only 6344 // Defend against cloned attroperties (jQuery gh-1709) 6345 uniqueCache = outerCache[ node.uniqueID ] || 6346 ( outerCache[ node.uniqueID ] = {} ); 6347 6348 cache = uniqueCache[ type ] || []; 6349 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 6350 diff = nodeIndex; 6351 } 6352 6353 // xml :nth-child(...) 6354 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 6355 if ( diff === false ) { 6356 6357 // Use the same loop as above to seek `elem` from the start 6358 while ( ( node = ++nodeIndex && node && node[ dir ] || 6359 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 6360 6361 if ( ( ofType ? 6362 node.nodeName.toLowerCase() === name : 6363 node.nodeType === 1 ) && 6364 ++diff ) { 6365 6366 // Cache the index of each encountered element 6367 if ( useCache ) { 6368 outerCache = node[ expando ] || 6369 ( node[ expando ] = {} ); 6370 6371 // Support: IE <9 only 6372 // Defend against cloned attroperties (jQuery gh-1709) 6373 uniqueCache = outerCache[ node.uniqueID ] || 6374 ( outerCache[ node.uniqueID ] = {} ); 6375 6376 uniqueCache[ type ] = [ dirruns, diff ]; 6377 } 6378 6379 if ( node === elem ) { 6380 break; 6381 } 6382 } 6383 } 6384 } 6385 } 6386 6387 // Incorporate the offset, then check against cycle size 6388 diff -= last; 6389 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 6390 } 6391 }; 6392 }, 6393 6394 "PSEUDO": function( pseudo, argument ) { 6395 6396 // pseudo-class names are case-insensitive 6397 // http://www.w3.org/TR/selectors/#pseudo-classes 6398 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 6399 // Remember that setFilters inherits from pseudos 6400 var args, 6401 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 6402 Sizzle.error( "unsupported pseudo: " + pseudo ); 6403 6404 // The user may use createPseudo to indicate that 6405 // arguments are needed to create the filter function 6406 // just as Sizzle does 6407 if ( fn[ expando ] ) { 6408 return fn( argument ); 6409 } 6410 6411 // But maintain support for old signatures 6412 if ( fn.length > 1 ) { 6413 args = [ pseudo, pseudo, "", argument ]; 6414 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 6415 markFunction( function( seed, matches ) { 6416 var idx, 6417 matched = fn( seed, argument ), 6418 i = matched.length; 6419 while ( i-- ) { 6420 idx = indexOf( seed, matched[ i ] ); 6421 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 6422 } 6423 } ) : 6424 function( elem ) { 6425 return fn( elem, 0, args ); 6426 }; 6427 } 6428 6429 return fn; 6430 } 6431 }, 6432 6433 pseudos: { 6434 6435 // Potentially complex pseudos 6436 "not": markFunction( function( selector ) { 6437 6438 // Trim the selector passed to compile 6439 // to avoid treating leading and trailing 6440 // spaces as combinators 6441 var input = [], 6442 results = [], 6443 matcher = compile( selector.replace( rtrim, "$1" ) ); 6444 6445 return matcher[ expando ] ? 6446 markFunction( function( seed, matches, _context, xml ) { 6447 var elem, 6448 unmatched = matcher( seed, null, xml, [] ), 6449 i = seed.length; 6450 6451 // Match elements unmatched by `matcher` 6452 while ( i-- ) { 6453 if ( ( elem = unmatched[ i ] ) ) { 6454 seed[ i ] = !( matches[ i ] = elem ); 6455 } 6456 } 6457 } ) : 6458 function( elem, _context, xml ) { 6459 input[ 0 ] = elem; 6460 matcher( input, null, xml, results ); 6461 6462 // Don't keep the element (issue #299) 6463 input[ 0 ] = null; 6464 return !results.pop(); 6465 }; 6466 } ), 6467 6468 "has": markFunction( function( selector ) { 6469 return function( elem ) { 6470 return Sizzle( selector, elem ).length > 0; 6471 }; 6472 } ), 6473 6474 "contains": markFunction( function( text ) { 6475 text = text.replace( runescape, funescape ); 6476 return function( elem ) { 6477 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; 6478 }; 6479 } ), 6480 6481 // "Whether an element is represented by a :lang() selector 6482 // is based solely on the element's language value 6483 // being equal to the identifier C, 6484 // or beginning with the identifier C immediately followed by "-". 6485 // The matching of C against the element's language value is performed case-insensitively. 6486 // The identifier C does not have to be a valid language name." 6487 // http://www.w3.org/TR/selectors/#lang-pseudo 6488 "lang": markFunction( function( lang ) { 6489 6490 // lang value must be a valid identifier 6491 if ( !ridentifier.test( lang || "" ) ) { 6492 Sizzle.error( "unsupported lang: " + lang ); 6493 } 6494 lang = lang.replace( runescape, funescape ).toLowerCase(); 6495 return function( elem ) { 6496 var elemLang; 6497 do { 6498 if ( ( elemLang = documentIsHTML ? 6499 elem.lang : 6500 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 6501 6502 elemLang = elemLang.toLowerCase(); 6503 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 6504 } 6505 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 6506 return false; 6507 }; 6508 } ), 6509 6510 // Miscellaneous 6511 "target": function( elem ) { 6512 var hash = window.location && window.location.hash; 6513 return hash && hash.slice( 1 ) === elem.id; 6514 }, 6515 6516 "root": function( elem ) { 6517 return elem === docElem; 6518 }, 6519 6520 "focus": function( elem ) { 6521 return elem === document.activeElement && 6522 ( !document.hasFocus || document.hasFocus() ) && 6523 !!( elem.type || elem.href || ~elem.tabIndex ); 6524 }, 6525 6526 // Boolean properties 6527 "enabled": createDisabledPseudo( false ), 6528 "disabled": createDisabledPseudo( true ), 6529 6530 "checked": function( elem ) { 6531 6532 // In CSS3, :checked should return both checked and selected elements 6533 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 6534 var nodeName = elem.nodeName.toLowerCase(); 6535 return ( nodeName === "input" && !!elem.checked ) || 6536 ( nodeName === "option" && !!elem.selected ); 6537 }, 6538 6539 "selected": function( elem ) { 6540 6541 // Accessing this property makes selected-by-default 6542 // options in Safari work properly 6543 if ( elem.parentNode ) { 6544 // eslint-disable-next-line no-unused-expressions 6545 elem.parentNode.selectedIndex; 6546 } 6547 6548 return elem.selected === true; 6549 }, 6550 6551 // Contents 6552 "empty": function( elem ) { 6553 6554 // http://www.w3.org/TR/selectors/#empty-pseudo 6555 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 6556 // but not by others (comment: 8; processing instruction: 7; etc.) 6557 // nodeType < 6 works because attributes (2) do not appear as children 6558 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 6559 if ( elem.nodeType < 6 ) { 6560 return false; 6561 } 6562 } 6563 return true; 6564 }, 6565 6566 "parent": function( elem ) { 6567 return !Expr.pseudos[ "empty" ]( elem ); 6568 }, 6569 6570 // Element/input types 6571 "header": function( elem ) { 6572 return rheader.test( elem.nodeName ); 6573 }, 6574 6575 "input": function( elem ) { 6576 return rinputs.test( elem.nodeName ); 6577 }, 6578 6579 "button": function( elem ) { 6580 var name = elem.nodeName.toLowerCase(); 6581 return name === "input" && elem.type === "button" || name === "button"; 6582 }, 6583 6584 "text": function( elem ) { 6585 var attr; 6586 return elem.nodeName.toLowerCase() === "input" && 6587 elem.type === "text" && 6588 6589 // Support: IE<8 6590 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 6591 ( ( attr = elem.getAttribute( "type" ) ) == null || 6592 attr.toLowerCase() === "text" ); 6593 }, 6594 6595 // Position-in-collection 6596 "first": createPositionalPseudo( function() { 6597 return [ 0 ]; 6598 } ), 6599 6600 "last": createPositionalPseudo( function( _matchIndexes, length ) { 6601 return [ length - 1 ]; 6602 } ), 6603 6604 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { 6605 return [ argument < 0 ? argument + length : argument ]; 6606 } ), 6607 6608 "even": createPositionalPseudo( function( matchIndexes, length ) { 6609 var i = 0; 6610 for ( ; i < length; i += 2 ) { 6611 matchIndexes.push( i ); 6612 } 6613 return matchIndexes; 6614 } ), 6615 6616 "odd": createPositionalPseudo( function( matchIndexes, length ) { 6617 var i = 1; 6618 for ( ; i < length; i += 2 ) { 6619 matchIndexes.push( i ); 6620 } 6621 return matchIndexes; 6622 } ), 6623 6624 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { 6625 var i = argument < 0 ? 6626 argument + length : 6627 argument > length ? 6628 length : 6629 argument; 6630 for ( ; --i >= 0; ) { 6631 matchIndexes.push( i ); 6632 } 6633 return matchIndexes; 6634 } ), 6635 6636 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { 6637 var i = argument < 0 ? argument + length : argument; 6638 for ( ; ++i < length; ) { 6639 matchIndexes.push( i ); 6640 } 6641 return matchIndexes; 6642 } ) 6643 } 6644}; 6645 6646Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; 6647 6648// Add button/input type pseudos 6649for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 6650 Expr.pseudos[ i ] = createInputPseudo( i ); 6651} 6652for ( i in { submit: true, reset: true } ) { 6653 Expr.pseudos[ i ] = createButtonPseudo( i ); 6654} 6655 6656// Easy API for creating new setFilters 6657function setFilters() {} 6658setFilters.prototype = Expr.filters = Expr.pseudos; 6659Expr.setFilters = new setFilters(); 6660 6661tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 6662 var matched, match, tokens, type, 6663 soFar, groups, preFilters, 6664 cached = tokenCache[ selector + " " ]; 6665 6666 if ( cached ) { 6667 return parseOnly ? 0 : cached.slice( 0 ); 6668 } 6669 6670 soFar = selector; 6671 groups = []; 6672 preFilters = Expr.preFilter; 6673 6674 while ( soFar ) { 6675 6676 // Comma and first run 6677 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 6678 if ( match ) { 6679 6680 // Don't consume trailing commas as valid 6681 soFar = soFar.slice( match[ 0 ].length ) || soFar; 6682 } 6683 groups.push( ( tokens = [] ) ); 6684 } 6685 6686 matched = false; 6687 6688 // Combinators 6689 if ( ( match = rcombinators.exec( soFar ) ) ) { 6690 matched = match.shift(); 6691 tokens.push( { 6692 value: matched, 6693 6694 // Cast descendant combinators to space 6695 type: match[ 0 ].replace( rtrim, " " ) 6696 } ); 6697 soFar = soFar.slice( matched.length ); 6698 } 6699 6700 // Filters 6701 for ( type in Expr.filter ) { 6702 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 6703 ( match = preFilters[ type ]( match ) ) ) ) { 6704 matched = match.shift(); 6705 tokens.push( { 6706 value: matched, 6707 type: type, 6708 matches: match 6709 } ); 6710 soFar = soFar.slice( matched.length ); 6711 } 6712 } 6713 6714 if ( !matched ) { 6715 break; 6716 } 6717 } 6718 6719 // Return the length of the invalid excess 6720 // if we're just parsing 6721 // Otherwise, throw an error or return tokens 6722 return parseOnly ? 6723 soFar.length : 6724 soFar ? 6725 Sizzle.error( selector ) : 6726 6727 // Cache the tokens 6728 tokenCache( selector, groups ).slice( 0 ); 6729}; 6730 6731function toSelector( tokens ) { 6732 var i = 0, 6733 len = tokens.length, 6734 selector = ""; 6735 for ( ; i < len; i++ ) { 6736 selector += tokens[ i ].value; 6737 } 6738 return selector; 6739} 6740 6741function addCombinator( matcher, combinator, base ) { 6742 var dir = combinator.dir, 6743 skip = combinator.next, 6744 key = skip || dir, 6745 checkNonElements = base && key === "parentNode", 6746 doneName = done++; 6747 6748 return combinator.first ? 6749 6750 // Check against closest ancestor/preceding element 6751 function( elem, context, xml ) { 6752 while ( ( elem = elem[ dir ] ) ) { 6753 if ( elem.nodeType === 1 || checkNonElements ) { 6754 return matcher( elem, context, xml ); 6755 } 6756 } 6757 return false; 6758 } : 6759 6760 // Check against all ancestor/preceding elements 6761 function( elem, context, xml ) { 6762 var oldCache, uniqueCache, outerCache, 6763 newCache = [ dirruns, doneName ]; 6764 6765 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 6766 if ( xml ) { 6767 while ( ( elem = elem[ dir ] ) ) { 6768 if ( elem.nodeType === 1 || checkNonElements ) { 6769 if ( matcher( elem, context, xml ) ) { 6770 return true; 6771 } 6772 } 6773 } 6774 } else { 6775 while ( ( elem = elem[ dir ] ) ) { 6776 if ( elem.nodeType === 1 || checkNonElements ) { 6777 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 6778 6779 // Support: IE <9 only 6780 // Defend against cloned attroperties (jQuery gh-1709) 6781 uniqueCache = outerCache[ elem.uniqueID ] || 6782 ( outerCache[ elem.uniqueID ] = {} ); 6783 6784 if ( skip && skip === elem.nodeName.toLowerCase() ) { 6785 elem = elem[ dir ] || elem; 6786 } else if ( ( oldCache = uniqueCache[ key ] ) && 6787 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 6788 6789 // Assign to newCache so results back-propagate to previous elements 6790 return ( newCache[ 2 ] = oldCache[ 2 ] ); 6791 } else { 6792 6793 // Reuse newcache so results back-propagate to previous elements 6794 uniqueCache[ key ] = newCache; 6795 6796 // A match means we're done; a fail means we have to keep checking 6797 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 6798 return true; 6799 } 6800 } 6801 } 6802 } 6803 } 6804 return false; 6805 }; 6806} 6807 6808function elementMatcher( matchers ) { 6809 return matchers.length > 1 ? 6810 function( elem, context, xml ) { 6811 var i = matchers.length; 6812 while ( i-- ) { 6813 if ( !matchers[ i ]( elem, context, xml ) ) { 6814 return false; 6815 } 6816 } 6817 return true; 6818 } : 6819 matchers[ 0 ]; 6820} 6821 6822function multipleContexts( selector, contexts, results ) { 6823 var i = 0, 6824 len = contexts.length; 6825 for ( ; i < len; i++ ) { 6826 Sizzle( selector, contexts[ i ], results ); 6827 } 6828 return results; 6829} 6830 6831function condense( unmatched, map, filter, context, xml ) { 6832 var elem, 6833 newUnmatched = [], 6834 i = 0, 6835 len = unmatched.length, 6836 mapped = map != null; 6837 6838 for ( ; i < len; i++ ) { 6839 if ( ( elem = unmatched[ i ] ) ) { 6840 if ( !filter || filter( elem, context, xml ) ) { 6841 newUnmatched.push( elem ); 6842 if ( mapped ) { 6843 map.push( i ); 6844 } 6845 } 6846 } 6847 } 6848 6849 return newUnmatched; 6850} 6851 6852function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 6853 if ( postFilter && !postFilter[ expando ] ) { 6854 postFilter = setMatcher( postFilter ); 6855 } 6856 if ( postFinder && !postFinder[ expando ] ) { 6857 postFinder = setMatcher( postFinder, postSelector ); 6858 } 6859 return markFunction( function( seed, results, context, xml ) { 6860 var temp, i, elem, 6861 preMap = [], 6862 postMap = [], 6863 preexisting = results.length, 6864 6865 // Get initial elements from seed or context 6866 elems = seed || multipleContexts( 6867 selector || "*", 6868 context.nodeType ? [ context ] : context, 6869 [] 6870 ), 6871 6872 // Prefilter to get matcher input, preserving a map for seed-results synchronization 6873 matcherIn = preFilter && ( seed || !selector ) ? 6874 condense( elems, preMap, preFilter, context, xml ) : 6875 elems, 6876 6877 matcherOut = matcher ? 6878 6879 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 6880 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 6881 6882 // ...intermediate processing is necessary 6883 [] : 6884 6885 // ...otherwise use results directly 6886 results : 6887 matcherIn; 6888 6889 // Find primary matches 6890 if ( matcher ) { 6891 matcher( matcherIn, matcherOut, context, xml ); 6892 } 6893 6894 // Apply postFilter 6895 if ( postFilter ) { 6896 temp = condense( matcherOut, postMap ); 6897 postFilter( temp, [], context, xml ); 6898 6899 // Un-match failing elements by moving them back to matcherIn 6900 i = temp.length; 6901 while ( i-- ) { 6902 if ( ( elem = temp[ i ] ) ) { 6903 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 6904 } 6905 } 6906 } 6907 6908 if ( seed ) { 6909 if ( postFinder || preFilter ) { 6910 if ( postFinder ) { 6911 6912 // Get the final matcherOut by condensing this intermediate into postFinder contexts 6913 temp = []; 6914 i = matcherOut.length; 6915 while ( i-- ) { 6916 if ( ( elem = matcherOut[ i ] ) ) { 6917 6918 // Restore matcherIn since elem is not yet a final match 6919 temp.push( ( matcherIn[ i ] = elem ) ); 6920 } 6921 } 6922 postFinder( null, ( matcherOut = [] ), temp, xml ); 6923 } 6924 6925 // Move matched elements from seed to results to keep them synchronized 6926 i = matcherOut.length; 6927 while ( i-- ) { 6928 if ( ( elem = matcherOut[ i ] ) && 6929 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { 6930 6931 seed[ temp ] = !( results[ temp ] = elem ); 6932 } 6933 } 6934 } 6935 6936 // Add elements to results, through postFinder if defined 6937 } else { 6938 matcherOut = condense( 6939 matcherOut === results ? 6940 matcherOut.splice( preexisting, matcherOut.length ) : 6941 matcherOut 6942 ); 6943 if ( postFinder ) { 6944 postFinder( null, results, matcherOut, xml ); 6945 } else { 6946 push.apply( results, matcherOut ); 6947 } 6948 } 6949 } ); 6950} 6951 6952function matcherFromTokens( tokens ) { 6953 var checkContext, matcher, j, 6954 len = tokens.length, 6955 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 6956 implicitRelative = leadingRelative || Expr.relative[ " " ], 6957 i = leadingRelative ? 1 : 0, 6958 6959 // The foundational matcher ensures that elements are reachable from top-level context(s) 6960 matchContext = addCombinator( function( elem ) { 6961 return elem === checkContext; 6962 }, implicitRelative, true ), 6963 matchAnyContext = addCombinator( function( elem ) { 6964 return indexOf( checkContext, elem ) > -1; 6965 }, implicitRelative, true ), 6966 matchers = [ function( elem, context, xml ) { 6967 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 6968 ( checkContext = context ).nodeType ? 6969 matchContext( elem, context, xml ) : 6970 matchAnyContext( elem, context, xml ) ); 6971 6972 // Avoid hanging onto element (issue #299) 6973 checkContext = null; 6974 return ret; 6975 } ]; 6976 6977 for ( ; i < len; i++ ) { 6978 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 6979 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 6980 } else { 6981 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 6982 6983 // Return special upon seeing a positional matcher 6984 if ( matcher[ expando ] ) { 6985 6986 // Find the next relative operator (if any) for proper handling 6987 j = ++i; 6988 for ( ; j < len; j++ ) { 6989 if ( Expr.relative[ tokens[ j ].type ] ) { 6990 break; 6991 } 6992 } 6993 return setMatcher( 6994 i > 1 && elementMatcher( matchers ), 6995 i > 1 && toSelector( 6996 6997 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 6998 tokens 6999 .slice( 0, i - 1 ) 7000 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 7001 ).replace( rtrim, "$1" ), 7002 matcher, 7003 i < j && matcherFromTokens( tokens.slice( i, j ) ), 7004 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 7005 j < len && toSelector( tokens ) 7006 ); 7007 } 7008 matchers.push( matcher ); 7009 } 7010 } 7011 7012 return elementMatcher( matchers ); 7013} 7014 7015function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 7016 var bySet = setMatchers.length > 0, 7017 byElement = elementMatchers.length > 0, 7018 superMatcher = function( seed, context, xml, results, outermost ) { 7019 var elem, j, matcher, 7020 matchedCount = 0, 7021 i = "0", 7022 unmatched = seed && [], 7023 setMatched = [], 7024 contextBackup = outermostContext, 7025 7026 // We must always have either seed elements or outermost context 7027 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), 7028 7029 // Use integer dirruns iff this is the outermost matcher 7030 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 7031 len = elems.length; 7032 7033 if ( outermost ) { 7034 7035 // Support: IE 11+, Edge 17 - 18+ 7036 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 7037 // two documents; shallow comparisons work. 7038 // eslint-disable-next-line eqeqeq 7039 outermostContext = context == document || context || outermost; 7040 } 7041 7042 // Add elements passing elementMatchers directly to results 7043 // Support: IE<9, Safari 7044 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 7045 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 7046 if ( byElement && elem ) { 7047 j = 0; 7048 7049 // Support: IE 11+, Edge 17 - 18+ 7050 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 7051 // two documents; shallow comparisons work. 7052 // eslint-disable-next-line eqeqeq 7053 if ( !context && elem.ownerDocument != document ) { 7054 setDocument( elem ); 7055 xml = !documentIsHTML; 7056 } 7057 while ( ( matcher = elementMatchers[ j++ ] ) ) { 7058 if ( matcher( elem, context || document, xml ) ) { 7059 results.push( elem ); 7060 break; 7061 } 7062 } 7063 if ( outermost ) { 7064 dirruns = dirrunsUnique; 7065 } 7066 } 7067 7068 // Track unmatched elements for set filters 7069 if ( bySet ) { 7070 7071 // They will have gone through all possible matchers 7072 if ( ( elem = !matcher && elem ) ) { 7073 matchedCount--; 7074 } 7075 7076 // Lengthen the array for every element, matched or not 7077 if ( seed ) { 7078 unmatched.push( elem ); 7079 } 7080 } 7081 } 7082 7083 // `i` is now the count of elements visited above, and adding it to `matchedCount` 7084 // makes the latter nonnegative. 7085 matchedCount += i; 7086 7087 // Apply set filters to unmatched elements 7088 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 7089 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 7090 // no element matchers and no seed. 7091 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 7092 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 7093 // numerically zero. 7094 if ( bySet && i !== matchedCount ) { 7095 j = 0; 7096 while ( ( matcher = setMatchers[ j++ ] ) ) { 7097 matcher( unmatched, setMatched, context, xml ); 7098 } 7099 7100 if ( seed ) { 7101 7102 // Reintegrate element matches to eliminate the need for sorting 7103 if ( matchedCount > 0 ) { 7104 while ( i-- ) { 7105 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 7106 setMatched[ i ] = pop.call( results ); 7107 } 7108 } 7109 } 7110 7111 // Discard index placeholder values to get only actual matches 7112 setMatched = condense( setMatched ); 7113 } 7114 7115 // Add matches to results 7116 push.apply( results, setMatched ); 7117 7118 // Seedless set matches succeeding multiple successful matchers stipulate sorting 7119 if ( outermost && !seed && setMatched.length > 0 && 7120 ( matchedCount + setMatchers.length ) > 1 ) { 7121 7122 Sizzle.uniqueSort( results ); 7123 } 7124 } 7125 7126 // Override manipulation of globals by nested matchers 7127 if ( outermost ) { 7128 dirruns = dirrunsUnique; 7129 outermostContext = contextBackup; 7130 } 7131 7132 return unmatched; 7133 }; 7134 7135 return bySet ? 7136 markFunction( superMatcher ) : 7137 superMatcher; 7138} 7139 7140compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 7141 var i, 7142 setMatchers = [], 7143 elementMatchers = [], 7144 cached = compilerCache[ selector + " " ]; 7145 7146 if ( !cached ) { 7147 7148 // Generate a function of recursive functions that can be used to check each element 7149 if ( !match ) { 7150 match = tokenize( selector ); 7151 } 7152 i = match.length; 7153 while ( i-- ) { 7154 cached = matcherFromTokens( match[ i ] ); 7155 if ( cached[ expando ] ) { 7156 setMatchers.push( cached ); 7157 } else { 7158 elementMatchers.push( cached ); 7159 } 7160 } 7161 7162 // Cache the compiled function 7163 cached = compilerCache( 7164 selector, 7165 matcherFromGroupMatchers( elementMatchers, setMatchers ) 7166 ); 7167 7168 // Save selector and tokenization 7169 cached.selector = selector; 7170 } 7171 return cached; 7172}; 7173 7174/** 7175 * A low-level selection function that works with Sizzle's compiled 7176 * selector functions 7177 * @param {String|Function} selector A selector or a pre-compiled 7178 * selector function built with Sizzle.compile 7179 * @param {Element} context 7180 * @param {Array} [results] 7181 * @param {Array} [seed] A set of elements to match against 7182 */ 7183select = Sizzle.select = function( selector, context, results, seed ) { 7184 var i, tokens, token, type, find, 7185 compiled = typeof selector === "function" && selector, 7186 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 7187 7188 results = results || []; 7189 7190 // Try to minimize operations if there is only one selector in the list and no seed 7191 // (the latter of which guarantees us context) 7192 if ( match.length === 1 ) { 7193 7194 // Reduce context if the leading compound selector is an ID 7195 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 7196 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 7197 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 7198 7199 context = ( Expr.find[ "ID" ]( token.matches[ 0 ] 7200 .replace( runescape, funescape ), context ) || [] )[ 0 ]; 7201 if ( !context ) { 7202 return results; 7203 7204 // Precompiled matchers will still verify ancestry, so step up a level 7205 } else if ( compiled ) { 7206 context = context.parentNode; 7207 } 7208 7209 selector = selector.slice( tokens.shift().value.length ); 7210 } 7211 7212 // Fetch a seed set for right-to-left matching 7213 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; 7214 while ( i-- ) { 7215 token = tokens[ i ]; 7216 7217 // Abort if we hit a combinator 7218 if ( Expr.relative[ ( type = token.type ) ] ) { 7219 break; 7220 } 7221 if ( ( find = Expr.find[ type ] ) ) { 7222 7223 // Search, expanding context for leading sibling combinators 7224 if ( ( seed = find( 7225 token.matches[ 0 ].replace( runescape, funescape ), 7226 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || 7227 context 7228 ) ) ) { 7229 7230 // If seed is empty or no tokens remain, we can return early 7231 tokens.splice( i, 1 ); 7232 selector = seed.length && toSelector( tokens ); 7233 if ( !selector ) { 7234 push.apply( results, seed ); 7235 return results; 7236 } 7237 7238 break; 7239 } 7240 } 7241 } 7242 } 7243 7244 // Compile and execute a filtering function if one is not provided 7245 // Provide `match` to avoid retokenization if we modified the selector above 7246 ( compiled || compile( selector, match ) )( 7247 seed, 7248 context, 7249 !documentIsHTML, 7250 results, 7251 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 7252 ); 7253 return results; 7254}; 7255 7256// One-time assignments 7257 7258// Sort stability 7259support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 7260 7261// Support: Chrome 14-35+ 7262// Always assume duplicates if they aren't passed to the comparison function 7263support.detectDuplicates = !!hasDuplicate; 7264 7265// Initialize against the default document 7266setDocument(); 7267 7268// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 7269// Detached nodes confoundingly follow *each other* 7270support.sortDetached = assert( function( el ) { 7271 7272 // Should return 1, but returns 4 (following) 7273 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 7274} ); 7275 7276// Support: IE<8 7277// Prevent attribute/property "interpolation" 7278// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 7279if ( !assert( function( el ) { 7280 el.innerHTML = "<a href='#'></a>"; 7281 return el.firstChild.getAttribute( "href" ) === "#"; 7282} ) ) { 7283 addHandle( "type|href|height|width", function( elem, name, isXML ) { 7284 if ( !isXML ) { 7285 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 7286 } 7287 } ); 7288} 7289 7290// Support: IE<9 7291// Use defaultValue in place of getAttribute("value") 7292if ( !support.attributes || !assert( function( el ) { 7293 el.innerHTML = "<input/>"; 7294 el.firstChild.setAttribute( "value", "" ); 7295 return el.firstChild.getAttribute( "value" ) === ""; 7296} ) ) { 7297 addHandle( "value", function( elem, _name, isXML ) { 7298 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 7299 return elem.defaultValue; 7300 } 7301 } ); 7302} 7303 7304// Support: IE<9 7305// Use getAttributeNode to fetch booleans when getAttribute lies 7306if ( !assert( function( el ) { 7307 return el.getAttribute( "disabled" ) == null; 7308} ) ) { 7309 addHandle( booleans, function( elem, name, isXML ) { 7310 var val; 7311 if ( !isXML ) { 7312 return elem[ name ] === true ? name.toLowerCase() : 7313 ( val = elem.getAttributeNode( name ) ) && val.specified ? 7314 val.value : 7315 null; 7316 } 7317 } ); 7318} 7319 7320return Sizzle; 7321 7322} )( window ); 7323 7324 7325 7326jQuery.find = Sizzle; 7327jQuery.expr = Sizzle.selectors; 7328 7329// Deprecated 7330jQuery.expr[ ":" ] = jQuery.expr.pseudos; 7331jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 7332jQuery.text = Sizzle.getText; 7333jQuery.isXMLDoc = Sizzle.isXML; 7334jQuery.contains = Sizzle.contains; 7335jQuery.escapeSelector = Sizzle.escape; 7336 7337 7338 7339 7340var dir = function( elem, dir, until ) { 7341 var matched = [], 7342 truncate = until !== undefined; 7343 7344 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 7345 if ( elem.nodeType === 1 ) { 7346 if ( truncate && jQuery( elem ).is( until ) ) { 7347 break; 7348 } 7349 matched.push( elem ); 7350 } 7351 } 7352 return matched; 7353}; 7354 7355 7356var siblings = function( n, elem ) { 7357 var matched = []; 7358 7359 for ( ; n; n = n.nextSibling ) { 7360 if ( n.nodeType === 1 && n !== elem ) { 7361 matched.push( n ); 7362 } 7363 } 7364 7365 return matched; 7366}; 7367 7368 7369var rneedsContext = jQuery.expr.match.needsContext; 7370 7371 7372 7373function nodeName( elem, name ) { 7374 7375 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 7376 7377} 7378var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 7379 7380 7381 7382// Implement the identical functionality for filter and not 7383function winnow( elements, qualifier, not ) { 7384 if ( isFunction( qualifier ) ) { 7385 return jQuery.grep( elements, function( elem, i ) { 7386 return !!qualifier.call( elem, i, elem ) !== not; 7387 } ); 7388 } 7389 7390 // Single element 7391 if ( qualifier.nodeType ) { 7392 return jQuery.grep( elements, function( elem ) { 7393 return ( elem === qualifier ) !== not; 7394 } ); 7395 } 7396 7397 // Arraylike of elements (jQuery, arguments, Array) 7398 if ( typeof qualifier !== "string" ) { 7399 return jQuery.grep( elements, function( elem ) { 7400 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 7401 } ); 7402 } 7403 7404 // Filtered directly for both simple and complex selectors 7405 return jQuery.filter( qualifier, elements, not ); 7406} 7407 7408jQuery.filter = function( expr, elems, not ) { 7409 var elem = elems[ 0 ]; 7410 7411 if ( not ) { 7412 expr = ":not(" + expr + ")"; 7413 } 7414 7415 if ( elems.length === 1 && elem.nodeType === 1 ) { 7416 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 7417 } 7418 7419 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 7420 return elem.nodeType === 1; 7421 } ) ); 7422}; 7423 7424jQuery.fn.extend( { 7425 find: function( selector ) { 7426 var i, ret, 7427 len = this.length, 7428 self = this; 7429 7430 if ( typeof selector !== "string" ) { 7431 return this.pushStack( jQuery( selector ).filter( function() { 7432 for ( i = 0; i < len; i++ ) { 7433 if ( jQuery.contains( self[ i ], this ) ) { 7434 return true; 7435 } 7436 } 7437 } ) ); 7438 } 7439 7440 ret = this.pushStack( [] ); 7441 7442 for ( i = 0; i < len; i++ ) { 7443 jQuery.find( selector, self[ i ], ret ); 7444 } 7445 7446 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 7447 }, 7448 filter: function( selector ) { 7449 return this.pushStack( winnow( this, selector || [], false ) ); 7450 }, 7451 not: function( selector ) { 7452 return this.pushStack( winnow( this, selector || [], true ) ); 7453 }, 7454 is: function( selector ) { 7455 return !!winnow( 7456 this, 7457 7458 // If this is a positional/relative selector, check membership in the returned set 7459 // so $("p:first").is("p:last") won't return true for a doc with two "p". 7460 typeof selector === "string" && rneedsContext.test( selector ) ? 7461 jQuery( selector ) : 7462 selector || [], 7463 false 7464 ).length; 7465 } 7466} ); 7467 7468 7469// Initialize a jQuery object 7470 7471 7472// A central reference to the root jQuery(document) 7473var rootjQuery, 7474 7475 // A simple way to check for HTML strings 7476 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 7477 // Strict HTML recognition (#11290: must start with <) 7478 // Shortcut simple #id case for speed 7479 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 7480 7481 init = jQuery.fn.init = function( selector, context, root ) { 7482 var match, elem; 7483 7484 // HANDLE: $(""), $(null), $(undefined), $(false) 7485 if ( !selector ) { 7486 return this; 7487 } 7488 7489 // Method init() accepts an alternate rootjQuery 7490 // so migrate can support jQuery.sub (gh-2101) 7491 root = root || rootjQuery; 7492 7493 // Handle HTML strings 7494 if ( typeof selector === "string" ) { 7495 if ( selector[ 0 ] === "<" && 7496 selector[ selector.length - 1 ] === ">" && 7497 selector.length >= 3 ) { 7498 7499 // Assume that strings that start and end with <> are HTML and skip the regex check 7500 match = [ null, selector, null ]; 7501 7502 } else { 7503 match = rquickExpr.exec( selector ); 7504 } 7505 7506 // Match html or make sure no context is specified for #id 7507 if ( match && ( match[ 1 ] || !context ) ) { 7508 7509 // HANDLE: $(html) -> $(array) 7510 if ( match[ 1 ] ) { 7511 context = context instanceof jQuery ? context[ 0 ] : context; 7512 7513 // Option to run scripts is true for back-compat 7514 // Intentionally let the error be thrown if parseHTML is not present 7515 jQuery.merge( this, jQuery.parseHTML( 7516 match[ 1 ], 7517 context && context.nodeType ? context.ownerDocument || context : document, 7518 true 7519 ) ); 7520 7521 // HANDLE: $(html, props) 7522 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 7523 for ( match in context ) { 7524 7525 // Properties of context are called as methods if possible 7526 if ( isFunction( this[ match ] ) ) { 7527 this[ match ]( context[ match ] ); 7528 7529 // ...and otherwise set as attributes 7530 } else { 7531 this.attr( match, context[ match ] ); 7532 } 7533 } 7534 } 7535 7536 return this; 7537 7538 // HANDLE: $(#id) 7539 } else { 7540 elem = document.getElementById( match[ 2 ] ); 7541 7542 if ( elem ) { 7543 7544 // Inject the element directly into the jQuery object 7545 this[ 0 ] = elem; 7546 this.length = 1; 7547 } 7548 return this; 7549 } 7550 7551 // HANDLE: $(expr, $(...)) 7552 } else if ( !context || context.jquery ) { 7553 return ( context || root ).find( selector ); 7554 7555 // HANDLE: $(expr, context) 7556 // (which is just equivalent to: $(context).find(expr) 7557 } else { 7558 return this.constructor( context ).find( selector ); 7559 } 7560 7561 // HANDLE: $(DOMElement) 7562 } else if ( selector.nodeType ) { 7563 this[ 0 ] = selector; 7564 this.length = 1; 7565 return this; 7566 7567 // HANDLE: $(function) 7568 // Shortcut for document ready 7569 } else if ( isFunction( selector ) ) { 7570 return root.ready !== undefined ? 7571 root.ready( selector ) : 7572 7573 // Execute immediately if ready is not present 7574 selector( jQuery ); 7575 } 7576 7577 return jQuery.makeArray( selector, this ); 7578 }; 7579 7580// Give the init function the jQuery prototype for later instantiation 7581init.prototype = jQuery.fn; 7582 7583// Initialize central reference 7584rootjQuery = jQuery( document ); 7585 7586 7587var rparentsprev = /^(?:parents|prev(?:Until|All))/, 7588 7589 // Methods guaranteed to produce a unique set when starting from a unique set 7590 guaranteedUnique = { 7591 children: true, 7592 contents: true, 7593 next: true, 7594 prev: true 7595 }; 7596 7597jQuery.fn.extend( { 7598 has: function( target ) { 7599 var targets = jQuery( target, this ), 7600 l = targets.length; 7601 7602 return this.filter( function() { 7603 var i = 0; 7604 for ( ; i < l; i++ ) { 7605 if ( jQuery.contains( this, targets[ i ] ) ) { 7606 return true; 7607 } 7608 } 7609 } ); 7610 }, 7611 7612 closest: function( selectors, context ) { 7613 var cur, 7614 i = 0, 7615 l = this.length, 7616 matched = [], 7617 targets = typeof selectors !== "string" && jQuery( selectors ); 7618 7619 // Positional selectors never match, since there's no _selection_ context 7620 if ( !rneedsContext.test( selectors ) ) { 7621 for ( ; i < l; i++ ) { 7622 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 7623 7624 // Always skip document fragments 7625 if ( cur.nodeType < 11 && ( targets ? 7626 targets.index( cur ) > -1 : 7627 7628 // Don't pass non-elements to Sizzle 7629 cur.nodeType === 1 && 7630 jQuery.find.matchesSelector( cur, selectors ) ) ) { 7631 7632 matched.push( cur ); 7633 break; 7634 } 7635 } 7636 } 7637 } 7638 7639 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 7640 }, 7641 7642 // Determine the position of an element within the set 7643 index: function( elem ) { 7644 7645 // No argument, return index in parent 7646 if ( !elem ) { 7647 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 7648 } 7649 7650 // Index in selector 7651 if ( typeof elem === "string" ) { 7652 return indexOf.call( jQuery( elem ), this[ 0 ] ); 7653 } 7654 7655 // Locate the position of the desired element 7656 return indexOf.call( this, 7657 7658 // If it receives a jQuery object, the first element is used 7659 elem.jquery ? elem[ 0 ] : elem 7660 ); 7661 }, 7662 7663 add: function( selector, context ) { 7664 return this.pushStack( 7665 jQuery.uniqueSort( 7666 jQuery.merge( this.get(), jQuery( selector, context ) ) 7667 ) 7668 ); 7669 }, 7670 7671 addBack: function( selector ) { 7672 return this.add( selector == null ? 7673 this.prevObject : this.prevObject.filter( selector ) 7674 ); 7675 } 7676} ); 7677 7678function sibling( cur, dir ) { 7679 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 7680 return cur; 7681} 7682 7683jQuery.each( { 7684 parent: function( elem ) { 7685 var parent = elem.parentNode; 7686 return parent && parent.nodeType !== 11 ? parent : null; 7687 }, 7688 parents: function( elem ) { 7689 return dir( elem, "parentNode" ); 7690 }, 7691 parentsUntil: function( elem, _i, until ) { 7692 return dir( elem, "parentNode", until ); 7693 }, 7694 next: function( elem ) { 7695 return sibling( elem, "nextSibling" ); 7696 }, 7697 prev: function( elem ) { 7698 return sibling( elem, "previousSibling" ); 7699 }, 7700 nextAll: function( elem ) { 7701 return dir( elem, "nextSibling" ); 7702 }, 7703 prevAll: function( elem ) { 7704 return dir( elem, "previousSibling" ); 7705 }, 7706 nextUntil: function( elem, _i, until ) { 7707 return dir( elem, "nextSibling", until ); 7708 }, 7709 prevUntil: function( elem, _i, until ) { 7710 return dir( elem, "previousSibling", until ); 7711 }, 7712 siblings: function( elem ) { 7713 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 7714 }, 7715 children: function( elem ) { 7716 return siblings( elem.firstChild ); 7717 }, 7718 contents: function( elem ) { 7719 if ( elem.contentDocument != null && 7720 7721 // Support: IE 11+ 7722 // <object> elements with no `data` attribute has an object 7723 // `contentDocument` with a `null` prototype. 7724 getProto( elem.contentDocument ) ) { 7725 7726 return elem.contentDocument; 7727 } 7728 7729 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 7730 // Treat the template element as a regular one in browsers that 7731 // don't support it. 7732 if ( nodeName( elem, "template" ) ) { 7733 elem = elem.content || elem; 7734 } 7735 7736 return jQuery.merge( [], elem.childNodes ); 7737 } 7738}, function( name, fn ) { 7739 jQuery.fn[ name ] = function( until, selector ) { 7740 var matched = jQuery.map( this, fn, until ); 7741 7742 if ( name.slice( -5 ) !== "Until" ) { 7743 selector = until; 7744 } 7745 7746 if ( selector && typeof selector === "string" ) { 7747 matched = jQuery.filter( selector, matched ); 7748 } 7749 7750 if ( this.length > 1 ) { 7751 7752 // Remove duplicates 7753 if ( !guaranteedUnique[ name ] ) { 7754 jQuery.uniqueSort( matched ); 7755 } 7756 7757 // Reverse order for parents* and prev-derivatives 7758 if ( rparentsprev.test( name ) ) { 7759 matched.reverse(); 7760 } 7761 } 7762 7763 return this.pushStack( matched ); 7764 }; 7765} ); 7766var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 7767 7768 7769 7770// Convert String-formatted options into Object-formatted ones 7771function createOptions( options ) { 7772 var object = {}; 7773 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 7774 object[ flag ] = true; 7775 } ); 7776 return object; 7777} 7778 7779/* 7780 * Create a callback list using the following parameters: 7781 * 7782 * options: an optional list of space-separated options that will change how 7783 * the callback list behaves or a more traditional option object 7784 * 7785 * By default a callback list will act like an event callback list and can be 7786 * "fired" multiple times. 7787 * 7788 * Possible options: 7789 * 7790 * once: will ensure the callback list can only be fired once (like a Deferred) 7791 * 7792 * memory: will keep track of previous values and will call any callback added 7793 * after the list has been fired right away with the latest "memorized" 7794 * values (like a Deferred) 7795 * 7796 * unique: will ensure a callback can only be added once (no duplicate in the list) 7797 * 7798 * stopOnFalse: interrupt callings when a callback returns false 7799 * 7800 */ 7801jQuery.Callbacks = function( options ) { 7802 7803 // Convert options from String-formatted to Object-formatted if needed 7804 // (we check in cache first) 7805 options = typeof options === "string" ? 7806 createOptions( options ) : 7807 jQuery.extend( {}, options ); 7808 7809 var // Flag to know if list is currently firing 7810 firing, 7811 7812 // Last fire value for non-forgettable lists 7813 memory, 7814 7815 // Flag to know if list was already fired 7816 fired, 7817 7818 // Flag to prevent firing 7819 locked, 7820 7821 // Actual callback list 7822 list = [], 7823 7824 // Queue of execution data for repeatable lists 7825 queue = [], 7826 7827 // Index of currently firing callback (modified by add/remove as needed) 7828 firingIndex = -1, 7829 7830 // Fire callbacks 7831 fire = function() { 7832 7833 // Enforce single-firing 7834 locked = locked || options.once; 7835 7836 // Execute callbacks for all pending executions, 7837 // respecting firingIndex overrides and runtime changes 7838 fired = firing = true; 7839 for ( ; queue.length; firingIndex = -1 ) { 7840 memory = queue.shift(); 7841 while ( ++firingIndex < list.length ) { 7842 7843 // Run callback and check for early termination 7844 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 7845 options.stopOnFalse ) { 7846 7847 // Jump to end and forget the data so .add doesn't re-fire 7848 firingIndex = list.length; 7849 memory = false; 7850 } 7851 } 7852 } 7853 7854 // Forget the data if we're done with it 7855 if ( !options.memory ) { 7856 memory = false; 7857 } 7858 7859 firing = false; 7860 7861 // Clean up if we're done firing for good 7862 if ( locked ) { 7863 7864 // Keep an empty list if we have data for future add calls 7865 if ( memory ) { 7866 list = []; 7867 7868 // Otherwise, this object is spent 7869 } else { 7870 list = ""; 7871 } 7872 } 7873 }, 7874 7875 // Actual Callbacks object 7876 self = { 7877 7878 // Add a callback or a collection of callbacks to the list 7879 add: function() { 7880 if ( list ) { 7881 7882 // If we have memory from a past run, we should fire after adding 7883 if ( memory && !firing ) { 7884 firingIndex = list.length - 1; 7885 queue.push( memory ); 7886 } 7887 7888 ( function add( args ) { 7889 jQuery.each( args, function( _, arg ) { 7890 if ( isFunction( arg ) ) { 7891 if ( !options.unique || !self.has( arg ) ) { 7892 list.push( arg ); 7893 } 7894 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 7895 7896 // Inspect recursively 7897 add( arg ); 7898 } 7899 } ); 7900 } )( arguments ); 7901 7902 if ( memory && !firing ) { 7903 fire(); 7904 } 7905 } 7906 return this; 7907 }, 7908 7909 // Remove a callback from the list 7910 remove: function() { 7911 jQuery.each( arguments, function( _, arg ) { 7912 var index; 7913 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 7914 list.splice( index, 1 ); 7915 7916 // Handle firing indexes 7917 if ( index <= firingIndex ) { 7918 firingIndex--; 7919 } 7920 } 7921 } ); 7922 return this; 7923 }, 7924 7925 // Check if a given callback is in the list. 7926 // If no argument is given, return whether or not list has callbacks attached. 7927 has: function( fn ) { 7928 return fn ? 7929 jQuery.inArray( fn, list ) > -1 : 7930 list.length > 0; 7931 }, 7932 7933 // Remove all callbacks from the list 7934 empty: function() { 7935 if ( list ) { 7936 list = []; 7937 } 7938 return this; 7939 }, 7940 7941 // Disable .fire and .add 7942 // Abort any current/pending executions 7943 // Clear all callbacks and values 7944 disable: function() { 7945 locked = queue = []; 7946 list = memory = ""; 7947 return this; 7948 }, 7949 disabled: function() { 7950 return !list; 7951 }, 7952 7953 // Disable .fire 7954 // Also disable .add unless we have memory (since it would have no effect) 7955 // Abort any pending executions 7956 lock: function() { 7957 locked = queue = []; 7958 if ( !memory && !firing ) { 7959 list = memory = ""; 7960 } 7961 return this; 7962 }, 7963 locked: function() { 7964 return !!locked; 7965 }, 7966 7967 // Call all callbacks with the given context and arguments 7968 fireWith: function( context, args ) { 7969 if ( !locked ) { 7970 args = args || []; 7971 args = [ context, args.slice ? args.slice() : args ]; 7972 queue.push( args ); 7973 if ( !firing ) { 7974 fire(); 7975 } 7976 } 7977 return this; 7978 }, 7979 7980 // Call all the callbacks with the given arguments 7981 fire: function() { 7982 self.fireWith( this, arguments ); 7983 return this; 7984 }, 7985 7986 // To know if the callbacks have already been called at least once 7987 fired: function() { 7988 return !!fired; 7989 } 7990 }; 7991 7992 return self; 7993}; 7994 7995 7996function Identity( v ) { 7997 return v; 7998} 7999function Thrower( ex ) { 8000 throw ex; 8001} 8002 8003function adoptValue( value, resolve, reject, noValue ) { 8004 var method; 8005 8006 try { 8007 8008 // Check for promise aspect first to privilege synchronous behavior 8009 if ( value && isFunction( ( method = value.promise ) ) ) { 8010 method.call( value ).done( resolve ).fail( reject ); 8011 8012 // Other thenables 8013 } else if ( value && isFunction( ( method = value.then ) ) ) { 8014 method.call( value, resolve, reject ); 8015 8016 // Other non-thenables 8017 } else { 8018 8019 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 8020 // * false: [ value ].slice( 0 ) => resolve( value ) 8021 // * true: [ value ].slice( 1 ) => resolve() 8022 resolve.apply( undefined, [ value ].slice( noValue ) ); 8023 } 8024 8025 // For Promises/A+, convert exceptions into rejections 8026 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 8027 // Deferred#then to conditionally suppress rejection. 8028 } catch ( value ) { 8029 8030 // Support: Android 4.0 only 8031 // Strict mode functions invoked without .call/.apply get global-object context 8032 reject.apply( undefined, [ value ] ); 8033 } 8034} 8035 8036jQuery.extend( { 8037 8038 Deferred: function( func ) { 8039 var tuples = [ 8040 8041 // action, add listener, callbacks, 8042 // ... .then handlers, argument index, [final state] 8043 [ "notify", "progress", jQuery.Callbacks( "memory" ), 8044 jQuery.Callbacks( "memory" ), 2 ], 8045 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 8046 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 8047 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 8048 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 8049 ], 8050 state = "pending", 8051 promise = { 8052 state: function() { 8053 return state; 8054 }, 8055 always: function() { 8056 deferred.done( arguments ).fail( arguments ); 8057 return this; 8058 }, 8059 "catch": function( fn ) { 8060 return promise.then( null, fn ); 8061 }, 8062 8063 // Keep pipe for back-compat 8064 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 8065 var fns = arguments; 8066 8067 return jQuery.Deferred( function( newDefer ) { 8068 jQuery.each( tuples, function( _i, tuple ) { 8069 8070 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 8071 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 8072 8073 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 8074 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 8075 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 8076 deferred[ tuple[ 1 ] ]( function() { 8077 var returned = fn && fn.apply( this, arguments ); 8078 if ( returned && isFunction( returned.promise ) ) { 8079 returned.promise() 8080 .progress( newDefer.notify ) 8081 .done( newDefer.resolve ) 8082 .fail( newDefer.reject ); 8083 } else { 8084 newDefer[ tuple[ 0 ] + "With" ]( 8085 this, 8086 fn ? [ returned ] : arguments 8087 ); 8088 } 8089 } ); 8090 } ); 8091 fns = null; 8092 } ).promise(); 8093 }, 8094 then: function( onFulfilled, onRejected, onProgress ) { 8095 var maxDepth = 0; 8096 function resolve( depth, deferred, handler, special ) { 8097 return function() { 8098 var that = this, 8099 args = arguments, 8100 mightThrow = function() { 8101 var returned, then; 8102 8103 // Support: Promises/A+ section 2.3.3.3.3 8104 // https://promisesaplus.com/#point-59 8105 // Ignore double-resolution attempts 8106 if ( depth < maxDepth ) { 8107 return; 8108 } 8109 8110 returned = handler.apply( that, args ); 8111 8112 // Support: Promises/A+ section 2.3.1 8113 // https://promisesaplus.com/#point-48 8114 if ( returned === deferred.promise() ) { 8115 throw new TypeError( "Thenable self-resolution" ); 8116 } 8117 8118 // Support: Promises/A+ sections 2.3.3.1, 3.5 8119 // https://promisesaplus.com/#point-54 8120 // https://promisesaplus.com/#point-75 8121 // Retrieve `then` only once 8122 then = returned && 8123 8124 // Support: Promises/A+ section 2.3.4 8125 // https://promisesaplus.com/#point-64 8126 // Only check objects and functions for thenability 8127 ( typeof returned === "object" || 8128 typeof returned === "function" ) && 8129 returned.then; 8130 8131 // Handle a returned thenable 8132 if ( isFunction( then ) ) { 8133 8134 // Special processors (notify) just wait for resolution 8135 if ( special ) { 8136 then.call( 8137 returned, 8138 resolve( maxDepth, deferred, Identity, special ), 8139 resolve( maxDepth, deferred, Thrower, special ) 8140 ); 8141 8142 // Normal processors (resolve) also hook into progress 8143 } else { 8144 8145 // ...and disregard older resolution values 8146 maxDepth++; 8147 8148 then.call( 8149 returned, 8150 resolve( maxDepth, deferred, Identity, special ), 8151 resolve( maxDepth, deferred, Thrower, special ), 8152 resolve( maxDepth, deferred, Identity, 8153 deferred.notifyWith ) 8154 ); 8155 } 8156 8157 // Handle all other returned values 8158 } else { 8159 8160 // Only substitute handlers pass on context 8161 // and multiple values (non-spec behavior) 8162 if ( handler !== Identity ) { 8163 that = undefined; 8164 args = [ returned ]; 8165 } 8166 8167 // Process the value(s) 8168 // Default process is resolve 8169 ( special || deferred.resolveWith )( that, args ); 8170 } 8171 }, 8172 8173 // Only normal processors (resolve) catch and reject exceptions 8174 process = special ? 8175 mightThrow : 8176 function() { 8177 try { 8178 mightThrow(); 8179 } catch ( e ) { 8180 8181 if ( jQuery.Deferred.exceptionHook ) { 8182 jQuery.Deferred.exceptionHook( e, 8183 process.stackTrace ); 8184 } 8185 8186 // Support: Promises/A+ section 2.3.3.3.4.1 8187 // https://promisesaplus.com/#point-61 8188 // Ignore post-resolution exceptions 8189 if ( depth + 1 >= maxDepth ) { 8190 8191 // Only substitute handlers pass on context 8192 // and multiple values (non-spec behavior) 8193 if ( handler !== Thrower ) { 8194 that = undefined; 8195 args = [ e ]; 8196 } 8197 8198 deferred.rejectWith( that, args ); 8199 } 8200 } 8201 }; 8202 8203 // Support: Promises/A+ section 2.3.3.3.1 8204 // https://promisesaplus.com/#point-57 8205 // Re-resolve promises immediately to dodge false rejection from 8206 // subsequent errors 8207 if ( depth ) { 8208 process(); 8209 } else { 8210 8211 // Call an optional hook to record the stack, in case of exception 8212 // since it's otherwise lost when execution goes async 8213 if ( jQuery.Deferred.getStackHook ) { 8214 process.stackTrace = jQuery.Deferred.getStackHook(); 8215 } 8216 window.setTimeout( process ); 8217 } 8218 }; 8219 } 8220 8221 return jQuery.Deferred( function( newDefer ) { 8222 8223 // progress_handlers.add( ... ) 8224 tuples[ 0 ][ 3 ].add( 8225 resolve( 8226 0, 8227 newDefer, 8228 isFunction( onProgress ) ? 8229 onProgress : 8230 Identity, 8231 newDefer.notifyWith 8232 ) 8233 ); 8234 8235 // fulfilled_handlers.add( ... ) 8236 tuples[ 1 ][ 3 ].add( 8237 resolve( 8238 0, 8239 newDefer, 8240 isFunction( onFulfilled ) ? 8241 onFulfilled : 8242 Identity 8243 ) 8244 ); 8245 8246 // rejected_handlers.add( ... ) 8247 tuples[ 2 ][ 3 ].add( 8248 resolve( 8249 0, 8250 newDefer, 8251 isFunction( onRejected ) ? 8252 onRejected : 8253 Thrower 8254 ) 8255 ); 8256 } ).promise(); 8257 }, 8258 8259 // Get a promise for this deferred 8260 // If obj is provided, the promise aspect is added to the object 8261 promise: function( obj ) { 8262 return obj != null ? jQuery.extend( obj, promise ) : promise; 8263 } 8264 }, 8265 deferred = {}; 8266 8267 // Add list-specific methods 8268 jQuery.each( tuples, function( i, tuple ) { 8269 var list = tuple[ 2 ], 8270 stateString = tuple[ 5 ]; 8271 8272 // promise.progress = list.add 8273 // promise.done = list.add 8274 // promise.fail = list.add 8275 promise[ tuple[ 1 ] ] = list.add; 8276 8277 // Handle state 8278 if ( stateString ) { 8279 list.add( 8280 function() { 8281 8282 // state = "resolved" (i.e., fulfilled) 8283 // state = "rejected" 8284 state = stateString; 8285 }, 8286 8287 // rejected_callbacks.disable 8288 // fulfilled_callbacks.disable 8289 tuples[ 3 - i ][ 2 ].disable, 8290 8291 // rejected_handlers.disable 8292 // fulfilled_handlers.disable 8293 tuples[ 3 - i ][ 3 ].disable, 8294 8295 // progress_callbacks.lock 8296 tuples[ 0 ][ 2 ].lock, 8297 8298 // progress_handlers.lock 8299 tuples[ 0 ][ 3 ].lock 8300 ); 8301 } 8302 8303 // progress_handlers.fire 8304 // fulfilled_handlers.fire 8305 // rejected_handlers.fire 8306 list.add( tuple[ 3 ].fire ); 8307 8308 // deferred.notify = function() { deferred.notifyWith(...) } 8309 // deferred.resolve = function() { deferred.resolveWith(...) } 8310 // deferred.reject = function() { deferred.rejectWith(...) } 8311 deferred[ tuple[ 0 ] ] = function() { 8312 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 8313 return this; 8314 }; 8315 8316 // deferred.notifyWith = list.fireWith 8317 // deferred.resolveWith = list.fireWith 8318 // deferred.rejectWith = list.fireWith 8319 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 8320 } ); 8321 8322 // Make the deferred a promise 8323 promise.promise( deferred ); 8324 8325 // Call given func if any 8326 if ( func ) { 8327 func.call( deferred, deferred ); 8328 } 8329 8330 // All done! 8331 return deferred; 8332 }, 8333 8334 // Deferred helper 8335 when: function( singleValue ) { 8336 var 8337 8338 // count of uncompleted subordinates 8339 remaining = arguments.length, 8340 8341 // count of unprocessed arguments 8342 i = remaining, 8343 8344 // subordinate fulfillment data 8345 resolveContexts = Array( i ), 8346 resolveValues = slice.call( arguments ), 8347 8348 // the primary Deferred 8349 primary = jQuery.Deferred(), 8350 8351 // subordinate callback factory 8352 updateFunc = function( i ) { 8353 return function( value ) { 8354 resolveContexts[ i ] = this; 8355 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 8356 if ( !( --remaining ) ) { 8357 primary.resolveWith( resolveContexts, resolveValues ); 8358 } 8359 }; 8360 }; 8361 8362 // Single- and empty arguments are adopted like Promise.resolve 8363 if ( remaining <= 1 ) { 8364 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 8365 !remaining ); 8366 8367 // Use .then() to unwrap secondary thenables (cf. gh-3000) 8368 if ( primary.state() === "pending" || 8369 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 8370 8371 return primary.then(); 8372 } 8373 } 8374 8375 // Multiple arguments are aggregated like Promise.all array elements 8376 while ( i-- ) { 8377 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 8378 } 8379 8380 return primary.promise(); 8381 } 8382} ); 8383 8384 8385// These usually indicate a programmer mistake during development, 8386// warn about them ASAP rather than swallowing them by default. 8387var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 8388 8389jQuery.Deferred.exceptionHook = function( error, stack ) { 8390 8391 // Support: IE 8 - 9 only 8392 // Console exists when dev tools are open, which can happen at any time 8393 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 8394 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 8395 } 8396}; 8397 8398 8399 8400 8401jQuery.readyException = function( error ) { 8402 window.setTimeout( function() { 8403 throw error; 8404 } ); 8405}; 8406 8407 8408 8409 8410// The deferred used on DOM ready 8411var readyList = jQuery.Deferred(); 8412 8413jQuery.fn.ready = function( fn ) { 8414 8415 readyList 8416 .then( fn ) 8417 8418 // Wrap jQuery.readyException in a function so that the lookup 8419 // happens at the time of error handling instead of callback 8420 // registration. 8421 .catch( function( error ) { 8422 jQuery.readyException( error ); 8423 } ); 8424 8425 return this; 8426}; 8427 8428jQuery.extend( { 8429 8430 // Is the DOM ready to be used? Set to true once it occurs. 8431 isReady: false, 8432 8433 // A counter to track how many items to wait for before 8434 // the ready event fires. See #6781 8435 readyWait: 1, 8436 8437 // Handle when the DOM is ready 8438 ready: function( wait ) { 8439 8440 // Abort if there are pending holds or we're already ready 8441 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 8442 return; 8443 } 8444 8445 // Remember that the DOM is ready 8446 jQuery.isReady = true; 8447 8448 // If a normal DOM Ready event fired, decrement, and wait if need be 8449 if ( wait !== true && --jQuery.readyWait > 0 ) { 8450 return; 8451 } 8452 8453 // If there are functions bound, to execute 8454 readyList.resolveWith( document, [ jQuery ] ); 8455 } 8456} ); 8457 8458jQuery.ready.then = readyList.then; 8459 8460// The ready event handler and self cleanup method 8461function completed() { 8462 document.removeEventListener( "DOMContentLoaded", completed ); 8463 window.removeEventListener( "load", completed ); 8464 jQuery.ready(); 8465} 8466 8467// Catch cases where $(document).ready() is called 8468// after the browser event has already occurred. 8469// Support: IE <=9 - 10 only 8470// Older IE sometimes signals "interactive" too soon 8471if ( document.readyState === "complete" || 8472 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 8473 8474 // Handle it asynchronously to allow scripts the opportunity to delay ready 8475 window.setTimeout( jQuery.ready ); 8476 8477} else { 8478 8479 // Use the handy event callback 8480 document.addEventListener( "DOMContentLoaded", completed ); 8481 8482 // A fallback to window.onload, that will always work 8483 window.addEventListener( "load", completed ); 8484} 8485 8486 8487 8488 8489// Multifunctional method to get and set values of a collection 8490// The value/s can optionally be executed if it's a function 8491var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 8492 var i = 0, 8493 len = elems.length, 8494 bulk = key == null; 8495 8496 // Sets many values 8497 if ( toType( key ) === "object" ) { 8498 chainable = true; 8499 for ( i in key ) { 8500 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 8501 } 8502 8503 // Sets one value 8504 } else if ( value !== undefined ) { 8505 chainable = true; 8506 8507 if ( !isFunction( value ) ) { 8508 raw = true; 8509 } 8510 8511 if ( bulk ) { 8512 8513 // Bulk operations run against the entire set 8514 if ( raw ) { 8515 fn.call( elems, value ); 8516 fn = null; 8517 8518 // ...except when executing function values 8519 } else { 8520 bulk = fn; 8521 fn = function( elem, _key, value ) { 8522 return bulk.call( jQuery( elem ), value ); 8523 }; 8524 } 8525 } 8526 8527 if ( fn ) { 8528 for ( ; i < len; i++ ) { 8529 fn( 8530 elems[ i ], key, raw ? 8531 value : 8532 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 8533 ); 8534 } 8535 } 8536 } 8537 8538 if ( chainable ) { 8539 return elems; 8540 } 8541 8542 // Gets 8543 if ( bulk ) { 8544 return fn.call( elems ); 8545 } 8546 8547 return len ? fn( elems[ 0 ], key ) : emptyGet; 8548}; 8549 8550 8551// Matches dashed string for camelizing 8552var rmsPrefix = /^-ms-/, 8553 rdashAlpha = /-([a-z])/g; 8554 8555// Used by camelCase as callback to replace() 8556function fcamelCase( _all, letter ) { 8557 return letter.toUpperCase(); 8558} 8559 8560// Convert dashed to camelCase; used by the css and data modules 8561// Support: IE <=9 - 11, Edge 12 - 15 8562// Microsoft forgot to hump their vendor prefix (#9572) 8563function camelCase( string ) { 8564 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 8565} 8566var acceptData = function( owner ) { 8567 8568 // Accepts only: 8569 // - Node 8570 // - Node.ELEMENT_NODE 8571 // - Node.DOCUMENT_NODE 8572 // - Object 8573 // - Any 8574 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 8575}; 8576 8577 8578 8579 8580function Data() { 8581 this.expando = jQuery.expando + Data.uid++; 8582} 8583 8584Data.uid = 1; 8585 8586Data.prototype = { 8587 8588 cache: function( owner ) { 8589 8590 // Check if the owner object already has a cache 8591 var value = owner[ this.expando ]; 8592 8593 // If not, create one 8594 if ( !value ) { 8595 value = {}; 8596 8597 // We can accept data for non-element nodes in modern browsers, 8598 // but we should not, see #8335. 8599 // Always return an empty object. 8600 if ( acceptData( owner ) ) { 8601 8602 // If it is a node unlikely to be stringify-ed or looped over 8603 // use plain assignment 8604 if ( owner.nodeType ) { 8605 owner[ this.expando ] = value; 8606 8607 // Otherwise secure it in a non-enumerable property 8608 // configurable must be true to allow the property to be 8609 // deleted when data is removed 8610 } else { 8611 Object.defineProperty( owner, this.expando, { 8612 value: value, 8613 configurable: true 8614 } ); 8615 } 8616 } 8617 } 8618 8619 return value; 8620 }, 8621 set: function( owner, data, value ) { 8622 var prop, 8623 cache = this.cache( owner ); 8624 8625 // Handle: [ owner, key, value ] args 8626 // Always use camelCase key (gh-2257) 8627 if ( typeof data === "string" ) { 8628 cache[ camelCase( data ) ] = value; 8629 8630 // Handle: [ owner, { properties } ] args 8631 } else { 8632 8633 // Copy the properties one-by-one to the cache object 8634 for ( prop in data ) { 8635 cache[ camelCase( prop ) ] = data[ prop ]; 8636 } 8637 } 8638 return cache; 8639 }, 8640 get: function( owner, key ) { 8641 return key === undefined ? 8642 this.cache( owner ) : 8643 8644 // Always use camelCase key (gh-2257) 8645 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 8646 }, 8647 access: function( owner, key, value ) { 8648 8649 // In cases where either: 8650 // 8651 // 1. No key was specified 8652 // 2. A string key was specified, but no value provided 8653 // 8654 // Take the "read" path and allow the get method to determine 8655 // which value to return, respectively either: 8656 // 8657 // 1. The entire cache object 8658 // 2. The data stored at the key 8659 // 8660 if ( key === undefined || 8661 ( ( key && typeof key === "string" ) && value === undefined ) ) { 8662 8663 return this.get( owner, key ); 8664 } 8665 8666 // When the key is not a string, or both a key and value 8667 // are specified, set or extend (existing objects) with either: 8668 // 8669 // 1. An object of properties 8670 // 2. A key and value 8671 // 8672 this.set( owner, key, value ); 8673 8674 // Since the "set" path can have two possible entry points 8675 // return the expected data based on which path was taken[*] 8676 return value !== undefined ? value : key; 8677 }, 8678 remove: function( owner, key ) { 8679 var i, 8680 cache = owner[ this.expando ]; 8681 8682 if ( cache === undefined ) { 8683 return; 8684 } 8685 8686 if ( key !== undefined ) { 8687 8688 // Support array or space separated string of keys 8689 if ( Array.isArray( key ) ) { 8690 8691 // If key is an array of keys... 8692 // We always set camelCase keys, so remove that. 8693 key = key.map( camelCase ); 8694 } else { 8695 key = camelCase( key ); 8696 8697 // If a key with the spaces exists, use it. 8698 // Otherwise, create an array by matching non-whitespace 8699 key = key in cache ? 8700 [ key ] : 8701 ( key.match( rnothtmlwhite ) || [] ); 8702 } 8703 8704 i = key.length; 8705 8706 while ( i-- ) { 8707 delete cache[ key[ i ] ]; 8708 } 8709 } 8710 8711 // Remove the expando if there's no more data 8712 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 8713 8714 // Support: Chrome <=35 - 45 8715 // Webkit & Blink performance suffers when deleting properties 8716 // from DOM nodes, so set to undefined instead 8717 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 8718 if ( owner.nodeType ) { 8719 owner[ this.expando ] = undefined; 8720 } else { 8721 delete owner[ this.expando ]; 8722 } 8723 } 8724 }, 8725 hasData: function( owner ) { 8726 var cache = owner[ this.expando ]; 8727 return cache !== undefined && !jQuery.isEmptyObject( cache ); 8728 } 8729}; 8730var dataPriv = new Data(); 8731 8732var dataUser = new Data(); 8733 8734 8735 8736// Implementation Summary 8737// 8738// 1. Enforce API surface and semantic compatibility with 1.9.x branch 8739// 2. Improve the module's maintainability by reducing the storage 8740// paths to a single mechanism. 8741// 3. Use the same single mechanism to support "private" and "user" data. 8742// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 8743// 5. Avoid exposing implementation details on user objects (eg. expando properties) 8744// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 8745 8746var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 8747 rmultiDash = /[A-Z]/g; 8748 8749function getData( data ) { 8750 if ( data === "true" ) { 8751 return true; 8752 } 8753 8754 if ( data === "false" ) { 8755 return false; 8756 } 8757 8758 if ( data === "null" ) { 8759 return null; 8760 } 8761 8762 // Only convert to a number if it doesn't change the string 8763 if ( data === +data + "" ) { 8764 return +data; 8765 } 8766 8767 if ( rbrace.test( data ) ) { 8768 return JSON.parse( data ); 8769 } 8770 8771 return data; 8772} 8773 8774function dataAttr( elem, key, data ) { 8775 var name; 8776 8777 // If nothing was found internally, try to fetch any 8778 // data from the HTML5 data-* attribute 8779 if ( data === undefined && elem.nodeType === 1 ) { 8780 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 8781 data = elem.getAttribute( name ); 8782 8783 if ( typeof data === "string" ) { 8784 try { 8785 data = getData( data ); 8786 } catch ( e ) {} 8787 8788 // Make sure we set the data so it isn't changed later 8789 dataUser.set( elem, key, data ); 8790 } else { 8791 data = undefined; 8792 } 8793 } 8794 return data; 8795} 8796 8797jQuery.extend( { 8798 hasData: function( elem ) { 8799 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 8800 }, 8801 8802 data: function( elem, name, data ) { 8803 return dataUser.access( elem, name, data ); 8804 }, 8805 8806 removeData: function( elem, name ) { 8807 dataUser.remove( elem, name ); 8808 }, 8809 8810 // TODO: Now that all calls to _data and _removeData have been replaced 8811 // with direct calls to dataPriv methods, these can be deprecated. 8812 _data: function( elem, name, data ) { 8813 return dataPriv.access( elem, name, data ); 8814 }, 8815 8816 _removeData: function( elem, name ) { 8817 dataPriv.remove( elem, name ); 8818 } 8819} ); 8820 8821jQuery.fn.extend( { 8822 data: function( key, value ) { 8823 var i, name, data, 8824 elem = this[ 0 ], 8825 attrs = elem && elem.attributes; 8826 8827 // Gets all values 8828 if ( key === undefined ) { 8829 if ( this.length ) { 8830 data = dataUser.get( elem ); 8831 8832 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 8833 i = attrs.length; 8834 while ( i-- ) { 8835 8836 // Support: IE 11 only 8837 // The attrs elements can be null (#14894) 8838 if ( attrs[ i ] ) { 8839 name = attrs[ i ].name; 8840 if ( name.indexOf( "data-" ) === 0 ) { 8841 name = camelCase( name.slice( 5 ) ); 8842 dataAttr( elem, name, data[ name ] ); 8843 } 8844 } 8845 } 8846 dataPriv.set( elem, "hasDataAttrs", true ); 8847 } 8848 } 8849 8850 return data; 8851 } 8852 8853 // Sets multiple values 8854 if ( typeof key === "object" ) { 8855 return this.each( function() { 8856 dataUser.set( this, key ); 8857 } ); 8858 } 8859 8860 return access( this, function( value ) { 8861 var data; 8862 8863 // The calling jQuery object (element matches) is not empty 8864 // (and therefore has an element appears at this[ 0 ]) and the 8865 // `value` parameter was not undefined. An empty jQuery object 8866 // will result in `undefined` for elem = this[ 0 ] which will 8867 // throw an exception if an attempt to read a data cache is made. 8868 if ( elem && value === undefined ) { 8869 8870 // Attempt to get data from the cache 8871 // The key will always be camelCased in Data 8872 data = dataUser.get( elem, key ); 8873 if ( data !== undefined ) { 8874 return data; 8875 } 8876 8877 // Attempt to "discover" the data in 8878 // HTML5 custom data-* attrs 8879 data = dataAttr( elem, key ); 8880 if ( data !== undefined ) { 8881 return data; 8882 } 8883 8884 // We tried really hard, but the data doesn't exist. 8885 return; 8886 } 8887 8888 // Set the data... 8889 this.each( function() { 8890 8891 // We always store the camelCased key 8892 dataUser.set( this, key, value ); 8893 } ); 8894 }, null, value, arguments.length > 1, null, true ); 8895 }, 8896 8897 removeData: function( key ) { 8898 return this.each( function() { 8899 dataUser.remove( this, key ); 8900 } ); 8901 } 8902} ); 8903 8904 8905jQuery.extend( { 8906 queue: function( elem, type, data ) { 8907 var queue; 8908 8909 if ( elem ) { 8910 type = ( type || "fx" ) + "queue"; 8911 queue = dataPriv.get( elem, type ); 8912 8913 // Speed up dequeue by getting out quickly if this is just a lookup 8914 if ( data ) { 8915 if ( !queue || Array.isArray( data ) ) { 8916 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 8917 } else { 8918 queue.push( data ); 8919 } 8920 } 8921 return queue || []; 8922 } 8923 }, 8924 8925 dequeue: function( elem, type ) { 8926 type = type || "fx"; 8927 8928 var queue = jQuery.queue( elem, type ), 8929 startLength = queue.length, 8930 fn = queue.shift(), 8931 hooks = jQuery._queueHooks( elem, type ), 8932 next = function() { 8933 jQuery.dequeue( elem, type ); 8934 }; 8935 8936 // If the fx queue is dequeued, always remove the progress sentinel 8937 if ( fn === "inprogress" ) { 8938 fn = queue.shift(); 8939 startLength--; 8940 } 8941 8942 if ( fn ) { 8943 8944 // Add a progress sentinel to prevent the fx queue from being 8945 // automatically dequeued 8946 if ( type === "fx" ) { 8947 queue.unshift( "inprogress" ); 8948 } 8949 8950 // Clear up the last queue stop function 8951 delete hooks.stop; 8952 fn.call( elem, next, hooks ); 8953 } 8954 8955 if ( !startLength && hooks ) { 8956 hooks.empty.fire(); 8957 } 8958 }, 8959 8960 // Not public - generate a queueHooks object, or return the current one 8961 _queueHooks: function( elem, type ) { 8962 var key = type + "queueHooks"; 8963 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 8964 empty: jQuery.Callbacks( "once memory" ).add( function() { 8965 dataPriv.remove( elem, [ type + "queue", key ] ); 8966 } ) 8967 } ); 8968 } 8969} ); 8970 8971jQuery.fn.extend( { 8972 queue: function( type, data ) { 8973 var setter = 2; 8974 8975 if ( typeof type !== "string" ) { 8976 data = type; 8977 type = "fx"; 8978 setter--; 8979 } 8980 8981 if ( arguments.length < setter ) { 8982 return jQuery.queue( this[ 0 ], type ); 8983 } 8984 8985 return data === undefined ? 8986 this : 8987 this.each( function() { 8988 var queue = jQuery.queue( this, type, data ); 8989 8990 // Ensure a hooks for this queue 8991 jQuery._queueHooks( this, type ); 8992 8993 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 8994 jQuery.dequeue( this, type ); 8995 } 8996 } ); 8997 }, 8998 dequeue: function( type ) { 8999 return this.each( function() { 9000 jQuery.dequeue( this, type ); 9001 } ); 9002 }, 9003 clearQueue: function( type ) { 9004 return this.queue( type || "fx", [] ); 9005 }, 9006 9007 // Get a promise resolved when queues of a certain type 9008 // are emptied (fx is the type by default) 9009 promise: function( type, obj ) { 9010 var tmp, 9011 count = 1, 9012 defer = jQuery.Deferred(), 9013 elements = this, 9014 i = this.length, 9015 resolve = function() { 9016 if ( !( --count ) ) { 9017 defer.resolveWith( elements, [ elements ] ); 9018 } 9019 }; 9020 9021 if ( typeof type !== "string" ) { 9022 obj = type; 9023 type = undefined; 9024 } 9025 type = type || "fx"; 9026 9027 while ( i-- ) { 9028 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 9029 if ( tmp && tmp.empty ) { 9030 count++; 9031 tmp.empty.add( resolve ); 9032 } 9033 } 9034 resolve(); 9035 return defer.promise( obj ); 9036 } 9037} ); 9038var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 9039 9040var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 9041 9042 9043var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 9044 9045var documentElement = document.documentElement; 9046 9047 9048 9049 var isAttached = function( elem ) { 9050 return jQuery.contains( elem.ownerDocument, elem ); 9051 }, 9052 composed = { composed: true }; 9053 9054 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 9055 // Check attachment across shadow DOM boundaries when possible (gh-3504) 9056 // Support: iOS 10.0-10.2 only 9057 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 9058 // leading to errors. We need to check for `getRootNode`. 9059 if ( documentElement.getRootNode ) { 9060 isAttached = function( elem ) { 9061 return jQuery.contains( elem.ownerDocument, elem ) || 9062 elem.getRootNode( composed ) === elem.ownerDocument; 9063 }; 9064 } 9065var isHiddenWithinTree = function( elem, el ) { 9066 9067 // isHiddenWithinTree might be called from jQuery#filter function; 9068 // in that case, element will be second argument 9069 elem = el || elem; 9070 9071 // Inline style trumps all 9072 return elem.style.display === "none" || 9073 elem.style.display === "" && 9074 9075 // Otherwise, check computed style 9076 // Support: Firefox <=43 - 45 9077 // Disconnected elements can have computed display: none, so first confirm that elem is 9078 // in the document. 9079 isAttached( elem ) && 9080 9081 jQuery.css( elem, "display" ) === "none"; 9082 }; 9083 9084 9085 9086function adjustCSS( elem, prop, valueParts, tween ) { 9087 var adjusted, scale, 9088 maxIterations = 20, 9089 currentValue = tween ? 9090 function() { 9091 return tween.cur(); 9092 } : 9093 function() { 9094 return jQuery.css( elem, prop, "" ); 9095 }, 9096 initial = currentValue(), 9097 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 9098 9099 // Starting value computation is required for potential unit mismatches 9100 initialInUnit = elem.nodeType && 9101 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 9102 rcssNum.exec( jQuery.css( elem, prop ) ); 9103 9104 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 9105 9106 // Support: Firefox <=54 9107 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 9108 initial = initial / 2; 9109 9110 // Trust units reported by jQuery.css 9111 unit = unit || initialInUnit[ 3 ]; 9112 9113 // Iteratively approximate from a nonzero starting point 9114 initialInUnit = +initial || 1; 9115 9116 while ( maxIterations-- ) { 9117 9118 // Evaluate and update our best guess (doubling guesses that zero out). 9119 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 9120 jQuery.style( elem, prop, initialInUnit + unit ); 9121 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 9122 maxIterations = 0; 9123 } 9124 initialInUnit = initialInUnit / scale; 9125 9126 } 9127 9128 initialInUnit = initialInUnit * 2; 9129 jQuery.style( elem, prop, initialInUnit + unit ); 9130 9131 // Make sure we update the tween properties later on 9132 valueParts = valueParts || []; 9133 } 9134 9135 if ( valueParts ) { 9136 initialInUnit = +initialInUnit || +initial || 0; 9137 9138 // Apply relative offset (+=/-=) if specified 9139 adjusted = valueParts[ 1 ] ? 9140 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 9141 +valueParts[ 2 ]; 9142 if ( tween ) { 9143 tween.unit = unit; 9144 tween.start = initialInUnit; 9145 tween.end = adjusted; 9146 } 9147 } 9148 return adjusted; 9149} 9150 9151 9152var defaultDisplayMap = {}; 9153 9154function getDefaultDisplay( elem ) { 9155 var temp, 9156 doc = elem.ownerDocument, 9157 nodeName = elem.nodeName, 9158 display = defaultDisplayMap[ nodeName ]; 9159 9160 if ( display ) { 9161 return display; 9162 } 9163 9164 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 9165 display = jQuery.css( temp, "display" ); 9166 9167 temp.parentNode.removeChild( temp ); 9168 9169 if ( display === "none" ) { 9170 display = "block"; 9171 } 9172 defaultDisplayMap[ nodeName ] = display; 9173 9174 return display; 9175} 9176 9177function showHide( elements, show ) { 9178 var display, elem, 9179 values = [], 9180 index = 0, 9181 length = elements.length; 9182 9183 // Determine new display value for elements that need to change 9184 for ( ; index < length; index++ ) { 9185 elem = elements[ index ]; 9186 if ( !elem.style ) { 9187 continue; 9188 } 9189 9190 display = elem.style.display; 9191 if ( show ) { 9192 9193 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 9194 // check is required in this first loop unless we have a nonempty display value (either 9195 // inline or about-to-be-restored) 9196 if ( display === "none" ) { 9197 values[ index ] = dataPriv.get( elem, "display" ) || null; 9198 if ( !values[ index ] ) { 9199 elem.style.display = ""; 9200 } 9201 } 9202 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 9203 values[ index ] = getDefaultDisplay( elem ); 9204 } 9205 } else { 9206 if ( display !== "none" ) { 9207 values[ index ] = "none"; 9208 9209 // Remember what we're overwriting 9210 dataPriv.set( elem, "display", display ); 9211 } 9212 } 9213 } 9214 9215 // Set the display of the elements in a second loop to avoid constant reflow 9216 for ( index = 0; index < length; index++ ) { 9217 if ( values[ index ] != null ) { 9218 elements[ index ].style.display = values[ index ]; 9219 } 9220 } 9221 9222 return elements; 9223} 9224 9225jQuery.fn.extend( { 9226 show: function() { 9227 return showHide( this, true ); 9228 }, 9229 hide: function() { 9230 return showHide( this ); 9231 }, 9232 toggle: function( state ) { 9233 if ( typeof state === "boolean" ) { 9234 return state ? this.show() : this.hide(); 9235 } 9236 9237 return this.each( function() { 9238 if ( isHiddenWithinTree( this ) ) { 9239 jQuery( this ).show(); 9240 } else { 9241 jQuery( this ).hide(); 9242 } 9243 } ); 9244 } 9245} ); 9246var rcheckableType = ( /^(?:checkbox|radio)$/i ); 9247 9248var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 9249 9250var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 9251 9252 9253 9254( function() { 9255 var fragment = document.createDocumentFragment(), 9256 div = fragment.appendChild( document.createElement( "div" ) ), 9257 input = document.createElement( "input" ); 9258 9259 // Support: Android 4.0 - 4.3 only 9260 // Check state lost if the name is set (#11217) 9261 // Support: Windows Web Apps (WWA) 9262 // `name` and `type` must use .setAttribute for WWA (#14901) 9263 input.setAttribute( "type", "radio" ); 9264 input.setAttribute( "checked", "checked" ); 9265 input.setAttribute( "name", "t" ); 9266 9267 div.appendChild( input ); 9268 9269 // Support: Android <=4.1 only 9270 // Older WebKit doesn't clone checked state correctly in fragments 9271 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 9272 9273 // Support: IE <=11 only 9274 // Make sure textarea (and checkbox) defaultValue is properly cloned 9275 div.innerHTML = "<textarea>x</textarea>"; 9276 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 9277 9278 // Support: IE <=9 only 9279 // IE <=9 replaces <option> tags with their contents when inserted outside of 9280 // the select element. 9281 div.innerHTML = "<option></option>"; 9282 support.option = !!div.lastChild; 9283} )(); 9284 9285 9286// We have to close these tags to support XHTML (#13200) 9287var wrapMap = { 9288 9289 // XHTML parsers do not magically insert elements in the 9290 // same way that tag soup parsers do. So we cannot shorten 9291 // this by omitting <tbody> or other required elements. 9292 thead: [ 1, "<table>", "</table>" ], 9293 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 9294 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 9295 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 9296 9297 _default: [ 0, "", "" ] 9298}; 9299 9300wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 9301wrapMap.th = wrapMap.td; 9302 9303// Support: IE <=9 only 9304if ( !support.option ) { 9305 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 9306} 9307 9308 9309function getAll( context, tag ) { 9310 9311 // Support: IE <=9 - 11 only 9312 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 9313 var ret; 9314 9315 if ( typeof context.getElementsByTagName !== "undefined" ) { 9316 ret = context.getElementsByTagName( tag || "*" ); 9317 9318 } else if ( typeof context.querySelectorAll !== "undefined" ) { 9319 ret = context.querySelectorAll( tag || "*" ); 9320 9321 } else { 9322 ret = []; 9323 } 9324 9325 if ( tag === undefined || tag && nodeName( context, tag ) ) { 9326 return jQuery.merge( [ context ], ret ); 9327 } 9328 9329 return ret; 9330} 9331 9332 9333// Mark scripts as having already been evaluated 9334function setGlobalEval( elems, refElements ) { 9335 var i = 0, 9336 l = elems.length; 9337 9338 for ( ; i < l; i++ ) { 9339 dataPriv.set( 9340 elems[ i ], 9341 "globalEval", 9342 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 9343 ); 9344 } 9345} 9346 9347 9348var rhtml = /<|&#?\w+;/; 9349 9350function buildFragment( elems, context, scripts, selection, ignored ) { 9351 var elem, tmp, tag, wrap, attached, j, 9352 fragment = context.createDocumentFragment(), 9353 nodes = [], 9354 i = 0, 9355 l = elems.length; 9356 9357 for ( ; i < l; i++ ) { 9358 elem = elems[ i ]; 9359 9360 if ( elem || elem === 0 ) { 9361 9362 // Add nodes directly 9363 if ( toType( elem ) === "object" ) { 9364 9365 // Support: Android <=4.0 only, PhantomJS 1 only 9366 // push.apply(_, arraylike) throws on ancient WebKit 9367 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 9368 9369 // Convert non-html into a text node 9370 } else if ( !rhtml.test( elem ) ) { 9371 nodes.push( context.createTextNode( elem ) ); 9372 9373 // Convert html into DOM nodes 9374 } else { 9375 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 9376 9377 // Deserialize a standard representation 9378 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 9379 wrap = wrapMap[ tag ] || wrapMap._default; 9380 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 9381 9382 // Descend through wrappers to the right content 9383 j = wrap[ 0 ]; 9384 while ( j-- ) { 9385 tmp = tmp.lastChild; 9386 } 9387 9388 // Support: Android <=4.0 only, PhantomJS 1 only 9389 // push.apply(_, arraylike) throws on ancient WebKit 9390 jQuery.merge( nodes, tmp.childNodes ); 9391 9392 // Remember the top-level container 9393 tmp = fragment.firstChild; 9394 9395 // Ensure the created nodes are orphaned (#12392) 9396 tmp.textContent = ""; 9397 } 9398 } 9399 } 9400 9401 // Remove wrapper from fragment 9402 fragment.textContent = ""; 9403 9404 i = 0; 9405 while ( ( elem = nodes[ i++ ] ) ) { 9406 9407 // Skip elements already in the context collection (trac-4087) 9408 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 9409 if ( ignored ) { 9410 ignored.push( elem ); 9411 } 9412 continue; 9413 } 9414 9415 attached = isAttached( elem ); 9416 9417 // Append to fragment 9418 tmp = getAll( fragment.appendChild( elem ), "script" ); 9419 9420 // Preserve script evaluation history 9421 if ( attached ) { 9422 setGlobalEval( tmp ); 9423 } 9424 9425 // Capture executables 9426 if ( scripts ) { 9427 j = 0; 9428 while ( ( elem = tmp[ j++ ] ) ) { 9429 if ( rscriptType.test( elem.type || "" ) ) { 9430 scripts.push( elem ); 9431 } 9432 } 9433 } 9434 } 9435 9436 return fragment; 9437} 9438 9439 9440var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 9441 9442function returnTrue() { 9443 return true; 9444} 9445 9446function returnFalse() { 9447 return false; 9448} 9449 9450// Support: IE <=9 - 11+ 9451// focus() and blur() are asynchronous, except when they are no-op. 9452// So expect focus to be synchronous when the element is already active, 9453// and blur to be synchronous when the element is not already active. 9454// (focus and blur are always synchronous in other supported browsers, 9455// this just defines when we can count on it). 9456function expectSync( elem, type ) { 9457 return ( elem === safeActiveElement() ) === ( type === "focus" ); 9458} 9459 9460// Support: IE <=9 only 9461// Accessing document.activeElement can throw unexpectedly 9462// https://bugs.jquery.com/ticket/13393 9463function safeActiveElement() { 9464 try { 9465 return document.activeElement; 9466 } catch ( err ) { } 9467} 9468 9469function on( elem, types, selector, data, fn, one ) { 9470 var origFn, type; 9471 9472 // Types can be a map of types/handlers 9473 if ( typeof types === "object" ) { 9474 9475 // ( types-Object, selector, data ) 9476 if ( typeof selector !== "string" ) { 9477 9478 // ( types-Object, data ) 9479 data = data || selector; 9480 selector = undefined; 9481 } 9482 for ( type in types ) { 9483 on( elem, type, selector, data, types[ type ], one ); 9484 } 9485 return elem; 9486 } 9487 9488 if ( data == null && fn == null ) { 9489 9490 // ( types, fn ) 9491 fn = selector; 9492 data = selector = undefined; 9493 } else if ( fn == null ) { 9494 if ( typeof selector === "string" ) { 9495 9496 // ( types, selector, fn ) 9497 fn = data; 9498 data = undefined; 9499 } else { 9500 9501 // ( types, data, fn ) 9502 fn = data; 9503 data = selector; 9504 selector = undefined; 9505 } 9506 } 9507 if ( fn === false ) { 9508 fn = returnFalse; 9509 } else if ( !fn ) { 9510 return elem; 9511 } 9512 9513 if ( one === 1 ) { 9514 origFn = fn; 9515 fn = function( event ) { 9516 9517 // Can use an empty set, since event contains the info 9518 jQuery().off( event ); 9519 return origFn.apply( this, arguments ); 9520 }; 9521 9522 // Use same guid so caller can remove using origFn 9523 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 9524 } 9525 return elem.each( function() { 9526 jQuery.event.add( this, types, fn, data, selector ); 9527 } ); 9528} 9529 9530/* 9531 * Helper functions for managing events -- not part of the public interface. 9532 * Props to Dean Edwards' addEvent library for many of the ideas. 9533 */ 9534jQuery.event = { 9535 9536 global: {}, 9537 9538 add: function( elem, types, handler, data, selector ) { 9539 9540 var handleObjIn, eventHandle, tmp, 9541 events, t, handleObj, 9542 special, handlers, type, namespaces, origType, 9543 elemData = dataPriv.get( elem ); 9544 9545 // Only attach events to objects that accept data 9546 if ( !acceptData( elem ) ) { 9547 return; 9548 } 9549 9550 // Caller can pass in an object of custom data in lieu of the handler 9551 if ( handler.handler ) { 9552 handleObjIn = handler; 9553 handler = handleObjIn.handler; 9554 selector = handleObjIn.selector; 9555 } 9556 9557 // Ensure that invalid selectors throw exceptions at attach time 9558 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 9559 if ( selector ) { 9560 jQuery.find.matchesSelector( documentElement, selector ); 9561 } 9562 9563 // Make sure that the handler has a unique ID, used to find/remove it later 9564 if ( !handler.guid ) { 9565 handler.guid = jQuery.guid++; 9566 } 9567 9568 // Init the element's event structure and main handler, if this is the first 9569 if ( !( events = elemData.events ) ) { 9570 events = elemData.events = Object.create( null ); 9571 } 9572 if ( !( eventHandle = elemData.handle ) ) { 9573 eventHandle = elemData.handle = function( e ) { 9574 9575 // Discard the second event of a jQuery.event.trigger() and 9576 // when an event is called after a page has unloaded 9577 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 9578 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 9579 }; 9580 } 9581 9582 // Handle multiple events separated by a space 9583 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 9584 t = types.length; 9585 while ( t-- ) { 9586 tmp = rtypenamespace.exec( types[ t ] ) || []; 9587 type = origType = tmp[ 1 ]; 9588 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 9589 9590 // There *must* be a type, no attaching namespace-only handlers 9591 if ( !type ) { 9592 continue; 9593 } 9594 9595 // If event changes its type, use the special event handlers for the changed type 9596 special = jQuery.event.special[ type ] || {}; 9597 9598 // If selector defined, determine special event api type, otherwise given type 9599 type = ( selector ? special.delegateType : special.bindType ) || type; 9600 9601 // Update special based on newly reset type 9602 special = jQuery.event.special[ type ] || {}; 9603 9604 // handleObj is passed to all event handlers 9605 handleObj = jQuery.extend( { 9606 type: type, 9607 origType: origType, 9608 data: data, 9609 handler: handler, 9610 guid: handler.guid, 9611 selector: selector, 9612 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 9613 namespace: namespaces.join( "." ) 9614 }, handleObjIn ); 9615 9616 // Init the event handler queue if we're the first 9617 if ( !( handlers = events[ type ] ) ) { 9618 handlers = events[ type ] = []; 9619 handlers.delegateCount = 0; 9620 9621 // Only use addEventListener if the special events handler returns false 9622 if ( !special.setup || 9623 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 9624 9625 if ( elem.addEventListener ) { 9626 elem.addEventListener( type, eventHandle ); 9627 } 9628 } 9629 } 9630 9631 if ( special.add ) { 9632 special.add.call( elem, handleObj ); 9633 9634 if ( !handleObj.handler.guid ) { 9635 handleObj.handler.guid = handler.guid; 9636 } 9637 } 9638 9639 // Add to the element's handler list, delegates in front 9640 if ( selector ) { 9641 handlers.splice( handlers.delegateCount++, 0, handleObj ); 9642 } else { 9643 handlers.push( handleObj ); 9644 } 9645 9646 // Keep track of which events have ever been used, for event optimization 9647 jQuery.event.global[ type ] = true; 9648 } 9649 9650 }, 9651 9652 // Detach an event or set of events from an element 9653 remove: function( elem, types, handler, selector, mappedTypes ) { 9654 9655 var j, origCount, tmp, 9656 events, t, handleObj, 9657 special, handlers, type, namespaces, origType, 9658 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 9659 9660 if ( !elemData || !( events = elemData.events ) ) { 9661 return; 9662 } 9663 9664 // Once for each type.namespace in types; type may be omitted 9665 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 9666 t = types.length; 9667 while ( t-- ) { 9668 tmp = rtypenamespace.exec( types[ t ] ) || []; 9669 type = origType = tmp[ 1 ]; 9670 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 9671 9672 // Unbind all events (on this namespace, if provided) for the element 9673 if ( !type ) { 9674 for ( type in events ) { 9675 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 9676 } 9677 continue; 9678 } 9679 9680 special = jQuery.event.special[ type ] || {}; 9681 type = ( selector ? special.delegateType : special.bindType ) || type; 9682 handlers = events[ type ] || []; 9683 tmp = tmp[ 2 ] && 9684 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 9685 9686 // Remove matching events 9687 origCount = j = handlers.length; 9688 while ( j-- ) { 9689 handleObj = handlers[ j ]; 9690 9691 if ( ( mappedTypes || origType === handleObj.origType ) && 9692 ( !handler || handler.guid === handleObj.guid ) && 9693 ( !tmp || tmp.test( handleObj.namespace ) ) && 9694 ( !selector || selector === handleObj.selector || 9695 selector === "**" && handleObj.selector ) ) { 9696 handlers.splice( j, 1 ); 9697 9698 if ( handleObj.selector ) { 9699 handlers.delegateCount--; 9700 } 9701 if ( special.remove ) { 9702 special.remove.call( elem, handleObj ); 9703 } 9704 } 9705 } 9706 9707 // Remove generic event handler if we removed something and no more handlers exist 9708 // (avoids potential for endless recursion during removal of special event handlers) 9709 if ( origCount && !handlers.length ) { 9710 if ( !special.teardown || 9711 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 9712 9713 jQuery.removeEvent( elem, type, elemData.handle ); 9714 } 9715 9716 delete events[ type ]; 9717 } 9718 } 9719 9720 // Remove data and the expando if it's no longer used 9721 if ( jQuery.isEmptyObject( events ) ) { 9722 dataPriv.remove( elem, "handle events" ); 9723 } 9724 }, 9725 9726 dispatch: function( nativeEvent ) { 9727 9728 var i, j, ret, matched, handleObj, handlerQueue, 9729 args = new Array( arguments.length ), 9730 9731 // Make a writable jQuery.Event from the native event object 9732 event = jQuery.event.fix( nativeEvent ), 9733 9734 handlers = ( 9735 dataPriv.get( this, "events" ) || Object.create( null ) 9736 )[ event.type ] || [], 9737 special = jQuery.event.special[ event.type ] || {}; 9738 9739 // Use the fix-ed jQuery.Event rather than the (read-only) native event 9740 args[ 0 ] = event; 9741 9742 for ( i = 1; i < arguments.length; i++ ) { 9743 args[ i ] = arguments[ i ]; 9744 } 9745 9746 event.delegateTarget = this; 9747 9748 // Call the preDispatch hook for the mapped type, and let it bail if desired 9749 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 9750 return; 9751 } 9752 9753 // Determine handlers 9754 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 9755 9756 // Run delegates first; they may want to stop propagation beneath us 9757 i = 0; 9758 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 9759 event.currentTarget = matched.elem; 9760 9761 j = 0; 9762 while ( ( handleObj = matched.handlers[ j++ ] ) && 9763 !event.isImmediatePropagationStopped() ) { 9764 9765 // If the event is namespaced, then each handler is only invoked if it is 9766 // specially universal or its namespaces are a superset of the event's. 9767 if ( !event.rnamespace || handleObj.namespace === false || 9768 event.rnamespace.test( handleObj.namespace ) ) { 9769 9770 event.handleObj = handleObj; 9771 event.data = handleObj.data; 9772 9773 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 9774 handleObj.handler ).apply( matched.elem, args ); 9775 9776 if ( ret !== undefined ) { 9777 if ( ( event.result = ret ) === false ) { 9778 event.preventDefault(); 9779 event.stopPropagation(); 9780 } 9781 } 9782 } 9783 } 9784 } 9785 9786 // Call the postDispatch hook for the mapped type 9787 if ( special.postDispatch ) { 9788 special.postDispatch.call( this, event ); 9789 } 9790 9791 return event.result; 9792 }, 9793 9794 handlers: function( event, handlers ) { 9795 var i, handleObj, sel, matchedHandlers, matchedSelectors, 9796 handlerQueue = [], 9797 delegateCount = handlers.delegateCount, 9798 cur = event.target; 9799 9800 // Find delegate handlers 9801 if ( delegateCount && 9802 9803 // Support: IE <=9 9804 // Black-hole SVG <use> instance trees (trac-13180) 9805 cur.nodeType && 9806 9807 // Support: Firefox <=42 9808 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 9809 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 9810 // Support: IE 11 only 9811 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 9812 !( event.type === "click" && event.button >= 1 ) ) { 9813 9814 for ( ; cur !== this; cur = cur.parentNode || this ) { 9815 9816 // Don't check non-elements (#13208) 9817 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 9818 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 9819 matchedHandlers = []; 9820 matchedSelectors = {}; 9821 for ( i = 0; i < delegateCount; i++ ) { 9822 handleObj = handlers[ i ]; 9823 9824 // Don't conflict with Object.prototype properties (#13203) 9825 sel = handleObj.selector + " "; 9826 9827 if ( matchedSelectors[ sel ] === undefined ) { 9828 matchedSelectors[ sel ] = handleObj.needsContext ? 9829 jQuery( sel, this ).index( cur ) > -1 : 9830 jQuery.find( sel, this, null, [ cur ] ).length; 9831 } 9832 if ( matchedSelectors[ sel ] ) { 9833 matchedHandlers.push( handleObj ); 9834 } 9835 } 9836 if ( matchedHandlers.length ) { 9837 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 9838 } 9839 } 9840 } 9841 } 9842 9843 // Add the remaining (directly-bound) handlers 9844 cur = this; 9845 if ( delegateCount < handlers.length ) { 9846 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 9847 } 9848 9849 return handlerQueue; 9850 }, 9851 9852 addProp: function( name, hook ) { 9853 Object.defineProperty( jQuery.Event.prototype, name, { 9854 enumerable: true, 9855 configurable: true, 9856 9857 get: isFunction( hook ) ? 9858 function() { 9859 if ( this.originalEvent ) { 9860 return hook( this.originalEvent ); 9861 } 9862 } : 9863 function() { 9864 if ( this.originalEvent ) { 9865 return this.originalEvent[ name ]; 9866 } 9867 }, 9868 9869 set: function( value ) { 9870 Object.defineProperty( this, name, { 9871 enumerable: true, 9872 configurable: true, 9873 writable: true, 9874 value: value 9875 } ); 9876 } 9877 } ); 9878 }, 9879 9880 fix: function( originalEvent ) { 9881 return originalEvent[ jQuery.expando ] ? 9882 originalEvent : 9883 new jQuery.Event( originalEvent ); 9884 }, 9885 9886 special: { 9887 load: { 9888 9889 // Prevent triggered image.load events from bubbling to window.load 9890 noBubble: true 9891 }, 9892 click: { 9893 9894 // Utilize native event to ensure correct state for checkable inputs 9895 setup: function( data ) { 9896 9897 // For mutual compressibility with _default, replace `this` access with a local var. 9898 // `|| data` is dead code meant only to preserve the variable through minification. 9899 var el = this || data; 9900 9901 // Claim the first handler 9902 if ( rcheckableType.test( el.type ) && 9903 el.click && nodeName( el, "input" ) ) { 9904 9905 // dataPriv.set( el, "click", ... ) 9906 leverageNative( el, "click", returnTrue ); 9907 } 9908 9909 // Return false to allow normal processing in the caller 9910 return false; 9911 }, 9912 trigger: function( data ) { 9913 9914 // For mutual compressibility with _default, replace `this` access with a local var. 9915 // `|| data` is dead code meant only to preserve the variable through minification. 9916 var el = this || data; 9917 9918 // Force setup before triggering a click 9919 if ( rcheckableType.test( el.type ) && 9920 el.click && nodeName( el, "input" ) ) { 9921 9922 leverageNative( el, "click" ); 9923 } 9924 9925 // Return non-false to allow normal event-path propagation 9926 return true; 9927 }, 9928 9929 // For cross-browser consistency, suppress native .click() on links 9930 // Also prevent it if we're currently inside a leveraged native-event stack 9931 _default: function( event ) { 9932 var target = event.target; 9933 return rcheckableType.test( target.type ) && 9934 target.click && nodeName( target, "input" ) && 9935 dataPriv.get( target, "click" ) || 9936 nodeName( target, "a" ); 9937 } 9938 }, 9939 9940 beforeunload: { 9941 postDispatch: function( event ) { 9942 9943 // Support: Firefox 20+ 9944 // Firefox doesn't alert if the returnValue field is not set. 9945 if ( event.result !== undefined && event.originalEvent ) { 9946 event.originalEvent.returnValue = event.result; 9947 } 9948 } 9949 } 9950 } 9951}; 9952 9953// Ensure the presence of an event listener that handles manually-triggered 9954// synthetic events by interrupting progress until reinvoked in response to 9955// *native* events that it fires directly, ensuring that state changes have 9956// already occurred before other listeners are invoked. 9957function leverageNative( el, type, expectSync ) { 9958 9959 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 9960 if ( !expectSync ) { 9961 if ( dataPriv.get( el, type ) === undefined ) { 9962 jQuery.event.add( el, type, returnTrue ); 9963 } 9964 return; 9965 } 9966 9967 // Register the controller as a special universal handler for all event namespaces 9968 dataPriv.set( el, type, false ); 9969 jQuery.event.add( el, type, { 9970 namespace: false, 9971 handler: function( event ) { 9972 var notAsync, result, 9973 saved = dataPriv.get( this, type ); 9974 9975 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 9976 9977 // Interrupt processing of the outer synthetic .trigger()ed event 9978 // Saved data should be false in such cases, but might be a leftover capture object 9979 // from an async native handler (gh-4350) 9980 if ( !saved.length ) { 9981 9982 // Store arguments for use when handling the inner native event 9983 // There will always be at least one argument (an event object), so this array 9984 // will not be confused with a leftover capture object. 9985 saved = slice.call( arguments ); 9986 dataPriv.set( this, type, saved ); 9987 9988 // Trigger the native event and capture its result 9989 // Support: IE <=9 - 11+ 9990 // focus() and blur() are asynchronous 9991 notAsync = expectSync( this, type ); 9992 this[ type ](); 9993 result = dataPriv.get( this, type ); 9994 if ( saved !== result || notAsync ) { 9995 dataPriv.set( this, type, false ); 9996 } else { 9997 result = {}; 9998 } 9999 if ( saved !== result ) { 10000 10001 // Cancel the outer synthetic event 10002 event.stopImmediatePropagation(); 10003 event.preventDefault(); 10004 10005 // Support: Chrome 86+ 10006 // In Chrome, if an element having a focusout handler is blurred by 10007 // clicking outside of it, it invokes the handler synchronously. If 10008 // that handler calls `.remove()` on the element, the data is cleared, 10009 // leaving `result` undefined. We need to guard against this. 10010 return result && result.value; 10011 } 10012 10013 // If this is an inner synthetic event for an event with a bubbling surrogate 10014 // (focus or blur), assume that the surrogate already propagated from triggering the 10015 // native event and prevent that from happening again here. 10016 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 10017 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 10018 // less bad than duplication. 10019 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 10020 event.stopPropagation(); 10021 } 10022 10023 // If this is a native event triggered above, everything is now in order 10024 // Fire an inner synthetic event with the original arguments 10025 } else if ( saved.length ) { 10026 10027 // ...and capture the result 10028 dataPriv.set( this, type, { 10029 value: jQuery.event.trigger( 10030 10031 // Support: IE <=9 - 11+ 10032 // Extend with the prototype to reset the above stopImmediatePropagation() 10033 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 10034 saved.slice( 1 ), 10035 this 10036 ) 10037 } ); 10038 10039 // Abort handling of the native event 10040 event.stopImmediatePropagation(); 10041 } 10042 } 10043 } ); 10044} 10045 10046jQuery.removeEvent = function( elem, type, handle ) { 10047 10048 // This "if" is needed for plain objects 10049 if ( elem.removeEventListener ) { 10050 elem.removeEventListener( type, handle ); 10051 } 10052}; 10053 10054jQuery.Event = function( src, props ) { 10055 10056 // Allow instantiation without the 'new' keyword 10057 if ( !( this instanceof jQuery.Event ) ) { 10058 return new jQuery.Event( src, props ); 10059 } 10060 10061 // Event object 10062 if ( src && src.type ) { 10063 this.originalEvent = src; 10064 this.type = src.type; 10065 10066 // Events bubbling up the document may have been marked as prevented 10067 // by a handler lower down the tree; reflect the correct value. 10068 this.isDefaultPrevented = src.defaultPrevented || 10069 src.defaultPrevented === undefined && 10070 10071 // Support: Android <=2.3 only 10072 src.returnValue === false ? 10073 returnTrue : 10074 returnFalse; 10075 10076 // Create target properties 10077 // Support: Safari <=6 - 7 only 10078 // Target should not be a text node (#504, #13143) 10079 this.target = ( src.target && src.target.nodeType === 3 ) ? 10080 src.target.parentNode : 10081 src.target; 10082 10083 this.currentTarget = src.currentTarget; 10084 this.relatedTarget = src.relatedTarget; 10085 10086 // Event type 10087 } else { 10088 this.type = src; 10089 } 10090 10091 // Put explicitly provided properties onto the event object 10092 if ( props ) { 10093 jQuery.extend( this, props ); 10094 } 10095 10096 // Create a timestamp if incoming event doesn't have one 10097 this.timeStamp = src && src.timeStamp || Date.now(); 10098 10099 // Mark it as fixed 10100 this[ jQuery.expando ] = true; 10101}; 10102 10103// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 10104// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 10105jQuery.Event.prototype = { 10106 constructor: jQuery.Event, 10107 isDefaultPrevented: returnFalse, 10108 isPropagationStopped: returnFalse, 10109 isImmediatePropagationStopped: returnFalse, 10110 isSimulated: false, 10111 10112 preventDefault: function() { 10113 var e = this.originalEvent; 10114 10115 this.isDefaultPrevented = returnTrue; 10116 10117 if ( e && !this.isSimulated ) { 10118 e.preventDefault(); 10119 } 10120 }, 10121 stopPropagation: function() { 10122 var e = this.originalEvent; 10123 10124 this.isPropagationStopped = returnTrue; 10125 10126 if ( e && !this.isSimulated ) { 10127 e.stopPropagation(); 10128 } 10129 }, 10130 stopImmediatePropagation: function() { 10131 var e = this.originalEvent; 10132 10133 this.isImmediatePropagationStopped = returnTrue; 10134 10135 if ( e && !this.isSimulated ) { 10136 e.stopImmediatePropagation(); 10137 } 10138 10139 this.stopPropagation(); 10140 } 10141}; 10142 10143// Includes all common event props including KeyEvent and MouseEvent specific props 10144jQuery.each( { 10145 altKey: true, 10146 bubbles: true, 10147 cancelable: true, 10148 changedTouches: true, 10149 ctrlKey: true, 10150 detail: true, 10151 eventPhase: true, 10152 metaKey: true, 10153 pageX: true, 10154 pageY: true, 10155 shiftKey: true, 10156 view: true, 10157 "char": true, 10158 code: true, 10159 charCode: true, 10160 key: true, 10161 keyCode: true, 10162 button: true, 10163 buttons: true, 10164 clientX: true, 10165 clientY: true, 10166 offsetX: true, 10167 offsetY: true, 10168 pointerId: true, 10169 pointerType: true, 10170 screenX: true, 10171 screenY: true, 10172 targetTouches: true, 10173 toElement: true, 10174 touches: true, 10175 which: true 10176}, jQuery.event.addProp ); 10177 10178jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 10179 jQuery.event.special[ type ] = { 10180 10181 // Utilize native event if possible so blur/focus sequence is correct 10182 setup: function() { 10183 10184 // Claim the first handler 10185 // dataPriv.set( this, "focus", ... ) 10186 // dataPriv.set( this, "blur", ... ) 10187 leverageNative( this, type, expectSync ); 10188 10189 // Return false to allow normal processing in the caller 10190 return false; 10191 }, 10192 trigger: function() { 10193 10194 // Force setup before trigger 10195 leverageNative( this, type ); 10196 10197 // Return non-false to allow normal event-path propagation 10198 return true; 10199 }, 10200 10201 // Suppress native focus or blur as it's already being fired 10202 // in leverageNative. 10203 _default: function() { 10204 return true; 10205 }, 10206 10207 delegateType: delegateType 10208 }; 10209} ); 10210 10211// Create mouseenter/leave events using mouseover/out and event-time checks 10212// so that event delegation works in jQuery. 10213// Do the same for pointerenter/pointerleave and pointerover/pointerout 10214// 10215// Support: Safari 7 only 10216// Safari sends mouseenter too often; see: 10217// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 10218// for the description of the bug (it existed in older Chrome versions as well). 10219jQuery.each( { 10220 mouseenter: "mouseover", 10221 mouseleave: "mouseout", 10222 pointerenter: "pointerover", 10223 pointerleave: "pointerout" 10224}, function( orig, fix ) { 10225 jQuery.event.special[ orig ] = { 10226 delegateType: fix, 10227 bindType: fix, 10228 10229 handle: function( event ) { 10230 var ret, 10231 target = this, 10232 related = event.relatedTarget, 10233 handleObj = event.handleObj; 10234 10235 // For mouseenter/leave call the handler if related is outside the target. 10236 // NB: No relatedTarget if the mouse left/entered the browser window 10237 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 10238 event.type = handleObj.origType; 10239 ret = handleObj.handler.apply( this, arguments ); 10240 event.type = fix; 10241 } 10242 return ret; 10243 } 10244 }; 10245} ); 10246 10247jQuery.fn.extend( { 10248 10249 on: function( types, selector, data, fn ) { 10250 return on( this, types, selector, data, fn ); 10251 }, 10252 one: function( types, selector, data, fn ) { 10253 return on( this, types, selector, data, fn, 1 ); 10254 }, 10255 off: function( types, selector, fn ) { 10256 var handleObj, type; 10257 if ( types && types.preventDefault && types.handleObj ) { 10258 10259 // ( event ) dispatched jQuery.Event 10260 handleObj = types.handleObj; 10261 jQuery( types.delegateTarget ).off( 10262 handleObj.namespace ? 10263 handleObj.origType + "." + handleObj.namespace : 10264 handleObj.origType, 10265 handleObj.selector, 10266 handleObj.handler 10267 ); 10268 return this; 10269 } 10270 if ( typeof types === "object" ) { 10271 10272 // ( types-object [, selector] ) 10273 for ( type in types ) { 10274 this.off( type, selector, types[ type ] ); 10275 } 10276 return this; 10277 } 10278 if ( selector === false || typeof selector === "function" ) { 10279 10280 // ( types [, fn] ) 10281 fn = selector; 10282 selector = undefined; 10283 } 10284 if ( fn === false ) { 10285 fn = returnFalse; 10286 } 10287 return this.each( function() { 10288 jQuery.event.remove( this, types, fn, selector ); 10289 } ); 10290 } 10291} ); 10292 10293 10294var 10295 10296 // Support: IE <=10 - 11, Edge 12 - 13 only 10297 // In IE/Edge using regex groups here causes severe slowdowns. 10298 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 10299 rnoInnerhtml = /<script|<style|<link/i, 10300 10301 // checked="checked" or checked 10302 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 10303 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 10304 10305// Prefer a tbody over its parent table for containing new rows 10306function manipulationTarget( elem, content ) { 10307 if ( nodeName( elem, "table" ) && 10308 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 10309 10310 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 10311 } 10312 10313 return elem; 10314} 10315 10316// Replace/restore the type attribute of script elements for safe DOM manipulation 10317function disableScript( elem ) { 10318 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 10319 return elem; 10320} 10321function restoreScript( elem ) { 10322 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 10323 elem.type = elem.type.slice( 5 ); 10324 } else { 10325 elem.removeAttribute( "type" ); 10326 } 10327 10328 return elem; 10329} 10330 10331function cloneCopyEvent( src, dest ) { 10332 var i, l, type, pdataOld, udataOld, udataCur, events; 10333 10334 if ( dest.nodeType !== 1 ) { 10335 return; 10336 } 10337 10338 // 1. Copy private data: events, handlers, etc. 10339 if ( dataPriv.hasData( src ) ) { 10340 pdataOld = dataPriv.get( src ); 10341 events = pdataOld.events; 10342 10343 if ( events ) { 10344 dataPriv.remove( dest, "handle events" ); 10345 10346 for ( type in events ) { 10347 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 10348 jQuery.event.add( dest, type, events[ type ][ i ] ); 10349 } 10350 } 10351 } 10352 } 10353 10354 // 2. Copy user data 10355 if ( dataUser.hasData( src ) ) { 10356 udataOld = dataUser.access( src ); 10357 udataCur = jQuery.extend( {}, udataOld ); 10358 10359 dataUser.set( dest, udataCur ); 10360 } 10361} 10362 10363// Fix IE bugs, see support tests 10364function fixInput( src, dest ) { 10365 var nodeName = dest.nodeName.toLowerCase(); 10366 10367 // Fails to persist the checked state of a cloned checkbox or radio button. 10368 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 10369 dest.checked = src.checked; 10370 10371 // Fails to return the selected option to the default selected state when cloning options 10372 } else if ( nodeName === "input" || nodeName === "textarea" ) { 10373 dest.defaultValue = src.defaultValue; 10374 } 10375} 10376 10377function domManip( collection, args, callback, ignored ) { 10378 10379 // Flatten any nested arrays 10380 args = flat( args ); 10381 10382 var fragment, first, scripts, hasScripts, node, doc, 10383 i = 0, 10384 l = collection.length, 10385 iNoClone = l - 1, 10386 value = args[ 0 ], 10387 valueIsFunction = isFunction( value ); 10388 10389 // We can't cloneNode fragments that contain checked, in WebKit 10390 if ( valueIsFunction || 10391 ( l > 1 && typeof value === "string" && 10392 !support.checkClone && rchecked.test( value ) ) ) { 10393 return collection.each( function( index ) { 10394 var self = collection.eq( index ); 10395 if ( valueIsFunction ) { 10396 args[ 0 ] = value.call( this, index, self.html() ); 10397 } 10398 domManip( self, args, callback, ignored ); 10399 } ); 10400 } 10401 10402 if ( l ) { 10403 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 10404 first = fragment.firstChild; 10405 10406 if ( fragment.childNodes.length === 1 ) { 10407 fragment = first; 10408 } 10409 10410 // Require either new content or an interest in ignored elements to invoke the callback 10411 if ( first || ignored ) { 10412 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 10413 hasScripts = scripts.length; 10414 10415 // Use the original fragment for the last item 10416 // instead of the first because it can end up 10417 // being emptied incorrectly in certain situations (#8070). 10418 for ( ; i < l; i++ ) { 10419 node = fragment; 10420 10421 if ( i !== iNoClone ) { 10422 node = jQuery.clone( node, true, true ); 10423 10424 // Keep references to cloned scripts for later restoration 10425 if ( hasScripts ) { 10426 10427 // Support: Android <=4.0 only, PhantomJS 1 only 10428 // push.apply(_, arraylike) throws on ancient WebKit 10429 jQuery.merge( scripts, getAll( node, "script" ) ); 10430 } 10431 } 10432 10433 callback.call( collection[ i ], node, i ); 10434 } 10435 10436 if ( hasScripts ) { 10437 doc = scripts[ scripts.length - 1 ].ownerDocument; 10438 10439 // Reenable scripts 10440 jQuery.map( scripts, restoreScript ); 10441 10442 // Evaluate executable scripts on first document insertion 10443 for ( i = 0; i < hasScripts; i++ ) { 10444 node = scripts[ i ]; 10445 if ( rscriptType.test( node.type || "" ) && 10446 !dataPriv.access( node, "globalEval" ) && 10447 jQuery.contains( doc, node ) ) { 10448 10449 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 10450 10451 // Optional AJAX dependency, but won't run scripts if not present 10452 if ( jQuery._evalUrl && !node.noModule ) { 10453 jQuery._evalUrl( node.src, { 10454 nonce: node.nonce || node.getAttribute( "nonce" ) 10455 }, doc ); 10456 } 10457 } else { 10458 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 10459 } 10460 } 10461 } 10462 } 10463 } 10464 } 10465 10466 return collection; 10467} 10468 10469function remove( elem, selector, keepData ) { 10470 var node, 10471 nodes = selector ? jQuery.filter( selector, elem ) : elem, 10472 i = 0; 10473 10474 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 10475 if ( !keepData && node.nodeType === 1 ) { 10476 jQuery.cleanData( getAll( node ) ); 10477 } 10478 10479 if ( node.parentNode ) { 10480 if ( keepData && isAttached( node ) ) { 10481 setGlobalEval( getAll( node, "script" ) ); 10482 } 10483 node.parentNode.removeChild( node ); 10484 } 10485 } 10486 10487 return elem; 10488} 10489 10490jQuery.extend( { 10491 htmlPrefilter: function( html ) { 10492 return html; 10493 }, 10494 10495 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 10496 var i, l, srcElements, destElements, 10497 clone = elem.cloneNode( true ), 10498 inPage = isAttached( elem ); 10499 10500 // Fix IE cloning issues 10501 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 10502 !jQuery.isXMLDoc( elem ) ) { 10503 10504 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 10505 destElements = getAll( clone ); 10506 srcElements = getAll( elem ); 10507 10508 for ( i = 0, l = srcElements.length; i < l; i++ ) { 10509 fixInput( srcElements[ i ], destElements[ i ] ); 10510 } 10511 } 10512 10513 // Copy the events from the original to the clone 10514 if ( dataAndEvents ) { 10515 if ( deepDataAndEvents ) { 10516 srcElements = srcElements || getAll( elem ); 10517 destElements = destElements || getAll( clone ); 10518 10519 for ( i = 0, l = srcElements.length; i < l; i++ ) { 10520 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 10521 } 10522 } else { 10523 cloneCopyEvent( elem, clone ); 10524 } 10525 } 10526 10527 // Preserve script evaluation history 10528 destElements = getAll( clone, "script" ); 10529 if ( destElements.length > 0 ) { 10530 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 10531 } 10532 10533 // Return the cloned set 10534 return clone; 10535 }, 10536 10537 cleanData: function( elems ) { 10538 var data, elem, type, 10539 special = jQuery.event.special, 10540 i = 0; 10541 10542 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 10543 if ( acceptData( elem ) ) { 10544 if ( ( data = elem[ dataPriv.expando ] ) ) { 10545 if ( data.events ) { 10546 for ( type in data.events ) { 10547 if ( special[ type ] ) { 10548 jQuery.event.remove( elem, type ); 10549 10550 // This is a shortcut to avoid jQuery.event.remove's overhead 10551 } else { 10552 jQuery.removeEvent( elem, type, data.handle ); 10553 } 10554 } 10555 } 10556 10557 // Support: Chrome <=35 - 45+ 10558 // Assign undefined instead of using delete, see Data#remove 10559 elem[ dataPriv.expando ] = undefined; 10560 } 10561 if ( elem[ dataUser.expando ] ) { 10562 10563 // Support: Chrome <=35 - 45+ 10564 // Assign undefined instead of using delete, see Data#remove 10565 elem[ dataUser.expando ] = undefined; 10566 } 10567 } 10568 } 10569 } 10570} ); 10571 10572jQuery.fn.extend( { 10573 detach: function( selector ) { 10574 return remove( this, selector, true ); 10575 }, 10576 10577 remove: function( selector ) { 10578 return remove( this, selector ); 10579 }, 10580 10581 text: function( value ) { 10582 return access( this, function( value ) { 10583 return value === undefined ? 10584 jQuery.text( this ) : 10585 this.empty().each( function() { 10586 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 10587 this.textContent = value; 10588 } 10589 } ); 10590 }, null, value, arguments.length ); 10591 }, 10592 10593 append: function() { 10594 return domManip( this, arguments, function( elem ) { 10595 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 10596 var target = manipulationTarget( this, elem ); 10597 target.appendChild( elem ); 10598 } 10599 } ); 10600 }, 10601 10602 prepend: function() { 10603 return domManip( this, arguments, function( elem ) { 10604 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 10605 var target = manipulationTarget( this, elem ); 10606 target.insertBefore( elem, target.firstChild ); 10607 } 10608 } ); 10609 }, 10610 10611 before: function() { 10612 return domManip( this, arguments, function( elem ) { 10613 if ( this.parentNode ) { 10614 this.parentNode.insertBefore( elem, this ); 10615 } 10616 } ); 10617 }, 10618 10619 after: function() { 10620 return domManip( this, arguments, function( elem ) { 10621 if ( this.parentNode ) { 10622 this.parentNode.insertBefore( elem, this.nextSibling ); 10623 } 10624 } ); 10625 }, 10626 10627 empty: function() { 10628 var elem, 10629 i = 0; 10630 10631 for ( ; ( elem = this[ i ] ) != null; i++ ) { 10632 if ( elem.nodeType === 1 ) { 10633 10634 // Prevent memory leaks 10635 jQuery.cleanData( getAll( elem, false ) ); 10636 10637 // Remove any remaining nodes 10638 elem.textContent = ""; 10639 } 10640 } 10641 10642 return this; 10643 }, 10644 10645 clone: function( dataAndEvents, deepDataAndEvents ) { 10646 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 10647 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 10648 10649 return this.map( function() { 10650 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 10651 } ); 10652 }, 10653 10654 html: function( value ) { 10655 return access( this, function( value ) { 10656 var elem = this[ 0 ] || {}, 10657 i = 0, 10658 l = this.length; 10659 10660 if ( value === undefined && elem.nodeType === 1 ) { 10661 return elem.innerHTML; 10662 } 10663 10664 // See if we can take a shortcut and just use innerHTML 10665 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 10666 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 10667 10668 value = jQuery.htmlPrefilter( value ); 10669 10670 try { 10671 for ( ; i < l; i++ ) { 10672 elem = this[ i ] || {}; 10673 10674 // Remove element nodes and prevent memory leaks 10675 if ( elem.nodeType === 1 ) { 10676 jQuery.cleanData( getAll( elem, false ) ); 10677 elem.innerHTML = value; 10678 } 10679 } 10680 10681 elem = 0; 10682 10683 // If using innerHTML throws an exception, use the fallback method 10684 } catch ( e ) {} 10685 } 10686 10687 if ( elem ) { 10688 this.empty().append( value ); 10689 } 10690 }, null, value, arguments.length ); 10691 }, 10692 10693 replaceWith: function() { 10694 var ignored = []; 10695 10696 // Make the changes, replacing each non-ignored context element with the new content 10697 return domManip( this, arguments, function( elem ) { 10698 var parent = this.parentNode; 10699 10700 if ( jQuery.inArray( this, ignored ) < 0 ) { 10701 jQuery.cleanData( getAll( this ) ); 10702 if ( parent ) { 10703 parent.replaceChild( elem, this ); 10704 } 10705 } 10706 10707 // Force callback invocation 10708 }, ignored ); 10709 } 10710} ); 10711 10712jQuery.each( { 10713 appendTo: "append", 10714 prependTo: "prepend", 10715 insertBefore: "before", 10716 insertAfter: "after", 10717 replaceAll: "replaceWith" 10718}, function( name, original ) { 10719 jQuery.fn[ name ] = function( selector ) { 10720 var elems, 10721 ret = [], 10722 insert = jQuery( selector ), 10723 last = insert.length - 1, 10724 i = 0; 10725 10726 for ( ; i <= last; i++ ) { 10727 elems = i === last ? this : this.clone( true ); 10728 jQuery( insert[ i ] )[ original ]( elems ); 10729 10730 // Support: Android <=4.0 only, PhantomJS 1 only 10731 // .get() because push.apply(_, arraylike) throws on ancient WebKit 10732 push.apply( ret, elems.get() ); 10733 } 10734 10735 return this.pushStack( ret ); 10736 }; 10737} ); 10738var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 10739 10740var getStyles = function( elem ) { 10741 10742 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 10743 // IE throws on elements created in popups 10744 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 10745 var view = elem.ownerDocument.defaultView; 10746 10747 if ( !view || !view.opener ) { 10748 view = window; 10749 } 10750 10751 return view.getComputedStyle( elem ); 10752 }; 10753 10754var swap = function( elem, options, callback ) { 10755 var ret, name, 10756 old = {}; 10757 10758 // Remember the old values, and insert the new ones 10759 for ( name in options ) { 10760 old[ name ] = elem.style[ name ]; 10761 elem.style[ name ] = options[ name ]; 10762 } 10763 10764 ret = callback.call( elem ); 10765 10766 // Revert the old values 10767 for ( name in options ) { 10768 elem.style[ name ] = old[ name ]; 10769 } 10770 10771 return ret; 10772}; 10773 10774 10775var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 10776 10777 10778 10779( function() { 10780 10781 // Executing both pixelPosition & boxSizingReliable tests require only one layout 10782 // so they're executed at the same time to save the second computation. 10783 function computeStyleTests() { 10784 10785 // This is a singleton, we need to execute it only once 10786 if ( !div ) { 10787 return; 10788 } 10789 10790 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 10791 "margin-top:1px;padding:0;border:0"; 10792 div.style.cssText = 10793 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 10794 "margin:auto;border:1px;padding:1px;" + 10795 "width:60%;top:1%"; 10796 documentElement.appendChild( container ).appendChild( div ); 10797 10798 var divStyle = window.getComputedStyle( div ); 10799 pixelPositionVal = divStyle.top !== "1%"; 10800 10801 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 10802 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 10803 10804 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 10805 // Some styles come back with percentage values, even though they shouldn't 10806 div.style.right = "60%"; 10807 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 10808 10809 // Support: IE 9 - 11 only 10810 // Detect misreporting of content dimensions for box-sizing:border-box elements 10811 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 10812 10813 // Support: IE 9 only 10814 // Detect overflow:scroll screwiness (gh-3699) 10815 // Support: Chrome <=64 10816 // Don't get tricked when zoom affects offsetWidth (gh-4029) 10817 div.style.position = "absolute"; 10818 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 10819 10820 documentElement.removeChild( container ); 10821 10822 // Nullify the div so it wouldn't be stored in the memory and 10823 // it will also be a sign that checks already performed 10824 div = null; 10825 } 10826 10827 function roundPixelMeasures( measure ) { 10828 return Math.round( parseFloat( measure ) ); 10829 } 10830 10831 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 10832 reliableTrDimensionsVal, reliableMarginLeftVal, 10833 container = document.createElement( "div" ), 10834 div = document.createElement( "div" ); 10835 10836 // Finish early in limited (non-browser) environments 10837 if ( !div.style ) { 10838 return; 10839 } 10840 10841 // Support: IE <=9 - 11 only 10842 // Style of cloned element affects source element cloned (#8908) 10843 div.style.backgroundClip = "content-box"; 10844 div.cloneNode( true ).style.backgroundClip = ""; 10845 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 10846 10847 jQuery.extend( support, { 10848 boxSizingReliable: function() { 10849 computeStyleTests(); 10850 return boxSizingReliableVal; 10851 }, 10852 pixelBoxStyles: function() { 10853 computeStyleTests(); 10854 return pixelBoxStylesVal; 10855 }, 10856 pixelPosition: function() { 10857 computeStyleTests(); 10858 return pixelPositionVal; 10859 }, 10860 reliableMarginLeft: function() { 10861 computeStyleTests(); 10862 return reliableMarginLeftVal; 10863 }, 10864 scrollboxSize: function() { 10865 computeStyleTests(); 10866 return scrollboxSizeVal; 10867 }, 10868 10869 // Support: IE 9 - 11+, Edge 15 - 18+ 10870 // IE/Edge misreport `getComputedStyle` of table rows with width/height 10871 // set in CSS while `offset*` properties report correct values. 10872 // Behavior in IE 9 is more subtle than in newer versions & it passes 10873 // some versions of this test; make sure not to make it pass there! 10874 // 10875 // Support: Firefox 70+ 10876 // Only Firefox includes border widths 10877 // in computed dimensions. (gh-4529) 10878 reliableTrDimensions: function() { 10879 var table, tr, trChild, trStyle; 10880 if ( reliableTrDimensionsVal == null ) { 10881 table = document.createElement( "table" ); 10882 tr = document.createElement( "tr" ); 10883 trChild = document.createElement( "div" ); 10884 10885 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 10886 tr.style.cssText = "border:1px solid"; 10887 10888 // Support: Chrome 86+ 10889 // Height set through cssText does not get applied. 10890 // Computed height then comes back as 0. 10891 tr.style.height = "1px"; 10892 trChild.style.height = "9px"; 10893 10894 // Support: Android 8 Chrome 86+ 10895 // In our bodyBackground.html iframe, 10896 // display for all div elements is set to "inline", 10897 // which causes a problem only in Android 8 Chrome 86. 10898 // Ensuring the div is display: block 10899 // gets around this issue. 10900 trChild.style.display = "block"; 10901 10902 documentElement 10903 .appendChild( table ) 10904 .appendChild( tr ) 10905 .appendChild( trChild ); 10906 10907 trStyle = window.getComputedStyle( tr ); 10908 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 10909 parseInt( trStyle.borderTopWidth, 10 ) + 10910 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 10911 10912 documentElement.removeChild( table ); 10913 } 10914 return reliableTrDimensionsVal; 10915 } 10916 } ); 10917} )(); 10918 10919 10920function curCSS( elem, name, computed ) { 10921 var width, minWidth, maxWidth, ret, 10922 10923 // Support: Firefox 51+ 10924 // Retrieving style before computed somehow 10925 // fixes an issue with getting wrong values 10926 // on detached elements 10927 style = elem.style; 10928 10929 computed = computed || getStyles( elem ); 10930 10931 // getPropertyValue is needed for: 10932 // .css('filter') (IE 9 only, #12537) 10933 // .css('--customProperty) (#3144) 10934 if ( computed ) { 10935 ret = computed.getPropertyValue( name ) || computed[ name ]; 10936 10937 if ( ret === "" && !isAttached( elem ) ) { 10938 ret = jQuery.style( elem, name ); 10939 } 10940 10941 // A tribute to the "awesome hack by Dean Edwards" 10942 // Android Browser returns percentage for some values, 10943 // but width seems to be reliably pixels. 10944 // This is against the CSSOM draft spec: 10945 // https://drafts.csswg.org/cssom/#resolved-values 10946 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 10947 10948 // Remember the original values 10949 width = style.width; 10950 minWidth = style.minWidth; 10951 maxWidth = style.maxWidth; 10952 10953 // Put in the new values to get a computed value out 10954 style.minWidth = style.maxWidth = style.width = ret; 10955 ret = computed.width; 10956 10957 // Revert the changed values 10958 style.width = width; 10959 style.minWidth = minWidth; 10960 style.maxWidth = maxWidth; 10961 } 10962 } 10963 10964 return ret !== undefined ? 10965 10966 // Support: IE <=9 - 11 only 10967 // IE returns zIndex value as an integer. 10968 ret + "" : 10969 ret; 10970} 10971 10972 10973function addGetHookIf( conditionFn, hookFn ) { 10974 10975 // Define the hook, we'll check on the first run if it's really needed. 10976 return { 10977 get: function() { 10978 if ( conditionFn() ) { 10979 10980 // Hook not needed (or it's not possible to use it due 10981 // to missing dependency), remove it. 10982 delete this.get; 10983 return; 10984 } 10985 10986 // Hook needed; redefine it so that the support test is not executed again. 10987 return ( this.get = hookFn ).apply( this, arguments ); 10988 } 10989 }; 10990} 10991 10992 10993var cssPrefixes = [ "Webkit", "Moz", "ms" ], 10994 emptyStyle = document.createElement( "div" ).style, 10995 vendorProps = {}; 10996 10997// Return a vendor-prefixed property or undefined 10998function vendorPropName( name ) { 10999 11000 // Check for vendor prefixed names 11001 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 11002 i = cssPrefixes.length; 11003 11004 while ( i-- ) { 11005 name = cssPrefixes[ i ] + capName; 11006 if ( name in emptyStyle ) { 11007 return name; 11008 } 11009 } 11010} 11011 11012// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 11013function finalPropName( name ) { 11014 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 11015 11016 if ( final ) { 11017 return final; 11018 } 11019 if ( name in emptyStyle ) { 11020 return name; 11021 } 11022 return vendorProps[ name ] = vendorPropName( name ) || name; 11023} 11024 11025 11026var 11027 11028 // Swappable if display is none or starts with table 11029 // except "table", "table-cell", or "table-caption" 11030 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 11031 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 11032 rcustomProp = /^--/, 11033 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 11034 cssNormalTransform = { 11035 letterSpacing: "0", 11036 fontWeight: "400" 11037 }; 11038 11039function setPositiveNumber( _elem, value, subtract ) { 11040 11041 // Any relative (+/-) values have already been 11042 // normalized at this point 11043 var matches = rcssNum.exec( value ); 11044 return matches ? 11045 11046 // Guard against undefined "subtract", e.g., when used as in cssHooks 11047 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 11048 value; 11049} 11050 11051function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 11052 var i = dimension === "width" ? 1 : 0, 11053 extra = 0, 11054 delta = 0; 11055 11056 // Adjustment may not be necessary 11057 if ( box === ( isBorderBox ? "border" : "content" ) ) { 11058 return 0; 11059 } 11060 11061 for ( ; i < 4; i += 2 ) { 11062 11063 // Both box models exclude margin 11064 if ( box === "margin" ) { 11065 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 11066 } 11067 11068 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 11069 if ( !isBorderBox ) { 11070 11071 // Add padding 11072 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 11073 11074 // For "border" or "margin", add border 11075 if ( box !== "padding" ) { 11076 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 11077 11078 // But still keep track of it otherwise 11079 } else { 11080 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 11081 } 11082 11083 // If we get here with a border-box (content + padding + border), we're seeking "content" or 11084 // "padding" or "margin" 11085 } else { 11086 11087 // For "content", subtract padding 11088 if ( box === "content" ) { 11089 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 11090 } 11091 11092 // For "content" or "padding", subtract border 11093 if ( box !== "margin" ) { 11094 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 11095 } 11096 } 11097 } 11098 11099 // Account for positive content-box scroll gutter when requested by providing computedVal 11100 if ( !isBorderBox && computedVal >= 0 ) { 11101 11102 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 11103 // Assuming integer scroll gutter, subtract the rest and round down 11104 delta += Math.max( 0, Math.ceil( 11105 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 11106 computedVal - 11107 delta - 11108 extra - 11109 0.5 11110 11111 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 11112 // Use an explicit zero to avoid NaN (gh-3964) 11113 ) ) || 0; 11114 } 11115 11116 return delta; 11117} 11118 11119function getWidthOrHeight( elem, dimension, extra ) { 11120 11121 // Start with computed style 11122 var styles = getStyles( elem ), 11123 11124 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 11125 // Fake content-box until we know it's needed to know the true value. 11126 boxSizingNeeded = !support.boxSizingReliable() || extra, 11127 isBorderBox = boxSizingNeeded && 11128 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 11129 valueIsBorderBox = isBorderBox, 11130 11131 val = curCSS( elem, dimension, styles ), 11132 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 11133 11134 // Support: Firefox <=54 11135 // Return a confounding non-pixel value or feign ignorance, as appropriate. 11136 if ( rnumnonpx.test( val ) ) { 11137 if ( !extra ) { 11138 return val; 11139 } 11140 val = "auto"; 11141 } 11142 11143 11144 // Support: IE 9 - 11 only 11145 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 11146 // In those cases, the computed value can be trusted to be border-box. 11147 if ( ( !support.boxSizingReliable() && isBorderBox || 11148 11149 // Support: IE 10 - 11+, Edge 15 - 18+ 11150 // IE/Edge misreport `getComputedStyle` of table rows with width/height 11151 // set in CSS while `offset*` properties report correct values. 11152 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 11153 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 11154 11155 // Fall back to offsetWidth/offsetHeight when value is "auto" 11156 // This happens for inline elements with no explicit setting (gh-3571) 11157 val === "auto" || 11158 11159 // Support: Android <=4.1 - 4.3 only 11160 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 11161 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 11162 11163 // Make sure the element is visible & connected 11164 elem.getClientRects().length ) { 11165 11166 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 11167 11168 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 11169 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 11170 // retrieved value as a content box dimension. 11171 valueIsBorderBox = offsetProp in elem; 11172 if ( valueIsBorderBox ) { 11173 val = elem[ offsetProp ]; 11174 } 11175 } 11176 11177 // Normalize "" and auto 11178 val = parseFloat( val ) || 0; 11179 11180 // Adjust for the element's box model 11181 return ( val + 11182 boxModelAdjustment( 11183 elem, 11184 dimension, 11185 extra || ( isBorderBox ? "border" : "content" ), 11186 valueIsBorderBox, 11187 styles, 11188 11189 // Provide the current computed size to request scroll gutter calculation (gh-3589) 11190 val 11191 ) 11192 ) + "px"; 11193} 11194 11195jQuery.extend( { 11196 11197 // Add in style property hooks for overriding the default 11198 // behavior of getting and setting a style property 11199 cssHooks: { 11200 opacity: { 11201 get: function( elem, computed ) { 11202 if ( computed ) { 11203 11204 // We should always get a number back from opacity 11205 var ret = curCSS( elem, "opacity" ); 11206 return ret === "" ? "1" : ret; 11207 } 11208 } 11209 } 11210 }, 11211 11212 // Don't automatically add "px" to these possibly-unitless properties 11213 cssNumber: { 11214 "animationIterationCount": true, 11215 "columnCount": true, 11216 "fillOpacity": true, 11217 "flexGrow": true, 11218 "flexShrink": true, 11219 "fontWeight": true, 11220 "gridArea": true, 11221 "gridColumn": true, 11222 "gridColumnEnd": true, 11223 "gridColumnStart": true, 11224 "gridRow": true, 11225 "gridRowEnd": true, 11226 "gridRowStart": true, 11227 "lineHeight": true, 11228 "opacity": true, 11229 "order": true, 11230 "orphans": true, 11231 "widows": true, 11232 "zIndex": true, 11233 "zoom": true 11234 }, 11235 11236 // Add in properties whose names you wish to fix before 11237 // setting or getting the value 11238 cssProps: {}, 11239 11240 // Get and set the style property on a DOM Node 11241 style: function( elem, name, value, extra ) { 11242 11243 // Don't set styles on text and comment nodes 11244 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 11245 return; 11246 } 11247 11248 // Make sure that we're working with the right name 11249 var ret, type, hooks, 11250 origName = camelCase( name ), 11251 isCustomProp = rcustomProp.test( name ), 11252 style = elem.style; 11253 11254 // Make sure that we're working with the right name. We don't 11255 // want to query the value if it is a CSS custom property 11256 // since they are user-defined. 11257 if ( !isCustomProp ) { 11258 name = finalPropName( origName ); 11259 } 11260 11261 // Gets hook for the prefixed version, then unprefixed version 11262 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 11263 11264 // Check if we're setting a value 11265 if ( value !== undefined ) { 11266 type = typeof value; 11267 11268 // Convert "+=" or "-=" to relative numbers (#7345) 11269 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 11270 value = adjustCSS( elem, name, ret ); 11271 11272 // Fixes bug #9237 11273 type = "number"; 11274 } 11275 11276 // Make sure that null and NaN values aren't set (#7116) 11277 if ( value == null || value !== value ) { 11278 return; 11279 } 11280 11281 // If a number was passed in, add the unit (except for certain CSS properties) 11282 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 11283 // "px" to a few hardcoded values. 11284 if ( type === "number" && !isCustomProp ) { 11285 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 11286 } 11287 11288 // background-* props affect original clone's values 11289 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 11290 style[ name ] = "inherit"; 11291 } 11292 11293 // If a hook was provided, use that value, otherwise just set the specified value 11294 if ( !hooks || !( "set" in hooks ) || 11295 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 11296 11297 if ( isCustomProp ) { 11298 style.setProperty( name, value ); 11299 } else { 11300 style[ name ] = value; 11301 } 11302 } 11303 11304 } else { 11305 11306 // If a hook was provided get the non-computed value from there 11307 if ( hooks && "get" in hooks && 11308 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 11309 11310 return ret; 11311 } 11312 11313 // Otherwise just get the value from the style object 11314 return style[ name ]; 11315 } 11316 }, 11317 11318 css: function( elem, name, extra, styles ) { 11319 var val, num, hooks, 11320 origName = camelCase( name ), 11321 isCustomProp = rcustomProp.test( name ); 11322 11323 // Make sure that we're working with the right name. We don't 11324 // want to modify the value if it is a CSS custom property 11325 // since they are user-defined. 11326 if ( !isCustomProp ) { 11327 name = finalPropName( origName ); 11328 } 11329 11330 // Try prefixed name followed by the unprefixed name 11331 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 11332 11333 // If a hook was provided get the computed value from there 11334 if ( hooks && "get" in hooks ) { 11335 val = hooks.get( elem, true, extra ); 11336 } 11337 11338 // Otherwise, if a way to get the computed value exists, use that 11339 if ( val === undefined ) { 11340 val = curCSS( elem, name, styles ); 11341 } 11342 11343 // Convert "normal" to computed value 11344 if ( val === "normal" && name in cssNormalTransform ) { 11345 val = cssNormalTransform[ name ]; 11346 } 11347 11348 // Make numeric if forced or a qualifier was provided and val looks numeric 11349 if ( extra === "" || extra ) { 11350 num = parseFloat( val ); 11351 return extra === true || isFinite( num ) ? num || 0 : val; 11352 } 11353 11354 return val; 11355 } 11356} ); 11357 11358jQuery.each( [ "height", "width" ], function( _i, dimension ) { 11359 jQuery.cssHooks[ dimension ] = { 11360 get: function( elem, computed, extra ) { 11361 if ( computed ) { 11362 11363 // Certain elements can have dimension info if we invisibly show them 11364 // but it must have a current display style that would benefit 11365 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 11366 11367 // Support: Safari 8+ 11368 // Table columns in Safari have non-zero offsetWidth & zero 11369 // getBoundingClientRect().width unless display is changed. 11370 // Support: IE <=11 only 11371 // Running getBoundingClientRect on a disconnected node 11372 // in IE throws an error. 11373 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 11374 swap( elem, cssShow, function() { 11375 return getWidthOrHeight( elem, dimension, extra ); 11376 } ) : 11377 getWidthOrHeight( elem, dimension, extra ); 11378 } 11379 }, 11380 11381 set: function( elem, value, extra ) { 11382 var matches, 11383 styles = getStyles( elem ), 11384 11385 // Only read styles.position if the test has a chance to fail 11386 // to avoid forcing a reflow. 11387 scrollboxSizeBuggy = !support.scrollboxSize() && 11388 styles.position === "absolute", 11389 11390 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 11391 boxSizingNeeded = scrollboxSizeBuggy || extra, 11392 isBorderBox = boxSizingNeeded && 11393 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 11394 subtract = extra ? 11395 boxModelAdjustment( 11396 elem, 11397 dimension, 11398 extra, 11399 isBorderBox, 11400 styles 11401 ) : 11402 0; 11403 11404 // Account for unreliable border-box dimensions by comparing offset* to computed and 11405 // faking a content-box to get border and padding (gh-3699) 11406 if ( isBorderBox && scrollboxSizeBuggy ) { 11407 subtract -= Math.ceil( 11408 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 11409 parseFloat( styles[ dimension ] ) - 11410 boxModelAdjustment( elem, dimension, "border", false, styles ) - 11411 0.5 11412 ); 11413 } 11414 11415 // Convert to pixels if value adjustment is needed 11416 if ( subtract && ( matches = rcssNum.exec( value ) ) && 11417 ( matches[ 3 ] || "px" ) !== "px" ) { 11418 11419 elem.style[ dimension ] = value; 11420 value = jQuery.css( elem, dimension ); 11421 } 11422 11423 return setPositiveNumber( elem, value, subtract ); 11424 } 11425 }; 11426} ); 11427 11428jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 11429 function( elem, computed ) { 11430 if ( computed ) { 11431 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 11432 elem.getBoundingClientRect().left - 11433 swap( elem, { marginLeft: 0 }, function() { 11434 return elem.getBoundingClientRect().left; 11435 } ) 11436 ) + "px"; 11437 } 11438 } 11439); 11440 11441// These hooks are used by animate to expand properties 11442jQuery.each( { 11443 margin: "", 11444 padding: "", 11445 border: "Width" 11446}, function( prefix, suffix ) { 11447 jQuery.cssHooks[ prefix + suffix ] = { 11448 expand: function( value ) { 11449 var i = 0, 11450 expanded = {}, 11451 11452 // Assumes a single number if not a string 11453 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 11454 11455 for ( ; i < 4; i++ ) { 11456 expanded[ prefix + cssExpand[ i ] + suffix ] = 11457 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 11458 } 11459 11460 return expanded; 11461 } 11462 }; 11463 11464 if ( prefix !== "margin" ) { 11465 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 11466 } 11467} ); 11468 11469jQuery.fn.extend( { 11470 css: function( name, value ) { 11471 return access( this, function( elem, name, value ) { 11472 var styles, len, 11473 map = {}, 11474 i = 0; 11475 11476 if ( Array.isArray( name ) ) { 11477 styles = getStyles( elem ); 11478 len = name.length; 11479 11480 for ( ; i < len; i++ ) { 11481 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 11482 } 11483 11484 return map; 11485 } 11486 11487 return value !== undefined ? 11488 jQuery.style( elem, name, value ) : 11489 jQuery.css( elem, name ); 11490 }, name, value, arguments.length > 1 ); 11491 } 11492} ); 11493 11494 11495function Tween( elem, options, prop, end, easing ) { 11496 return new Tween.prototype.init( elem, options, prop, end, easing ); 11497} 11498jQuery.Tween = Tween; 11499 11500Tween.prototype = { 11501 constructor: Tween, 11502 init: function( elem, options, prop, end, easing, unit ) { 11503 this.elem = elem; 11504 this.prop = prop; 11505 this.easing = easing || jQuery.easing._default; 11506 this.options = options; 11507 this.start = this.now = this.cur(); 11508 this.end = end; 11509 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 11510 }, 11511 cur: function() { 11512 var hooks = Tween.propHooks[ this.prop ]; 11513 11514 return hooks && hooks.get ? 11515 hooks.get( this ) : 11516 Tween.propHooks._default.get( this ); 11517 }, 11518 run: function( percent ) { 11519 var eased, 11520 hooks = Tween.propHooks[ this.prop ]; 11521 11522 if ( this.options.duration ) { 11523 this.pos = eased = jQuery.easing[ this.easing ]( 11524 percent, this.options.duration * percent, 0, 1, this.options.duration 11525 ); 11526 } else { 11527 this.pos = eased = percent; 11528 } 11529 this.now = ( this.end - this.start ) * eased + this.start; 11530 11531 if ( this.options.step ) { 11532 this.options.step.call( this.elem, this.now, this ); 11533 } 11534 11535 if ( hooks && hooks.set ) { 11536 hooks.set( this ); 11537 } else { 11538 Tween.propHooks._default.set( this ); 11539 } 11540 return this; 11541 } 11542}; 11543 11544Tween.prototype.init.prototype = Tween.prototype; 11545 11546Tween.propHooks = { 11547 _default: { 11548 get: function( tween ) { 11549 var result; 11550 11551 // Use a property on the element directly when it is not a DOM element, 11552 // or when there is no matching style property that exists. 11553 if ( tween.elem.nodeType !== 1 || 11554 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 11555 return tween.elem[ tween.prop ]; 11556 } 11557 11558 // Passing an empty string as a 3rd parameter to .css will automatically 11559 // attempt a parseFloat and fallback to a string if the parse fails. 11560 // Simple values such as "10px" are parsed to Float; 11561 // complex values such as "rotate(1rad)" are returned as-is. 11562 result = jQuery.css( tween.elem, tween.prop, "" ); 11563 11564 // Empty strings, null, undefined and "auto" are converted to 0. 11565 return !result || result === "auto" ? 0 : result; 11566 }, 11567 set: function( tween ) { 11568 11569 // Use step hook for back compat. 11570 // Use cssHook if its there. 11571 // Use .style if available and use plain properties where available. 11572 if ( jQuery.fx.step[ tween.prop ] ) { 11573 jQuery.fx.step[ tween.prop ]( tween ); 11574 } else if ( tween.elem.nodeType === 1 && ( 11575 jQuery.cssHooks[ tween.prop ] || 11576 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 11577 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 11578 } else { 11579 tween.elem[ tween.prop ] = tween.now; 11580 } 11581 } 11582 } 11583}; 11584 11585// Support: IE <=9 only 11586// Panic based approach to setting things on disconnected nodes 11587Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 11588 set: function( tween ) { 11589 if ( tween.elem.nodeType && tween.elem.parentNode ) { 11590 tween.elem[ tween.prop ] = tween.now; 11591 } 11592 } 11593}; 11594 11595jQuery.easing = { 11596 linear: function( p ) { 11597 return p; 11598 }, 11599 swing: function( p ) { 11600 return 0.5 - Math.cos( p * Math.PI ) / 2; 11601 }, 11602 _default: "swing" 11603}; 11604 11605jQuery.fx = Tween.prototype.init; 11606 11607// Back compat <1.8 extension point 11608jQuery.fx.step = {}; 11609 11610 11611 11612 11613var 11614 fxNow, inProgress, 11615 rfxtypes = /^(?:toggle|show|hide)$/, 11616 rrun = /queueHooks$/; 11617 11618function schedule() { 11619 if ( inProgress ) { 11620 if ( document.hidden === false && window.requestAnimationFrame ) { 11621 window.requestAnimationFrame( schedule ); 11622 } else { 11623 window.setTimeout( schedule, jQuery.fx.interval ); 11624 } 11625 11626 jQuery.fx.tick(); 11627 } 11628} 11629 11630// Animations created synchronously will run synchronously 11631function createFxNow() { 11632 window.setTimeout( function() { 11633 fxNow = undefined; 11634 } ); 11635 return ( fxNow = Date.now() ); 11636} 11637 11638// Generate parameters to create a standard animation 11639function genFx( type, includeWidth ) { 11640 var which, 11641 i = 0, 11642 attrs = { height: type }; 11643 11644 // If we include width, step value is 1 to do all cssExpand values, 11645 // otherwise step value is 2 to skip over Left and Right 11646 includeWidth = includeWidth ? 1 : 0; 11647 for ( ; i < 4; i += 2 - includeWidth ) { 11648 which = cssExpand[ i ]; 11649 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 11650 } 11651 11652 if ( includeWidth ) { 11653 attrs.opacity = attrs.width = type; 11654 } 11655 11656 return attrs; 11657} 11658 11659function createTween( value, prop, animation ) { 11660 var tween, 11661 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 11662 index = 0, 11663 length = collection.length; 11664 for ( ; index < length; index++ ) { 11665 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 11666 11667 // We're done with this property 11668 return tween; 11669 } 11670 } 11671} 11672 11673function defaultPrefilter( elem, props, opts ) { 11674 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 11675 isBox = "width" in props || "height" in props, 11676 anim = this, 11677 orig = {}, 11678 style = elem.style, 11679 hidden = elem.nodeType && isHiddenWithinTree( elem ), 11680 dataShow = dataPriv.get( elem, "fxshow" ); 11681 11682 // Queue-skipping animations hijack the fx hooks 11683 if ( !opts.queue ) { 11684 hooks = jQuery._queueHooks( elem, "fx" ); 11685 if ( hooks.unqueued == null ) { 11686 hooks.unqueued = 0; 11687 oldfire = hooks.empty.fire; 11688 hooks.empty.fire = function() { 11689 if ( !hooks.unqueued ) { 11690 oldfire(); 11691 } 11692 }; 11693 } 11694 hooks.unqueued++; 11695 11696 anim.always( function() { 11697 11698 // Ensure the complete handler is called before this completes 11699 anim.always( function() { 11700 hooks.unqueued--; 11701 if ( !jQuery.queue( elem, "fx" ).length ) { 11702 hooks.empty.fire(); 11703 } 11704 } ); 11705 } ); 11706 } 11707 11708 // Detect show/hide animations 11709 for ( prop in props ) { 11710 value = props[ prop ]; 11711 if ( rfxtypes.test( value ) ) { 11712 delete props[ prop ]; 11713 toggle = toggle || value === "toggle"; 11714 if ( value === ( hidden ? "hide" : "show" ) ) { 11715 11716 // Pretend to be hidden if this is a "show" and 11717 // there is still data from a stopped show/hide 11718 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 11719 hidden = true; 11720 11721 // Ignore all other no-op show/hide data 11722 } else { 11723 continue; 11724 } 11725 } 11726 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 11727 } 11728 } 11729 11730 // Bail out if this is a no-op like .hide().hide() 11731 propTween = !jQuery.isEmptyObject( props ); 11732 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 11733 return; 11734 } 11735 11736 // Restrict "overflow" and "display" styles during box animations 11737 if ( isBox && elem.nodeType === 1 ) { 11738 11739 // Support: IE <=9 - 11, Edge 12 - 15 11740 // Record all 3 overflow attributes because IE does not infer the shorthand 11741 // from identically-valued overflowX and overflowY and Edge just mirrors 11742 // the overflowX value there. 11743 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 11744 11745 // Identify a display type, preferring old show/hide data over the CSS cascade 11746 restoreDisplay = dataShow && dataShow.display; 11747 if ( restoreDisplay == null ) { 11748 restoreDisplay = dataPriv.get( elem, "display" ); 11749 } 11750 display = jQuery.css( elem, "display" ); 11751 if ( display === "none" ) { 11752 if ( restoreDisplay ) { 11753 display = restoreDisplay; 11754 } else { 11755 11756 // Get nonempty value(s) by temporarily forcing visibility 11757 showHide( [ elem ], true ); 11758 restoreDisplay = elem.style.display || restoreDisplay; 11759 display = jQuery.css( elem, "display" ); 11760 showHide( [ elem ] ); 11761 } 11762 } 11763 11764 // Animate inline elements as inline-block 11765 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 11766 if ( jQuery.css( elem, "float" ) === "none" ) { 11767 11768 // Restore the original display value at the end of pure show/hide animations 11769 if ( !propTween ) { 11770 anim.done( function() { 11771 style.display = restoreDisplay; 11772 } ); 11773 if ( restoreDisplay == null ) { 11774 display = style.display; 11775 restoreDisplay = display === "none" ? "" : display; 11776 } 11777 } 11778 style.display = "inline-block"; 11779 } 11780 } 11781 } 11782 11783 if ( opts.overflow ) { 11784 style.overflow = "hidden"; 11785 anim.always( function() { 11786 style.overflow = opts.overflow[ 0 ]; 11787 style.overflowX = opts.overflow[ 1 ]; 11788 style.overflowY = opts.overflow[ 2 ]; 11789 } ); 11790 } 11791 11792 // Implement show/hide animations 11793 propTween = false; 11794 for ( prop in orig ) { 11795 11796 // General show/hide setup for this element animation 11797 if ( !propTween ) { 11798 if ( dataShow ) { 11799 if ( "hidden" in dataShow ) { 11800 hidden = dataShow.hidden; 11801 } 11802 } else { 11803 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 11804 } 11805 11806 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 11807 if ( toggle ) { 11808 dataShow.hidden = !hidden; 11809 } 11810 11811 // Show elements before animating them 11812 if ( hidden ) { 11813 showHide( [ elem ], true ); 11814 } 11815 11816 /* eslint-disable no-loop-func */ 11817 11818 anim.done( function() { 11819 11820 /* eslint-enable no-loop-func */ 11821 11822 // The final step of a "hide" animation is actually hiding the element 11823 if ( !hidden ) { 11824 showHide( [ elem ] ); 11825 } 11826 dataPriv.remove( elem, "fxshow" ); 11827 for ( prop in orig ) { 11828 jQuery.style( elem, prop, orig[ prop ] ); 11829 } 11830 } ); 11831 } 11832 11833 // Per-property setup 11834 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 11835 if ( !( prop in dataShow ) ) { 11836 dataShow[ prop ] = propTween.start; 11837 if ( hidden ) { 11838 propTween.end = propTween.start; 11839 propTween.start = 0; 11840 } 11841 } 11842 } 11843} 11844 11845function propFilter( props, specialEasing ) { 11846 var index, name, easing, value, hooks; 11847 11848 // camelCase, specialEasing and expand cssHook pass 11849 for ( index in props ) { 11850 name = camelCase( index ); 11851 easing = specialEasing[ name ]; 11852 value = props[ index ]; 11853 if ( Array.isArray( value ) ) { 11854 easing = value[ 1 ]; 11855 value = props[ index ] = value[ 0 ]; 11856 } 11857 11858 if ( index !== name ) { 11859 props[ name ] = value; 11860 delete props[ index ]; 11861 } 11862 11863 hooks = jQuery.cssHooks[ name ]; 11864 if ( hooks && "expand" in hooks ) { 11865 value = hooks.expand( value ); 11866 delete props[ name ]; 11867 11868 // Not quite $.extend, this won't overwrite existing keys. 11869 // Reusing 'index' because we have the correct "name" 11870 for ( index in value ) { 11871 if ( !( index in props ) ) { 11872 props[ index ] = value[ index ]; 11873 specialEasing[ index ] = easing; 11874 } 11875 } 11876 } else { 11877 specialEasing[ name ] = easing; 11878 } 11879 } 11880} 11881 11882function Animation( elem, properties, options ) { 11883 var result, 11884 stopped, 11885 index = 0, 11886 length = Animation.prefilters.length, 11887 deferred = jQuery.Deferred().always( function() { 11888 11889 // Don't match elem in the :animated selector 11890 delete tick.elem; 11891 } ), 11892 tick = function() { 11893 if ( stopped ) { 11894 return false; 11895 } 11896 var currentTime = fxNow || createFxNow(), 11897 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 11898 11899 // Support: Android 2.3 only 11900 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 11901 temp = remaining / animation.duration || 0, 11902 percent = 1 - temp, 11903 index = 0, 11904 length = animation.tweens.length; 11905 11906 for ( ; index < length; index++ ) { 11907 animation.tweens[ index ].run( percent ); 11908 } 11909 11910 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 11911 11912 // If there's more to do, yield 11913 if ( percent < 1 && length ) { 11914 return remaining; 11915 } 11916 11917 // If this was an empty animation, synthesize a final progress notification 11918 if ( !length ) { 11919 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 11920 } 11921 11922 // Resolve the animation and report its conclusion 11923 deferred.resolveWith( elem, [ animation ] ); 11924 return false; 11925 }, 11926 animation = deferred.promise( { 11927 elem: elem, 11928 props: jQuery.extend( {}, properties ), 11929 opts: jQuery.extend( true, { 11930 specialEasing: {}, 11931 easing: jQuery.easing._default 11932 }, options ), 11933 originalProperties: properties, 11934 originalOptions: options, 11935 startTime: fxNow || createFxNow(), 11936 duration: options.duration, 11937 tweens: [], 11938 createTween: function( prop, end ) { 11939 var tween = jQuery.Tween( elem, animation.opts, prop, end, 11940 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 11941 animation.tweens.push( tween ); 11942 return tween; 11943 }, 11944 stop: function( gotoEnd ) { 11945 var index = 0, 11946 11947 // If we are going to the end, we want to run all the tweens 11948 // otherwise we skip this part 11949 length = gotoEnd ? animation.tweens.length : 0; 11950 if ( stopped ) { 11951 return this; 11952 } 11953 stopped = true; 11954 for ( ; index < length; index++ ) { 11955 animation.tweens[ index ].run( 1 ); 11956 } 11957 11958 // Resolve when we played the last frame; otherwise, reject 11959 if ( gotoEnd ) { 11960 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 11961 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 11962 } else { 11963 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 11964 } 11965 return this; 11966 } 11967 } ), 11968 props = animation.props; 11969 11970 propFilter( props, animation.opts.specialEasing ); 11971 11972 for ( ; index < length; index++ ) { 11973 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 11974 if ( result ) { 11975 if ( isFunction( result.stop ) ) { 11976 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 11977 result.stop.bind( result ); 11978 } 11979 return result; 11980 } 11981 } 11982 11983 jQuery.map( props, createTween, animation ); 11984 11985 if ( isFunction( animation.opts.start ) ) { 11986 animation.opts.start.call( elem, animation ); 11987 } 11988 11989 // Attach callbacks from options 11990 animation 11991 .progress( animation.opts.progress ) 11992 .done( animation.opts.done, animation.opts.complete ) 11993 .fail( animation.opts.fail ) 11994 .always( animation.opts.always ); 11995 11996 jQuery.fx.timer( 11997 jQuery.extend( tick, { 11998 elem: elem, 11999 anim: animation, 12000 queue: animation.opts.queue 12001 } ) 12002 ); 12003 12004 return animation; 12005} 12006 12007jQuery.Animation = jQuery.extend( Animation, { 12008 12009 tweeners: { 12010 "*": [ function( prop, value ) { 12011 var tween = this.createTween( prop, value ); 12012 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 12013 return tween; 12014 } ] 12015 }, 12016 12017 tweener: function( props, callback ) { 12018 if ( isFunction( props ) ) { 12019 callback = props; 12020 props = [ "*" ]; 12021 } else { 12022 props = props.match( rnothtmlwhite ); 12023 } 12024 12025 var prop, 12026 index = 0, 12027 length = props.length; 12028 12029 for ( ; index < length; index++ ) { 12030 prop = props[ index ]; 12031 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 12032 Animation.tweeners[ prop ].unshift( callback ); 12033 } 12034 }, 12035 12036 prefilters: [ defaultPrefilter ], 12037 12038 prefilter: function( callback, prepend ) { 12039 if ( prepend ) { 12040 Animation.prefilters.unshift( callback ); 12041 } else { 12042 Animation.prefilters.push( callback ); 12043 } 12044 } 12045} ); 12046 12047jQuery.speed = function( speed, easing, fn ) { 12048 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 12049 complete: fn || !fn && easing || 12050 isFunction( speed ) && speed, 12051 duration: speed, 12052 easing: fn && easing || easing && !isFunction( easing ) && easing 12053 }; 12054 12055 // Go to the end state if fx are off 12056 if ( jQuery.fx.off ) { 12057 opt.duration = 0; 12058 12059 } else { 12060 if ( typeof opt.duration !== "number" ) { 12061 if ( opt.duration in jQuery.fx.speeds ) { 12062 opt.duration = jQuery.fx.speeds[ opt.duration ]; 12063 12064 } else { 12065 opt.duration = jQuery.fx.speeds._default; 12066 } 12067 } 12068 } 12069 12070 // Normalize opt.queue - true/undefined/null -> "fx" 12071 if ( opt.queue == null || opt.queue === true ) { 12072 opt.queue = "fx"; 12073 } 12074 12075 // Queueing 12076 opt.old = opt.complete; 12077 12078 opt.complete = function() { 12079 if ( isFunction( opt.old ) ) { 12080 opt.old.call( this ); 12081 } 12082 12083 if ( opt.queue ) { 12084 jQuery.dequeue( this, opt.queue ); 12085 } 12086 }; 12087 12088 return opt; 12089}; 12090 12091jQuery.fn.extend( { 12092 fadeTo: function( speed, to, easing, callback ) { 12093 12094 // Show any hidden elements after setting opacity to 0 12095 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 12096 12097 // Animate to the value specified 12098 .end().animate( { opacity: to }, speed, easing, callback ); 12099 }, 12100 animate: function( prop, speed, easing, callback ) { 12101 var empty = jQuery.isEmptyObject( prop ), 12102 optall = jQuery.speed( speed, easing, callback ), 12103 doAnimation = function() { 12104 12105 // Operate on a copy of prop so per-property easing won't be lost 12106 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 12107 12108 // Empty animations, or finishing resolves immediately 12109 if ( empty || dataPriv.get( this, "finish" ) ) { 12110 anim.stop( true ); 12111 } 12112 }; 12113 12114 doAnimation.finish = doAnimation; 12115 12116 return empty || optall.queue === false ? 12117 this.each( doAnimation ) : 12118 this.queue( optall.queue, doAnimation ); 12119 }, 12120 stop: function( type, clearQueue, gotoEnd ) { 12121 var stopQueue = function( hooks ) { 12122 var stop = hooks.stop; 12123 delete hooks.stop; 12124 stop( gotoEnd ); 12125 }; 12126 12127 if ( typeof type !== "string" ) { 12128 gotoEnd = clearQueue; 12129 clearQueue = type; 12130 type = undefined; 12131 } 12132 if ( clearQueue ) { 12133 this.queue( type || "fx", [] ); 12134 } 12135 12136 return this.each( function() { 12137 var dequeue = true, 12138 index = type != null && type + "queueHooks", 12139 timers = jQuery.timers, 12140 data = dataPriv.get( this ); 12141 12142 if ( index ) { 12143 if ( data[ index ] && data[ index ].stop ) { 12144 stopQueue( data[ index ] ); 12145 } 12146 } else { 12147 for ( index in data ) { 12148 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 12149 stopQueue( data[ index ] ); 12150 } 12151 } 12152 } 12153 12154 for ( index = timers.length; index--; ) { 12155 if ( timers[ index ].elem === this && 12156 ( type == null || timers[ index ].queue === type ) ) { 12157 12158 timers[ index ].anim.stop( gotoEnd ); 12159 dequeue = false; 12160 timers.splice( index, 1 ); 12161 } 12162 } 12163 12164 // Start the next in the queue if the last step wasn't forced. 12165 // Timers currently will call their complete callbacks, which 12166 // will dequeue but only if they were gotoEnd. 12167 if ( dequeue || !gotoEnd ) { 12168 jQuery.dequeue( this, type ); 12169 } 12170 } ); 12171 }, 12172 finish: function( type ) { 12173 if ( type !== false ) { 12174 type = type || "fx"; 12175 } 12176 return this.each( function() { 12177 var index, 12178 data = dataPriv.get( this ), 12179 queue = data[ type + "queue" ], 12180 hooks = data[ type + "queueHooks" ], 12181 timers = jQuery.timers, 12182 length = queue ? queue.length : 0; 12183 12184 // Enable finishing flag on private data 12185 data.finish = true; 12186 12187 // Empty the queue first 12188 jQuery.queue( this, type, [] ); 12189 12190 if ( hooks && hooks.stop ) { 12191 hooks.stop.call( this, true ); 12192 } 12193 12194 // Look for any active animations, and finish them 12195 for ( index = timers.length; index--; ) { 12196 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 12197 timers[ index ].anim.stop( true ); 12198 timers.splice( index, 1 ); 12199 } 12200 } 12201 12202 // Look for any animations in the old queue and finish them 12203 for ( index = 0; index < length; index++ ) { 12204 if ( queue[ index ] && queue[ index ].finish ) { 12205 queue[ index ].finish.call( this ); 12206 } 12207 } 12208 12209 // Turn off finishing flag 12210 delete data.finish; 12211 } ); 12212 } 12213} ); 12214 12215jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 12216 var cssFn = jQuery.fn[ name ]; 12217 jQuery.fn[ name ] = function( speed, easing, callback ) { 12218 return speed == null || typeof speed === "boolean" ? 12219 cssFn.apply( this, arguments ) : 12220 this.animate( genFx( name, true ), speed, easing, callback ); 12221 }; 12222} ); 12223 12224// Generate shortcuts for custom animations 12225jQuery.each( { 12226 slideDown: genFx( "show" ), 12227 slideUp: genFx( "hide" ), 12228 slideToggle: genFx( "toggle" ), 12229 fadeIn: { opacity: "show" }, 12230 fadeOut: { opacity: "hide" }, 12231 fadeToggle: { opacity: "toggle" } 12232}, function( name, props ) { 12233 jQuery.fn[ name ] = function( speed, easing, callback ) { 12234 return this.animate( props, speed, easing, callback ); 12235 }; 12236} ); 12237 12238jQuery.timers = []; 12239jQuery.fx.tick = function() { 12240 var timer, 12241 i = 0, 12242 timers = jQuery.timers; 12243 12244 fxNow = Date.now(); 12245 12246 for ( ; i < timers.length; i++ ) { 12247 timer = timers[ i ]; 12248 12249 // Run the timer and safely remove it when done (allowing for external removal) 12250 if ( !timer() && timers[ i ] === timer ) { 12251 timers.splice( i--, 1 ); 12252 } 12253 } 12254 12255 if ( !timers.length ) { 12256 jQuery.fx.stop(); 12257 } 12258 fxNow = undefined; 12259}; 12260 12261jQuery.fx.timer = function( timer ) { 12262 jQuery.timers.push( timer ); 12263 jQuery.fx.start(); 12264}; 12265 12266jQuery.fx.interval = 13; 12267jQuery.fx.start = function() { 12268 if ( inProgress ) { 12269 return; 12270 } 12271 12272 inProgress = true; 12273 schedule(); 12274}; 12275 12276jQuery.fx.stop = function() { 12277 inProgress = null; 12278}; 12279 12280jQuery.fx.speeds = { 12281 slow: 600, 12282 fast: 200, 12283 12284 // Default speed 12285 _default: 400 12286}; 12287 12288 12289// Based off of the plugin by Clint Helfers, with permission. 12290// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 12291jQuery.fn.delay = function( time, type ) { 12292 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 12293 type = type || "fx"; 12294 12295 return this.queue( type, function( next, hooks ) { 12296 var timeout = window.setTimeout( next, time ); 12297 hooks.stop = function() { 12298 window.clearTimeout( timeout ); 12299 }; 12300 } ); 12301}; 12302 12303 12304( function() { 12305 var input = document.createElement( "input" ), 12306 select = document.createElement( "select" ), 12307 opt = select.appendChild( document.createElement( "option" ) ); 12308 12309 input.type = "checkbox"; 12310 12311 // Support: Android <=4.3 only 12312 // Default value for a checkbox should be "on" 12313 support.checkOn = input.value !== ""; 12314 12315 // Support: IE <=11 only 12316 // Must access selectedIndex to make default options select 12317 support.optSelected = opt.selected; 12318 12319 // Support: IE <=11 only 12320 // An input loses its value after becoming a radio 12321 input = document.createElement( "input" ); 12322 input.value = "t"; 12323 input.type = "radio"; 12324 support.radioValue = input.value === "t"; 12325} )(); 12326 12327 12328var boolHook, 12329 attrHandle = jQuery.expr.attrHandle; 12330 12331jQuery.fn.extend( { 12332 attr: function( name, value ) { 12333 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 12334 }, 12335 12336 removeAttr: function( name ) { 12337 return this.each( function() { 12338 jQuery.removeAttr( this, name ); 12339 } ); 12340 } 12341} ); 12342 12343jQuery.extend( { 12344 attr: function( elem, name, value ) { 12345 var ret, hooks, 12346 nType = elem.nodeType; 12347 12348 // Don't get/set attributes on text, comment and attribute nodes 12349 if ( nType === 3 || nType === 8 || nType === 2 ) { 12350 return; 12351 } 12352 12353 // Fallback to prop when attributes are not supported 12354 if ( typeof elem.getAttribute === "undefined" ) { 12355 return jQuery.prop( elem, name, value ); 12356 } 12357 12358 // Attribute hooks are determined by the lowercase version 12359 // Grab necessary hook if one is defined 12360 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 12361 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 12362 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 12363 } 12364 12365 if ( value !== undefined ) { 12366 if ( value === null ) { 12367 jQuery.removeAttr( elem, name ); 12368 return; 12369 } 12370 12371 if ( hooks && "set" in hooks && 12372 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 12373 return ret; 12374 } 12375 12376 elem.setAttribute( name, value + "" ); 12377 return value; 12378 } 12379 12380 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 12381 return ret; 12382 } 12383 12384 ret = jQuery.find.attr( elem, name ); 12385 12386 // Non-existent attributes return null, we normalize to undefined 12387 return ret == null ? undefined : ret; 12388 }, 12389 12390 attrHooks: { 12391 type: { 12392 set: function( elem, value ) { 12393 if ( !support.radioValue && value === "radio" && 12394 nodeName( elem, "input" ) ) { 12395 var val = elem.value; 12396 elem.setAttribute( "type", value ); 12397 if ( val ) { 12398 elem.value = val; 12399 } 12400 return value; 12401 } 12402 } 12403 } 12404 }, 12405 12406 removeAttr: function( elem, value ) { 12407 var name, 12408 i = 0, 12409 12410 // Attribute names can contain non-HTML whitespace characters 12411 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 12412 attrNames = value && value.match( rnothtmlwhite ); 12413 12414 if ( attrNames && elem.nodeType === 1 ) { 12415 while ( ( name = attrNames[ i++ ] ) ) { 12416 elem.removeAttribute( name ); 12417 } 12418 } 12419 } 12420} ); 12421 12422// Hooks for boolean attributes 12423boolHook = { 12424 set: function( elem, value, name ) { 12425 if ( value === false ) { 12426 12427 // Remove boolean attributes when set to false 12428 jQuery.removeAttr( elem, name ); 12429 } else { 12430 elem.setAttribute( name, name ); 12431 } 12432 return name; 12433 } 12434}; 12435 12436jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 12437 var getter = attrHandle[ name ] || jQuery.find.attr; 12438 12439 attrHandle[ name ] = function( elem, name, isXML ) { 12440 var ret, handle, 12441 lowercaseName = name.toLowerCase(); 12442 12443 if ( !isXML ) { 12444 12445 // Avoid an infinite loop by temporarily removing this function from the getter 12446 handle = attrHandle[ lowercaseName ]; 12447 attrHandle[ lowercaseName ] = ret; 12448 ret = getter( elem, name, isXML ) != null ? 12449 lowercaseName : 12450 null; 12451 attrHandle[ lowercaseName ] = handle; 12452 } 12453 return ret; 12454 }; 12455} ); 12456 12457 12458 12459 12460var rfocusable = /^(?:input|select|textarea|button)$/i, 12461 rclickable = /^(?:a|area)$/i; 12462 12463jQuery.fn.extend( { 12464 prop: function( name, value ) { 12465 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 12466 }, 12467 12468 removeProp: function( name ) { 12469 return this.each( function() { 12470 delete this[ jQuery.propFix[ name ] || name ]; 12471 } ); 12472 } 12473} ); 12474 12475jQuery.extend( { 12476 prop: function( elem, name, value ) { 12477 var ret, hooks, 12478 nType = elem.nodeType; 12479 12480 // Don't get/set properties on text, comment and attribute nodes 12481 if ( nType === 3 || nType === 8 || nType === 2 ) { 12482 return; 12483 } 12484 12485 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 12486 12487 // Fix name and attach hooks 12488 name = jQuery.propFix[ name ] || name; 12489 hooks = jQuery.propHooks[ name ]; 12490 } 12491 12492 if ( value !== undefined ) { 12493 if ( hooks && "set" in hooks && 12494 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 12495 return ret; 12496 } 12497 12498 return ( elem[ name ] = value ); 12499 } 12500 12501 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 12502 return ret; 12503 } 12504 12505 return elem[ name ]; 12506 }, 12507 12508 propHooks: { 12509 tabIndex: { 12510 get: function( elem ) { 12511 12512 // Support: IE <=9 - 11 only 12513 // elem.tabIndex doesn't always return the 12514 // correct value when it hasn't been explicitly set 12515 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 12516 // Use proper attribute retrieval(#12072) 12517 var tabindex = jQuery.find.attr( elem, "tabindex" ); 12518 12519 if ( tabindex ) { 12520 return parseInt( tabindex, 10 ); 12521 } 12522 12523 if ( 12524 rfocusable.test( elem.nodeName ) || 12525 rclickable.test( elem.nodeName ) && 12526 elem.href 12527 ) { 12528 return 0; 12529 } 12530 12531 return -1; 12532 } 12533 } 12534 }, 12535 12536 propFix: { 12537 "for": "htmlFor", 12538 "class": "className" 12539 } 12540} ); 12541 12542// Support: IE <=11 only 12543// Accessing the selectedIndex property 12544// forces the browser to respect setting selected 12545// on the option 12546// The getter ensures a default option is selected 12547// when in an optgroup 12548// eslint rule "no-unused-expressions" is disabled for this code 12549// since it considers such accessions noop 12550if ( !support.optSelected ) { 12551 jQuery.propHooks.selected = { 12552 get: function( elem ) { 12553 12554 /* eslint no-unused-expressions: "off" */ 12555 12556 var parent = elem.parentNode; 12557 if ( parent && parent.parentNode ) { 12558 parent.parentNode.selectedIndex; 12559 } 12560 return null; 12561 }, 12562 set: function( elem ) { 12563 12564 /* eslint no-unused-expressions: "off" */ 12565 12566 var parent = elem.parentNode; 12567 if ( parent ) { 12568 parent.selectedIndex; 12569 12570 if ( parent.parentNode ) { 12571 parent.parentNode.selectedIndex; 12572 } 12573 } 12574 } 12575 }; 12576} 12577 12578jQuery.each( [ 12579 "tabIndex", 12580 "readOnly", 12581 "maxLength", 12582 "cellSpacing", 12583 "cellPadding", 12584 "rowSpan", 12585 "colSpan", 12586 "useMap", 12587 "frameBorder", 12588 "contentEditable" 12589], function() { 12590 jQuery.propFix[ this.toLowerCase() ] = this; 12591} ); 12592 12593 12594 12595 12596 // Strip and collapse whitespace according to HTML spec 12597 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 12598 function stripAndCollapse( value ) { 12599 var tokens = value.match( rnothtmlwhite ) || []; 12600 return tokens.join( " " ); 12601 } 12602 12603 12604function getClass( elem ) { 12605 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 12606} 12607 12608function classesToArray( value ) { 12609 if ( Array.isArray( value ) ) { 12610 return value; 12611 } 12612 if ( typeof value === "string" ) { 12613 return value.match( rnothtmlwhite ) || []; 12614 } 12615 return []; 12616} 12617 12618jQuery.fn.extend( { 12619 addClass: function( value ) { 12620 var classes, elem, cur, curValue, clazz, j, finalValue, 12621 i = 0; 12622 12623 if ( isFunction( value ) ) { 12624 return this.each( function( j ) { 12625 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 12626 } ); 12627 } 12628 12629 classes = classesToArray( value ); 12630 12631 if ( classes.length ) { 12632 while ( ( elem = this[ i++ ] ) ) { 12633 curValue = getClass( elem ); 12634 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 12635 12636 if ( cur ) { 12637 j = 0; 12638 while ( ( clazz = classes[ j++ ] ) ) { 12639 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 12640 cur += clazz + " "; 12641 } 12642 } 12643 12644 // Only assign if different to avoid unneeded rendering. 12645 finalValue = stripAndCollapse( cur ); 12646 if ( curValue !== finalValue ) { 12647 elem.setAttribute( "class", finalValue ); 12648 } 12649 } 12650 } 12651 } 12652 12653 return this; 12654 }, 12655 12656 removeClass: function( value ) { 12657 var classes, elem, cur, curValue, clazz, j, finalValue, 12658 i = 0; 12659 12660 if ( isFunction( value ) ) { 12661 return this.each( function( j ) { 12662 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 12663 } ); 12664 } 12665 12666 if ( !arguments.length ) { 12667 return this.attr( "class", "" ); 12668 } 12669 12670 classes = classesToArray( value ); 12671 12672 if ( classes.length ) { 12673 while ( ( elem = this[ i++ ] ) ) { 12674 curValue = getClass( elem ); 12675 12676 // This expression is here for better compressibility (see addClass) 12677 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 12678 12679 if ( cur ) { 12680 j = 0; 12681 while ( ( clazz = classes[ j++ ] ) ) { 12682 12683 // Remove *all* instances 12684 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 12685 cur = cur.replace( " " + clazz + " ", " " ); 12686 } 12687 } 12688 12689 // Only assign if different to avoid unneeded rendering. 12690 finalValue = stripAndCollapse( cur ); 12691 if ( curValue !== finalValue ) { 12692 elem.setAttribute( "class", finalValue ); 12693 } 12694 } 12695 } 12696 } 12697 12698 return this; 12699 }, 12700 12701 toggleClass: function( value, stateVal ) { 12702 var type = typeof value, 12703 isValidValue = type === "string" || Array.isArray( value ); 12704 12705 if ( typeof stateVal === "boolean" && isValidValue ) { 12706 return stateVal ? this.addClass( value ) : this.removeClass( value ); 12707 } 12708 12709 if ( isFunction( value ) ) { 12710 return this.each( function( i ) { 12711 jQuery( this ).toggleClass( 12712 value.call( this, i, getClass( this ), stateVal ), 12713 stateVal 12714 ); 12715 } ); 12716 } 12717 12718 return this.each( function() { 12719 var className, i, self, classNames; 12720 12721 if ( isValidValue ) { 12722 12723 // Toggle individual class names 12724 i = 0; 12725 self = jQuery( this ); 12726 classNames = classesToArray( value ); 12727 12728 while ( ( className = classNames[ i++ ] ) ) { 12729 12730 // Check each className given, space separated list 12731 if ( self.hasClass( className ) ) { 12732 self.removeClass( className ); 12733 } else { 12734 self.addClass( className ); 12735 } 12736 } 12737 12738 // Toggle whole class name 12739 } else if ( value === undefined || type === "boolean" ) { 12740 className = getClass( this ); 12741 if ( className ) { 12742 12743 // Store className if set 12744 dataPriv.set( this, "__className__", className ); 12745 } 12746 12747 // If the element has a class name or if we're passed `false`, 12748 // then remove the whole classname (if there was one, the above saved it). 12749 // Otherwise bring back whatever was previously saved (if anything), 12750 // falling back to the empty string if nothing was stored. 12751 if ( this.setAttribute ) { 12752 this.setAttribute( "class", 12753 className || value === false ? 12754 "" : 12755 dataPriv.get( this, "__className__" ) || "" 12756 ); 12757 } 12758 } 12759 } ); 12760 }, 12761 12762 hasClass: function( selector ) { 12763 var className, elem, 12764 i = 0; 12765 12766 className = " " + selector + " "; 12767 while ( ( elem = this[ i++ ] ) ) { 12768 if ( elem.nodeType === 1 && 12769 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 12770 return true; 12771 } 12772 } 12773 12774 return false; 12775 } 12776} ); 12777 12778 12779 12780 12781var rreturn = /\r/g; 12782 12783jQuery.fn.extend( { 12784 val: function( value ) { 12785 var hooks, ret, valueIsFunction, 12786 elem = this[ 0 ]; 12787 12788 if ( !arguments.length ) { 12789 if ( elem ) { 12790 hooks = jQuery.valHooks[ elem.type ] || 12791 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 12792 12793 if ( hooks && 12794 "get" in hooks && 12795 ( ret = hooks.get( elem, "value" ) ) !== undefined 12796 ) { 12797 return ret; 12798 } 12799 12800 ret = elem.value; 12801 12802 // Handle most common string cases 12803 if ( typeof ret === "string" ) { 12804 return ret.replace( rreturn, "" ); 12805 } 12806 12807 // Handle cases where value is null/undef or number 12808 return ret == null ? "" : ret; 12809 } 12810 12811 return; 12812 } 12813 12814 valueIsFunction = isFunction( value ); 12815 12816 return this.each( function( i ) { 12817 var val; 12818 12819 if ( this.nodeType !== 1 ) { 12820 return; 12821 } 12822 12823 if ( valueIsFunction ) { 12824 val = value.call( this, i, jQuery( this ).val() ); 12825 } else { 12826 val = value; 12827 } 12828 12829 // Treat null/undefined as ""; convert numbers to string 12830 if ( val == null ) { 12831 val = ""; 12832 12833 } else if ( typeof val === "number" ) { 12834 val += ""; 12835 12836 } else if ( Array.isArray( val ) ) { 12837 val = jQuery.map( val, function( value ) { 12838 return value == null ? "" : value + ""; 12839 } ); 12840 } 12841 12842 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 12843 12844 // If set returns undefined, fall back to normal setting 12845 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 12846 this.value = val; 12847 } 12848 } ); 12849 } 12850} ); 12851 12852jQuery.extend( { 12853 valHooks: { 12854 option: { 12855 get: function( elem ) { 12856 12857 var val = jQuery.find.attr( elem, "value" ); 12858 return val != null ? 12859 val : 12860 12861 // Support: IE <=10 - 11 only 12862 // option.text throws exceptions (#14686, #14858) 12863 // Strip and collapse whitespace 12864 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 12865 stripAndCollapse( jQuery.text( elem ) ); 12866 } 12867 }, 12868 select: { 12869 get: function( elem ) { 12870 var value, option, i, 12871 options = elem.options, 12872 index = elem.selectedIndex, 12873 one = elem.type === "select-one", 12874 values = one ? null : [], 12875 max = one ? index + 1 : options.length; 12876 12877 if ( index < 0 ) { 12878 i = max; 12879 12880 } else { 12881 i = one ? index : 0; 12882 } 12883 12884 // Loop through all the selected options 12885 for ( ; i < max; i++ ) { 12886 option = options[ i ]; 12887 12888 // Support: IE <=9 only 12889 // IE8-9 doesn't update selected after form reset (#2551) 12890 if ( ( option.selected || i === index ) && 12891 12892 // Don't return options that are disabled or in a disabled optgroup 12893 !option.disabled && 12894 ( !option.parentNode.disabled || 12895 !nodeName( option.parentNode, "optgroup" ) ) ) { 12896 12897 // Get the specific value for the option 12898 value = jQuery( option ).val(); 12899 12900 // We don't need an array for one selects 12901 if ( one ) { 12902 return value; 12903 } 12904 12905 // Multi-Selects return an array 12906 values.push( value ); 12907 } 12908 } 12909 12910 return values; 12911 }, 12912 12913 set: function( elem, value ) { 12914 var optionSet, option, 12915 options = elem.options, 12916 values = jQuery.makeArray( value ), 12917 i = options.length; 12918 12919 while ( i-- ) { 12920 option = options[ i ]; 12921 12922 /* eslint-disable no-cond-assign */ 12923 12924 if ( option.selected = 12925 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 12926 ) { 12927 optionSet = true; 12928 } 12929 12930 /* eslint-enable no-cond-assign */ 12931 } 12932 12933 // Force browsers to behave consistently when non-matching value is set 12934 if ( !optionSet ) { 12935 elem.selectedIndex = -1; 12936 } 12937 return values; 12938 } 12939 } 12940 } 12941} ); 12942 12943// Radios and checkboxes getter/setter 12944jQuery.each( [ "radio", "checkbox" ], function() { 12945 jQuery.valHooks[ this ] = { 12946 set: function( elem, value ) { 12947 if ( Array.isArray( value ) ) { 12948 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 12949 } 12950 } 12951 }; 12952 if ( !support.checkOn ) { 12953 jQuery.valHooks[ this ].get = function( elem ) { 12954 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 12955 }; 12956 } 12957} ); 12958 12959 12960 12961 12962// Return jQuery for attributes-only inclusion 12963 12964 12965support.focusin = "onfocusin" in window; 12966 12967 12968var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 12969 stopPropagationCallback = function( e ) { 12970 e.stopPropagation(); 12971 }; 12972 12973jQuery.extend( jQuery.event, { 12974 12975 trigger: function( event, data, elem, onlyHandlers ) { 12976 12977 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 12978 eventPath = [ elem || document ], 12979 type = hasOwn.call( event, "type" ) ? event.type : event, 12980 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 12981 12982 cur = lastElement = tmp = elem = elem || document; 12983 12984 // Don't do events on text and comment nodes 12985 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 12986 return; 12987 } 12988 12989 // focus/blur morphs to focusin/out; ensure we're not firing them right now 12990 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 12991 return; 12992 } 12993 12994 if ( type.indexOf( "." ) > -1 ) { 12995 12996 // Namespaced trigger; create a regexp to match event type in handle() 12997 namespaces = type.split( "." ); 12998 type = namespaces.shift(); 12999 namespaces.sort(); 13000 } 13001 ontype = type.indexOf( ":" ) < 0 && "on" + type; 13002 13003 // Caller can pass in a jQuery.Event object, Object, or just an event type string 13004 event = event[ jQuery.expando ] ? 13005 event : 13006 new jQuery.Event( type, typeof event === "object" && event ); 13007 13008 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 13009 event.isTrigger = onlyHandlers ? 2 : 3; 13010 event.namespace = namespaces.join( "." ); 13011 event.rnamespace = event.namespace ? 13012 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 13013 null; 13014 13015 // Clean up the event in case it is being reused 13016 event.result = undefined; 13017 if ( !event.target ) { 13018 event.target = elem; 13019 } 13020 13021 // Clone any incoming data and prepend the event, creating the handler arg list 13022 data = data == null ? 13023 [ event ] : 13024 jQuery.makeArray( data, [ event ] ); 13025 13026 // Allow special events to draw outside the lines 13027 special = jQuery.event.special[ type ] || {}; 13028 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 13029 return; 13030 } 13031 13032 // Determine event propagation path in advance, per W3C events spec (#9951) 13033 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 13034 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 13035 13036 bubbleType = special.delegateType || type; 13037 if ( !rfocusMorph.test( bubbleType + type ) ) { 13038 cur = cur.parentNode; 13039 } 13040 for ( ; cur; cur = cur.parentNode ) { 13041 eventPath.push( cur ); 13042 tmp = cur; 13043 } 13044 13045 // Only add window if we got to document (e.g., not plain obj or detached DOM) 13046 if ( tmp === ( elem.ownerDocument || document ) ) { 13047 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 13048 } 13049 } 13050 13051 // Fire handlers on the event path 13052 i = 0; 13053 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 13054 lastElement = cur; 13055 event.type = i > 1 ? 13056 bubbleType : 13057 special.bindType || type; 13058 13059 // jQuery handler 13060 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 13061 dataPriv.get( cur, "handle" ); 13062 if ( handle ) { 13063 handle.apply( cur, data ); 13064 } 13065 13066 // Native handler 13067 handle = ontype && cur[ ontype ]; 13068 if ( handle && handle.apply && acceptData( cur ) ) { 13069 event.result = handle.apply( cur, data ); 13070 if ( event.result === false ) { 13071 event.preventDefault(); 13072 } 13073 } 13074 } 13075 event.type = type; 13076 13077 // If nobody prevented the default action, do it now 13078 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 13079 13080 if ( ( !special._default || 13081 special._default.apply( eventPath.pop(), data ) === false ) && 13082 acceptData( elem ) ) { 13083 13084 // Call a native DOM method on the target with the same name as the event. 13085 // Don't do default actions on window, that's where global variables be (#6170) 13086 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 13087 13088 // Don't re-trigger an onFOO event when we call its FOO() method 13089 tmp = elem[ ontype ]; 13090 13091 if ( tmp ) { 13092 elem[ ontype ] = null; 13093 } 13094 13095 // Prevent re-triggering of the same event, since we already bubbled it above 13096 jQuery.event.triggered = type; 13097 13098 if ( event.isPropagationStopped() ) { 13099 lastElement.addEventListener( type, stopPropagationCallback ); 13100 } 13101 13102 elem[ type ](); 13103 13104 if ( event.isPropagationStopped() ) { 13105 lastElement.removeEventListener( type, stopPropagationCallback ); 13106 } 13107 13108 jQuery.event.triggered = undefined; 13109 13110 if ( tmp ) { 13111 elem[ ontype ] = tmp; 13112 } 13113 } 13114 } 13115 } 13116 13117 return event.result; 13118 }, 13119 13120 // Piggyback on a donor event to simulate a different one 13121 // Used only for `focus(in | out)` events 13122 simulate: function( type, elem, event ) { 13123 var e = jQuery.extend( 13124 new jQuery.Event(), 13125 event, 13126 { 13127 type: type, 13128 isSimulated: true 13129 } 13130 ); 13131 13132 jQuery.event.trigger( e, null, elem ); 13133 } 13134 13135} ); 13136 13137jQuery.fn.extend( { 13138 13139 trigger: function( type, data ) { 13140 return this.each( function() { 13141 jQuery.event.trigger( type, data, this ); 13142 } ); 13143 }, 13144 triggerHandler: function( type, data ) { 13145 var elem = this[ 0 ]; 13146 if ( elem ) { 13147 return jQuery.event.trigger( type, data, elem, true ); 13148 } 13149 } 13150} ); 13151 13152 13153// Support: Firefox <=44 13154// Firefox doesn't have focus(in | out) events 13155// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 13156// 13157// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 13158// focus(in | out) events fire after focus & blur events, 13159// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 13160// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 13161if ( !support.focusin ) { 13162 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 13163 13164 // Attach a single capturing handler on the document while someone wants focusin/focusout 13165 var handler = function( event ) { 13166 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 13167 }; 13168 13169 jQuery.event.special[ fix ] = { 13170 setup: function() { 13171 13172 // Handle: regular nodes (via `this.ownerDocument`), window 13173 // (via `this.document`) & document (via `this`). 13174 var doc = this.ownerDocument || this.document || this, 13175 attaches = dataPriv.access( doc, fix ); 13176 13177 if ( !attaches ) { 13178 doc.addEventListener( orig, handler, true ); 13179 } 13180 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 13181 }, 13182 teardown: function() { 13183 var doc = this.ownerDocument || this.document || this, 13184 attaches = dataPriv.access( doc, fix ) - 1; 13185 13186 if ( !attaches ) { 13187 doc.removeEventListener( orig, handler, true ); 13188 dataPriv.remove( doc, fix ); 13189 13190 } else { 13191 dataPriv.access( doc, fix, attaches ); 13192 } 13193 } 13194 }; 13195 } ); 13196} 13197var location = window.location; 13198 13199var nonce = { guid: Date.now() }; 13200 13201var rquery = ( /\?/ ); 13202 13203 13204 13205// Cross-browser xml parsing 13206jQuery.parseXML = function( data ) { 13207 var xml, parserErrorElem; 13208 if ( !data || typeof data !== "string" ) { 13209 return null; 13210 } 13211 13212 // Support: IE 9 - 11 only 13213 // IE throws on parseFromString with invalid input. 13214 try { 13215 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 13216 } catch ( e ) {} 13217 13218 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 13219 if ( !xml || parserErrorElem ) { 13220 jQuery.error( "Invalid XML: " + ( 13221 parserErrorElem ? 13222 jQuery.map( parserErrorElem.childNodes, function( el ) { 13223 return el.textContent; 13224 } ).join( "\n" ) : 13225 data 13226 ) ); 13227 } 13228 return xml; 13229}; 13230 13231 13232var 13233 rbracket = /\[\]$/, 13234 rCRLF = /\r?\n/g, 13235 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 13236 rsubmittable = /^(?:input|select|textarea|keygen)/i; 13237 13238function buildParams( prefix, obj, traditional, add ) { 13239 var name; 13240 13241 if ( Array.isArray( obj ) ) { 13242 13243 // Serialize array item. 13244 jQuery.each( obj, function( i, v ) { 13245 if ( traditional || rbracket.test( prefix ) ) { 13246 13247 // Treat each array item as a scalar. 13248 add( prefix, v ); 13249 13250 } else { 13251 13252 // Item is non-scalar (array or object), encode its numeric index. 13253 buildParams( 13254 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 13255 v, 13256 traditional, 13257 add 13258 ); 13259 } 13260 } ); 13261 13262 } else if ( !traditional && toType( obj ) === "object" ) { 13263 13264 // Serialize object item. 13265 for ( name in obj ) { 13266 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 13267 } 13268 13269 } else { 13270 13271 // Serialize scalar item. 13272 add( prefix, obj ); 13273 } 13274} 13275 13276// Serialize an array of form elements or a set of 13277// key/values into a query string 13278jQuery.param = function( a, traditional ) { 13279 var prefix, 13280 s = [], 13281 add = function( key, valueOrFunction ) { 13282 13283 // If value is a function, invoke it and use its return value 13284 var value = isFunction( valueOrFunction ) ? 13285 valueOrFunction() : 13286 valueOrFunction; 13287 13288 s[ s.length ] = encodeURIComponent( key ) + "=" + 13289 encodeURIComponent( value == null ? "" : value ); 13290 }; 13291 13292 if ( a == null ) { 13293 return ""; 13294 } 13295 13296 // If an array was passed in, assume that it is an array of form elements. 13297 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 13298 13299 // Serialize the form elements 13300 jQuery.each( a, function() { 13301 add( this.name, this.value ); 13302 } ); 13303 13304 } else { 13305 13306 // If traditional, encode the "old" way (the way 1.3.2 or older 13307 // did it), otherwise encode params recursively. 13308 for ( prefix in a ) { 13309 buildParams( prefix, a[ prefix ], traditional, add ); 13310 } 13311 } 13312 13313 // Return the resulting serialization 13314 return s.join( "&" ); 13315}; 13316 13317jQuery.fn.extend( { 13318 serialize: function() { 13319 return jQuery.param( this.serializeArray() ); 13320 }, 13321 serializeArray: function() { 13322 return this.map( function() { 13323 13324 // Can add propHook for "elements" to filter or add form elements 13325 var elements = jQuery.prop( this, "elements" ); 13326 return elements ? jQuery.makeArray( elements ) : this; 13327 } ).filter( function() { 13328 var type = this.type; 13329 13330 // Use .is( ":disabled" ) so that fieldset[disabled] works 13331 return this.name && !jQuery( this ).is( ":disabled" ) && 13332 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 13333 ( this.checked || !rcheckableType.test( type ) ); 13334 } ).map( function( _i, elem ) { 13335 var val = jQuery( this ).val(); 13336 13337 if ( val == null ) { 13338 return null; 13339 } 13340 13341 if ( Array.isArray( val ) ) { 13342 return jQuery.map( val, function( val ) { 13343 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 13344 } ); 13345 } 13346 13347 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 13348 } ).get(); 13349 } 13350} ); 13351 13352 13353var 13354 r20 = /%20/g, 13355 rhash = /#.*$/, 13356 rantiCache = /([?&])_=[^&]*/, 13357 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 13358 13359 // #7653, #8125, #8152: local protocol detection 13360 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 13361 rnoContent = /^(?:GET|HEAD)$/, 13362 rprotocol = /^\/\//, 13363 13364 /* Prefilters 13365 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 13366 * 2) These are called: 13367 * - BEFORE asking for a transport 13368 * - AFTER param serialization (s.data is a string if s.processData is true) 13369 * 3) key is the dataType 13370 * 4) the catchall symbol "*" can be used 13371 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 13372 */ 13373 prefilters = {}, 13374 13375 /* Transports bindings 13376 * 1) key is the dataType 13377 * 2) the catchall symbol "*" can be used 13378 * 3) selection will start with transport dataType and THEN go to "*" if needed 13379 */ 13380 transports = {}, 13381 13382 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 13383 allTypes = "*/".concat( "*" ), 13384 13385 // Anchor tag for parsing the document origin 13386 originAnchor = document.createElement( "a" ); 13387 13388originAnchor.href = location.href; 13389 13390// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 13391function addToPrefiltersOrTransports( structure ) { 13392 13393 // dataTypeExpression is optional and defaults to "*" 13394 return function( dataTypeExpression, func ) { 13395 13396 if ( typeof dataTypeExpression !== "string" ) { 13397 func = dataTypeExpression; 13398 dataTypeExpression = "*"; 13399 } 13400 13401 var dataType, 13402 i = 0, 13403 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 13404 13405 if ( isFunction( func ) ) { 13406 13407 // For each dataType in the dataTypeExpression 13408 while ( ( dataType = dataTypes[ i++ ] ) ) { 13409 13410 // Prepend if requested 13411 if ( dataType[ 0 ] === "+" ) { 13412 dataType = dataType.slice( 1 ) || "*"; 13413 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 13414 13415 // Otherwise append 13416 } else { 13417 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 13418 } 13419 } 13420 } 13421 }; 13422} 13423 13424// Base inspection function for prefilters and transports 13425function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 13426 13427 var inspected = {}, 13428 seekingTransport = ( structure === transports ); 13429 13430 function inspect( dataType ) { 13431 var selected; 13432 inspected[ dataType ] = true; 13433 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 13434 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 13435 if ( typeof dataTypeOrTransport === "string" && 13436 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 13437 13438 options.dataTypes.unshift( dataTypeOrTransport ); 13439 inspect( dataTypeOrTransport ); 13440 return false; 13441 } else if ( seekingTransport ) { 13442 return !( selected = dataTypeOrTransport ); 13443 } 13444 } ); 13445 return selected; 13446 } 13447 13448 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 13449} 13450 13451// A special extend for ajax options 13452// that takes "flat" options (not to be deep extended) 13453// Fixes #9887 13454function ajaxExtend( target, src ) { 13455 var key, deep, 13456 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 13457 13458 for ( key in src ) { 13459 if ( src[ key ] !== undefined ) { 13460 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 13461 } 13462 } 13463 if ( deep ) { 13464 jQuery.extend( true, target, deep ); 13465 } 13466 13467 return target; 13468} 13469 13470/* Handles responses to an ajax request: 13471 * - finds the right dataType (mediates between content-type and expected dataType) 13472 * - returns the corresponding response 13473 */ 13474function ajaxHandleResponses( s, jqXHR, responses ) { 13475 13476 var ct, type, finalDataType, firstDataType, 13477 contents = s.contents, 13478 dataTypes = s.dataTypes; 13479 13480 // Remove auto dataType and get content-type in the process 13481 while ( dataTypes[ 0 ] === "*" ) { 13482 dataTypes.shift(); 13483 if ( ct === undefined ) { 13484 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 13485 } 13486 } 13487 13488 // Check if we're dealing with a known content-type 13489 if ( ct ) { 13490 for ( type in contents ) { 13491 if ( contents[ type ] && contents[ type ].test( ct ) ) { 13492 dataTypes.unshift( type ); 13493 break; 13494 } 13495 } 13496 } 13497 13498 // Check to see if we have a response for the expected dataType 13499 if ( dataTypes[ 0 ] in responses ) { 13500 finalDataType = dataTypes[ 0 ]; 13501 } else { 13502 13503 // Try convertible dataTypes 13504 for ( type in responses ) { 13505 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 13506 finalDataType = type; 13507 break; 13508 } 13509 if ( !firstDataType ) { 13510 firstDataType = type; 13511 } 13512 } 13513 13514 // Or just use first one 13515 finalDataType = finalDataType || firstDataType; 13516 } 13517 13518 // If we found a dataType 13519 // We add the dataType to the list if needed 13520 // and return the corresponding response 13521 if ( finalDataType ) { 13522 if ( finalDataType !== dataTypes[ 0 ] ) { 13523 dataTypes.unshift( finalDataType ); 13524 } 13525 return responses[ finalDataType ]; 13526 } 13527} 13528 13529/* Chain conversions given the request and the original response 13530 * Also sets the responseXXX fields on the jqXHR instance 13531 */ 13532function ajaxConvert( s, response, jqXHR, isSuccess ) { 13533 var conv2, current, conv, tmp, prev, 13534 converters = {}, 13535 13536 // Work with a copy of dataTypes in case we need to modify it for conversion 13537 dataTypes = s.dataTypes.slice(); 13538 13539 // Create converters map with lowercased keys 13540 if ( dataTypes[ 1 ] ) { 13541 for ( conv in s.converters ) { 13542 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 13543 } 13544 } 13545 13546 current = dataTypes.shift(); 13547 13548 // Convert to each sequential dataType 13549 while ( current ) { 13550 13551 if ( s.responseFields[ current ] ) { 13552 jqXHR[ s.responseFields[ current ] ] = response; 13553 } 13554 13555 // Apply the dataFilter if provided 13556 if ( !prev && isSuccess && s.dataFilter ) { 13557 response = s.dataFilter( response, s.dataType ); 13558 } 13559 13560 prev = current; 13561 current = dataTypes.shift(); 13562 13563 if ( current ) { 13564 13565 // There's only work to do if current dataType is non-auto 13566 if ( current === "*" ) { 13567 13568 current = prev; 13569 13570 // Convert response if prev dataType is non-auto and differs from current 13571 } else if ( prev !== "*" && prev !== current ) { 13572 13573 // Seek a direct converter 13574 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 13575 13576 // If none found, seek a pair 13577 if ( !conv ) { 13578 for ( conv2 in converters ) { 13579 13580 // If conv2 outputs current 13581 tmp = conv2.split( " " ); 13582 if ( tmp[ 1 ] === current ) { 13583 13584 // If prev can be converted to accepted input 13585 conv = converters[ prev + " " + tmp[ 0 ] ] || 13586 converters[ "* " + tmp[ 0 ] ]; 13587 if ( conv ) { 13588 13589 // Condense equivalence converters 13590 if ( conv === true ) { 13591 conv = converters[ conv2 ]; 13592 13593 // Otherwise, insert the intermediate dataType 13594 } else if ( converters[ conv2 ] !== true ) { 13595 current = tmp[ 0 ]; 13596 dataTypes.unshift( tmp[ 1 ] ); 13597 } 13598 break; 13599 } 13600 } 13601 } 13602 } 13603 13604 // Apply converter (if not an equivalence) 13605 if ( conv !== true ) { 13606 13607 // Unless errors are allowed to bubble, catch and return them 13608 if ( conv && s.throws ) { 13609 response = conv( response ); 13610 } else { 13611 try { 13612 response = conv( response ); 13613 } catch ( e ) { 13614 return { 13615 state: "parsererror", 13616 error: conv ? e : "No conversion from " + prev + " to " + current 13617 }; 13618 } 13619 } 13620 } 13621 } 13622 } 13623 } 13624 13625 return { state: "success", data: response }; 13626} 13627 13628jQuery.extend( { 13629 13630 // Counter for holding the number of active queries 13631 active: 0, 13632 13633 // Last-Modified header cache for next request 13634 lastModified: {}, 13635 etag: {}, 13636 13637 ajaxSettings: { 13638 url: location.href, 13639 type: "GET", 13640 isLocal: rlocalProtocol.test( location.protocol ), 13641 global: true, 13642 processData: true, 13643 async: true, 13644 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 13645 13646 /* 13647 timeout: 0, 13648 data: null, 13649 dataType: null, 13650 username: null, 13651 password: null, 13652 cache: null, 13653 throws: false, 13654 traditional: false, 13655 headers: {}, 13656 */ 13657 13658 accepts: { 13659 "*": allTypes, 13660 text: "text/plain", 13661 html: "text/html", 13662 xml: "application/xml, text/xml", 13663 json: "application/json, text/javascript" 13664 }, 13665 13666 contents: { 13667 xml: /\bxml\b/, 13668 html: /\bhtml/, 13669 json: /\bjson\b/ 13670 }, 13671 13672 responseFields: { 13673 xml: "responseXML", 13674 text: "responseText", 13675 json: "responseJSON" 13676 }, 13677 13678 // Data converters 13679 // Keys separate source (or catchall "*") and destination types with a single space 13680 converters: { 13681 13682 // Convert anything to text 13683 "* text": String, 13684 13685 // Text to html (true = no transformation) 13686 "text html": true, 13687 13688 // Evaluate text as a json expression 13689 "text json": JSON.parse, 13690 13691 // Parse text as xml 13692 "text xml": jQuery.parseXML 13693 }, 13694 13695 // For options that shouldn't be deep extended: 13696 // you can add your own custom options here if 13697 // and when you create one that shouldn't be 13698 // deep extended (see ajaxExtend) 13699 flatOptions: { 13700 url: true, 13701 context: true 13702 } 13703 }, 13704 13705 // Creates a full fledged settings object into target 13706 // with both ajaxSettings and settings fields. 13707 // If target is omitted, writes into ajaxSettings. 13708 ajaxSetup: function( target, settings ) { 13709 return settings ? 13710 13711 // Building a settings object 13712 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 13713 13714 // Extending ajaxSettings 13715 ajaxExtend( jQuery.ajaxSettings, target ); 13716 }, 13717 13718 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 13719 ajaxTransport: addToPrefiltersOrTransports( transports ), 13720 13721 // Main method 13722 ajax: function( url, options ) { 13723 13724 // If url is an object, simulate pre-1.5 signature 13725 if ( typeof url === "object" ) { 13726 options = url; 13727 url = undefined; 13728 } 13729 13730 // Force options to be an object 13731 options = options || {}; 13732 13733 var transport, 13734 13735 // URL without anti-cache param 13736 cacheURL, 13737 13738 // Response headers 13739 responseHeadersString, 13740 responseHeaders, 13741 13742 // timeout handle 13743 timeoutTimer, 13744 13745 // Url cleanup var 13746 urlAnchor, 13747 13748 // Request state (becomes false upon send and true upon completion) 13749 completed, 13750 13751 // To know if global events are to be dispatched 13752 fireGlobals, 13753 13754 // Loop variable 13755 i, 13756 13757 // uncached part of the url 13758 uncached, 13759 13760 // Create the final options object 13761 s = jQuery.ajaxSetup( {}, options ), 13762 13763 // Callbacks context 13764 callbackContext = s.context || s, 13765 13766 // Context for global events is callbackContext if it is a DOM node or jQuery collection 13767 globalEventContext = s.context && 13768 ( callbackContext.nodeType || callbackContext.jquery ) ? 13769 jQuery( callbackContext ) : 13770 jQuery.event, 13771 13772 // Deferreds 13773 deferred = jQuery.Deferred(), 13774 completeDeferred = jQuery.Callbacks( "once memory" ), 13775 13776 // Status-dependent callbacks 13777 statusCode = s.statusCode || {}, 13778 13779 // Headers (they are sent all at once) 13780 requestHeaders = {}, 13781 requestHeadersNames = {}, 13782 13783 // Default abort message 13784 strAbort = "canceled", 13785 13786 // Fake xhr 13787 jqXHR = { 13788 readyState: 0, 13789 13790 // Builds headers hashtable if needed 13791 getResponseHeader: function( key ) { 13792 var match; 13793 if ( completed ) { 13794 if ( !responseHeaders ) { 13795 responseHeaders = {}; 13796 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 13797 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 13798 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 13799 .concat( match[ 2 ] ); 13800 } 13801 } 13802 match = responseHeaders[ key.toLowerCase() + " " ]; 13803 } 13804 return match == null ? null : match.join( ", " ); 13805 }, 13806 13807 // Raw string 13808 getAllResponseHeaders: function() { 13809 return completed ? responseHeadersString : null; 13810 }, 13811 13812 // Caches the header 13813 setRequestHeader: function( name, value ) { 13814 if ( completed == null ) { 13815 name = requestHeadersNames[ name.toLowerCase() ] = 13816 requestHeadersNames[ name.toLowerCase() ] || name; 13817 requestHeaders[ name ] = value; 13818 } 13819 return this; 13820 }, 13821 13822 // Overrides response content-type header 13823 overrideMimeType: function( type ) { 13824 if ( completed == null ) { 13825 s.mimeType = type; 13826 } 13827 return this; 13828 }, 13829 13830 // Status-dependent callbacks 13831 statusCode: function( map ) { 13832 var code; 13833 if ( map ) { 13834 if ( completed ) { 13835 13836 // Execute the appropriate callbacks 13837 jqXHR.always( map[ jqXHR.status ] ); 13838 } else { 13839 13840 // Lazy-add the new callbacks in a way that preserves old ones 13841 for ( code in map ) { 13842 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 13843 } 13844 } 13845 } 13846 return this; 13847 }, 13848 13849 // Cancel the request 13850 abort: function( statusText ) { 13851 var finalText = statusText || strAbort; 13852 if ( transport ) { 13853 transport.abort( finalText ); 13854 } 13855 done( 0, finalText ); 13856 return this; 13857 } 13858 }; 13859 13860 // Attach deferreds 13861 deferred.promise( jqXHR ); 13862 13863 // Add protocol if not provided (prefilters might expect it) 13864 // Handle falsy url in the settings object (#10093: consistency with old signature) 13865 // We also use the url parameter if available 13866 s.url = ( ( url || s.url || location.href ) + "" ) 13867 .replace( rprotocol, location.protocol + "//" ); 13868 13869 // Alias method option to type as per ticket #12004 13870 s.type = options.method || options.type || s.method || s.type; 13871 13872 // Extract dataTypes list 13873 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 13874 13875 // A cross-domain request is in order when the origin doesn't match the current origin. 13876 if ( s.crossDomain == null ) { 13877 urlAnchor = document.createElement( "a" ); 13878 13879 // Support: IE <=8 - 11, Edge 12 - 15 13880 // IE throws exception on accessing the href property if url is malformed, 13881 // e.g. http://example.com:80x/ 13882 try { 13883 urlAnchor.href = s.url; 13884 13885 // Support: IE <=8 - 11 only 13886 // Anchor's host property isn't correctly set when s.url is relative 13887 urlAnchor.href = urlAnchor.href; 13888 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 13889 urlAnchor.protocol + "//" + urlAnchor.host; 13890 } catch ( e ) { 13891 13892 // If there is an error parsing the URL, assume it is crossDomain, 13893 // it can be rejected by the transport if it is invalid 13894 s.crossDomain = true; 13895 } 13896 } 13897 13898 // Convert data if not already a string 13899 if ( s.data && s.processData && typeof s.data !== "string" ) { 13900 s.data = jQuery.param( s.data, s.traditional ); 13901 } 13902 13903 // Apply prefilters 13904 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 13905 13906 // If request was aborted inside a prefilter, stop there 13907 if ( completed ) { 13908 return jqXHR; 13909 } 13910 13911 // We can fire global events as of now if asked to 13912 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 13913 fireGlobals = jQuery.event && s.global; 13914 13915 // Watch for a new set of requests 13916 if ( fireGlobals && jQuery.active++ === 0 ) { 13917 jQuery.event.trigger( "ajaxStart" ); 13918 } 13919 13920 // Uppercase the type 13921 s.type = s.type.toUpperCase(); 13922 13923 // Determine if request has content 13924 s.hasContent = !rnoContent.test( s.type ); 13925 13926 // Save the URL in case we're toying with the If-Modified-Since 13927 // and/or If-None-Match header later on 13928 // Remove hash to simplify url manipulation 13929 cacheURL = s.url.replace( rhash, "" ); 13930 13931 // More options handling for requests with no content 13932 if ( !s.hasContent ) { 13933 13934 // Remember the hash so we can put it back 13935 uncached = s.url.slice( cacheURL.length ); 13936 13937 // If data is available and should be processed, append data to url 13938 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 13939 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 13940 13941 // #9682: remove data so that it's not used in an eventual retry 13942 delete s.data; 13943 } 13944 13945 // Add or update anti-cache param if needed 13946 if ( s.cache === false ) { 13947 cacheURL = cacheURL.replace( rantiCache, "$1" ); 13948 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 13949 uncached; 13950 } 13951 13952 // Put hash and anti-cache on the URL that will be requested (gh-1732) 13953 s.url = cacheURL + uncached; 13954 13955 // Change '%20' to '+' if this is encoded form body content (gh-2658) 13956 } else if ( s.data && s.processData && 13957 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 13958 s.data = s.data.replace( r20, "+" ); 13959 } 13960 13961 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 13962 if ( s.ifModified ) { 13963 if ( jQuery.lastModified[ cacheURL ] ) { 13964 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 13965 } 13966 if ( jQuery.etag[ cacheURL ] ) { 13967 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 13968 } 13969 } 13970 13971 // Set the correct header, if data is being sent 13972 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 13973 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 13974 } 13975 13976 // Set the Accepts header for the server, depending on the dataType 13977 jqXHR.setRequestHeader( 13978 "Accept", 13979 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 13980 s.accepts[ s.dataTypes[ 0 ] ] + 13981 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 13982 s.accepts[ "*" ] 13983 ); 13984 13985 // Check for headers option 13986 for ( i in s.headers ) { 13987 jqXHR.setRequestHeader( i, s.headers[ i ] ); 13988 } 13989 13990 // Allow custom headers/mimetypes and early abort 13991 if ( s.beforeSend && 13992 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 13993 13994 // Abort if not done already and return 13995 return jqXHR.abort(); 13996 } 13997 13998 // Aborting is no longer a cancellation 13999 strAbort = "abort"; 14000 14001 // Install callbacks on deferreds 14002 completeDeferred.add( s.complete ); 14003 jqXHR.done( s.success ); 14004 jqXHR.fail( s.error ); 14005 14006 // Get transport 14007 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 14008 14009 // If no transport, we auto-abort 14010 if ( !transport ) { 14011 done( -1, "No Transport" ); 14012 } else { 14013 jqXHR.readyState = 1; 14014 14015 // Send global event 14016 if ( fireGlobals ) { 14017 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 14018 } 14019 14020 // If request was aborted inside ajaxSend, stop there 14021 if ( completed ) { 14022 return jqXHR; 14023 } 14024 14025 // Timeout 14026 if ( s.async && s.timeout > 0 ) { 14027 timeoutTimer = window.setTimeout( function() { 14028 jqXHR.abort( "timeout" ); 14029 }, s.timeout ); 14030 } 14031 14032 try { 14033 completed = false; 14034 transport.send( requestHeaders, done ); 14035 } catch ( e ) { 14036 14037 // Rethrow post-completion exceptions 14038 if ( completed ) { 14039 throw e; 14040 } 14041 14042 // Propagate others as results 14043 done( -1, e ); 14044 } 14045 } 14046 14047 // Callback for when everything is done 14048 function done( status, nativeStatusText, responses, headers ) { 14049 var isSuccess, success, error, response, modified, 14050 statusText = nativeStatusText; 14051 14052 // Ignore repeat invocations 14053 if ( completed ) { 14054 return; 14055 } 14056 14057 completed = true; 14058 14059 // Clear timeout if it exists 14060 if ( timeoutTimer ) { 14061 window.clearTimeout( timeoutTimer ); 14062 } 14063 14064 // Dereference transport for early garbage collection 14065 // (no matter how long the jqXHR object will be used) 14066 transport = undefined; 14067 14068 // Cache response headers 14069 responseHeadersString = headers || ""; 14070 14071 // Set readyState 14072 jqXHR.readyState = status > 0 ? 4 : 0; 14073 14074 // Determine if successful 14075 isSuccess = status >= 200 && status < 300 || status === 304; 14076 14077 // Get response data 14078 if ( responses ) { 14079 response = ajaxHandleResponses( s, jqXHR, responses ); 14080 } 14081 14082 // Use a noop converter for missing script but not if jsonp 14083 if ( !isSuccess && 14084 jQuery.inArray( "script", s.dataTypes ) > -1 && 14085 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 14086 s.converters[ "text script" ] = function() {}; 14087 } 14088 14089 // Convert no matter what (that way responseXXX fields are always set) 14090 response = ajaxConvert( s, response, jqXHR, isSuccess ); 14091 14092 // If successful, handle type chaining 14093 if ( isSuccess ) { 14094 14095 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 14096 if ( s.ifModified ) { 14097 modified = jqXHR.getResponseHeader( "Last-Modified" ); 14098 if ( modified ) { 14099 jQuery.lastModified[ cacheURL ] = modified; 14100 } 14101 modified = jqXHR.getResponseHeader( "etag" ); 14102 if ( modified ) { 14103 jQuery.etag[ cacheURL ] = modified; 14104 } 14105 } 14106 14107 // if no content 14108 if ( status === 204 || s.type === "HEAD" ) { 14109 statusText = "nocontent"; 14110 14111 // if not modified 14112 } else if ( status === 304 ) { 14113 statusText = "notmodified"; 14114 14115 // If we have data, let's convert it 14116 } else { 14117 statusText = response.state; 14118 success = response.data; 14119 error = response.error; 14120 isSuccess = !error; 14121 } 14122 } else { 14123 14124 // Extract error from statusText and normalize for non-aborts 14125 error = statusText; 14126 if ( status || !statusText ) { 14127 statusText = "error"; 14128 if ( status < 0 ) { 14129 status = 0; 14130 } 14131 } 14132 } 14133 14134 // Set data for the fake xhr object 14135 jqXHR.status = status; 14136 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 14137 14138 // Success/Error 14139 if ( isSuccess ) { 14140 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 14141 } else { 14142 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 14143 } 14144 14145 // Status-dependent callbacks 14146 jqXHR.statusCode( statusCode ); 14147 statusCode = undefined; 14148 14149 if ( fireGlobals ) { 14150 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 14151 [ jqXHR, s, isSuccess ? success : error ] ); 14152 } 14153 14154 // Complete 14155 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 14156 14157 if ( fireGlobals ) { 14158 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 14159 14160 // Handle the global AJAX counter 14161 if ( !( --jQuery.active ) ) { 14162 jQuery.event.trigger( "ajaxStop" ); 14163 } 14164 } 14165 } 14166 14167 return jqXHR; 14168 }, 14169 14170 getJSON: function( url, data, callback ) { 14171 return jQuery.get( url, data, callback, "json" ); 14172 }, 14173 14174 getScript: function( url, callback ) { 14175 return jQuery.get( url, undefined, callback, "script" ); 14176 } 14177} ); 14178 14179jQuery.each( [ "get", "post" ], function( _i, method ) { 14180 jQuery[ method ] = function( url, data, callback, type ) { 14181 14182 // Shift arguments if data argument was omitted 14183 if ( isFunction( data ) ) { 14184 type = type || callback; 14185 callback = data; 14186 data = undefined; 14187 } 14188 14189 // The url can be an options object (which then must have .url) 14190 return jQuery.ajax( jQuery.extend( { 14191 url: url, 14192 type: method, 14193 dataType: type, 14194 data: data, 14195 success: callback 14196 }, jQuery.isPlainObject( url ) && url ) ); 14197 }; 14198} ); 14199 14200jQuery.ajaxPrefilter( function( s ) { 14201 var i; 14202 for ( i in s.headers ) { 14203 if ( i.toLowerCase() === "content-type" ) { 14204 s.contentType = s.headers[ i ] || ""; 14205 } 14206 } 14207} ); 14208 14209 14210jQuery._evalUrl = function( url, options, doc ) { 14211 return jQuery.ajax( { 14212 url: url, 14213 14214 // Make this explicit, since user can override this through ajaxSetup (#11264) 14215 type: "GET", 14216 dataType: "script", 14217 cache: true, 14218 async: false, 14219 global: false, 14220 14221 // Only evaluate the response if it is successful (gh-4126) 14222 // dataFilter is not invoked for failure responses, so using it instead 14223 // of the default converter is kludgy but it works. 14224 converters: { 14225 "text script": function() {} 14226 }, 14227 dataFilter: function( response ) { 14228 jQuery.globalEval( response, options, doc ); 14229 } 14230 } ); 14231}; 14232 14233 14234jQuery.fn.extend( { 14235 wrapAll: function( html ) { 14236 var wrap; 14237 14238 if ( this[ 0 ] ) { 14239 if ( isFunction( html ) ) { 14240 html = html.call( this[ 0 ] ); 14241 } 14242 14243 // The elements to wrap the target around 14244 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 14245 14246 if ( this[ 0 ].parentNode ) { 14247 wrap.insertBefore( this[ 0 ] ); 14248 } 14249 14250 wrap.map( function() { 14251 var elem = this; 14252 14253 while ( elem.firstElementChild ) { 14254 elem = elem.firstElementChild; 14255 } 14256 14257 return elem; 14258 } ).append( this ); 14259 } 14260 14261 return this; 14262 }, 14263 14264 wrapInner: function( html ) { 14265 if ( isFunction( html ) ) { 14266 return this.each( function( i ) { 14267 jQuery( this ).wrapInner( html.call( this, i ) ); 14268 } ); 14269 } 14270 14271 return this.each( function() { 14272 var self = jQuery( this ), 14273 contents = self.contents(); 14274 14275 if ( contents.length ) { 14276 contents.wrapAll( html ); 14277 14278 } else { 14279 self.append( html ); 14280 } 14281 } ); 14282 }, 14283 14284 wrap: function( html ) { 14285 var htmlIsFunction = isFunction( html ); 14286 14287 return this.each( function( i ) { 14288 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 14289 } ); 14290 }, 14291 14292 unwrap: function( selector ) { 14293 this.parent( selector ).not( "body" ).each( function() { 14294 jQuery( this ).replaceWith( this.childNodes ); 14295 } ); 14296 return this; 14297 } 14298} ); 14299 14300 14301jQuery.expr.pseudos.hidden = function( elem ) { 14302 return !jQuery.expr.pseudos.visible( elem ); 14303}; 14304jQuery.expr.pseudos.visible = function( elem ) { 14305 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 14306}; 14307 14308 14309 14310 14311jQuery.ajaxSettings.xhr = function() { 14312 try { 14313 return new window.XMLHttpRequest(); 14314 } catch ( e ) {} 14315}; 14316 14317var xhrSuccessStatus = { 14318 14319 // File protocol always yields status code 0, assume 200 14320 0: 200, 14321 14322 // Support: IE <=9 only 14323 // #1450: sometimes IE returns 1223 when it should be 204 14324 1223: 204 14325 }, 14326 xhrSupported = jQuery.ajaxSettings.xhr(); 14327 14328support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 14329support.ajax = xhrSupported = !!xhrSupported; 14330 14331jQuery.ajaxTransport( function( options ) { 14332 var callback, errorCallback; 14333 14334 // Cross domain only allowed if supported through XMLHttpRequest 14335 if ( support.cors || xhrSupported && !options.crossDomain ) { 14336 return { 14337 send: function( headers, complete ) { 14338 var i, 14339 xhr = options.xhr(); 14340 14341 xhr.open( 14342 options.type, 14343 options.url, 14344 options.async, 14345 options.username, 14346 options.password 14347 ); 14348 14349 // Apply custom fields if provided 14350 if ( options.xhrFields ) { 14351 for ( i in options.xhrFields ) { 14352 xhr[ i ] = options.xhrFields[ i ]; 14353 } 14354 } 14355 14356 // Override mime type if needed 14357 if ( options.mimeType && xhr.overrideMimeType ) { 14358 xhr.overrideMimeType( options.mimeType ); 14359 } 14360 14361 // X-Requested-With header 14362 // For cross-domain requests, seeing as conditions for a preflight are 14363 // akin to a jigsaw puzzle, we simply never set it to be sure. 14364 // (it can always be set on a per-request basis or even using ajaxSetup) 14365 // For same-domain requests, won't change header if already provided. 14366 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 14367 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 14368 } 14369 14370 // Set headers 14371 for ( i in headers ) { 14372 xhr.setRequestHeader( i, headers[ i ] ); 14373 } 14374 14375 // Callback 14376 callback = function( type ) { 14377 return function() { 14378 if ( callback ) { 14379 callback = errorCallback = xhr.onload = 14380 xhr.onerror = xhr.onabort = xhr.ontimeout = 14381 xhr.onreadystatechange = null; 14382 14383 if ( type === "abort" ) { 14384 xhr.abort(); 14385 } else if ( type === "error" ) { 14386 14387 // Support: IE <=9 only 14388 // On a manual native abort, IE9 throws 14389 // errors on any property access that is not readyState 14390 if ( typeof xhr.status !== "number" ) { 14391 complete( 0, "error" ); 14392 } else { 14393 complete( 14394 14395 // File: protocol always yields status 0; see #8605, #14207 14396 xhr.status, 14397 xhr.statusText 14398 ); 14399 } 14400 } else { 14401 complete( 14402 xhrSuccessStatus[ xhr.status ] || xhr.status, 14403 xhr.statusText, 14404 14405 // Support: IE <=9 only 14406 // IE9 has no XHR2 but throws on binary (trac-11426) 14407 // For XHR2 non-text, let the caller handle it (gh-2498) 14408 ( xhr.responseType || "text" ) !== "text" || 14409 typeof xhr.responseText !== "string" ? 14410 { binary: xhr.response } : 14411 { text: xhr.responseText }, 14412 xhr.getAllResponseHeaders() 14413 ); 14414 } 14415 } 14416 }; 14417 }; 14418 14419 // Listen to events 14420 xhr.onload = callback(); 14421 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 14422 14423 // Support: IE 9 only 14424 // Use onreadystatechange to replace onabort 14425 // to handle uncaught aborts 14426 if ( xhr.onabort !== undefined ) { 14427 xhr.onabort = errorCallback; 14428 } else { 14429 xhr.onreadystatechange = function() { 14430 14431 // Check readyState before timeout as it changes 14432 if ( xhr.readyState === 4 ) { 14433 14434 // Allow onerror to be called first, 14435 // but that will not handle a native abort 14436 // Also, save errorCallback to a variable 14437 // as xhr.onerror cannot be accessed 14438 window.setTimeout( function() { 14439 if ( callback ) { 14440 errorCallback(); 14441 } 14442 } ); 14443 } 14444 }; 14445 } 14446 14447 // Create the abort callback 14448 callback = callback( "abort" ); 14449 14450 try { 14451 14452 // Do send the request (this may raise an exception) 14453 xhr.send( options.hasContent && options.data || null ); 14454 } catch ( e ) { 14455 14456 // #14683: Only rethrow if this hasn't been notified as an error yet 14457 if ( callback ) { 14458 throw e; 14459 } 14460 } 14461 }, 14462 14463 abort: function() { 14464 if ( callback ) { 14465 callback(); 14466 } 14467 } 14468 }; 14469 } 14470} ); 14471 14472 14473 14474 14475// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 14476jQuery.ajaxPrefilter( function( s ) { 14477 if ( s.crossDomain ) { 14478 s.contents.script = false; 14479 } 14480} ); 14481 14482// Install script dataType 14483jQuery.ajaxSetup( { 14484 accepts: { 14485 script: "text/javascript, application/javascript, " + 14486 "application/ecmascript, application/x-ecmascript" 14487 }, 14488 contents: { 14489 script: /\b(?:java|ecma)script\b/ 14490 }, 14491 converters: { 14492 "text script": function( text ) { 14493 jQuery.globalEval( text ); 14494 return text; 14495 } 14496 } 14497} ); 14498 14499// Handle cache's special case and crossDomain 14500jQuery.ajaxPrefilter( "script", function( s ) { 14501 if ( s.cache === undefined ) { 14502 s.cache = false; 14503 } 14504 if ( s.crossDomain ) { 14505 s.type = "GET"; 14506 } 14507} ); 14508 14509// Bind script tag hack transport 14510jQuery.ajaxTransport( "script", function( s ) { 14511 14512 // This transport only deals with cross domain or forced-by-attrs requests 14513 if ( s.crossDomain || s.scriptAttrs ) { 14514 var script, callback; 14515 return { 14516 send: function( _, complete ) { 14517 script = jQuery( "<script>" ) 14518 .attr( s.scriptAttrs || {} ) 14519 .prop( { charset: s.scriptCharset, src: s.url } ) 14520 .on( "load error", callback = function( evt ) { 14521 script.remove(); 14522 callback = null; 14523 if ( evt ) { 14524 complete( evt.type === "error" ? 404 : 200, evt.type ); 14525 } 14526 } ); 14527 14528 // Use native DOM manipulation to avoid our domManip AJAX trickery 14529 document.head.appendChild( script[ 0 ] ); 14530 }, 14531 abort: function() { 14532 if ( callback ) { 14533 callback(); 14534 } 14535 } 14536 }; 14537 } 14538} ); 14539 14540 14541 14542 14543var oldCallbacks = [], 14544 rjsonp = /(=)\?(?=&|$)|\?\?/; 14545 14546// Default jsonp settings 14547jQuery.ajaxSetup( { 14548 jsonp: "callback", 14549 jsonpCallback: function() { 14550 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 14551 this[ callback ] = true; 14552 return callback; 14553 } 14554} ); 14555 14556// Detect, normalize options and install callbacks for jsonp requests 14557jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 14558 14559 var callbackName, overwritten, responseContainer, 14560 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 14561 "url" : 14562 typeof s.data === "string" && 14563 ( s.contentType || "" ) 14564 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 14565 rjsonp.test( s.data ) && "data" 14566 ); 14567 14568 // Handle iff the expected data type is "jsonp" or we have a parameter to set 14569 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 14570 14571 // Get callback name, remembering preexisting value associated with it 14572 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 14573 s.jsonpCallback() : 14574 s.jsonpCallback; 14575 14576 // Insert callback into url or form data 14577 if ( jsonProp ) { 14578 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 14579 } else if ( s.jsonp !== false ) { 14580 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 14581 } 14582 14583 // Use data converter to retrieve json after script execution 14584 s.converters[ "script json" ] = function() { 14585 if ( !responseContainer ) { 14586 jQuery.error( callbackName + " was not called" ); 14587 } 14588 return responseContainer[ 0 ]; 14589 }; 14590 14591 // Force json dataType 14592 s.dataTypes[ 0 ] = "json"; 14593 14594 // Install callback 14595 overwritten = window[ callbackName ]; 14596 window[ callbackName ] = function() { 14597 responseContainer = arguments; 14598 }; 14599 14600 // Clean-up function (fires after converters) 14601 jqXHR.always( function() { 14602 14603 // If previous value didn't exist - remove it 14604 if ( overwritten === undefined ) { 14605 jQuery( window ).removeProp( callbackName ); 14606 14607 // Otherwise restore preexisting value 14608 } else { 14609 window[ callbackName ] = overwritten; 14610 } 14611 14612 // Save back as free 14613 if ( s[ callbackName ] ) { 14614 14615 // Make sure that re-using the options doesn't screw things around 14616 s.jsonpCallback = originalSettings.jsonpCallback; 14617 14618 // Save the callback name for future use 14619 oldCallbacks.push( callbackName ); 14620 } 14621 14622 // Call if it was a function and we have a response 14623 if ( responseContainer && isFunction( overwritten ) ) { 14624 overwritten( responseContainer[ 0 ] ); 14625 } 14626 14627 responseContainer = overwritten = undefined; 14628 } ); 14629 14630 // Delegate to script 14631 return "script"; 14632 } 14633} ); 14634 14635 14636 14637 14638// Support: Safari 8 only 14639// In Safari 8 documents created via document.implementation.createHTMLDocument 14640// collapse sibling forms: the second one becomes a child of the first one. 14641// Because of that, this security measure has to be disabled in Safari 8. 14642// https://bugs.webkit.org/show_bug.cgi?id=137337 14643support.createHTMLDocument = ( function() { 14644 var body = document.implementation.createHTMLDocument( "" ).body; 14645 body.innerHTML = "<form></form><form></form>"; 14646 return body.childNodes.length === 2; 14647} )(); 14648 14649 14650// Argument "data" should be string of html 14651// context (optional): If specified, the fragment will be created in this context, 14652// defaults to document 14653// keepScripts (optional): If true, will include scripts passed in the html string 14654jQuery.parseHTML = function( data, context, keepScripts ) { 14655 if ( typeof data !== "string" ) { 14656 return []; 14657 } 14658 if ( typeof context === "boolean" ) { 14659 keepScripts = context; 14660 context = false; 14661 } 14662 14663 var base, parsed, scripts; 14664 14665 if ( !context ) { 14666 14667 // Stop scripts or inline event handlers from being executed immediately 14668 // by using document.implementation 14669 if ( support.createHTMLDocument ) { 14670 context = document.implementation.createHTMLDocument( "" ); 14671 14672 // Set the base href for the created document 14673 // so any parsed elements with URLs 14674 // are based on the document's URL (gh-2965) 14675 base = context.createElement( "base" ); 14676 base.href = document.location.href; 14677 context.head.appendChild( base ); 14678 } else { 14679 context = document; 14680 } 14681 } 14682 14683 parsed = rsingleTag.exec( data ); 14684 scripts = !keepScripts && []; 14685 14686 // Single tag 14687 if ( parsed ) { 14688 return [ context.createElement( parsed[ 1 ] ) ]; 14689 } 14690 14691 parsed = buildFragment( [ data ], context, scripts ); 14692 14693 if ( scripts && scripts.length ) { 14694 jQuery( scripts ).remove(); 14695 } 14696 14697 return jQuery.merge( [], parsed.childNodes ); 14698}; 14699 14700 14701/** 14702 * Load a url into a page 14703 */ 14704jQuery.fn.load = function( url, params, callback ) { 14705 var selector, type, response, 14706 self = this, 14707 off = url.indexOf( " " ); 14708 14709 if ( off > -1 ) { 14710 selector = stripAndCollapse( url.slice( off ) ); 14711 url = url.slice( 0, off ); 14712 } 14713 14714 // If it's a function 14715 if ( isFunction( params ) ) { 14716 14717 // We assume that it's the callback 14718 callback = params; 14719 params = undefined; 14720 14721 // Otherwise, build a param string 14722 } else if ( params && typeof params === "object" ) { 14723 type = "POST"; 14724 } 14725 14726 // If we have elements to modify, make the request 14727 if ( self.length > 0 ) { 14728 jQuery.ajax( { 14729 url: url, 14730 14731 // If "type" variable is undefined, then "GET" method will be used. 14732 // Make value of this field explicit since 14733 // user can override it through ajaxSetup method 14734 type: type || "GET", 14735 dataType: "html", 14736 data: params 14737 } ).done( function( responseText ) { 14738 14739 // Save response for use in complete callback 14740 response = arguments; 14741 14742 self.html( selector ? 14743 14744 // If a selector was specified, locate the right elements in a dummy div 14745 // Exclude scripts to avoid IE 'Permission Denied' errors 14746 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 14747 14748 // Otherwise use the full result 14749 responseText ); 14750 14751 // If the request succeeds, this function gets "data", "status", "jqXHR" 14752 // but they are ignored because response was set above. 14753 // If it fails, this function gets "jqXHR", "status", "error" 14754 } ).always( callback && function( jqXHR, status ) { 14755 self.each( function() { 14756 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 14757 } ); 14758 } ); 14759 } 14760 14761 return this; 14762}; 14763 14764 14765 14766 14767jQuery.expr.pseudos.animated = function( elem ) { 14768 return jQuery.grep( jQuery.timers, function( fn ) { 14769 return elem === fn.elem; 14770 } ).length; 14771}; 14772 14773 14774 14775 14776jQuery.offset = { 14777 setOffset: function( elem, options, i ) { 14778 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 14779 position = jQuery.css( elem, "position" ), 14780 curElem = jQuery( elem ), 14781 props = {}; 14782 14783 // Set position first, in-case top/left are set even on static elem 14784 if ( position === "static" ) { 14785 elem.style.position = "relative"; 14786 } 14787 14788 curOffset = curElem.offset(); 14789 curCSSTop = jQuery.css( elem, "top" ); 14790 curCSSLeft = jQuery.css( elem, "left" ); 14791 calculatePosition = ( position === "absolute" || position === "fixed" ) && 14792 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 14793 14794 // Need to be able to calculate position if either 14795 // top or left is auto and position is either absolute or fixed 14796 if ( calculatePosition ) { 14797 curPosition = curElem.position(); 14798 curTop = curPosition.top; 14799 curLeft = curPosition.left; 14800 14801 } else { 14802 curTop = parseFloat( curCSSTop ) || 0; 14803 curLeft = parseFloat( curCSSLeft ) || 0; 14804 } 14805 14806 if ( isFunction( options ) ) { 14807 14808 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 14809 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 14810 } 14811 14812 if ( options.top != null ) { 14813 props.top = ( options.top - curOffset.top ) + curTop; 14814 } 14815 if ( options.left != null ) { 14816 props.left = ( options.left - curOffset.left ) + curLeft; 14817 } 14818 14819 if ( "using" in options ) { 14820 options.using.call( elem, props ); 14821 14822 } else { 14823 curElem.css( props ); 14824 } 14825 } 14826}; 14827 14828jQuery.fn.extend( { 14829 14830 // offset() relates an element's border box to the document origin 14831 offset: function( options ) { 14832 14833 // Preserve chaining for setter 14834 if ( arguments.length ) { 14835 return options === undefined ? 14836 this : 14837 this.each( function( i ) { 14838 jQuery.offset.setOffset( this, options, i ); 14839 } ); 14840 } 14841 14842 var rect, win, 14843 elem = this[ 0 ]; 14844 14845 if ( !elem ) { 14846 return; 14847 } 14848 14849 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 14850 // Support: IE <=11 only 14851 // Running getBoundingClientRect on a 14852 // disconnected node in IE throws an error 14853 if ( !elem.getClientRects().length ) { 14854 return { top: 0, left: 0 }; 14855 } 14856 14857 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 14858 rect = elem.getBoundingClientRect(); 14859 win = elem.ownerDocument.defaultView; 14860 return { 14861 top: rect.top + win.pageYOffset, 14862 left: rect.left + win.pageXOffset 14863 }; 14864 }, 14865 14866 // position() relates an element's margin box to its offset parent's padding box 14867 // This corresponds to the behavior of CSS absolute positioning 14868 position: function() { 14869 if ( !this[ 0 ] ) { 14870 return; 14871 } 14872 14873 var offsetParent, offset, doc, 14874 elem = this[ 0 ], 14875 parentOffset = { top: 0, left: 0 }; 14876 14877 // position:fixed elements are offset from the viewport, which itself always has zero offset 14878 if ( jQuery.css( elem, "position" ) === "fixed" ) { 14879 14880 // Assume position:fixed implies availability of getBoundingClientRect 14881 offset = elem.getBoundingClientRect(); 14882 14883 } else { 14884 offset = this.offset(); 14885 14886 // Account for the *real* offset parent, which can be the document or its root element 14887 // when a statically positioned element is identified 14888 doc = elem.ownerDocument; 14889 offsetParent = elem.offsetParent || doc.documentElement; 14890 while ( offsetParent && 14891 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 14892 jQuery.css( offsetParent, "position" ) === "static" ) { 14893 14894 offsetParent = offsetParent.parentNode; 14895 } 14896 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 14897 14898 // Incorporate borders into its offset, since they are outside its content origin 14899 parentOffset = jQuery( offsetParent ).offset(); 14900 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 14901 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 14902 } 14903 } 14904 14905 // Subtract parent offsets and element margins 14906 return { 14907 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 14908 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 14909 }; 14910 }, 14911 14912 // This method will return documentElement in the following cases: 14913 // 1) For the element inside the iframe without offsetParent, this method will return 14914 // documentElement of the parent window 14915 // 2) For the hidden or detached element 14916 // 3) For body or html element, i.e. in case of the html node - it will return itself 14917 // 14918 // but those exceptions were never presented as a real life use-cases 14919 // and might be considered as more preferable results. 14920 // 14921 // This logic, however, is not guaranteed and can change at any point in the future 14922 offsetParent: function() { 14923 return this.map( function() { 14924 var offsetParent = this.offsetParent; 14925 14926 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 14927 offsetParent = offsetParent.offsetParent; 14928 } 14929 14930 return offsetParent || documentElement; 14931 } ); 14932 } 14933} ); 14934 14935// Create scrollLeft and scrollTop methods 14936jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 14937 var top = "pageYOffset" === prop; 14938 14939 jQuery.fn[ method ] = function( val ) { 14940 return access( this, function( elem, method, val ) { 14941 14942 // Coalesce documents and windows 14943 var win; 14944 if ( isWindow( elem ) ) { 14945 win = elem; 14946 } else if ( elem.nodeType === 9 ) { 14947 win = elem.defaultView; 14948 } 14949 14950 if ( val === undefined ) { 14951 return win ? win[ prop ] : elem[ method ]; 14952 } 14953 14954 if ( win ) { 14955 win.scrollTo( 14956 !top ? val : win.pageXOffset, 14957 top ? val : win.pageYOffset 14958 ); 14959 14960 } else { 14961 elem[ method ] = val; 14962 } 14963 }, method, val, arguments.length ); 14964 }; 14965} ); 14966 14967// Support: Safari <=7 - 9.1, Chrome <=37 - 49 14968// Add the top/left cssHooks using jQuery.fn.position 14969// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 14970// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 14971// getComputedStyle returns percent when specified for top/left/bottom/right; 14972// rather than make the css module depend on the offset module, just check for it here 14973jQuery.each( [ "top", "left" ], function( _i, prop ) { 14974 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 14975 function( elem, computed ) { 14976 if ( computed ) { 14977 computed = curCSS( elem, prop ); 14978 14979 // If curCSS returns percentage, fallback to offset 14980 return rnumnonpx.test( computed ) ? 14981 jQuery( elem ).position()[ prop ] + "px" : 14982 computed; 14983 } 14984 } 14985 ); 14986} ); 14987 14988 14989// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 14990jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 14991 jQuery.each( { 14992 padding: "inner" + name, 14993 content: type, 14994 "": "outer" + name 14995 }, function( defaultExtra, funcName ) { 14996 14997 // Margin is only for outerHeight, outerWidth 14998 jQuery.fn[ funcName ] = function( margin, value ) { 14999 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 15000 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 15001 15002 return access( this, function( elem, type, value ) { 15003 var doc; 15004 15005 if ( isWindow( elem ) ) { 15006 15007 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 15008 return funcName.indexOf( "outer" ) === 0 ? 15009 elem[ "inner" + name ] : 15010 elem.document.documentElement[ "client" + name ]; 15011 } 15012 15013 // Get document width or height 15014 if ( elem.nodeType === 9 ) { 15015 doc = elem.documentElement; 15016 15017 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 15018 // whichever is greatest 15019 return Math.max( 15020 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 15021 elem.body[ "offset" + name ], doc[ "offset" + name ], 15022 doc[ "client" + name ] 15023 ); 15024 } 15025 15026 return value === undefined ? 15027 15028 // Get width or height on the element, requesting but not forcing parseFloat 15029 jQuery.css( elem, type, extra ) : 15030 15031 // Set width or height on the element 15032 jQuery.style( elem, type, value, extra ); 15033 }, type, chainable ? margin : undefined, chainable ); 15034 }; 15035 } ); 15036} ); 15037 15038 15039jQuery.each( [ 15040 "ajaxStart", 15041 "ajaxStop", 15042 "ajaxComplete", 15043 "ajaxError", 15044 "ajaxSuccess", 15045 "ajaxSend" 15046], function( _i, type ) { 15047 jQuery.fn[ type ] = function( fn ) { 15048 return this.on( type, fn ); 15049 }; 15050} ); 15051 15052 15053 15054 15055jQuery.fn.extend( { 15056 15057 bind: function( types, data, fn ) { 15058 return this.on( types, null, data, fn ); 15059 }, 15060 unbind: function( types, fn ) { 15061 return this.off( types, null, fn ); 15062 }, 15063 15064 delegate: function( selector, types, data, fn ) { 15065 return this.on( types, selector, data, fn ); 15066 }, 15067 undelegate: function( selector, types, fn ) { 15068 15069 // ( namespace ) or ( selector, types [, fn] ) 15070 return arguments.length === 1 ? 15071 this.off( selector, "**" ) : 15072 this.off( types, selector || "**", fn ); 15073 }, 15074 15075 hover: function( fnOver, fnOut ) { 15076 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 15077 } 15078} ); 15079 15080jQuery.each( 15081 ( "blur focus focusin focusout resize scroll click dblclick " + 15082 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 15083 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 15084 function( _i, name ) { 15085 15086 // Handle event binding 15087 jQuery.fn[ name ] = function( data, fn ) { 15088 return arguments.length > 0 ? 15089 this.on( name, null, data, fn ) : 15090 this.trigger( name ); 15091 }; 15092 } 15093); 15094 15095 15096 15097 15098// Support: Android <=4.0 only 15099// Make sure we trim BOM and NBSP 15100var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 15101 15102// Bind a function to a context, optionally partially applying any 15103// arguments. 15104// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 15105// However, it is not slated for removal any time soon 15106jQuery.proxy = function( fn, context ) { 15107 var tmp, args, proxy; 15108 15109 if ( typeof context === "string" ) { 15110 tmp = fn[ context ]; 15111 context = fn; 15112 fn = tmp; 15113 } 15114 15115 // Quick check to determine if target is callable, in the spec 15116 // this throws a TypeError, but we will just return undefined. 15117 if ( !isFunction( fn ) ) { 15118 return undefined; 15119 } 15120 15121 // Simulated bind 15122 args = slice.call( arguments, 2 ); 15123 proxy = function() { 15124 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 15125 }; 15126 15127 // Set the guid of unique handler to the same of original handler, so it can be removed 15128 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 15129 15130 return proxy; 15131}; 15132 15133jQuery.holdReady = function( hold ) { 15134 if ( hold ) { 15135 jQuery.readyWait++; 15136 } else { 15137 jQuery.ready( true ); 15138 } 15139}; 15140jQuery.isArray = Array.isArray; 15141jQuery.parseJSON = JSON.parse; 15142jQuery.nodeName = nodeName; 15143jQuery.isFunction = isFunction; 15144jQuery.isWindow = isWindow; 15145jQuery.camelCase = camelCase; 15146jQuery.type = toType; 15147 15148jQuery.now = Date.now; 15149 15150jQuery.isNumeric = function( obj ) { 15151 15152 // As of jQuery 3.0, isNumeric is limited to 15153 // strings and numbers (primitives or objects) 15154 // that can be coerced to finite numbers (gh-2662) 15155 var type = jQuery.type( obj ); 15156 return ( type === "number" || type === "string" ) && 15157 15158 // parseFloat NaNs numeric-cast false positives ("") 15159 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 15160 // subtraction forces infinities to NaN 15161 !isNaN( obj - parseFloat( obj ) ); 15162}; 15163 15164jQuery.trim = function( text ) { 15165 return text == null ? 15166 "" : 15167 ( text + "" ).replace( rtrim, "" ); 15168}; 15169 15170 15171 15172// Register as a named AMD module, since jQuery can be concatenated with other 15173// files that may use define, but not via a proper concatenation script that 15174// understands anonymous AMD modules. A named AMD is safest and most robust 15175// way to register. Lowercase jquery is used because AMD module names are 15176// derived from file names, and jQuery is normally delivered in a lowercase 15177// file name. Do this after creating the global so that if an AMD module wants 15178// to call noConflict to hide this version of jQuery, it will work. 15179 15180// Note that for maximum portability, libraries that are not jQuery should 15181// declare themselves as anonymous modules, and avoid setting a global if an 15182// AMD loader is present. jQuery is a special case. For more information, see 15183// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 15184 15185if ( true ) { 15186 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 15187 return jQuery; 15188 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 15189 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 15190} 15191 15192 15193 15194 15195var 15196 15197 // Map over jQuery in case of overwrite 15198 _jQuery = window.jQuery, 15199 15200 // Map over the $ in case of overwrite 15201 _$ = window.$; 15202 15203jQuery.noConflict = function( deep ) { 15204 if ( window.$ === jQuery ) { 15205 window.$ = _$; 15206 } 15207 15208 if ( deep && window.jQuery === jQuery ) { 15209 window.jQuery = _jQuery; 15210 } 15211 15212 return jQuery; 15213}; 15214 15215// Expose jQuery and $ identifiers, even in AMD 15216// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 15217// and CommonJS for browser emulators (#13566) 15218if ( typeof noGlobal === "undefined" ) { 15219 window.jQuery = window.$ = jQuery; 15220} 15221 15222 15223 15224 15225return jQuery; 15226} ); 15227 15228 15229/***/ }), 15230
vendor: 44,445 bytes, lines 15231-17097
15231/***/ "./node_modules/magnific-popup/dist/jquery.magnific-popup.js": 15232/*!*******************************************************************!*\ 15233 !*** ./node_modules/magnific-popup/dist/jquery.magnific-popup.js ***! 15234 \*******************************************************************/ 15235/***/ ((module, exports, __webpack_require__) => { 15236 15237/* provided dependency */ var __webpack_provided_window_dot_jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 15238var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Magnific Popup - v1.1.0 - 2016-02-20 15239* http://dimsemenov.com/plugins/magnific-popup/ 15240* Copyright (c) 2016 Dmitry Semenov; */ 15241;(function (factory) { 15242if (true) { 15243 // AMD. Register as an anonymous module. 15244 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 15245 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 15246 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 15247 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 15248 } else {} 15249 }(function($) { 15250 15251/*>>core*/ 15252/** 15253 * 15254 * Magnific Popup Core JS file 15255 * 15256 */ 15257 15258 15259/** 15260 * Private static constants 15261 */ 15262var CLOSE_EVENT = 'Close', 15263 BEFORE_CLOSE_EVENT = 'BeforeClose', 15264 AFTER_CLOSE_EVENT = 'AfterClose', 15265 BEFORE_APPEND_EVENT = 'BeforeAppend', 15266 MARKUP_PARSE_EVENT = 'MarkupParse', 15267 OPEN_EVENT = 'Open', 15268 CHANGE_EVENT = 'Change', 15269 NS = 'mfp', 15270 EVENT_NS = '.' + NS, 15271 READY_CLASS = 'mfp-ready', 15272 REMOVING_CLASS = 'mfp-removing', 15273 PREVENT_CLOSE_CLASS = 'mfp-prevent-close'; 15274 15275 15276/** 15277 * Private vars 15278 */ 15279/*jshint -W079 */ 15280var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this' 15281 MagnificPopup = function(){}, 15282 _isJQ = !!(__webpack_provided_window_dot_jQuery), 15283 _prevStatus, 15284 _window = $(window), 15285 _document, 15286 _prevContentType, 15287 _wrapClasses, 15288 _currPopupType; 15289 15290 15291/** 15292 * Private functions 15293 */ 15294var _mfpOn = function(name, f) { 15295 mfp.ev.on(NS + name + EVENT_NS, f); 15296 }, 15297 _getEl = function(className, appendTo, html, raw) { 15298 var el = document.createElement('div'); 15299 el.className = 'mfp-'+className; 15300 if(html) { 15301 el.innerHTML = html; 15302 } 15303 if(!raw) { 15304 el = $(el); 15305 if(appendTo) { 15306 el.appendTo(appendTo); 15307 } 15308 } else if(appendTo) { 15309 appendTo.appendChild(el); 15310 } 15311 return el; 15312 }, 15313 _mfpTrigger = function(e, data) { 15314 mfp.ev.triggerHandler(NS + e, data); 15315 15316 if(mfp.st.callbacks) { 15317 // converts "mfpEventName" to "eventName" callback and triggers it if it's present 15318 e = e.charAt(0).toLowerCase() + e.slice(1); 15319 if(mfp.st.callbacks[e]) { 15320 mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]); 15321 } 15322 } 15323 }, 15324 _getCloseBtn = function(type) { 15325 if(type !== _currPopupType || !mfp.currTemplate.closeBtn) { 15326 mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) ); 15327 _currPopupType = type; 15328 } 15329 return mfp.currTemplate.closeBtn; 15330 }, 15331 // Initialize Magnific Popup only when called at least once 15332 _checkInstance = function() { 15333 if(!$.magnificPopup.instance) { 15334 /*jshint -W020 */ 15335 mfp = new MagnificPopup(); 15336 mfp.init(); 15337 $.magnificPopup.instance = mfp; 15338 } 15339 }, 15340 // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr 15341 supportsTransitions = function() { 15342 var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist 15343 v = ['ms','O','Moz','Webkit']; // 'v' for vendor 15344 15345 if( s['transition'] !== undefined ) { 15346 return true; 15347 } 15348 15349 while( v.length ) { 15350 if( v.pop() + 'Transition' in s ) { 15351 return true; 15352 } 15353 } 15354 15355 return false; 15356 }; 15357 15358 15359 15360/** 15361 * Public functions 15362 */ 15363MagnificPopup.prototype = { 15364 15365 constructor: MagnificPopup, 15366 15367 /** 15368 * Initializes Magnific Popup plugin. 15369 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed 15370 */ 15371 init: function() { 15372 var appVersion = navigator.appVersion; 15373 mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener; 15374 mfp.isAndroid = (/android/gi).test(appVersion); 15375 mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion); 15376 mfp.supportsTransition = supportsTransitions(); 15377 15378 // We disable fixed positioned lightbox on devices that don't handle it nicely. 15379 // If you know a better way of detecting this - let me know. 15380 mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) ); 15381 _document = $(document); 15382 15383 mfp.popupsCache = {}; 15384 }, 15385 15386 /** 15387 * Opens popup 15388 * @param data [description] 15389 */ 15390 open: function(data) { 15391 15392 var i; 15393 15394 if(data.isObj === false) { 15395 // convert jQuery collection to array to avoid conflicts later 15396 mfp.items = data.items.toArray(); 15397 15398 mfp.index = 0; 15399 var items = data.items, 15400 item; 15401 for(i = 0; i < items.length; i++) { 15402 item = items[i]; 15403 if(item.parsed) { 15404 item = item.el[0]; 15405 } 15406 if(item === data.el[0]) { 15407 mfp.index = i; 15408 break; 15409 } 15410 } 15411 } else { 15412 mfp.items = $.isArray(data.items) ? data.items : [data.items]; 15413 mfp.index = data.index || 0; 15414 } 15415 15416 // if popup is already opened - we just update the content 15417 if(mfp.isOpen) { 15418 mfp.updateItemHTML(); 15419 return; 15420 } 15421 15422 mfp.types = []; 15423 _wrapClasses = ''; 15424 if(data.mainEl && data.mainEl.length) { 15425 mfp.ev = data.mainEl.eq(0); 15426 } else { 15427 mfp.ev = _document; 15428 } 15429 15430 if(data.key) { 15431 if(!mfp.popupsCache[data.key]) { 15432 mfp.popupsCache[data.key] = {}; 15433 } 15434 mfp.currTemplate = mfp.popupsCache[data.key]; 15435 } else { 15436 mfp.currTemplate = {}; 15437 } 15438 15439 15440 15441 mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 15442 mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos; 15443 15444 if(mfp.st.modal) { 15445 mfp.st.closeOnContentClick = false; 15446 mfp.st.closeOnBgClick = false; 15447 mfp.st.showCloseBtn = false; 15448 mfp.st.enableEscapeKey = false; 15449 } 15450 15451 15452 // Building markup 15453 // main containers are created only once 15454 if(!mfp.bgOverlay) { 15455 15456 // Dark overlay 15457 mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() { 15458 mfp.close(); 15459 }); 15460 15461 mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) { 15462 if(mfp._checkIfClose(e.target)) { 15463 mfp.close(); 15464 } 15465 }); 15466 15467 mfp.container = _getEl('container', mfp.wrap); 15468 } 15469 15470 mfp.contentContainer = _getEl('content'); 15471 if(mfp.st.preloader) { 15472 mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading); 15473 } 15474 15475 15476 // Initializing modules 15477 var modules = $.magnificPopup.modules; 15478 for(i = 0; i < modules.length; i++) { 15479 var n = modules[i]; 15480 n = n.charAt(0).toUpperCase() + n.slice(1); 15481 mfp['init'+n].call(mfp); 15482 } 15483 _mfpTrigger('BeforeOpen'); 15484 15485 15486 if(mfp.st.showCloseBtn) { 15487 // Close button 15488 if(!mfp.st.closeBtnInside) { 15489 mfp.wrap.append( _getCloseBtn() ); 15490 } else { 15491 _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) { 15492 values.close_replaceWith = _getCloseBtn(item.type); 15493 }); 15494 _wrapClasses += ' mfp-close-btn-in'; 15495 } 15496 } 15497 15498 if(mfp.st.alignTop) { 15499 _wrapClasses += ' mfp-align-top'; 15500 } 15501 15502 15503 15504 if(mfp.fixedContentPos) { 15505 mfp.wrap.css({ 15506 overflow: mfp.st.overflowY, 15507 overflowX: 'hidden', 15508 overflowY: mfp.st.overflowY 15509 }); 15510 } else { 15511 mfp.wrap.css({ 15512 top: _window.scrollTop(), 15513 position: 'absolute' 15514 }); 15515 } 15516 if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) { 15517 mfp.bgOverlay.css({ 15518 height: _document.height(), 15519 position: 'absolute' 15520 }); 15521 } 15522 15523 15524 15525 if(mfp.st.enableEscapeKey) { 15526 // Close on ESC key 15527 _document.on('keyup' + EVENT_NS, function(e) { 15528 if(e.keyCode === 27) { 15529 mfp.close(); 15530 } 15531 }); 15532 } 15533 15534 _window.on('resize' + EVENT_NS, function() { 15535 mfp.updateSize(); 15536 }); 15537 15538 15539 if(!mfp.st.closeOnContentClick) { 15540 _wrapClasses += ' mfp-auto-cursor'; 15541 } 15542 15543 if(_wrapClasses) 15544 mfp.wrap.addClass(_wrapClasses); 15545 15546 15547 // this triggers recalculation of layout, so we get it once to not to trigger twice 15548 var windowHeight = mfp.wH = _window.height(); 15549 15550 15551 var windowStyles = {}; 15552 15553 if( mfp.fixedContentPos ) { 15554 if(mfp._hasScrollBar(windowHeight)){ 15555 var s = mfp._getScrollbarSize(); 15556 if(s) { 15557 windowStyles.marginRight = s; 15558 } 15559 } 15560 } 15561 15562 if(mfp.fixedContentPos) { 15563 if(!mfp.isIE7) { 15564 windowStyles.overflow = 'hidden'; 15565 } else { 15566 // ie7 double-scroll bug 15567 $('body, html').css('overflow', 'hidden'); 15568 } 15569 } 15570 15571 15572 15573 var classesToadd = mfp.st.mainClass; 15574 if(mfp.isIE7) { 15575 classesToadd += ' mfp-ie7'; 15576 } 15577 if(classesToadd) { 15578 mfp._addClassToMFP( classesToadd ); 15579 } 15580 15581 // add content 15582 mfp.updateItemHTML(); 15583 15584 _mfpTrigger('BuildControls'); 15585 15586 // remove scrollbar, add margin e.t.c 15587 $('html').css(windowStyles); 15588 15589 // add everything to DOM 15590 mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) ); 15591 15592 // Save last focused element 15593 mfp._lastFocusedEl = document.activeElement; 15594 15595 // Wait for next cycle to allow CSS transition 15596 setTimeout(function() { 15597 15598 if(mfp.content) { 15599 mfp._addClassToMFP(READY_CLASS); 15600 mfp._setFocus(); 15601 } else { 15602 // if content is not defined (not loaded e.t.c) we add class only for BG 15603 mfp.bgOverlay.addClass(READY_CLASS); 15604 } 15605 15606 // Trap the focus in popup 15607 _document.on('focusin' + EVENT_NS, mfp._onFocusIn); 15608 15609 }, 16); 15610 15611 mfp.isOpen = true; 15612 mfp.updateSize(windowHeight); 15613 _mfpTrigger(OPEN_EVENT); 15614 15615 return data; 15616 }, 15617 15618 /** 15619 * Closes the popup 15620 */ 15621 close: function() { 15622 if(!mfp.isOpen) return; 15623 _mfpTrigger(BEFORE_CLOSE_EVENT); 15624 15625 mfp.isOpen = false; 15626 // for CSS3 animation 15627 if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) { 15628 mfp._addClassToMFP(REMOVING_CLASS); 15629 setTimeout(function() { 15630 mfp._close(); 15631 }, mfp.st.removalDelay); 15632 } else { 15633 mfp._close(); 15634 } 15635 }, 15636 15637 /** 15638 * Helper for close() function 15639 */ 15640 _close: function() { 15641 _mfpTrigger(CLOSE_EVENT); 15642 15643 var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' '; 15644 15645 mfp.bgOverlay.detach(); 15646 mfp.wrap.detach(); 15647 mfp.container.empty(); 15648 15649 if(mfp.st.mainClass) { 15650 classesToRemove += mfp.st.mainClass + ' '; 15651 } 15652 15653 mfp._removeClassFromMFP(classesToRemove); 15654 15655 if(mfp.fixedContentPos) { 15656 var windowStyles = {marginRight: ''}; 15657 if(mfp.isIE7) { 15658 $('body, html').css('overflow', ''); 15659 } else { 15660 windowStyles.overflow = ''; 15661 } 15662 $('html').css(windowStyles); 15663 } 15664 15665 _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS); 15666 mfp.ev.off(EVENT_NS); 15667 15668 // clean up DOM elements that aren't removed 15669 mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style'); 15670 mfp.bgOverlay.attr('class', 'mfp-bg'); 15671 mfp.container.attr('class', 'mfp-container'); 15672 15673 // remove close button from target element 15674 if(mfp.st.showCloseBtn && 15675 (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) { 15676 if(mfp.currTemplate.closeBtn) 15677 mfp.currTemplate.closeBtn.detach(); 15678 } 15679 15680 15681 if(mfp.st.autoFocusLast && mfp._lastFocusedEl) { 15682 $(mfp._lastFocusedEl).focus(); // put tab focus back 15683 } 15684 mfp.currItem = null; 15685 mfp.content = null; 15686 mfp.currTemplate = null; 15687 mfp.prevHeight = 0; 15688 15689 _mfpTrigger(AFTER_CLOSE_EVENT); 15690 }, 15691 15692 updateSize: function(winHeight) { 15693 15694 if(mfp.isIOS) { 15695 // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2 15696 var zoomLevel = document.documentElement.clientWidth / window.innerWidth; 15697 var height = window.innerHeight * zoomLevel; 15698 mfp.wrap.css('height', height); 15699 mfp.wH = height; 15700 } else { 15701 mfp.wH = winHeight || _window.height(); 15702 } 15703 // Fixes #84: popup incorrectly positioned with position:relative on body 15704 if(!mfp.fixedContentPos) { 15705 mfp.wrap.css('height', mfp.wH); 15706 } 15707 15708 _mfpTrigger('Resize'); 15709 15710 }, 15711 15712 /** 15713 * Set content of popup based on current index 15714 */ 15715 updateItemHTML: function() { 15716 var item = mfp.items[mfp.index]; 15717 15718 // Detach and perform modifications 15719 mfp.contentContainer.detach(); 15720 15721 if(mfp.content) 15722 mfp.content.detach(); 15723 15724 if(!item.parsed) { 15725 item = mfp.parseEl( mfp.index ); 15726 } 15727 15728 var type = item.type; 15729 15730 _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]); 15731 // BeforeChange event works like so: 15732 // _mfpOn('BeforeChange', function(e, prevType, newType) { }); 15733 15734 mfp.currItem = item; 15735 15736 if(!mfp.currTemplate[type]) { 15737 var markup = mfp.st[type] ? mfp.st[type].markup : false; 15738 15739 // allows to modify markup 15740 _mfpTrigger('FirstMarkupParse', markup); 15741 15742 if(markup) { 15743 mfp.currTemplate[type] = $(markup); 15744 } else { 15745 // if there is no markup found we just define that template is parsed 15746 mfp.currTemplate[type] = true; 15747 } 15748 } 15749 15750 if(_prevContentType && _prevContentType !== item.type) { 15751 mfp.container.removeClass('mfp-'+_prevContentType+'-holder'); 15752 } 15753 15754 var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]); 15755 mfp.appendContent(newContent, type); 15756 15757 item.preloaded = true; 15758 15759 _mfpTrigger(CHANGE_EVENT, item); 15760 _prevContentType = item.type; 15761 15762 // Append container back after its content changed 15763 mfp.container.prepend(mfp.contentContainer); 15764 15765 _mfpTrigger('AfterChange'); 15766 }, 15767 15768 15769 /** 15770 * Set HTML content of popup 15771 */ 15772 appendContent: function(newContent, type) { 15773 mfp.content = newContent; 15774 15775 if(newContent) { 15776 if(mfp.st.showCloseBtn && mfp.st.closeBtnInside && 15777 mfp.currTemplate[type] === true) { 15778 // if there is no markup, we just append close button element inside 15779 if(!mfp.content.find('.mfp-close').length) { 15780 mfp.content.append(_getCloseBtn()); 15781 } 15782 } else { 15783 mfp.content = newContent; 15784 } 15785 } else { 15786 mfp.content = ''; 15787 } 15788 15789 _mfpTrigger(BEFORE_APPEND_EVENT); 15790 mfp.container.addClass('mfp-'+type+'-holder'); 15791 15792 mfp.contentContainer.append(mfp.content); 15793 }, 15794 15795 15796 /** 15797 * Creates Magnific Popup data object based on given data 15798 * @param {int} index Index of item to parse 15799 */ 15800 parseEl: function(index) { 15801 var item = mfp.items[index], 15802 type; 15803 15804 if(item.tagName) { 15805 item = { el: $(item) }; 15806 } else { 15807 type = item.type; 15808 item = { data: item, src: item.src }; 15809 } 15810 15811 if(item.el) { 15812 var types = mfp.types; 15813 15814 // check for 'mfp-TYPE' class 15815 for(var i = 0; i < types.length; i++) { 15816 if( item.el.hasClass('mfp-'+types[i]) ) { 15817 type = types[i]; 15818 break; 15819 } 15820 } 15821 15822 item.src = item.el.attr('data-mfp-src'); 15823 if(!item.src) { 15824 item.src = item.el.attr('href'); 15825 } 15826 } 15827 15828 item.type = type || mfp.st.type || 'inline'; 15829 item.index = index; 15830 item.parsed = true; 15831 mfp.items[index] = item; 15832 _mfpTrigger('ElementParse', item); 15833 15834 return mfp.items[index]; 15835 }, 15836 15837 15838 /** 15839 * Initializes single popup or a group of popups 15840 */ 15841 addGroup: function(el, options) { 15842 var eHandler = function(e) { 15843 e.mfpEl = this; 15844 mfp._openClick(e, el, options); 15845 }; 15846 15847 if(!options) { 15848 options = {}; 15849 } 15850 15851 var eName = 'click.magnificPopup'; 15852 options.mainEl = el; 15853 15854 if(options.items) { 15855 options.isObj = true; 15856 el.off(eName).on(eName, eHandler); 15857 } else { 15858 options.isObj = false; 15859 if(options.delegate) { 15860 el.off(eName).on(eName, options.delegate , eHandler); 15861 } else { 15862 options.items = el; 15863 el.off(eName).on(eName, eHandler); 15864 } 15865 } 15866 }, 15867 _openClick: function(e, el, options) { 15868 var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick; 15869 15870 15871 if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) { 15872 return; 15873 } 15874 15875 var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn; 15876 15877 if(disableOn) { 15878 if($.isFunction(disableOn)) { 15879 if( !disableOn.call(mfp) ) { 15880 return true; 15881 } 15882 } else { // else it's number 15883 if( _window.width() < disableOn ) { 15884 return true; 15885 } 15886 } 15887 } 15888 15889 if(e.type) { 15890 e.preventDefault(); 15891 15892 // This will prevent popup from closing if element is inside and popup is already opened 15893 if(mfp.isOpen) { 15894 e.stopPropagation(); 15895 } 15896 } 15897 15898 options.el = $(e.mfpEl); 15899 if(options.delegate) { 15900 options.items = el.find(options.delegate); 15901 } 15902 mfp.open(options); 15903 }, 15904 15905 15906 /** 15907 * Updates text on preloader 15908 */ 15909 updateStatus: function(status, text) { 15910 15911 if(mfp.preloader) { 15912 if(_prevStatus !== status) { 15913 mfp.container.removeClass('mfp-s-'+_prevStatus); 15914 } 15915 15916 if(!text && status === 'loading') { 15917 text = mfp.st.tLoading; 15918 } 15919 15920 var data = { 15921 status: status, 15922 text: text 15923 }; 15924 // allows to modify status 15925 _mfpTrigger('UpdateStatus', data); 15926 15927 status = data.status; 15928 text = data.text; 15929 15930 mfp.preloader.html(text); 15931 15932 mfp.preloader.find('a').on('click', function(e) { 15933 e.stopImmediatePropagation(); 15934 }); 15935 15936 mfp.container.addClass('mfp-s-'+status); 15937 _prevStatus = status; 15938 } 15939 }, 15940 15941 15942 /* 15943 "Private" helpers that aren't private at all 15944 */ 15945 // Check to close popup or not 15946 // "target" is an element that was clicked 15947 _checkIfClose: function(target) { 15948 15949 if($(target).hasClass(PREVENT_CLOSE_CLASS)) { 15950 return; 15951 } 15952 15953 var closeOnContent = mfp.st.closeOnContentClick; 15954 var closeOnBg = mfp.st.closeOnBgClick; 15955 15956 if(closeOnContent && closeOnBg) { 15957 return true; 15958 } else { 15959 15960 // We close the popup if click is on close button or on preloader. Or if there is no content. 15961 if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) { 15962 return true; 15963 } 15964 15965 // if click is outside the content 15966 if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) { 15967 if(closeOnBg) { 15968 // last check, if the clicked element is in DOM, (in case it's removed onclick) 15969 if( $.contains(document, target) ) { 15970 return true; 15971 } 15972 } 15973 } else if(closeOnContent) { 15974 return true; 15975 } 15976 15977 } 15978 return false; 15979 }, 15980 _addClassToMFP: function(cName) { 15981 mfp.bgOverlay.addClass(cName); 15982 mfp.wrap.addClass(cName); 15983 }, 15984 _removeClassFromMFP: function(cName) { 15985 this.bgOverlay.removeClass(cName); 15986 mfp.wrap.removeClass(cName); 15987 }, 15988 _hasScrollBar: function(winHeight) { 15989 return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) ); 15990 }, 15991 _setFocus: function() { 15992 (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus(); 15993 }, 15994 _onFocusIn: function(e) { 15995 if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) { 15996 mfp._setFocus(); 15997 return false; 15998 } 15999 }, 16000 _parseMarkup: function(template, values, item) { 16001 var arr; 16002 if(item.data) { 16003 values = $.extend(item.data, values); 16004 } 16005 _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] ); 16006 16007 $.each(values, function(key, value) { 16008 if(value === undefined || value === false) { 16009 return true; 16010 } 16011 arr = key.split('_'); 16012 if(arr.length > 1) { 16013 var el = template.find(EVENT_NS + '-'+arr[0]); 16014 16015 if(el.length > 0) { 16016 var attr = arr[1]; 16017 if(attr === 'replaceWith') { 16018 if(el[0] !== value[0]) { 16019 el.replaceWith(value); 16020 } 16021 } else if(attr === 'img') { 16022 if(el.is('img')) { 16023 el.attr('src', value); 16024 } else { 16025 el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) ); 16026 } 16027 } else { 16028 el.attr(arr[1], value); 16029 } 16030 } 16031 16032 } else { 16033 template.find(EVENT_NS + '-'+key).html(value); 16034 } 16035 }); 16036 }, 16037 16038 _getScrollbarSize: function() { 16039 // thx David 16040 if(mfp.scrollbarSize === undefined) { 16041 var scrollDiv = document.createElement("div"); 16042 scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; 16043 document.body.appendChild(scrollDiv); 16044 mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; 16045 document.body.removeChild(scrollDiv); 16046 } 16047 return mfp.scrollbarSize; 16048 } 16049 16050}; /* MagnificPopup core prototype end */ 16051 16052 16053 16054 16055/** 16056 * Public static functions 16057 */ 16058$.magnificPopup = { 16059 instance: null, 16060 proto: MagnificPopup.prototype, 16061 modules: [], 16062 16063 open: function(options, index) { 16064 _checkInstance(); 16065 16066 if(!options) { 16067 options = {}; 16068 } else { 16069 options = $.extend(true, {}, options); 16070 } 16071 16072 options.isObj = true; 16073 options.index = index || 0; 16074 return this.instance.open(options); 16075 }, 16076 16077 close: function() { 16078 return $.magnificPopup.instance && $.magnificPopup.instance.close(); 16079 }, 16080 16081 registerModule: function(name, module) { 16082 if(module.options) { 16083 $.magnificPopup.defaults[name] = module.options; 16084 } 16085 $.extend(this.proto, module.proto); 16086 this.modules.push(name); 16087 }, 16088 16089 defaults: { 16090 16091 // Info about options is in docs: 16092 // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options 16093 16094 disableOn: 0, 16095 16096 key: null, 16097 16098 midClick: false, 16099 16100 mainClass: '', 16101 16102 preloader: true, 16103 16104 focus: '', // CSS selector of input to focus after popup is opened 16105 16106 closeOnContentClick: false, 16107 16108 closeOnBgClick: true, 16109 16110 closeBtnInside: true, 16111 16112 showCloseBtn: true, 16113 16114 enableEscapeKey: true, 16115 16116 modal: false, 16117 16118 alignTop: false, 16119 16120 removalDelay: 0, 16121 16122 prependTo: null, 16123 16124 fixedContentPos: 'auto', 16125 16126 fixedBgPos: 'auto', 16127 16128 overflowY: 'auto', 16129 16130 closeMarkup: '<button title="%title%" type="button" class="mfp-close">×</button>', 16131 16132 tClose: 'Close (Esc)', 16133 16134 tLoading: 'Loading...', 16135 16136 autoFocusLast: true 16137 16138 } 16139}; 16140 16141 16142 16143$.fn.magnificPopup = function(options) { 16144 _checkInstance(); 16145 16146 var jqEl = $(this); 16147 16148 // We call some API method of first param is a string 16149 if (typeof options === "string" ) { 16150 16151 if(options === 'open') { 16152 var items, 16153 itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup, 16154 index = parseInt(arguments[1], 10) || 0; 16155 16156 if(itemOpts.items) { 16157 items = itemOpts.items[index]; 16158 } else { 16159 items = jqEl; 16160 if(itemOpts.delegate) { 16161 items = items.find(itemOpts.delegate); 16162 } 16163 items = items.eq( index ); 16164 } 16165 mfp._openClick({mfpEl:items}, jqEl, itemOpts); 16166 } else { 16167 if(mfp.isOpen) 16168 mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1)); 16169 } 16170 16171 } else { 16172 // clone options obj 16173 options = $.extend(true, {}, options); 16174 16175 /* 16176 * As Zepto doesn't support .data() method for objects 16177 * and it works only in normal browsers 16178 * we assign "options" object directly to the DOM element. FTW! 16179 */ 16180 if(_isJQ) { 16181 jqEl.data('magnificPopup', options); 16182 } else { 16183 jqEl[0].magnificPopup = options; 16184 } 16185 16186 mfp.addGroup(jqEl, options); 16187 16188 } 16189 return jqEl; 16190}; 16191 16192/*>>core*/ 16193 16194/*>>inline*/ 16195 16196var INLINE_NS = 'inline', 16197 _hiddenClass, 16198 _inlinePlaceholder, 16199 _lastInlineElement, 16200 _putInlineElementsBack = function() { 16201 if(_lastInlineElement) { 16202 _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach(); 16203 _lastInlineElement = null; 16204 } 16205 }; 16206 16207$.magnificPopup.registerModule(INLINE_NS, { 16208 options: { 16209 hiddenClass: 'hide', // will be appended with `mfp-` prefix 16210 markup: '', 16211 tNotFound: 'Content not found' 16212 }, 16213 proto: { 16214 16215 initInline: function() { 16216 mfp.types.push(INLINE_NS); 16217 16218 _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() { 16219 _putInlineElementsBack(); 16220 }); 16221 }, 16222 16223 getInline: function(item, template) { 16224 16225 _putInlineElementsBack(); 16226 16227 if(item.src) { 16228 var inlineSt = mfp.st.inline, 16229 el = $(item.src); 16230 16231 if(el.length) { 16232 16233 // If target element has parent - we replace it with placeholder and put it back after popup is closed 16234 var parent = el[0].parentNode; 16235 if(parent && parent.tagName) { 16236 if(!_inlinePlaceholder) { 16237 _hiddenClass = inlineSt.hiddenClass; 16238 _inlinePlaceholder = _getEl(_hiddenClass); 16239 _hiddenClass = 'mfp-'+_hiddenClass; 16240 } 16241 // replace target inline element with placeholder 16242 _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass); 16243 } 16244 16245 mfp.updateStatus('ready'); 16246 } else { 16247 mfp.updateStatus('error', inlineSt.tNotFound); 16248 el = $('<div>'); 16249 } 16250 16251 item.inlineElement = el; 16252 return el; 16253 } 16254 16255 mfp.updateStatus('ready'); 16256 mfp._parseMarkup(template, {}, item); 16257 return template; 16258 } 16259 } 16260}); 16261 16262/*>>inline*/ 16263 16264/*>>ajax*/ 16265var AJAX_NS = 'ajax', 16266 _ajaxCur, 16267 _removeAjaxCursor = function() { 16268 if(_ajaxCur) { 16269 $(document.body).removeClass(_ajaxCur); 16270 } 16271 }, 16272 _destroyAjaxRequest = function() { 16273 _removeAjaxCursor(); 16274 if(mfp.req) { 16275 mfp.req.abort(); 16276 } 16277 }; 16278 16279$.magnificPopup.registerModule(AJAX_NS, { 16280 16281 options: { 16282 settings: null, 16283 cursor: 'mfp-ajax-cur', 16284 tError: '<a href="%url%">The content</a> could not be loaded.' 16285 }, 16286 16287 proto: { 16288 initAjax: function() { 16289 mfp.types.push(AJAX_NS); 16290 _ajaxCur = mfp.st.ajax.cursor; 16291 16292 _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest); 16293 _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest); 16294 }, 16295 getAjax: function(item) { 16296 16297 if(_ajaxCur) { 16298 $(document.body).addClass(_ajaxCur); 16299 } 16300 16301 mfp.updateStatus('loading'); 16302 16303 var opts = $.extend({ 16304 url: item.src, 16305 success: function(data, textStatus, jqXHR) { 16306 var temp = { 16307 data:data, 16308 xhr:jqXHR 16309 }; 16310 16311 _mfpTrigger('ParseAjax', temp); 16312 16313 mfp.appendContent( $(temp.data), AJAX_NS ); 16314 16315 item.finished = true; 16316 16317 _removeAjaxCursor(); 16318 16319 mfp._setFocus(); 16320 16321 setTimeout(function() { 16322 mfp.wrap.addClass(READY_CLASS); 16323 }, 16); 16324 16325 mfp.updateStatus('ready'); 16326 16327 _mfpTrigger('AjaxContentAdded'); 16328 }, 16329 error: function() { 16330 _removeAjaxCursor(); 16331 item.finished = item.loadError = true; 16332 mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src)); 16333 } 16334 }, mfp.st.ajax.settings); 16335 16336 mfp.req = $.ajax(opts); 16337 16338 return ''; 16339 } 16340 } 16341}); 16342 16343/*>>ajax*/ 16344 16345/*>>image*/ 16346var _imgInterval, 16347 _getTitle = function(item) { 16348 if(item.data && item.data.title !== undefined) 16349 return item.data.title; 16350 16351 var src = mfp.st.image.titleSrc; 16352 16353 if(src) { 16354 if($.isFunction(src)) { 16355 return src.call(mfp, item); 16356 } else if(item.el) { 16357 return item.el.attr(src) || ''; 16358 } 16359 } 16360 return ''; 16361 }; 16362 16363$.magnificPopup.registerModule('image', { 16364 16365 options: { 16366 markup: '<div class="mfp-figure">'+ 16367 '<div class="mfp-close"></div>'+ 16368 '<figure>'+ 16369 '<div class="mfp-img"></div>'+ 16370 '<figcaption>'+ 16371 '<div class="mfp-bottom-bar">'+ 16372 '<div class="mfp-title"></div>'+ 16373 '<div class="mfp-counter"></div>'+ 16374 '</div>'+ 16375 '</figcaption>'+ 16376 '</figure>'+ 16377 '</div>', 16378 cursor: 'mfp-zoom-out-cur', 16379 titleSrc: 'title', 16380 verticalFit: true, 16381 tError: '<a href="%url%">The image</a> could not be loaded.' 16382 }, 16383 16384 proto: { 16385 initImage: function() { 16386 var imgSt = mfp.st.image, 16387 ns = '.image'; 16388 16389 mfp.types.push('image'); 16390 16391 _mfpOn(OPEN_EVENT+ns, function() { 16392 if(mfp.currItem.type === 'image' && imgSt.cursor) { 16393 $(document.body).addClass(imgSt.cursor); 16394 } 16395 }); 16396 16397 _mfpOn(CLOSE_EVENT+ns, function() { 16398 if(imgSt.cursor) { 16399 $(document.body).removeClass(imgSt.cursor); 16400 } 16401 _window.off('resize' + EVENT_NS); 16402 }); 16403 16404 _mfpOn('Resize'+ns, mfp.resizeImage); 16405 if(mfp.isLowIE) { 16406 _mfpOn('AfterChange', mfp.resizeImage); 16407 } 16408 }, 16409 resizeImage: function() { 16410 var item = mfp.currItem; 16411 if(!item || !item.img) return; 16412 16413 if(mfp.st.image.verticalFit) { 16414 var decr = 0; 16415 // fix box-sizing in ie7/8 16416 if(mfp.isLowIE) { 16417 decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); 16418 } 16419 item.img.css('max-height', mfp.wH-decr); 16420 } 16421 }, 16422 _onImageHasSize: function(item) { 16423 if(item.img) { 16424 16425 item.hasSize = true; 16426 16427 if(_imgInterval) { 16428 clearInterval(_imgInterval); 16429 } 16430 16431 item.isCheckingImgSize = false; 16432 16433 _mfpTrigger('ImageHasSize', item); 16434 16435 if(item.imgHidden) { 16436 if(mfp.content) 16437 mfp.content.removeClass('mfp-loading'); 16438 16439 item.imgHidden = false; 16440 } 16441 16442 } 16443 }, 16444 16445 /** 16446 * Function that loops until the image has size to display elements that rely on it asap 16447 */ 16448 findImageSize: function(item) { 16449 16450 var counter = 0, 16451 img = item.img[0], 16452 mfpSetInterval = function(delay) { 16453 16454 if(_imgInterval) { 16455 clearInterval(_imgInterval); 16456 } 16457 // decelerating interval that checks for size of an image 16458 _imgInterval = setInterval(function() { 16459 if(img.naturalWidth > 0) { 16460 mfp._onImageHasSize(item); 16461 return; 16462 } 16463 16464 if(counter > 200) { 16465 clearInterval(_imgInterval); 16466 } 16467 16468 counter++; 16469 if(counter === 3) { 16470 mfpSetInterval(10); 16471 } else if(counter === 40) { 16472 mfpSetInterval(50); 16473 } else if(counter === 100) { 16474 mfpSetInterval(500); 16475 } 16476 }, delay); 16477 }; 16478 16479 mfpSetInterval(1); 16480 }, 16481 16482 getImage: function(item, template) { 16483 16484 var guard = 0, 16485 16486 // image load complete handler 16487 onLoadComplete = function() { 16488 if(item) { 16489 if (item.img[0].complete) { 16490 item.img.off('.mfploader'); 16491 16492 if(item === mfp.currItem){ 16493 mfp._onImageHasSize(item); 16494 16495 mfp.updateStatus('ready'); 16496 } 16497 16498 item.hasSize = true; 16499 item.loaded = true; 16500 16501 _mfpTrigger('ImageLoadComplete'); 16502 16503 } 16504 else { 16505 // if image complete check fails 200 times (20 sec), we assume that there was an error. 16506 guard++; 16507 if(guard < 200) { 16508 setTimeout(onLoadComplete,100); 16509 } else { 16510 onLoadError(); 16511 } 16512 } 16513 } 16514 }, 16515 16516 // image error handler 16517 onLoadError = function() { 16518 if(item) { 16519 item.img.off('.mfploader'); 16520 if(item === mfp.currItem){ 16521 mfp._onImageHasSize(item); 16522 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 16523 } 16524 16525 item.hasSize = true; 16526 item.loaded = true; 16527 item.loadError = true; 16528 } 16529 }, 16530 imgSt = mfp.st.image; 16531 16532 16533 var el = template.find('.mfp-img'); 16534 if(el.length) { 16535 var img = document.createElement('img'); 16536 img.className = 'mfp-img'; 16537 if(item.el && item.el.find('img').length) { 16538 img.alt = item.el.find('img').attr('alt'); 16539 } 16540 item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError); 16541 img.src = item.src; 16542 16543 // without clone() "error" event is not firing when IMG is replaced by new IMG 16544 // TODO: find a way to avoid such cloning 16545 if(el.is('img')) { 16546 item.img = item.img.clone(); 16547 } 16548 16549 img = item.img[0]; 16550 if(img.naturalWidth > 0) { 16551 item.hasSize = true; 16552 } else if(!img.width) { 16553 item.hasSize = false; 16554 } 16555 } 16556 16557 mfp._parseMarkup(template, { 16558 title: _getTitle(item), 16559 img_replaceWith: item.img 16560 }, item); 16561 16562 mfp.resizeImage(); 16563 16564 if(item.hasSize) { 16565 if(_imgInterval) clearInterval(_imgInterval); 16566 16567 if(item.loadError) { 16568 template.addClass('mfp-loading'); 16569 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 16570 } else { 16571 template.removeClass('mfp-loading'); 16572 mfp.updateStatus('ready'); 16573 } 16574 return template; 16575 } 16576 16577 mfp.updateStatus('loading'); 16578 item.loading = true; 16579 16580 if(!item.hasSize) { 16581 item.imgHidden = true; 16582 template.addClass('mfp-loading'); 16583 mfp.findImageSize(item); 16584 } 16585 16586 return template; 16587 } 16588 } 16589}); 16590 16591/*>>image*/ 16592 16593/*>>zoom*/ 16594var hasMozTransform, 16595 getHasMozTransform = function() { 16596 if(hasMozTransform === undefined) { 16597 hasMozTransform = document.createElement('p').style.MozTransform !== undefined; 16598 } 16599 return hasMozTransform; 16600 }; 16601 16602$.magnificPopup.registerModule('zoom', { 16603 16604 options: { 16605 enabled: false, 16606 easing: 'ease-in-out', 16607 duration: 300, 16608 opener: function(element) { 16609 return element.is('img') ? element : element.find('img'); 16610 } 16611 }, 16612 16613 proto: { 16614 16615 initZoom: function() { 16616 var zoomSt = mfp.st.zoom, 16617 ns = '.zoom', 16618 image; 16619 16620 if(!zoomSt.enabled || !mfp.supportsTransition) { 16621 return; 16622 } 16623 16624 var duration = zoomSt.duration, 16625 getElToAnimate = function(image) { 16626 var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'), 16627 transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing, 16628 cssObj = { 16629 position: 'fixed', 16630 zIndex: 9999, 16631 left: 0, 16632 top: 0, 16633 '-webkit-backface-visibility': 'hidden' 16634 }, 16635 t = 'transition'; 16636 16637 cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition; 16638 16639 newImg.css(cssObj); 16640 return newImg; 16641 }, 16642 showMainContent = function() { 16643 mfp.content.css('visibility', 'visible'); 16644 }, 16645 openTimeout, 16646 animatedImg; 16647 16648 _mfpOn('BuildControls'+ns, function() { 16649 if(mfp._allowZoom()) { 16650 16651 clearTimeout(openTimeout); 16652 mfp.content.css('visibility', 'hidden'); 16653 16654 // Basically, all code below does is clones existing image, puts in on top of the current one and animated it 16655 16656 image = mfp._getItemToZoom(); 16657 16658 if(!image) { 16659 showMainContent(); 16660 return; 16661 } 16662 16663 animatedImg = getElToAnimate(image); 16664 16665 animatedImg.css( mfp._getOffset() ); 16666 16667 mfp.wrap.append(animatedImg); 16668 16669 openTimeout = setTimeout(function() { 16670 animatedImg.css( mfp._getOffset( true ) ); 16671 openTimeout = setTimeout(function() { 16672 16673 showMainContent(); 16674 16675 setTimeout(function() { 16676 animatedImg.remove(); 16677 image = animatedImg = null; 16678 _mfpTrigger('ZoomAnimationEnded'); 16679 }, 16); // avoid blink when switching images 16680 16681 }, duration); // this timeout equals animation duration 16682 16683 }, 16); // by adding this timeout we avoid short glitch at the beginning of animation 16684 16685 16686 // Lots of timeouts... 16687 } 16688 }); 16689 _mfpOn(BEFORE_CLOSE_EVENT+ns, function() { 16690 if(mfp._allowZoom()) { 16691 16692 clearTimeout(openTimeout); 16693 16694 mfp.st.removalDelay = duration; 16695 16696 if(!image) { 16697 image = mfp._getItemToZoom(); 16698 if(!image) { 16699 return; 16700 } 16701 animatedImg = getElToAnimate(image); 16702 } 16703 16704 animatedImg.css( mfp._getOffset(true) ); 16705 mfp.wrap.append(animatedImg); 16706 mfp.content.css('visibility', 'hidden'); 16707 16708 setTimeout(function() { 16709 animatedImg.css( mfp._getOffset() ); 16710 }, 16); 16711 } 16712 16713 }); 16714 16715 _mfpOn(CLOSE_EVENT+ns, function() { 16716 if(mfp._allowZoom()) { 16717 showMainContent(); 16718 if(animatedImg) { 16719 animatedImg.remove(); 16720 } 16721 image = null; 16722 } 16723 }); 16724 }, 16725 16726 _allowZoom: function() { 16727 return mfp.currItem.type === 'image'; 16728 }, 16729 16730 _getItemToZoom: function() { 16731 if(mfp.currItem.hasSize) { 16732 return mfp.currItem.img; 16733 } else { 16734 return false; 16735 } 16736 }, 16737 16738 // Get element postion relative to viewport 16739 _getOffset: function(isLarge) { 16740 var el; 16741 if(isLarge) { 16742 el = mfp.currItem.img; 16743 } else { 16744 el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem); 16745 } 16746 16747 var offset = el.offset(); 16748 var paddingTop = parseInt(el.css('padding-top'),10); 16749 var paddingBottom = parseInt(el.css('padding-bottom'),10); 16750 offset.top -= ( $(window).scrollTop() - paddingTop ); 16751 16752 16753 /* 16754 16755 Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa. 16756 16757 */ 16758 var obj = { 16759 width: el.width(), 16760 // fix Zepto height+padding issue 16761 height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop 16762 }; 16763 16764 // I hate to do this, but there is no another option 16765 if( getHasMozTransform() ) { 16766 obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)'; 16767 } else { 16768 obj.left = offset.left; 16769 obj.top = offset.top; 16770 } 16771 return obj; 16772 } 16773 16774 } 16775}); 16776 16777 16778 16779/*>>zoom*/ 16780 16781/*>>iframe*/ 16782 16783var IFRAME_NS = 'iframe', 16784 _emptyPage = '//about:blank', 16785 16786 _fixIframeBugs = function(isShowing) { 16787 if(mfp.currTemplate[IFRAME_NS]) { 16788 var el = mfp.currTemplate[IFRAME_NS].find('iframe'); 16789 if(el.length) { 16790 // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug 16791 if(!isShowing) { 16792 el[0].src = _emptyPage; 16793 } 16794 16795 // IE8 black screen bug fix 16796 if(mfp.isIE8) { 16797 el.css('display', isShowing ? 'block' : 'none'); 16798 } 16799 } 16800 } 16801 }; 16802 16803$.magnificPopup.registerModule(IFRAME_NS, { 16804 16805 options: { 16806 markup: '<div class="mfp-iframe-scaler">'+ 16807 '<div class="mfp-close"></div>'+ 16808 '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+ 16809 '</div>', 16810 16811 srcAction: 'iframe_src', 16812 16813 // we don't care and support only one default type of URL by default 16814 patterns: { 16815 youtube: { 16816 index: 'youtube.com', 16817 id: 'v=', 16818 src: '//www.youtube.com/embed/%id%?autoplay=1' 16819 }, 16820 vimeo: { 16821 index: 'vimeo.com/', 16822 id: '/', 16823 src: '//player.vimeo.com/video/%id%?autoplay=1' 16824 }, 16825 gmaps: { 16826 index: '//maps.google.', 16827 src: '%id%&output=embed' 16828 } 16829 } 16830 }, 16831 16832 proto: { 16833 initIframe: function() { 16834 mfp.types.push(IFRAME_NS); 16835 16836 _mfpOn('BeforeChange', function(e, prevType, newType) { 16837 if(prevType !== newType) { 16838 if(prevType === IFRAME_NS) { 16839 _fixIframeBugs(); // iframe if removed 16840 } else if(newType === IFRAME_NS) { 16841 _fixIframeBugs(true); // iframe is showing 16842 } 16843 }// else { 16844 // iframe source is switched, don't do anything 16845 //} 16846 }); 16847 16848 _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() { 16849 _fixIframeBugs(); 16850 }); 16851 }, 16852 16853 getIframe: function(item, template) { 16854 var embedSrc = item.src; 16855 var iframeSt = mfp.st.iframe; 16856 16857 $.each(iframeSt.patterns, function() { 16858 if(embedSrc.indexOf( this.index ) > -1) { 16859 if(this.id) { 16860 if(typeof this.id === 'string') { 16861 embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length); 16862 } else { 16863 embedSrc = this.id.call( this, embedSrc ); 16864 } 16865 } 16866 embedSrc = this.src.replace('%id%', embedSrc ); 16867 return false; // break; 16868 } 16869 }); 16870 16871 var dataObj = {}; 16872 if(iframeSt.srcAction) { 16873 dataObj[iframeSt.srcAction] = embedSrc; 16874 } 16875 mfp._parseMarkup(template, dataObj, item); 16876 16877 mfp.updateStatus('ready'); 16878 16879 return template; 16880 } 16881 } 16882}); 16883 16884 16885 16886/*>>iframe*/ 16887 16888/*>>gallery*/ 16889/** 16890 * Get looped index depending on number of slides 16891 */ 16892var _getLoopedId = function(index) { 16893 var numSlides = mfp.items.length; 16894 if(index > numSlides - 1) { 16895 return index - numSlides; 16896 } else if(index < 0) { 16897 return numSlides + index; 16898 } 16899 return index; 16900 }, 16901 _replaceCurrTotal = function(text, curr, total) { 16902 return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total); 16903 }; 16904 16905$.magnificPopup.registerModule('gallery', { 16906 16907 options: { 16908 enabled: false, 16909 arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>', 16910 preload: [0,2], 16911 navigateByImgClick: true, 16912 arrows: true, 16913 16914 tPrev: 'Previous (Left arrow key)', 16915 tNext: 'Next (Right arrow key)', 16916 tCounter: '%curr% of %total%' 16917 }, 16918 16919 proto: { 16920 initGallery: function() { 16921 16922 var gSt = mfp.st.gallery, 16923 ns = '.mfp-gallery'; 16924 16925 mfp.direction = true; // true - next, false - prev 16926 16927 if(!gSt || !gSt.enabled ) return false; 16928 16929 _wrapClasses += ' mfp-gallery'; 16930 16931 _mfpOn(OPEN_EVENT+ns, function() { 16932 16933 if(gSt.navigateByImgClick) { 16934 mfp.wrap.on('click'+ns, '.mfp-img', function() { 16935 if(mfp.items.length > 1) { 16936 mfp.next(); 16937 return false; 16938 } 16939 }); 16940 } 16941 16942 _document.on('keydown'+ns, function(e) { 16943 if (e.keyCode === 37) { 16944 mfp.prev(); 16945 } else if (e.keyCode === 39) { 16946 mfp.next(); 16947 } 16948 }); 16949 }); 16950 16951 _mfpOn('UpdateStatus'+ns, function(e, data) { 16952 if(data.text) { 16953 data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length); 16954 } 16955 }); 16956 16957 _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) { 16958 var l = mfp.items.length; 16959 values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : ''; 16960 }); 16961 16962 _mfpOn('BuildControls' + ns, function() { 16963 if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) { 16964 var markup = gSt.arrowMarkup, 16965 arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS), 16966 arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS); 16967 16968 arrowLeft.click(function() { 16969 mfp.prev(); 16970 }); 16971 arrowRight.click(function() { 16972 mfp.next(); 16973 }); 16974 16975 mfp.container.append(arrowLeft.add(arrowRight)); 16976 } 16977 }); 16978 16979 _mfpOn(CHANGE_EVENT+ns, function() { 16980 if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout); 16981 16982 mfp._preloadTimeout = setTimeout(function() { 16983 mfp.preloadNearbyImages(); 16984 mfp._preloadTimeout = null; 16985 }, 16); 16986 }); 16987 16988 16989 _mfpOn(CLOSE_EVENT+ns, function() { 16990 _document.off(ns); 16991 mfp.wrap.off('click'+ns); 16992 mfp.arrowRight = mfp.arrowLeft = null; 16993 }); 16994 16995 }, 16996 next: function() { 16997 mfp.direction = true; 16998 mfp.index = _getLoopedId(mfp.index + 1); 16999 mfp.updateItemHTML(); 17000 }, 17001 prev: function() { 17002 mfp.direction = false; 17003 mfp.index = _getLoopedId(mfp.index - 1); 17004 mfp.updateItemHTML(); 17005 }, 17006 goTo: function(newIndex) { 17007 mfp.direction = (newIndex >= mfp.index); 17008 mfp.index = newIndex; 17009 mfp.updateItemHTML(); 17010 }, 17011 preloadNearbyImages: function() { 17012 var p = mfp.st.gallery.preload, 17013 preloadBefore = Math.min(p[0], mfp.items.length), 17014 preloadAfter = Math.min(p[1], mfp.items.length), 17015 i; 17016 17017 for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) { 17018 mfp._preloadItem(mfp.index+i); 17019 } 17020 for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) { 17021 mfp._preloadItem(mfp.index-i); 17022 } 17023 }, 17024 _preloadItem: function(index) { 17025 index = _getLoopedId(index); 17026 17027 if(mfp.items[index].preloaded) { 17028 return; 17029 } 17030 17031 var item = mfp.items[index]; 17032 if(!item.parsed) { 17033 item = mfp.parseEl( index ); 17034 } 17035 17036 _mfpTrigger('LazyLoad', item); 17037 17038 if(item.type === 'image') { 17039 item.img = $('<img class="mfp-img" />').on('load.mfploader', function() { 17040 item.hasSize = true; 17041 }).on('error.mfploader', function() { 17042 item.hasSize = true; 17043 item.loadError = true; 17044 _mfpTrigger('LazyLoadError', item); 17045 }).attr('src', item.src); 17046 } 17047 17048 17049 item.preloaded = true; 17050 } 17051 } 17052}); 17053 17054/*>>gallery*/ 17055 17056/*>>retina*/ 17057 17058var RETINA_NS = 'retina'; 17059 17060$.magnificPopup.registerModule(RETINA_NS, { 17061 options: { 17062 replaceSrc: function(item) { 17063 return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; }); 17064 }, 17065 ratio: 1 // Function or number. Set to 1 to disable. 17066 }, 17067 proto: { 17068 initRetina: function() { 17069 if(window.devicePixelRatio > 1) { 17070 17071 var st = mfp.st.retina, 17072 ratio = st.ratio; 17073 17074 ratio = !isNaN(ratio) ? ratio : ratio(); 17075 17076 if(ratio > 1) { 17077 _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) { 17078 item.img.css({ 17079 'max-width': item.img[0].naturalWidth / ratio, 17080 'width': '100%' 17081 }); 17082 }); 17083 _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) { 17084 item.src = st.replaceSrc(item, ratio); 17085 }); 17086 } 17087 } 17088 17089 } 17090 } 17091}); 17092 17093/*>>retina*/ 17094 _checkInstance(); })); 17095 17096/***/ }), 17097
17098/***/ "./assets/styles/main.scss": 17099/*!*********************************!*\ 17100 !*** ./assets/styles/main.scss ***! 17101 \*********************************/ 17102/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 17103 17104"use strict"; 17105__webpack_require__.r(__webpack_exports__); 17106// extracted by mini-css-extract-plugin 17107 17108 17109/***/ }), 17110
17111/***/ "./assets/styles/admin-main.scss": 17112/*!***************************************!*\ 17113 !*** ./assets/styles/admin-main.scss ***! 17114 \***************************************/ 17115/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 17116 17117"use strict"; 17118__webpack_require__.r(__webpack_exports__); 17119// extracted by mini-css-extract-plugin 17120 17121 17122/***/ }), 17123
vendor: 94,282 bytes, lines 17124-20583
17124/***/ "./node_modules/owl.carousel/dist/owl.carousel.js": 17125/*!********************************************************!*\ 17126 !*** ./node_modules/owl.carousel/dist/owl.carousel.js ***! 17127 \********************************************************/ 17128/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { 17129 17130/* provided dependency */ var jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 17131/* provided dependency */ var __webpack_provided_window_dot_jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 17132/** 17133 * Owl Carousel v2.3.4 17134 * Copyright 2013-2018 David Deutsch 17135 * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE 17136 */ 17137/** 17138 * Owl carousel 17139 * @version 2.3.4 17140 * @author Bartosz Wojciechowski 17141 * @author David Deutsch 17142 * @license The MIT License (MIT) 17143 * @todo Lazy Load Icon 17144 * @todo prevent animationend bubling 17145 * @todo itemsScaleUp 17146 * @todo Test Zepto 17147 * @todo stagePadding calculate wrong active classes 17148 */ 17149;(function($, window, document, undefined) { 17150 17151 /** 17152 * Creates a carousel. 17153 * @class The Owl Carousel. 17154 * @public 17155 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 17156 * @param {Object} [options] - The options 17157 */ 17158 function Owl(element, options) { 17159 17160 /** 17161 * Current settings for the carousel. 17162 * @public 17163 */ 17164 this.settings = null; 17165 17166 /** 17167 * Current options set by the caller including defaults. 17168 * @public 17169 */ 17170 this.options = $.extend({}, Owl.Defaults, options); 17171 17172 /** 17173 * Plugin element. 17174 * @public 17175 */ 17176 this.$element = $(element); 17177 17178 /** 17179 * Proxied event handlers. 17180 * @protected 17181 */ 17182 this._handlers = {}; 17183 17184 /** 17185 * References to the running plugins of this carousel. 17186 * @protected 17187 */ 17188 this._plugins = {}; 17189 17190 /** 17191 * Currently suppressed events to prevent them from being retriggered. 17192 * @protected 17193 */ 17194 this._supress = {}; 17195 17196 /** 17197 * Absolute current position. 17198 * @protected 17199 */ 17200 this._current = null; 17201 17202 /** 17203 * Animation speed in milliseconds. 17204 * @protected 17205 */ 17206 this._speed = null; 17207 17208 /** 17209 * Coordinates of all items in pixel. 17210 * @todo The name of this member is missleading. 17211 * @protected 17212 */ 17213 this._coordinates = []; 17214 17215 /** 17216 * Current breakpoint. 17217 * @todo Real media queries would be nice. 17218 * @protected 17219 */ 17220 this._breakpoint = null; 17221 17222 /** 17223 * Current width of the plugin element. 17224 */ 17225 this._width = null; 17226 17227 /** 17228 * All real items. 17229 * @protected 17230 */ 17231 this._items = []; 17232 17233 /** 17234 * All cloned items. 17235 * @protected 17236 */ 17237 this._clones = []; 17238 17239 /** 17240 * Merge values of all items. 17241 * @todo Maybe this could be part of a plugin. 17242 * @protected 17243 */ 17244 this._mergers = []; 17245 17246 /** 17247 * Widths of all items. 17248 */ 17249 this._widths = []; 17250 17251 /** 17252 * Invalidated parts within the update process. 17253 * @protected 17254 */ 17255 this._invalidated = {}; 17256 17257 /** 17258 * Ordered list of workers for the update process. 17259 * @protected 17260 */ 17261 this._pipe = []; 17262 17263 /** 17264 * Current state information for the drag operation. 17265 * @todo #261 17266 * @protected 17267 */ 17268 this._drag = { 17269 time: null, 17270 target: null, 17271 pointer: null, 17272 stage: { 17273 start: null, 17274 current: null 17275 }, 17276 direction: null 17277 }; 17278 17279 /** 17280 * Current state information and their tags. 17281 * @type {Object} 17282 * @protected 17283 */ 17284 this._states = { 17285 current: {}, 17286 tags: { 17287 'initializing': [ 'busy' ], 17288 'animating': [ 'busy' ], 17289 'dragging': [ 'interacting' ] 17290 } 17291 }; 17292 17293 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 17294 this._handlers[handler] = $.proxy(this[handler], this); 17295 }, this)); 17296 17297 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 17298 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 17299 = new plugin(this); 17300 }, this)); 17301 17302 $.each(Owl.Workers, $.proxy(function(priority, worker) { 17303 this._pipe.push({ 17304 'filter': worker.filter, 17305 'run': $.proxy(worker.run, this) 17306 }); 17307 }, this)); 17308 17309 this.setup(); 17310 this.initialize(); 17311 } 17312 17313 /** 17314 * Default options for the carousel. 17315 * @public 17316 */ 17317 Owl.Defaults = { 17318 items: 3, 17319 loop: false, 17320 center: false, 17321 rewind: false, 17322 checkVisibility: true, 17323 17324 mouseDrag: true, 17325 touchDrag: true, 17326 pullDrag: true, 17327 freeDrag: false, 17328 17329 margin: 0, 17330 stagePadding: 0, 17331 17332 merge: false, 17333 mergeFit: true, 17334 autoWidth: false, 17335 17336 startPosition: 0, 17337 rtl: false, 17338 17339 smartSpeed: 250, 17340 fluidSpeed: false, 17341 dragEndSpeed: false, 17342 17343 responsive: {}, 17344 responsiveRefreshRate: 200, 17345 responsiveBaseElement: window, 17346 17347 fallbackEasing: 'swing', 17348 slideTransition: '', 17349 17350 info: false, 17351 17352 nestedItemSelector: false, 17353 itemElement: 'div', 17354 stageElement: 'div', 17355 17356 refreshClass: 'owl-refresh', 17357 loadedClass: 'owl-loaded', 17358 loadingClass: 'owl-loading', 17359 rtlClass: 'owl-rtl', 17360 responsiveClass: 'owl-responsive', 17361 dragClass: 'owl-drag', 17362 itemClass: 'owl-item', 17363 stageClass: 'owl-stage', 17364 stageOuterClass: 'owl-stage-outer', 17365 grabClass: 'owl-grab' 17366 }; 17367 17368 /** 17369 * Enumeration for width. 17370 * @public 17371 * @readonly 17372 * @enum {String} 17373 */ 17374 Owl.Width = { 17375 Default: 'default', 17376 Inner: 'inner', 17377 Outer: 'outer' 17378 }; 17379 17380 /** 17381 * Enumeration for types. 17382 * @public 17383 * @readonly 17384 * @enum {String} 17385 */ 17386 Owl.Type = { 17387 Event: 'event', 17388 State: 'state' 17389 }; 17390 17391 /** 17392 * Contains all registered plugins. 17393 * @public 17394 */ 17395 Owl.Plugins = {}; 17396 17397 /** 17398 * List of workers involved in the update process. 17399 */ 17400 Owl.Workers = [ { 17401 filter: [ 'width', 'settings' ], 17402 run: function() { 17403 this._width = this.$element.width(); 17404 } 17405 }, { 17406 filter: [ 'width', 'items', 'settings' ], 17407 run: function(cache) { 17408 cache.current = this._items && this._items[this.relative(this._current)]; 17409 } 17410 }, { 17411 filter: [ 'items', 'settings' ], 17412 run: function() { 17413 this.$stage.children('.cloned').remove(); 17414 } 17415 }, { 17416 filter: [ 'width', 'items', 'settings' ], 17417 run: function(cache) { 17418 var margin = this.settings.margin || '', 17419 grid = !this.settings.autoWidth, 17420 rtl = this.settings.rtl, 17421 css = { 17422 'width': 'auto', 17423 'margin-left': rtl ? margin : '', 17424 'margin-right': rtl ? '' : margin 17425 }; 17426 17427 !grid && this.$stage.children().css(css); 17428 17429 cache.css = css; 17430 } 17431 }, { 17432 filter: [ 'width', 'items', 'settings' ], 17433 run: function(cache) { 17434 var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin, 17435 merge = null, 17436 iterator = this._items.length, 17437 grid = !this.settings.autoWidth, 17438 widths = []; 17439 17440 cache.items = { 17441 merge: false, 17442 width: width 17443 }; 17444 17445 while (iterator--) { 17446 merge = this._mergers[iterator]; 17447 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 17448 17449 cache.items.merge = merge > 1 || cache.items.merge; 17450 17451 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 17452 } 17453 17454 this._widths = widths; 17455 } 17456 }, { 17457 filter: [ 'items', 'settings' ], 17458 run: function() { 17459 var clones = [], 17460 items = this._items, 17461 settings = this.settings, 17462 // TODO: Should be computed from number of min width items in stage 17463 view = Math.max(settings.items * 2, 4), 17464 size = Math.ceil(items.length / 2) * 2, 17465 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 17466 append = '', 17467 prepend = ''; 17468 17469 repeat /= 2; 17470 17471 while (repeat > 0) { 17472 // Switch to only using appended clones 17473 clones.push(this.normalize(clones.length / 2, true)); 17474 append = append + items[clones[clones.length - 1]][0].outerHTML; 17475 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 17476 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 17477 repeat -= 1; 17478 } 17479 17480 this._clones = clones; 17481 17482 $(append).addClass('cloned').appendTo(this.$stage); 17483 $(prepend).addClass('cloned').prependTo(this.$stage); 17484 } 17485 }, { 17486 filter: [ 'width', 'items', 'settings' ], 17487 run: function() { 17488 var rtl = this.settings.rtl ? 1 : -1, 17489 size = this._clones.length + this._items.length, 17490 iterator = -1, 17491 previous = 0, 17492 current = 0, 17493 coordinates = []; 17494 17495 while (++iterator < size) { 17496 previous = coordinates[iterator - 1] || 0; 17497 current = this._widths[this.relative(iterator)] + this.settings.margin; 17498 coordinates.push(previous + current * rtl); 17499 } 17500 17501 this._coordinates = coordinates; 17502 } 17503 }, { 17504 filter: [ 'width', 'items', 'settings' ], 17505 run: function() { 17506 var padding = this.settings.stagePadding, 17507 coordinates = this._coordinates, 17508 css = { 17509 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 17510 'padding-left': padding || '', 17511 'padding-right': padding || '' 17512 }; 17513 17514 this.$stage.css(css); 17515 } 17516 }, { 17517 filter: [ 'width', 'items', 'settings' ], 17518 run: function(cache) { 17519 var iterator = this._coordinates.length, 17520 grid = !this.settings.autoWidth, 17521 items = this.$stage.children(); 17522 17523 if (grid && cache.items.merge) { 17524 while (iterator--) { 17525 cache.css.width = this._widths[this.relative(iterator)]; 17526 items.eq(iterator).css(cache.css); 17527 } 17528 } else if (grid) { 17529 cache.css.width = cache.items.width; 17530 items.css(cache.css); 17531 } 17532 } 17533 }, { 17534 filter: [ 'items' ], 17535 run: function() { 17536 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 17537 } 17538 }, { 17539 filter: [ 'width', 'items', 'settings' ], 17540 run: function(cache) { 17541 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 17542 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 17543 this.reset(cache.current); 17544 } 17545 }, { 17546 filter: [ 'position' ], 17547 run: function() { 17548 this.animate(this.coordinates(this._current)); 17549 } 17550 }, { 17551 filter: [ 'width', 'position', 'items', 'settings' ], 17552 run: function() { 17553 var rtl = this.settings.rtl ? 1 : -1, 17554 padding = this.settings.stagePadding * 2, 17555 begin = this.coordinates(this.current()) + padding, 17556 end = begin + this.width() * rtl, 17557 inner, outer, matches = [], i, n; 17558 17559 for (i = 0, n = this._coordinates.length; i < n; i++) { 17560 inner = this._coordinates[i - 1] || 0; 17561 outer = Math.abs(this._coordinates[i]) + padding * rtl; 17562 17563 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 17564 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 17565 matches.push(i); 17566 } 17567 } 17568 17569 this.$stage.children('.active').removeClass('active'); 17570 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 17571 17572 this.$stage.children('.center').removeClass('center'); 17573 if (this.settings.center) { 17574 this.$stage.children().eq(this.current()).addClass('center'); 17575 } 17576 } 17577 } ]; 17578 17579 /** 17580 * Create the stage DOM element 17581 */ 17582 Owl.prototype.initializeStage = function() { 17583 this.$stage = this.$element.find('.' + this.settings.stageClass); 17584 17585 // if the stage is already in the DOM, grab it and skip stage initialization 17586 if (this.$stage.length) { 17587 return; 17588 } 17589 17590 this.$element.addClass(this.options.loadingClass); 17591 17592 // create stage 17593 this.$stage = $('<' + this.settings.stageElement + '>', { 17594 "class": this.settings.stageClass 17595 }).wrap( $( '<div/>', { 17596 "class": this.settings.stageOuterClass 17597 })); 17598 17599 // append stage 17600 this.$element.append(this.$stage.parent()); 17601 }; 17602 17603 /** 17604 * Create item DOM elements 17605 */ 17606 Owl.prototype.initializeItems = function() { 17607 var $items = this.$element.find('.owl-item'); 17608 17609 // if the items are already in the DOM, grab them and skip item initialization 17610 if ($items.length) { 17611 this._items = $items.get().map(function(item) { 17612 return $(item); 17613 }); 17614 17615 this._mergers = this._items.map(function() { 17616 return 1; 17617 }); 17618 17619 this.refresh(); 17620 17621 return; 17622 } 17623 17624 // append content 17625 this.replace(this.$element.children().not(this.$stage.parent())); 17626 17627 // check visibility 17628 if (this.isVisible()) { 17629 // update view 17630 this.refresh(); 17631 } else { 17632 // invalidate width 17633 this.invalidate('width'); 17634 } 17635 17636 this.$element 17637 .removeClass(this.options.loadingClass) 17638 .addClass(this.options.loadedClass); 17639 }; 17640 17641 /** 17642 * Initializes the carousel. 17643 * @protected 17644 */ 17645 Owl.prototype.initialize = function() { 17646 this.enter('initializing'); 17647 this.trigger('initialize'); 17648 17649 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 17650 17651 if (this.settings.autoWidth && !this.is('pre-loading')) { 17652 var imgs, nestedSelector, width; 17653 imgs = this.$element.find('img'); 17654 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 17655 width = this.$element.children(nestedSelector).width(); 17656 17657 if (imgs.length && width <= 0) { 17658 this.preloadAutoWidthImages(imgs); 17659 } 17660 } 17661 17662 this.initializeStage(); 17663 this.initializeItems(); 17664 17665 // register event handlers 17666 this.registerEventHandlers(); 17667 17668 this.leave('initializing'); 17669 this.trigger('initialized'); 17670 }; 17671 17672 /** 17673 * @returns {Boolean} visibility of $element 17674 * if you know the carousel will always be visible you can set `checkVisibility` to `false` to 17675 * prevent the expensive browser layout forced reflow the $element.is(':visible') does 17676 */ 17677 Owl.prototype.isVisible = function() { 17678 return this.settings.checkVisibility 17679 ? this.$element.is(':visible') 17680 : true; 17681 }; 17682 17683 /** 17684 * Setups the current settings. 17685 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 17686 * @todo Support for media queries by using `matchMedia` would be nice. 17687 * @public 17688 */ 17689 Owl.prototype.setup = function() { 17690 var viewport = this.viewport(), 17691 overwrites = this.options.responsive, 17692 match = -1, 17693 settings = null; 17694 17695 if (!overwrites) { 17696 settings = $.extend({}, this.options); 17697 } else { 17698 $.each(overwrites, function(breakpoint) { 17699 if (breakpoint <= viewport && breakpoint > match) { 17700 match = Number(breakpoint); 17701 } 17702 }); 17703 17704 settings = $.extend({}, this.options, overwrites[match]); 17705 if (typeof settings.stagePadding === 'function') { 17706 settings.stagePadding = settings.stagePadding(); 17707 } 17708 delete settings.responsive; 17709 17710 // responsive class 17711 if (settings.responsiveClass) { 17712 this.$element.attr('class', 17713 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 17714 ); 17715 } 17716 } 17717 17718 this.trigger('change', { property: { name: 'settings', value: settings } }); 17719 this._breakpoint = match; 17720 this.settings = settings; 17721 this.invalidate('settings'); 17722 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 17723 }; 17724 17725 /** 17726 * Updates option logic if necessery. 17727 * @protected 17728 */ 17729 Owl.prototype.optionsLogic = function() { 17730 if (this.settings.autoWidth) { 17731 this.settings.stagePadding = false; 17732 this.settings.merge = false; 17733 } 17734 }; 17735 17736 /** 17737 * Prepares an item before add. 17738 * @todo Rename event parameter `content` to `item`. 17739 * @protected 17740 * @returns {jQuery|HTMLElement} - The item container. 17741 */ 17742 Owl.prototype.prepare = function(item) { 17743 var event = this.trigger('prepare', { content: item }); 17744 17745 if (!event.data) { 17746 event.data = $('<' + this.settings.itemElement + '/>') 17747 .addClass(this.options.itemClass).append(item) 17748 } 17749 17750 this.trigger('prepared', { content: event.data }); 17751 17752 return event.data; 17753 }; 17754 17755 /** 17756 * Updates the view. 17757 * @public 17758 */ 17759 Owl.prototype.update = function() { 17760 var i = 0, 17761 n = this._pipe.length, 17762 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 17763 cache = {}; 17764 17765 while (i < n) { 17766 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 17767 this._pipe[i].run(cache); 17768 } 17769 i++; 17770 } 17771 17772 this._invalidated = {}; 17773 17774 !this.is('valid') && this.enter('valid'); 17775 }; 17776 17777 /** 17778 * Gets the width of the view. 17779 * @public 17780 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 17781 * @returns {Number} - The width of the view in pixel. 17782 */ 17783 Owl.prototype.width = function(dimension) { 17784 dimension = dimension || Owl.Width.Default; 17785 switch (dimension) { 17786 case Owl.Width.Inner: 17787 case Owl.Width.Outer: 17788 return this._width; 17789 default: 17790 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 17791 } 17792 }; 17793 17794 /** 17795 * Refreshes the carousel primarily for adaptive purposes. 17796 * @public 17797 */ 17798 Owl.prototype.refresh = function() { 17799 this.enter('refreshing'); 17800 this.trigger('refresh'); 17801 17802 this.setup(); 17803 17804 this.optionsLogic(); 17805 17806 this.$element.addClass(this.options.refreshClass); 17807 17808 this.update(); 17809 17810 this.$element.removeClass(this.options.refreshClass); 17811 17812 this.leave('refreshing'); 17813 this.trigger('refreshed'); 17814 }; 17815 17816 /** 17817 * Checks window `resize` event. 17818 * @protected 17819 */ 17820 Owl.prototype.onThrottledResize = function() { 17821 window.clearTimeout(this.resizeTimer); 17822 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 17823 }; 17824 17825 /** 17826 * Checks window `resize` event. 17827 * @protected 17828 */ 17829 Owl.prototype.onResize = function() { 17830 if (!this._items.length) { 17831 return false; 17832 } 17833 17834 if (this._width === this.$element.width()) { 17835 return false; 17836 } 17837 17838 if (!this.isVisible()) { 17839 return false; 17840 } 17841 17842 this.enter('resizing'); 17843 17844 if (this.trigger('resize').isDefaultPrevented()) { 17845 this.leave('resizing'); 17846 return false; 17847 } 17848 17849 this.invalidate('width'); 17850 17851 this.refresh(); 17852 17853 this.leave('resizing'); 17854 this.trigger('resized'); 17855 }; 17856 17857 /** 17858 * Registers event handlers. 17859 * @todo Check `msPointerEnabled` 17860 * @todo #261 17861 * @protected 17862 */ 17863 Owl.prototype.registerEventHandlers = function() { 17864 if ($.support.transition) { 17865 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 17866 } 17867 17868 if (this.settings.responsive !== false) { 17869 this.on(window, 'resize', this._handlers.onThrottledResize); 17870 } 17871 17872 if (this.settings.mouseDrag) { 17873 this.$element.addClass(this.options.dragClass); 17874 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 17875 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 17876 } 17877 17878 if (this.settings.touchDrag){ 17879 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 17880 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 17881 } 17882 }; 17883 17884 /** 17885 * Handles `touchstart` and `mousedown` events. 17886 * @todo Horizontal swipe threshold as option 17887 * @todo #261 17888 * @protected 17889 * @param {Event} event - The event arguments. 17890 */ 17891 Owl.prototype.onDragStart = function(event) { 17892 var stage = null; 17893 17894 if (event.which === 3) { 17895 return; 17896 } 17897 17898 if ($.support.transform) { 17899 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 17900 stage = { 17901 x: stage[stage.length === 16 ? 12 : 4], 17902 y: stage[stage.length === 16 ? 13 : 5] 17903 }; 17904 } else { 17905 stage = this.$stage.position(); 17906 stage = { 17907 x: this.settings.rtl ? 17908 stage.left + this.$stage.width() - this.width() + this.settings.margin : 17909 stage.left, 17910 y: stage.top 17911 }; 17912 } 17913 17914 if (this.is('animating')) { 17915 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 17916 this.invalidate('position'); 17917 } 17918 17919 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 17920 17921 this.speed(0); 17922 17923 this._drag.time = new Date().getTime(); 17924 this._drag.target = $(event.target); 17925 this._drag.stage.start = stage; 17926 this._drag.stage.current = stage; 17927 this._drag.pointer = this.pointer(event); 17928 17929 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 17930 17931 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 17932 var delta = this.difference(this._drag.pointer, this.pointer(event)); 17933 17934 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 17935 17936 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 17937 return; 17938 } 17939 17940 event.preventDefault(); 17941 17942 this.enter('dragging'); 17943 this.trigger('drag'); 17944 }, this)); 17945 }; 17946 17947 /** 17948 * Handles the `touchmove` and `mousemove` events. 17949 * @todo #261 17950 * @protected 17951 * @param {Event} event - The event arguments. 17952 */ 17953 Owl.prototype.onDragMove = function(event) { 17954 var minimum = null, 17955 maximum = null, 17956 pull = null, 17957 delta = this.difference(this._drag.pointer, this.pointer(event)), 17958 stage = this.difference(this._drag.stage.start, delta); 17959 17960 if (!this.is('dragging')) { 17961 return; 17962 } 17963 17964 event.preventDefault(); 17965 17966 if (this.settings.loop) { 17967 minimum = this.coordinates(this.minimum()); 17968 maximum = this.coordinates(this.maximum() + 1) - minimum; 17969 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 17970 } else { 17971 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 17972 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 17973 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 17974 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 17975 } 17976 17977 this._drag.stage.current = stage; 17978 17979 this.animate(stage.x); 17980 }; 17981 17982 /** 17983 * Handles the `touchend` and `mouseup` events. 17984 * @todo #261 17985 * @todo Threshold for click event 17986 * @protected 17987 * @param {Event} event - The event arguments. 17988 */ 17989 Owl.prototype.onDragEnd = function(event) { 17990 var delta = this.difference(this._drag.pointer, this.pointer(event)), 17991 stage = this._drag.stage.current, 17992 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 17993 17994 $(document).off('.owl.core'); 17995 17996 this.$element.removeClass(this.options.grabClass); 17997 17998 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 17999 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 18000 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 18001 this.invalidate('position'); 18002 this.update(); 18003 18004 this._drag.direction = direction; 18005 18006 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 18007 this._drag.target.one('click.owl.core', function() { return false; }); 18008 } 18009 } 18010 18011 if (!this.is('dragging')) { 18012 return; 18013 } 18014 18015 this.leave('dragging'); 18016 this.trigger('dragged'); 18017 }; 18018 18019 /** 18020 * Gets absolute position of the closest item for a coordinate. 18021 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 18022 * @protected 18023 * @param {Number} coordinate - The coordinate in pixel. 18024 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 18025 * @return {Number} - The absolute position of the closest item. 18026 */ 18027 Owl.prototype.closest = function(coordinate, direction) { 18028 var position = -1, 18029 pull = 30, 18030 width = this.width(), 18031 coordinates = this.coordinates(); 18032 18033 if (!this.settings.freeDrag) { 18034 // check closest item 18035 $.each(coordinates, $.proxy(function(index, value) { 18036 // on a left pull, check on current index 18037 if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) { 18038 position = index; 18039 // on a right pull, check on previous index 18040 // to do so, subtract width from value and set position = index + 1 18041 } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) { 18042 position = index + 1; 18043 } else if (this.op(coordinate, '<', value) 18044 && this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) { 18045 position = direction === 'left' ? index + 1 : index; 18046 } 18047 return position === -1; 18048 }, this)); 18049 } 18050 18051 if (!this.settings.loop) { 18052 // non loop boundries 18053 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 18054 position = coordinate = this.minimum(); 18055 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 18056 position = coordinate = this.maximum(); 18057 } 18058 } 18059 18060 return position; 18061 }; 18062 18063 /** 18064 * Animates the stage. 18065 * @todo #270 18066 * @public 18067 * @param {Number} coordinate - The coordinate in pixels. 18068 */ 18069 Owl.prototype.animate = function(coordinate) { 18070 var animate = this.speed() > 0; 18071 18072 this.is('animating') && this.onTransitionEnd(); 18073 18074 if (animate) { 18075 this.enter('animating'); 18076 this.trigger('translate'); 18077 } 18078 18079 if ($.support.transform3d && $.support.transition) { 18080 this.$stage.css({ 18081 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 18082 transition: (this.speed() / 1000) + 's' + ( 18083 this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' 18084 ) 18085 }); 18086 } else if (animate) { 18087 this.$stage.animate({ 18088 left: coordinate + 'px' 18089 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 18090 } else { 18091 this.$stage.css({ 18092 left: coordinate + 'px' 18093 }); 18094 } 18095 }; 18096 18097 /** 18098 * Checks whether the carousel is in a specific state or not. 18099 * @param {String} state - The state to check. 18100 * @returns {Boolean} - The flag which indicates if the carousel is busy. 18101 */ 18102 Owl.prototype.is = function(state) { 18103 return this._states.current[state] && this._states.current[state] > 0; 18104 }; 18105 18106 /** 18107 * Sets the absolute position of the current item. 18108 * @public 18109 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 18110 * @returns {Number} - The absolute position of the current item. 18111 */ 18112 Owl.prototype.current = function(position) { 18113 if (position === undefined) { 18114 return this._current; 18115 } 18116 18117 if (this._items.length === 0) { 18118 return undefined; 18119 } 18120 18121 position = this.normalize(position); 18122 18123 if (this._current !== position) { 18124 var event = this.trigger('change', { property: { name: 'position', value: position } }); 18125 18126 if (event.data !== undefined) { 18127 position = this.normalize(event.data); 18128 } 18129 18130 this._current = position; 18131 18132 this.invalidate('position'); 18133 18134 this.trigger('changed', { property: { name: 'position', value: this._current } }); 18135 } 18136 18137 return this._current; 18138 }; 18139 18140 /** 18141 * Invalidates the given part of the update routine. 18142 * @param {String} [part] - The part to invalidate. 18143 * @returns {Array.<String>} - The invalidated parts. 18144 */ 18145 Owl.prototype.invalidate = function(part) { 18146 if ($.type(part) === 'string') { 18147 this._invalidated[part] = true; 18148 this.is('valid') && this.leave('valid'); 18149 } 18150 return $.map(this._invalidated, function(v, i) { return i }); 18151 }; 18152 18153 /** 18154 * Resets the absolute position of the current item. 18155 * @public 18156 * @param {Number} position - The absolute position of the new item. 18157 */ 18158 Owl.prototype.reset = function(position) { 18159 position = this.normalize(position); 18160 18161 if (position === undefined) { 18162 return; 18163 } 18164 18165 this._speed = 0; 18166 this._current = position; 18167 18168 this.suppress([ 'translate', 'translated' ]); 18169 18170 this.animate(this.coordinates(position)); 18171 18172 this.release([ 'translate', 'translated' ]); 18173 }; 18174 18175 /** 18176 * Normalizes an absolute or a relative position of an item. 18177 * @public 18178 * @param {Number} position - The absolute or relative position to normalize. 18179 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 18180 * @returns {Number} - The normalized position. 18181 */ 18182 Owl.prototype.normalize = function(position, relative) { 18183 var n = this._items.length, 18184 m = relative ? 0 : this._clones.length; 18185 18186 if (!this.isNumeric(position) || n < 1) { 18187 position = undefined; 18188 } else if (position < 0 || position >= n + m) { 18189 position = ((position - m / 2) % n + n) % n + m / 2; 18190 } 18191 18192 return position; 18193 }; 18194 18195 /** 18196 * Converts an absolute position of an item into a relative one. 18197 * @public 18198 * @param {Number} position - The absolute position to convert. 18199 * @returns {Number} - The converted position. 18200 */ 18201 Owl.prototype.relative = function(position) { 18202 position -= this._clones.length / 2; 18203 return this.normalize(position, true); 18204 }; 18205 18206 /** 18207 * Gets the maximum position for the current item. 18208 * @public 18209 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 18210 * @returns {Number} 18211 */ 18212 Owl.prototype.maximum = function(relative) { 18213 var settings = this.settings, 18214 maximum = this._coordinates.length, 18215 iterator, 18216 reciprocalItemsWidth, 18217 elementWidth; 18218 18219 if (settings.loop) { 18220 maximum = this._clones.length / 2 + this._items.length - 1; 18221 } else if (settings.autoWidth || settings.merge) { 18222 iterator = this._items.length; 18223 if (iterator) { 18224 reciprocalItemsWidth = this._items[--iterator].width(); 18225 elementWidth = this.$element.width(); 18226 while (iterator--) { 18227 reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin; 18228 if (reciprocalItemsWidth > elementWidth) { 18229 break; 18230 } 18231 } 18232 } 18233 maximum = iterator + 1; 18234 } else if (settings.center) { 18235 maximum = this._items.length - 1; 18236 } else { 18237 maximum = this._items.length - settings.items; 18238 } 18239 18240 if (relative) { 18241 maximum -= this._clones.length / 2; 18242 } 18243 18244 return Math.max(maximum, 0); 18245 }; 18246 18247 /** 18248 * Gets the minimum position for the current item. 18249 * @public 18250 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 18251 * @returns {Number} 18252 */ 18253 Owl.prototype.minimum = function(relative) { 18254 return relative ? 0 : this._clones.length / 2; 18255 }; 18256 18257 /** 18258 * Gets an item at the specified relative position. 18259 * @public 18260 * @param {Number} [position] - The relative position of the item. 18261 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 18262 */ 18263 Owl.prototype.items = function(position) { 18264 if (position === undefined) { 18265 return this._items.slice(); 18266 } 18267 18268 position = this.normalize(position, true); 18269 return this._items[position]; 18270 }; 18271 18272 /** 18273 * Gets an item at the specified relative position. 18274 * @public 18275 * @param {Number} [position] - The relative position of the item. 18276 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 18277 */ 18278 Owl.prototype.mergers = function(position) { 18279 if (position === undefined) { 18280 return this._mergers.slice(); 18281 } 18282 18283 position = this.normalize(position, true); 18284 return this._mergers[position]; 18285 }; 18286 18287 /** 18288 * Gets the absolute positions of clones for an item. 18289 * @public 18290 * @param {Number} [position] - The relative position of the item. 18291 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 18292 */ 18293 Owl.prototype.clones = function(position) { 18294 var odd = this._clones.length / 2, 18295 even = odd + this._items.length, 18296 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 18297 18298 if (position === undefined) { 18299 return $.map(this._clones, function(v, i) { return map(i) }); 18300 } 18301 18302 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 18303 }; 18304 18305 /** 18306 * Sets the current animation speed. 18307 * @public 18308 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 18309 * @returns {Number} - The current animation speed in milliseconds. 18310 */ 18311 Owl.prototype.speed = function(speed) { 18312 if (speed !== undefined) { 18313 this._speed = speed; 18314 } 18315 18316 return this._speed; 18317 }; 18318 18319 /** 18320 * Gets the coordinate of an item. 18321 * @todo The name of this method is missleanding. 18322 * @public 18323 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 18324 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 18325 */ 18326 Owl.prototype.coordinates = function(position) { 18327 var multiplier = 1, 18328 newPosition = position - 1, 18329 coordinate; 18330 18331 if (position === undefined) { 18332 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 18333 return this.coordinates(index); 18334 }, this)); 18335 } 18336 18337 if (this.settings.center) { 18338 if (this.settings.rtl) { 18339 multiplier = -1; 18340 newPosition = position + 1; 18341 } 18342 18343 coordinate = this._coordinates[position]; 18344 coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier; 18345 } else { 18346 coordinate = this._coordinates[newPosition] || 0; 18347 } 18348 18349 coordinate = Math.ceil(coordinate); 18350 18351 return coordinate; 18352 }; 18353 18354 /** 18355 * Calculates the speed for a translation. 18356 * @protected 18357 * @param {Number} from - The absolute position of the start item. 18358 * @param {Number} to - The absolute position of the target item. 18359 * @param {Number} [factor=undefined] - The time factor in milliseconds. 18360 * @returns {Number} - The time in milliseconds for the translation. 18361 */ 18362 Owl.prototype.duration = function(from, to, factor) { 18363 if (factor === 0) { 18364 return 0; 18365 } 18366 18367 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 18368 }; 18369 18370 /** 18371 * Slides to the specified item. 18372 * @public 18373 * @param {Number} position - The position of the item. 18374 * @param {Number} [speed] - The time in milliseconds for the transition. 18375 */ 18376 Owl.prototype.to = function(position, speed) { 18377 var current = this.current(), 18378 revert = null, 18379 distance = position - this.relative(current), 18380 direction = (distance > 0) - (distance < 0), 18381 items = this._items.length, 18382 minimum = this.minimum(), 18383 maximum = this.maximum(); 18384 18385 if (this.settings.loop) { 18386 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 18387 distance += direction * -1 * items; 18388 } 18389 18390 position = current + distance; 18391 revert = ((position - minimum) % items + items) % items + minimum; 18392 18393 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 18394 current = revert - distance; 18395 position = revert; 18396 this.reset(current); 18397 } 18398 } else if (this.settings.rewind) { 18399 maximum += 1; 18400 position = (position % maximum + maximum) % maximum; 18401 } else { 18402 position = Math.max(minimum, Math.min(maximum, position)); 18403 } 18404 18405 this.speed(this.duration(current, position, speed)); 18406 this.current(position); 18407 18408 if (this.isVisible()) { 18409 this.update(); 18410 } 18411 }; 18412 18413 /** 18414 * Slides to the next item. 18415 * @public 18416 * @param {Number} [speed] - The time in milliseconds for the transition. 18417 */ 18418 Owl.prototype.next = function(speed) { 18419 speed = speed || false; 18420 this.to(this.relative(this.current()) + 1, speed); 18421 }; 18422 18423 /** 18424 * Slides to the previous item. 18425 * @public 18426 * @param {Number} [speed] - The time in milliseconds for the transition. 18427 */ 18428 Owl.prototype.prev = function(speed) { 18429 speed = speed || false; 18430 this.to(this.relative(this.current()) - 1, speed); 18431 }; 18432 18433 /** 18434 * Handles the end of an animation. 18435 * @protected 18436 * @param {Event} event - The event arguments. 18437 */ 18438 Owl.prototype.onTransitionEnd = function(event) { 18439 18440 // if css2 animation then event object is undefined 18441 if (event !== undefined) { 18442 event.stopPropagation(); 18443 18444 // Catch only owl-stage transitionEnd event 18445 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 18446 return false; 18447 } 18448 } 18449 18450 this.leave('animating'); 18451 this.trigger('translated'); 18452 }; 18453 18454 /** 18455 * Gets viewport width. 18456 * @protected 18457 * @return {Number} - The width in pixel. 18458 */ 18459 Owl.prototype.viewport = function() { 18460 var width; 18461 if (this.options.responsiveBaseElement !== window) { 18462 width = $(this.options.responsiveBaseElement).width(); 18463 } else if (window.innerWidth) { 18464 width = window.innerWidth; 18465 } else if (document.documentElement && document.documentElement.clientWidth) { 18466 width = document.documentElement.clientWidth; 18467 } else { 18468 console.warn('Can not detect viewport width.'); 18469 } 18470 return width; 18471 }; 18472 18473 /** 18474 * Replaces the current content. 18475 * @public 18476 * @param {HTMLElement|jQuery|String} content - The new content. 18477 */ 18478 Owl.prototype.replace = function(content) { 18479 this.$stage.empty(); 18480 this._items = []; 18481 18482 if (content) { 18483 content = (content instanceof jQuery) ? content : $(content); 18484 } 18485 18486 if (this.settings.nestedItemSelector) { 18487 content = content.find('.' + this.settings.nestedItemSelector); 18488 } 18489 18490 content.filter(function() { 18491 return this.nodeType === 1; 18492 }).each($.proxy(function(index, item) { 18493 item = this.prepare(item); 18494 this.$stage.append(item); 18495 this._items.push(item); 18496 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 18497 }, this)); 18498 18499 this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 18500 18501 this.invalidate('items'); 18502 }; 18503 18504 /** 18505 * Adds an item. 18506 * @todo Use `item` instead of `content` for the event arguments. 18507 * @public 18508 * @param {HTMLElement|jQuery|String} content - The item content to add. 18509 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 18510 */ 18511 Owl.prototype.add = function(content, position) { 18512 var current = this.relative(this._current); 18513 18514 position = position === undefined ? this._items.length : this.normalize(position, true); 18515 content = content instanceof jQuery ? content : $(content); 18516 18517 this.trigger('add', { content: content, position: position }); 18518 18519 content = this.prepare(content); 18520 18521 if (this._items.length === 0 || position === this._items.length) { 18522 this._items.length === 0 && this.$stage.append(content); 18523 this._items.length !== 0 && this._items[position - 1].after(content); 18524 this._items.push(content); 18525 this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 18526 } else { 18527 this._items[position].before(content); 18528 this._items.splice(position, 0, content); 18529 this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 18530 } 18531 18532 this._items[current] && this.reset(this._items[current].index()); 18533 18534 this.invalidate('items'); 18535 18536 this.trigger('added', { content: content, position: position }); 18537 }; 18538 18539 /** 18540 * Removes an item by its position. 18541 * @todo Use `item` instead of `content` for the event arguments. 18542 * @public 18543 * @param {Number} position - The relative position of the item to remove. 18544 */ 18545 Owl.prototype.remove = function(position) { 18546 position = this.normalize(position, true); 18547 18548 if (position === undefined) { 18549 return; 18550 } 18551 18552 this.trigger('remove', { content: this._items[position], position: position }); 18553 18554 this._items[position].remove(); 18555 this._items.splice(position, 1); 18556 this._mergers.splice(position, 1); 18557 18558 this.invalidate('items'); 18559 18560 this.trigger('removed', { content: null, position: position }); 18561 }; 18562 18563 /** 18564 * Preloads images with auto width. 18565 * @todo Replace by a more generic approach 18566 * @protected 18567 */ 18568 Owl.prototype.preloadAutoWidthImages = function(images) { 18569 images.each($.proxy(function(i, element) { 18570 this.enter('pre-loading'); 18571 element = $(element); 18572 $(new Image()).one('load', $.proxy(function(e) { 18573 element.attr('src', e.target.src); 18574 element.css('opacity', 1); 18575 this.leave('pre-loading'); 18576 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 18577 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 18578 }, this)); 18579 }; 18580 18581 /** 18582 * Destroys the carousel. 18583 * @public 18584 */ 18585 Owl.prototype.destroy = function() { 18586 18587 this.$element.off('.owl.core'); 18588 this.$stage.off('.owl.core'); 18589 $(document).off('.owl.core'); 18590 18591 if (this.settings.responsive !== false) { 18592 window.clearTimeout(this.resizeTimer); 18593 this.off(window, 'resize', this._handlers.onThrottledResize); 18594 } 18595 18596 for (var i in this._plugins) { 18597 this._plugins[i].destroy(); 18598 } 18599 18600 this.$stage.children('.cloned').remove(); 18601 18602 this.$stage.unwrap(); 18603 this.$stage.children().contents().unwrap(); 18604 this.$stage.children().unwrap(); 18605 this.$stage.remove(); 18606 this.$element 18607 .removeClass(this.options.refreshClass) 18608 .removeClass(this.options.loadingClass) 18609 .removeClass(this.options.loadedClass) 18610 .removeClass(this.options.rtlClass) 18611 .removeClass(this.options.dragClass) 18612 .removeClass(this.options.grabClass) 18613 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 18614 .removeData('owl.carousel'); 18615 }; 18616 18617 /** 18618 * Operators to calculate right-to-left and left-to-right. 18619 * @protected 18620 * @param {Number} [a] - The left side operand. 18621 * @param {String} [o] - The operator. 18622 * @param {Number} [b] - The right side operand. 18623 */ 18624 Owl.prototype.op = function(a, o, b) { 18625 var rtl = this.settings.rtl; 18626 switch (o) { 18627 case '<': 18628 return rtl ? a > b : a < b; 18629 case '>': 18630 return rtl ? a < b : a > b; 18631 case '>=': 18632 return rtl ? a <= b : a >= b; 18633 case '<=': 18634 return rtl ? a >= b : a <= b; 18635 default: 18636 break; 18637 } 18638 }; 18639 18640 /** 18641 * Attaches to an internal event. 18642 * @protected 18643 * @param {HTMLElement} element - The event source. 18644 * @param {String} event - The event name. 18645 * @param {Function} listener - The event handler to attach. 18646 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 18647 */ 18648 Owl.prototype.on = function(element, event, listener, capture) { 18649 if (element.addEventListener) { 18650 element.addEventListener(event, listener, capture); 18651 } else if (element.attachEvent) { 18652 element.attachEvent('on' + event, listener); 18653 } 18654 }; 18655 18656 /** 18657 * Detaches from an internal event. 18658 * @protected 18659 * @param {HTMLElement} element - The event source. 18660 * @param {String} event - The event name. 18661 * @param {Function} listener - The attached event handler to detach. 18662 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 18663 */ 18664 Owl.prototype.off = function(element, event, listener, capture) { 18665 if (element.removeEventListener) { 18666 element.removeEventListener(event, listener, capture); 18667 } else if (element.detachEvent) { 18668 element.detachEvent('on' + event, listener); 18669 } 18670 }; 18671 18672 /** 18673 * Triggers a public event. 18674 * @todo Remove `status`, `relatedTarget` should be used instead. 18675 * @protected 18676 * @param {String} name - The event name. 18677 * @param {*} [data=null] - The event data. 18678 * @param {String} [namespace=carousel] - The event namespace. 18679 * @param {String} [state] - The state which is associated with the event. 18680 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 18681 * @returns {Event} - The event arguments. 18682 */ 18683 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 18684 var status = { 18685 item: { count: this._items.length, index: this.current() } 18686 }, handler = $.camelCase( 18687 $.grep([ 'on', name, namespace ], function(v) { return v }) 18688 .join('-').toLowerCase() 18689 ), event = $.Event( 18690 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 18691 $.extend({ relatedTarget: this }, status, data) 18692 ); 18693 18694 if (!this._supress[name]) { 18695 $.each(this._plugins, function(name, plugin) { 18696 if (plugin.onTrigger) { 18697 plugin.onTrigger(event); 18698 } 18699 }); 18700 18701 this.register({ type: Owl.Type.Event, name: name }); 18702 this.$element.trigger(event); 18703 18704 if (this.settings && typeof this.settings[handler] === 'function') { 18705 this.settings[handler].call(this, event); 18706 } 18707 } 18708 18709 return event; 18710 }; 18711 18712 /** 18713 * Enters a state. 18714 * @param name - The state name. 18715 */ 18716 Owl.prototype.enter = function(name) { 18717 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 18718 if (this._states.current[name] === undefined) { 18719 this._states.current[name] = 0; 18720 } 18721 18722 this._states.current[name]++; 18723 }, this)); 18724 }; 18725 18726 /** 18727 * Leaves a state. 18728 * @param name - The state name. 18729 */ 18730 Owl.prototype.leave = function(name) { 18731 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 18732 this._states.current[name]--; 18733 }, this)); 18734 }; 18735 18736 /** 18737 * Registers an event or state. 18738 * @public 18739 * @param {Object} object - The event or state to register. 18740 */ 18741 Owl.prototype.register = function(object) { 18742 if (object.type === Owl.Type.Event) { 18743 if (!$.event.special[object.name]) { 18744 $.event.special[object.name] = {}; 18745 } 18746 18747 if (!$.event.special[object.name].owl) { 18748 var _default = $.event.special[object.name]._default; 18749 $.event.special[object.name]._default = function(e) { 18750 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 18751 return _default.apply(this, arguments); 18752 } 18753 return e.namespace && e.namespace.indexOf('owl') > -1; 18754 }; 18755 $.event.special[object.name].owl = true; 18756 } 18757 } else if (object.type === Owl.Type.State) { 18758 if (!this._states.tags[object.name]) { 18759 this._states.tags[object.name] = object.tags; 18760 } else { 18761 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 18762 } 18763 18764 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 18765 return $.inArray(tag, this._states.tags[object.name]) === i; 18766 }, this)); 18767 } 18768 }; 18769 18770 /** 18771 * Suppresses events. 18772 * @protected 18773 * @param {Array.<String>} events - The events to suppress. 18774 */ 18775 Owl.prototype.suppress = function(events) { 18776 $.each(events, $.proxy(function(index, event) { 18777 this._supress[event] = true; 18778 }, this)); 18779 }; 18780 18781 /** 18782 * Releases suppressed events. 18783 * @protected 18784 * @param {Array.<String>} events - The events to release. 18785 */ 18786 Owl.prototype.release = function(events) { 18787 $.each(events, $.proxy(function(index, event) { 18788 delete this._supress[event]; 18789 }, this)); 18790 }; 18791 18792 /** 18793 * Gets unified pointer coordinates from event. 18794 * @todo #261 18795 * @protected 18796 * @param {Event} - The `mousedown` or `touchstart` event. 18797 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 18798 */ 18799 Owl.prototype.pointer = function(event) { 18800 var result = { x: null, y: null }; 18801 18802 event = event.originalEvent || event || window.event; 18803 18804 event = event.touches && event.touches.length ? 18805 event.touches[0] : event.changedTouches && event.changedTouches.length ? 18806 event.changedTouches[0] : event; 18807 18808 if (event.pageX) { 18809 result.x = event.pageX; 18810 result.y = event.pageY; 18811 } else { 18812 result.x = event.clientX; 18813 result.y = event.clientY; 18814 } 18815 18816 return result; 18817 }; 18818 18819 /** 18820 * Determines if the input is a Number or something that can be coerced to a Number 18821 * @protected 18822 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested 18823 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number 18824 */ 18825 Owl.prototype.isNumeric = function(number) { 18826 return !isNaN(parseFloat(number)); 18827 }; 18828 18829 /** 18830 * Gets the difference of two vectors. 18831 * @todo #261 18832 * @protected 18833 * @param {Object} - The first vector. 18834 * @param {Object} - The second vector. 18835 * @returns {Object} - The difference. 18836 */ 18837 Owl.prototype.difference = function(first, second) { 18838 return { 18839 x: first.x - second.x, 18840 y: first.y - second.y 18841 }; 18842 }; 18843 18844 /** 18845 * The jQuery Plugin for the Owl Carousel 18846 * @todo Navigation plugin `next` and `prev` 18847 * @public 18848 */ 18849 $.fn.owlCarousel = function(option) { 18850 var args = Array.prototype.slice.call(arguments, 1); 18851 18852 return this.each(function() { 18853 var $this = $(this), 18854 data = $this.data('owl.carousel'); 18855 18856 if (!data) { 18857 data = new Owl(this, typeof option == 'object' && option); 18858 $this.data('owl.carousel', data); 18859 18860 $.each([ 18861 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 18862 ], function(i, event) { 18863 data.register({ type: Owl.Type.Event, name: event }); 18864 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 18865 if (e.namespace && e.relatedTarget !== this) { 18866 this.suppress([ event ]); 18867 data[event].apply(this, [].slice.call(arguments, 1)); 18868 this.release([ event ]); 18869 } 18870 }, data)); 18871 }); 18872 } 18873 18874 if (typeof option == 'string' && option.charAt(0) !== '_') { 18875 data[option].apply(data, args); 18876 } 18877 }); 18878 }; 18879 18880 /** 18881 * The constructor for the jQuery Plugin 18882 * @public 18883 */ 18884 $.fn.owlCarousel.Constructor = Owl; 18885 18886})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 18887 18888/** 18889 * AutoRefresh Plugin 18890 * @version 2.3.4 18891 * @author Artus Kolanowski 18892 * @author David Deutsch 18893 * @license The MIT License (MIT) 18894 */ 18895;(function($, window, document, undefined) { 18896 18897 /** 18898 * Creates the auto refresh plugin. 18899 * @class The Auto Refresh Plugin 18900 * @param {Owl} carousel - The Owl Carousel 18901 */ 18902 var AutoRefresh = function(carousel) { 18903 /** 18904 * Reference to the core. 18905 * @protected 18906 * @type {Owl} 18907 */ 18908 this._core = carousel; 18909 18910 /** 18911 * Refresh interval. 18912 * @protected 18913 * @type {number} 18914 */ 18915 this._interval = null; 18916 18917 /** 18918 * Whether the element is currently visible or not. 18919 * @protected 18920 * @type {Boolean} 18921 */ 18922 this._visible = null; 18923 18924 /** 18925 * All event handlers. 18926 * @protected 18927 * @type {Object} 18928 */ 18929 this._handlers = { 18930 'initialized.owl.carousel': $.proxy(function(e) { 18931 if (e.namespace && this._core.settings.autoRefresh) { 18932 this.watch(); 18933 } 18934 }, this) 18935 }; 18936 18937 // set default options 18938 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 18939 18940 // register event handlers 18941 this._core.$element.on(this._handlers); 18942 }; 18943 18944 /** 18945 * Default options. 18946 * @public 18947 */ 18948 AutoRefresh.Defaults = { 18949 autoRefresh: true, 18950 autoRefreshInterval: 500 18951 }; 18952 18953 /** 18954 * Watches the element. 18955 */ 18956 AutoRefresh.prototype.watch = function() { 18957 if (this._interval) { 18958 return; 18959 } 18960 18961 this._visible = this._core.isVisible(); 18962 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 18963 }; 18964 18965 /** 18966 * Refreshes the element. 18967 */ 18968 AutoRefresh.prototype.refresh = function() { 18969 if (this._core.isVisible() === this._visible) { 18970 return; 18971 } 18972 18973 this._visible = !this._visible; 18974 18975 this._core.$element.toggleClass('owl-hidden', !this._visible); 18976 18977 this._visible && (this._core.invalidate('width') && this._core.refresh()); 18978 }; 18979 18980 /** 18981 * Destroys the plugin. 18982 */ 18983 AutoRefresh.prototype.destroy = function() { 18984 var handler, property; 18985 18986 window.clearInterval(this._interval); 18987 18988 for (handler in this._handlers) { 18989 this._core.$element.off(handler, this._handlers[handler]); 18990 } 18991 for (property in Object.getOwnPropertyNames(this)) { 18992 typeof this[property] != 'function' && (this[property] = null); 18993 } 18994 }; 18995 18996 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 18997 18998})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 18999 19000/** 19001 * Lazy Plugin 19002 * @version 2.3.4 19003 * @author Bartosz Wojciechowski 19004 * @author David Deutsch 19005 * @license The MIT License (MIT) 19006 */ 19007;(function($, window, document, undefined) { 19008 19009 /** 19010 * Creates the lazy plugin. 19011 * @class The Lazy Plugin 19012 * @param {Owl} carousel - The Owl Carousel 19013 */ 19014 var Lazy = function(carousel) { 19015 19016 /** 19017 * Reference to the core. 19018 * @protected 19019 * @type {Owl} 19020 */ 19021 this._core = carousel; 19022 19023 /** 19024 * Already loaded items. 19025 * @protected 19026 * @type {Array.<jQuery>} 19027 */ 19028 this._loaded = []; 19029 19030 /** 19031 * Event handlers. 19032 * @protected 19033 * @type {Object} 19034 */ 19035 this._handlers = { 19036 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) { 19037 if (!e.namespace) { 19038 return; 19039 } 19040 19041 if (!this._core.settings || !this._core.settings.lazyLoad) { 19042 return; 19043 } 19044 19045 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 19046 var settings = this._core.settings, 19047 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 19048 i = ((settings.center && n * -1) || 0), 19049 position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i, 19050 clones = this._core.clones().length, 19051 load = $.proxy(function(i, v) { this.load(v) }, this); 19052 //TODO: Need documentation for this new option 19053 if (settings.lazyLoadEager > 0) { 19054 n += settings.lazyLoadEager; 19055 // If the carousel is looping also preload images that are to the "left" 19056 if (settings.loop) { 19057 position -= settings.lazyLoadEager; 19058 n++; 19059 } 19060 } 19061 19062 while (i++ < n) { 19063 this.load(clones / 2 + this._core.relative(position)); 19064 clones && $.each(this._core.clones(this._core.relative(position)), load); 19065 position++; 19066 } 19067 } 19068 }, this) 19069 }; 19070 19071 // set the default options 19072 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 19073 19074 // register event handler 19075 this._core.$element.on(this._handlers); 19076 }; 19077 19078 /** 19079 * Default options. 19080 * @public 19081 */ 19082 Lazy.Defaults = { 19083 lazyLoad: false, 19084 lazyLoadEager: 0 19085 }; 19086 19087 /** 19088 * Loads all resources of an item at the specified position. 19089 * @param {Number} position - The absolute position of the item. 19090 * @protected 19091 */ 19092 Lazy.prototype.load = function(position) { 19093 var $item = this._core.$stage.children().eq(position), 19094 $elements = $item && $item.find('.owl-lazy'); 19095 19096 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 19097 return; 19098 } 19099 19100 $elements.each($.proxy(function(index, element) { 19101 var $element = $(element), image, 19102 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset'); 19103 19104 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 19105 19106 if ($element.is('img')) { 19107 $element.one('load.owl.lazy', $.proxy(function() { 19108 $element.css('opacity', 1); 19109 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 19110 }, this)).attr('src', url); 19111 } else if ($element.is('source')) { 19112 $element.one('load.owl.lazy', $.proxy(function() { 19113 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 19114 }, this)).attr('srcset', url); 19115 } else { 19116 image = new Image(); 19117 image.onload = $.proxy(function() { 19118 $element.css({ 19119 'background-image': 'url("' + url + '")', 19120 'opacity': '1' 19121 }); 19122 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 19123 }, this); 19124 image.src = url; 19125 } 19126 }, this)); 19127 19128 this._loaded.push($item.get(0)); 19129 }; 19130 19131 /** 19132 * Destroys the plugin. 19133 * @public 19134 */ 19135 Lazy.prototype.destroy = function() { 19136 var handler, property; 19137 19138 for (handler in this.handlers) { 19139 this._core.$element.off(handler, this.handlers[handler]); 19140 } 19141 for (property in Object.getOwnPropertyNames(this)) { 19142 typeof this[property] != 'function' && (this[property] = null); 19143 } 19144 }; 19145 19146 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 19147 19148})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 19149 19150/** 19151 * AutoHeight Plugin 19152 * @version 2.3.4 19153 * @author Bartosz Wojciechowski 19154 * @author David Deutsch 19155 * @license The MIT License (MIT) 19156 */ 19157;(function($, window, document, undefined) { 19158 19159 /** 19160 * Creates the auto height plugin. 19161 * @class The Auto Height Plugin 19162 * @param {Owl} carousel - The Owl Carousel 19163 */ 19164 var AutoHeight = function(carousel) { 19165 /** 19166 * Reference to the core. 19167 * @protected 19168 * @type {Owl} 19169 */ 19170 this._core = carousel; 19171 19172 this._previousHeight = null; 19173 19174 /** 19175 * All event handlers. 19176 * @protected 19177 * @type {Object} 19178 */ 19179 this._handlers = { 19180 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 19181 if (e.namespace && this._core.settings.autoHeight) { 19182 this.update(); 19183 } 19184 }, this), 19185 'changed.owl.carousel': $.proxy(function(e) { 19186 if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){ 19187 this.update(); 19188 } 19189 }, this), 19190 'loaded.owl.lazy': $.proxy(function(e) { 19191 if (e.namespace && this._core.settings.autoHeight 19192 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 19193 this.update(); 19194 } 19195 }, this) 19196 }; 19197 19198 // set default options 19199 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 19200 19201 // register event handlers 19202 this._core.$element.on(this._handlers); 19203 this._intervalId = null; 19204 var refThis = this; 19205 19206 // These changes have been taken from a PR by gavrochelegnou proposed in #1575 19207 // and have been made compatible with the latest jQuery version 19208 $(window).on('load', function() { 19209 if (refThis._core.settings.autoHeight) { 19210 refThis.update(); 19211 } 19212 }); 19213 19214 // Autoresize the height of the carousel when window is resized 19215 // When carousel has images, the height is dependent on the width 19216 // and should also change on resize 19217 $(window).resize(function() { 19218 if (refThis._core.settings.autoHeight) { 19219 if (refThis._intervalId != null) { 19220 clearTimeout(refThis._intervalId); 19221 } 19222 19223 refThis._intervalId = setTimeout(function() { 19224 refThis.update(); 19225 }, 250); 19226 } 19227 }); 19228 19229 }; 19230 19231 /** 19232 * Default options. 19233 * @public 19234 */ 19235 AutoHeight.Defaults = { 19236 autoHeight: false, 19237 autoHeightClass: 'owl-height' 19238 }; 19239 19240 /** 19241 * Updates the view. 19242 */ 19243 AutoHeight.prototype.update = function() { 19244 var start = this._core._current, 19245 end = start + this._core.settings.items, 19246 lazyLoadEnabled = this._core.settings.lazyLoad, 19247 visible = this._core.$stage.children().toArray().slice(start, end), 19248 heights = [], 19249 maxheight = 0; 19250 19251 $.each(visible, function(index, item) { 19252 heights.push($(item).height()); 19253 }); 19254 19255 maxheight = Math.max.apply(null, heights); 19256 19257 if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) { 19258 maxheight = this._previousHeight; 19259 } 19260 19261 this._previousHeight = maxheight; 19262 19263 this._core.$stage.parent() 19264 .height(maxheight) 19265 .addClass(this._core.settings.autoHeightClass); 19266 }; 19267 19268 AutoHeight.prototype.destroy = function() { 19269 var handler, property; 19270 19271 for (handler in this._handlers) { 19272 this._core.$element.off(handler, this._handlers[handler]); 19273 } 19274 for (property in Object.getOwnPropertyNames(this)) { 19275 typeof this[property] !== 'function' && (this[property] = null); 19276 } 19277 }; 19278 19279 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 19280 19281})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 19282 19283/** 19284 * Video Plugin 19285 * @version 2.3.4 19286 * @author Bartosz Wojciechowski 19287 * @author David Deutsch 19288 * @license The MIT License (MIT) 19289 */ 19290;(function($, window, document, undefined) { 19291 19292 /** 19293 * Creates the video plugin. 19294 * @class The Video Plugin 19295 * @param {Owl} carousel - The Owl Carousel 19296 */ 19297 var Video = function(carousel) { 19298 /** 19299 * Reference to the core. 19300 * @protected 19301 * @type {Owl} 19302 */ 19303 this._core = carousel; 19304 19305 /** 19306 * Cache all video URLs. 19307 * @protected 19308 * @type {Object} 19309 */ 19310 this._videos = {}; 19311 19312 /** 19313 * Current playing item. 19314 * @protected 19315 * @type {jQuery} 19316 */ 19317 this._playing = null; 19318 19319 /** 19320 * All event handlers. 19321 * @todo The cloned content removale is too late 19322 * @protected 19323 * @type {Object} 19324 */ 19325 this._handlers = { 19326 'initialized.owl.carousel': $.proxy(function(e) { 19327 if (e.namespace) { 19328 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 19329 } 19330 }, this), 19331 'resize.owl.carousel': $.proxy(function(e) { 19332 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 19333 e.preventDefault(); 19334 } 19335 }, this), 19336 'refreshed.owl.carousel': $.proxy(function(e) { 19337 if (e.namespace && this._core.is('resizing')) { 19338 this._core.$stage.find('.cloned .owl-video-frame').remove(); 19339 } 19340 }, this), 19341 'changed.owl.carousel': $.proxy(function(e) { 19342 if (e.namespace && e.property.name === 'position' && this._playing) { 19343 this.stop(); 19344 } 19345 }, this), 19346 'prepared.owl.carousel': $.proxy(function(e) { 19347 if (!e.namespace) { 19348 return; 19349 } 19350 19351 var $element = $(e.content).find('.owl-video'); 19352 19353 if ($element.length) { 19354 $element.css('display', 'none'); 19355 this.fetch($element, $(e.content)); 19356 } 19357 }, this) 19358 }; 19359 19360 // set default options 19361 this._core.options = $.extend({}, Video.Defaults, this._core.options); 19362 19363 // register event handlers 19364 this._core.$element.on(this._handlers); 19365 19366 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 19367 this.play(e); 19368 }, this)); 19369 }; 19370 19371 /** 19372 * Default options. 19373 * @public 19374 */ 19375 Video.Defaults = { 19376 video: false, 19377 videoHeight: false, 19378 videoWidth: false 19379 }; 19380 19381 /** 19382 * Gets the video ID and the type (YouTube/Vimeo/vzaar only). 19383 * @protected 19384 * @param {jQuery} target - The target containing the video data. 19385 * @param {jQuery} item - The item containing the video. 19386 */ 19387 Video.prototype.fetch = function(target, item) { 19388 var type = (function() { 19389 if (target.attr('data-vimeo-id')) { 19390 return 'vimeo'; 19391 } else if (target.attr('data-vzaar-id')) { 19392 return 'vzaar' 19393 } else { 19394 return 'youtube'; 19395 } 19396 })(), 19397 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'), 19398 width = target.attr('data-width') || this._core.settings.videoWidth, 19399 height = target.attr('data-height') || this._core.settings.videoHeight, 19400 url = target.attr('href'); 19401 19402 if (url) { 19403 19404 /* 19405 Parses the id's out of the following urls (and probably more): 19406 https://www.youtube.com/watch?v=:id 19407 https://youtu.be/:id 19408 https://vimeo.com/:id 19409 https://vimeo.com/channels/:channel/:id 19410 https://vimeo.com/groups/:group/videos/:id 19411 https://app.vzaar.com/videos/:id 19412 19413 Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F 19414 */ 19415 19416 id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); 19417 19418 if (id[3].indexOf('youtu') > -1) { 19419 type = 'youtube'; 19420 } else if (id[3].indexOf('vimeo') > -1) { 19421 type = 'vimeo'; 19422 } else if (id[3].indexOf('vzaar') > -1) { 19423 type = 'vzaar'; 19424 } else { 19425 throw new Error('Video URL not supported.'); 19426 } 19427 id = id[6]; 19428 } else { 19429 throw new Error('Missing video URL.'); 19430 } 19431 19432 this._videos[url] = { 19433 type: type, 19434 id: id, 19435 width: width, 19436 height: height 19437 }; 19438 19439 item.attr('data-video', url); 19440 19441 this.thumbnail(target, this._videos[url]); 19442 }; 19443 19444 /** 19445 * Creates video thumbnail. 19446 * @protected 19447 * @param {jQuery} target - The target containing the video data. 19448 * @param {Object} info - The video info object. 19449 * @see `fetch` 19450 */ 19451 Video.prototype.thumbnail = function(target, video) { 19452 var tnLink, 19453 icon, 19454 path, 19455 dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '', 19456 customTn = target.find('img'), 19457 srcType = 'src', 19458 lazyClass = '', 19459 settings = this._core.settings, 19460 create = function(path) { 19461 icon = '<div class="owl-video-play-icon"></div>'; 19462 19463 if (settings.lazyLoad) { 19464 tnLink = $('<div/>',{ 19465 "class": 'owl-video-tn ' + lazyClass, 19466 "srcType": path 19467 }); 19468 } else { 19469 tnLink = $( '<div/>', { 19470 "class": "owl-video-tn", 19471 "style": 'opacity:1;background-image:url(' + path + ')' 19472 }); 19473 } 19474 target.after(tnLink); 19475 target.after(icon); 19476 }; 19477 19478 // wrap video content into owl-video-wrapper div 19479 target.wrap( $( '<div/>', { 19480 "class": "owl-video-wrapper", 19481 "style": dimensions 19482 })); 19483 19484 if (this._core.settings.lazyLoad) { 19485 srcType = 'data-src'; 19486 lazyClass = 'owl-lazy'; 19487 } 19488 19489 // custom thumbnail 19490 if (customTn.length) { 19491 create(customTn.attr(srcType)); 19492 customTn.remove(); 19493 return false; 19494 } 19495 19496 if (video.type === 'youtube') { 19497 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 19498 create(path); 19499 } else if (video.type === 'vimeo') { 19500 $.ajax({ 19501 type: 'GET', 19502 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 19503 jsonp: 'callback', 19504 dataType: 'jsonp', 19505 success: function(data) { 19506 path = data[0].thumbnail_large; 19507 create(path); 19508 } 19509 }); 19510 } else if (video.type === 'vzaar') { 19511 $.ajax({ 19512 type: 'GET', 19513 url: '//vzaar.com/api/videos/' + video.id + '.json', 19514 jsonp: 'callback', 19515 dataType: 'jsonp', 19516 success: function(data) { 19517 path = data.framegrab_url; 19518 create(path); 19519 } 19520 }); 19521 } 19522 }; 19523 19524 /** 19525 * Stops the current video. 19526 * @public 19527 */ 19528 Video.prototype.stop = function() { 19529 this._core.trigger('stop', null, 'video'); 19530 this._playing.find('.owl-video-frame').remove(); 19531 this._playing.removeClass('owl-video-playing'); 19532 this._playing = null; 19533 this._core.leave('playing'); 19534 this._core.trigger('stopped', null, 'video'); 19535 }; 19536 19537 /** 19538 * Starts the current video. 19539 * @public 19540 * @param {Event} event - The event arguments. 19541 */ 19542 Video.prototype.play = function(event) { 19543 var target = $(event.target), 19544 item = target.closest('.' + this._core.settings.itemClass), 19545 video = this._videos[item.attr('data-video')], 19546 width = video.width || '100%', 19547 height = video.height || this._core.$stage.height(), 19548 html, 19549 iframe; 19550 19551 if (this._playing) { 19552 return; 19553 } 19554 19555 this._core.enter('playing'); 19556 this._core.trigger('play', null, 'video'); 19557 19558 item = this._core.items(this._core.relative(item.index())); 19559 19560 this._core.reset(item.index()); 19561 19562 html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' ); 19563 html.attr( 'height', height ); 19564 html.attr( 'width', width ); 19565 if (video.type === 'youtube') { 19566 html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id ); 19567 } else if (video.type === 'vimeo') { 19568 html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' ); 19569 } else if (video.type === 'vzaar') { 19570 html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' ); 19571 } 19572 19573 iframe = $(html).wrap( '<div class="owl-video-frame" />' ).insertAfter(item.find('.owl-video')); 19574 19575 this._playing = item.addClass('owl-video-playing'); 19576 }; 19577 19578 /** 19579 * Checks whether an video is currently in full screen mode or not. 19580 * @todo Bad style because looks like a readonly method but changes members. 19581 * @protected 19582 * @returns {Boolean} 19583 */ 19584 Video.prototype.isInFullScreen = function() { 19585 var element = document.fullscreenElement || document.mozFullScreenElement || 19586 document.webkitFullscreenElement; 19587 19588 return element && $(element).parent().hasClass('owl-video-frame'); 19589 }; 19590 19591 /** 19592 * Destroys the plugin. 19593 */ 19594 Video.prototype.destroy = function() { 19595 var handler, property; 19596 19597 this._core.$element.off('click.owl.video'); 19598 19599 for (handler in this._handlers) { 19600 this._core.$element.off(handler, this._handlers[handler]); 19601 } 19602 for (property in Object.getOwnPropertyNames(this)) { 19603 typeof this[property] != 'function' && (this[property] = null); 19604 } 19605 }; 19606 19607 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 19608 19609})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 19610 19611/** 19612 * Animate Plugin 19613 * @version 2.3.4 19614 * @author Bartosz Wojciechowski 19615 * @author David Deutsch 19616 * @license The MIT License (MIT) 19617 */ 19618;(function($, window, document, undefined) { 19619 19620 /** 19621 * Creates the animate plugin. 19622 * @class The Navigation Plugin 19623 * @param {Owl} scope - The Owl Carousel 19624 */ 19625 var Animate = function(scope) { 19626 this.core = scope; 19627 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 19628 this.swapping = true; 19629 this.previous = undefined; 19630 this.next = undefined; 19631 19632 this.handlers = { 19633 'change.owl.carousel': $.proxy(function(e) { 19634 if (e.namespace && e.property.name == 'position') { 19635 this.previous = this.core.current(); 19636 this.next = e.property.value; 19637 } 19638 }, this), 19639 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 19640 if (e.namespace) { 19641 this.swapping = e.type == 'translated'; 19642 } 19643 }, this), 19644 'translate.owl.carousel': $.proxy(function(e) { 19645 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 19646 this.swap(); 19647 } 19648 }, this) 19649 }; 19650 19651 this.core.$element.on(this.handlers); 19652 }; 19653 19654 /** 19655 * Default options. 19656 * @public 19657 */ 19658 Animate.Defaults = { 19659 animateOut: false, 19660 animateIn: false 19661 }; 19662 19663 /** 19664 * Toggles the animation classes whenever an translations starts. 19665 * @protected 19666 * @returns {Boolean|undefined} 19667 */ 19668 Animate.prototype.swap = function() { 19669 19670 if (this.core.settings.items !== 1) { 19671 return; 19672 } 19673 19674 if (!$.support.animation || !$.support.transition) { 19675 return; 19676 } 19677 19678 this.core.speed(0); 19679 19680 var left, 19681 clear = $.proxy(this.clear, this), 19682 previous = this.core.$stage.children().eq(this.previous), 19683 next = this.core.$stage.children().eq(this.next), 19684 incoming = this.core.settings.animateIn, 19685 outgoing = this.core.settings.animateOut; 19686 19687 if (this.core.current() === this.previous) { 19688 return; 19689 } 19690 19691 if (outgoing) { 19692 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 19693 previous.one($.support.animation.end, clear) 19694 .css( { 'left': left + 'px' } ) 19695 .addClass('animated owl-animated-out') 19696 .addClass(outgoing); 19697 } 19698 19699 if (incoming) { 19700 next.one($.support.animation.end, clear) 19701 .addClass('animated owl-animated-in') 19702 .addClass(incoming); 19703 } 19704 }; 19705 19706 Animate.prototype.clear = function(e) { 19707 $(e.target).css( { 'left': '' } ) 19708 .removeClass('animated owl-animated-out owl-animated-in') 19709 .removeClass(this.core.settings.animateIn) 19710 .removeClass(this.core.settings.animateOut); 19711 this.core.onTransitionEnd(); 19712 }; 19713 19714 /** 19715 * Destroys the plugin. 19716 * @public 19717 */ 19718 Animate.prototype.destroy = function() { 19719 var handler, property; 19720 19721 for (handler in this.handlers) { 19722 this.core.$element.off(handler, this.handlers[handler]); 19723 } 19724 for (property in Object.getOwnPropertyNames(this)) { 19725 typeof this[property] != 'function' && (this[property] = null); 19726 } 19727 }; 19728 19729 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 19730 19731})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 19732 19733/** 19734 * Autoplay Plugin 19735 * @version 2.3.4 19736 * @author Bartosz Wojciechowski 19737 * @author Artus Kolanowski 19738 * @author David Deutsch 19739 * @author Tom De Caluwé 19740 * @license The MIT License (MIT) 19741 */ 19742;(function($, window, document, undefined) { 19743 19744 /** 19745 * Creates the autoplay plugin. 19746 * @class The Autoplay Plugin 19747 * @param {Owl} scope - The Owl Carousel 19748 */ 19749 var Autoplay = function(carousel) { 19750 /** 19751 * Reference to the core. 19752 * @protected 19753 * @type {Owl} 19754 */ 19755 this._core = carousel; 19756 19757 /** 19758 * The autoplay timeout id. 19759 * @type {Number} 19760 */ 19761 this._call = null; 19762 19763 /** 19764 * Depending on the state of the plugin, this variable contains either 19765 * the start time of the timer or the current timer value if it's 19766 * paused. Since we start in a paused state we initialize the timer 19767 * value. 19768 * @type {Number} 19769 */ 19770 this._time = 0; 19771 19772 /** 19773 * Stores the timeout currently used. 19774 * @type {Number} 19775 */ 19776 this._timeout = 0; 19777 19778 /** 19779 * Indicates whenever the autoplay is paused. 19780 * @type {Boolean} 19781 */ 19782 this._paused = true; 19783 19784 /** 19785 * All event handlers. 19786 * @protected 19787 * @type {Object} 19788 */ 19789 this._handlers = { 19790 'changed.owl.carousel': $.proxy(function(e) { 19791 if (e.namespace && e.property.name === 'settings') { 19792 if (this._core.settings.autoplay) { 19793 this.play(); 19794 } else { 19795 this.stop(); 19796 } 19797 } else if (e.namespace && e.property.name === 'position' && this._paused) { 19798 // Reset the timer. This code is triggered when the position 19799 // of the carousel was changed through user interaction. 19800 this._time = 0; 19801 } 19802 }, this), 19803 'initialized.owl.carousel': $.proxy(function(e) { 19804 if (e.namespace && this._core.settings.autoplay) { 19805 this.play(); 19806 } 19807 }, this), 19808 'play.owl.autoplay': $.proxy(function(e, t, s) { 19809 if (e.namespace) { 19810 this.play(t, s); 19811 } 19812 }, this), 19813 'stop.owl.autoplay': $.proxy(function(e) { 19814 if (e.namespace) { 19815 this.stop(); 19816 } 19817 }, this), 19818 'mouseover.owl.autoplay': $.proxy(function() { 19819 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 19820 this.pause(); 19821 } 19822 }, this), 19823 'mouseleave.owl.autoplay': $.proxy(function() { 19824 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 19825 this.play(); 19826 } 19827 }, this), 19828 'touchstart.owl.core': $.proxy(function() { 19829 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 19830 this.pause(); 19831 } 19832 }, this), 19833 'touchend.owl.core': $.proxy(function() { 19834 if (this._core.settings.autoplayHoverPause) { 19835 this.play(); 19836 } 19837 }, this) 19838 }; 19839 19840 // register event handlers 19841 this._core.$element.on(this._handlers); 19842 19843 // set default options 19844 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 19845 }; 19846 19847 /** 19848 * Default options. 19849 * @public 19850 */ 19851 Autoplay.Defaults = { 19852 autoplay: false, 19853 autoplayTimeout: 5000, 19854 autoplayHoverPause: false, 19855 autoplaySpeed: false 19856 }; 19857 19858 /** 19859 * Transition to the next slide and set a timeout for the next transition. 19860 * @private 19861 * @param {Number} [speed] - The animation speed for the animations. 19862 */ 19863 Autoplay.prototype._next = function(speed) { 19864 this._call = window.setTimeout( 19865 $.proxy(this._next, this, speed), 19866 this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read() 19867 ); 19868 19869 if (this._core.is('interacting') || document.hidden) { 19870 return; 19871 } 19872 this._core.next(speed || this._core.settings.autoplaySpeed); 19873 } 19874 19875 /** 19876 * Reads the current timer value when the timer is playing. 19877 * @public 19878 */ 19879 Autoplay.prototype.read = function() { 19880 return new Date().getTime() - this._time; 19881 }; 19882 19883 /** 19884 * Starts the autoplay. 19885 * @public 19886 * @param {Number} [timeout] - The interval before the next animation starts. 19887 * @param {Number} [speed] - The animation speed for the animations. 19888 */ 19889 Autoplay.prototype.play = function(timeout, speed) { 19890 var elapsed; 19891 19892 if (!this._core.is('rotating')) { 19893 this._core.enter('rotating'); 19894 } 19895 19896 timeout = timeout || this._core.settings.autoplayTimeout; 19897 19898 // Calculate the elapsed time since the last transition. If the carousel 19899 // wasn't playing this calculation will yield zero. 19900 elapsed = Math.min(this._time % (this._timeout || timeout), timeout); 19901 19902 if (this._paused) { 19903 // Start the clock. 19904 this._time = this.read(); 19905 this._paused = false; 19906 } else { 19907 // Clear the active timeout to allow replacement. 19908 window.clearTimeout(this._call); 19909 } 19910 19911 // Adjust the origin of the timer to match the new timeout value. 19912 this._time += this.read() % timeout - elapsed; 19913 19914 this._timeout = timeout; 19915 this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed); 19916 }; 19917 19918 /** 19919 * Stops the autoplay. 19920 * @public 19921 */ 19922 Autoplay.prototype.stop = function() { 19923 if (this._core.is('rotating')) { 19924 // Reset the clock. 19925 this._time = 0; 19926 this._paused = true; 19927 19928 window.clearTimeout(this._call); 19929 this._core.leave('rotating'); 19930 } 19931 }; 19932 19933 /** 19934 * Pauses the autoplay. 19935 * @public 19936 */ 19937 Autoplay.prototype.pause = function() { 19938 if (this._core.is('rotating') && !this._paused) { 19939 // Pause the clock. 19940 this._time = this.read(); 19941 this._paused = true; 19942 19943 window.clearTimeout(this._call); 19944 } 19945 }; 19946 19947 /** 19948 * Destroys the plugin. 19949 */ 19950 Autoplay.prototype.destroy = function() { 19951 var handler, property; 19952 19953 this.stop(); 19954 19955 for (handler in this._handlers) { 19956 this._core.$element.off(handler, this._handlers[handler]); 19957 } 19958 for (property in Object.getOwnPropertyNames(this)) { 19959 typeof this[property] != 'function' && (this[property] = null); 19960 } 19961 }; 19962 19963 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 19964 19965})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 19966 19967/** 19968 * Navigation Plugin 19969 * @version 2.3.4 19970 * @author Artus Kolanowski 19971 * @author David Deutsch 19972 * @license The MIT License (MIT) 19973 */ 19974;(function($, window, document, undefined) { 19975 'use strict'; 19976 19977 /** 19978 * Creates the navigation plugin. 19979 * @class The Navigation Plugin 19980 * @param {Owl} carousel - The Owl Carousel. 19981 */ 19982 var Navigation = function(carousel) { 19983 /** 19984 * Reference to the core. 19985 * @protected 19986 * @type {Owl} 19987 */ 19988 this._core = carousel; 19989 19990 /** 19991 * Indicates whether the plugin is initialized or not. 19992 * @protected 19993 * @type {Boolean} 19994 */ 19995 this._initialized = false; 19996 19997 /** 19998 * The current paging indexes. 19999 * @protected 20000 * @type {Array} 20001 */ 20002 this._pages = []; 20003 20004 /** 20005 * All DOM elements of the user interface. 20006 * @protected 20007 * @type {Object} 20008 */ 20009 this._controls = {}; 20010 20011 /** 20012 * Markup for an indicator. 20013 * @protected 20014 * @type {Array.<String>} 20015 */ 20016 this._templates = []; 20017 20018 /** 20019 * The carousel element. 20020 * @type {jQuery} 20021 */ 20022 this.$element = this._core.$element; 20023 20024 /** 20025 * Overridden methods of the carousel. 20026 * @protected 20027 * @type {Object} 20028 */ 20029 this._overrides = { 20030 next: this._core.next, 20031 prev: this._core.prev, 20032 to: this._core.to 20033 }; 20034 20035 /** 20036 * All event handlers. 20037 * @protected 20038 * @type {Object} 20039 */ 20040 this._handlers = { 20041 'prepared.owl.carousel': $.proxy(function(e) { 20042 if (e.namespace && this._core.settings.dotsData) { 20043 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 20044 $(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>'); 20045 } 20046 }, this), 20047 'added.owl.carousel': $.proxy(function(e) { 20048 if (e.namespace && this._core.settings.dotsData) { 20049 this._templates.splice(e.position, 0, this._templates.pop()); 20050 } 20051 }, this), 20052 'remove.owl.carousel': $.proxy(function(e) { 20053 if (e.namespace && this._core.settings.dotsData) { 20054 this._templates.splice(e.position, 1); 20055 } 20056 }, this), 20057 'changed.owl.carousel': $.proxy(function(e) { 20058 if (e.namespace && e.property.name == 'position') { 20059 this.draw(); 20060 } 20061 }, this), 20062 'initialized.owl.carousel': $.proxy(function(e) { 20063 if (e.namespace && !this._initialized) { 20064 this._core.trigger('initialize', null, 'navigation'); 20065 this.initialize(); 20066 this.update(); 20067 this.draw(); 20068 this._initialized = true; 20069 this._core.trigger('initialized', null, 'navigation'); 20070 } 20071 }, this), 20072 'refreshed.owl.carousel': $.proxy(function(e) { 20073 if (e.namespace && this._initialized) { 20074 this._core.trigger('refresh', null, 'navigation'); 20075 this.update(); 20076 this.draw(); 20077 this._core.trigger('refreshed', null, 'navigation'); 20078 } 20079 }, this) 20080 }; 20081 20082 // set default options 20083 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 20084 20085 // register event handlers 20086 this.$element.on(this._handlers); 20087 }; 20088 20089 /** 20090 * Default options. 20091 * @public 20092 * @todo Rename `slideBy` to `navBy` 20093 */ 20094 Navigation.Defaults = { 20095 nav: false, 20096 navText: [ 20097 '<span aria-label="' + 'Previous' + '">‹</span>', 20098 '<span aria-label="' + 'Next' + '">›</span>' 20099 ], 20100 navSpeed: false, 20101 navElement: 'button type="button" role="presentation"', 20102 navContainer: false, 20103 navContainerClass: 'owl-nav', 20104 navClass: [ 20105 'owl-prev', 20106 'owl-next' 20107 ], 20108 slideBy: 1, 20109 dotClass: 'owl-dot', 20110 dotsClass: 'owl-dots', 20111 dots: true, 20112 dotsEach: false, 20113 dotsData: false, 20114 dotsSpeed: false, 20115 dotsContainer: false 20116 }; 20117 20118 /** 20119 * Initializes the layout of the plugin and extends the carousel. 20120 * @protected 20121 */ 20122 Navigation.prototype.initialize = function() { 20123 var override, 20124 settings = this._core.settings; 20125 20126 // create DOM structure for relative navigation 20127 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 20128 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 20129 20130 this._controls.$previous = $('<' + settings.navElement + '>') 20131 .addClass(settings.navClass[0]) 20132 .html(settings.navText[0]) 20133 .prependTo(this._controls.$relative) 20134 .on('click', $.proxy(function(e) { 20135 this.prev(settings.navSpeed); 20136 }, this)); 20137 this._controls.$next = $('<' + settings.navElement + '>') 20138 .addClass(settings.navClass[1]) 20139 .html(settings.navText[1]) 20140 .appendTo(this._controls.$relative) 20141 .on('click', $.proxy(function(e) { 20142 this.next(settings.navSpeed); 20143 }, this)); 20144 20145 // create DOM structure for absolute navigation 20146 if (!settings.dotsData) { 20147 this._templates = [ $('<button role="button">') 20148 .addClass(settings.dotClass) 20149 .append($('<span>')) 20150 .prop('outerHTML') ]; 20151 } 20152 20153 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 20154 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 20155 20156 this._controls.$absolute.on('click', 'button', $.proxy(function(e) { 20157 var index = $(e.target).parent().is(this._controls.$absolute) 20158 ? $(e.target).index() : $(e.target).parent().index(); 20159 20160 e.preventDefault(); 20161 20162 this.to(index, settings.dotsSpeed); 20163 }, this)); 20164 20165 /*$el.on('focusin', function() { 20166 $(document).off(".carousel"); 20167 20168 $(document).on('keydown.carousel', function(e) { 20169 if(e.keyCode == 37) { 20170 $el.trigger('prev.owl') 20171 } 20172 if(e.keyCode == 39) { 20173 $el.trigger('next.owl') 20174 } 20175 }); 20176 });*/ 20177 20178 // override public methods of the carousel 20179 for (override in this._overrides) { 20180 this._core[override] = $.proxy(this[override], this); 20181 } 20182 }; 20183 20184 /** 20185 * Destroys the plugin. 20186 * @protected 20187 */ 20188 Navigation.prototype.destroy = function() { 20189 var handler, control, property, override, settings; 20190 settings = this._core.settings; 20191 20192 for (handler in this._handlers) { 20193 this.$element.off(handler, this._handlers[handler]); 20194 } 20195 for (control in this._controls) { 20196 if (control === '$relative' && settings.navContainer) { 20197 this._controls[control].html(''); 20198 } else { 20199 this._controls[control].remove(); 20200 } 20201 } 20202 for (override in this.overides) { 20203 this._core[override] = this._overrides[override]; 20204 } 20205 for (property in Object.getOwnPropertyNames(this)) { 20206 typeof this[property] != 'function' && (this[property] = null); 20207 } 20208 }; 20209 20210 /** 20211 * Updates the internal state. 20212 * @protected 20213 */ 20214 Navigation.prototype.update = function() { 20215 var i, j, k, 20216 lower = this._core.clones().length / 2, 20217 upper = lower + this._core.items().length, 20218 maximum = this._core.maximum(true), 20219 settings = this._core.settings, 20220 size = settings.center || settings.autoWidth || settings.dotsData 20221 ? 1 : settings.dotsEach || settings.items; 20222 20223 if (settings.slideBy !== 'page') { 20224 settings.slideBy = Math.min(settings.slideBy, settings.items); 20225 } 20226 20227 if (settings.dots || settings.slideBy == 'page') { 20228 this._pages = []; 20229 20230 for (i = lower, j = 0, k = 0; i < upper; i++) { 20231 if (j >= size || j === 0) { 20232 this._pages.push({ 20233 start: Math.min(maximum, i - lower), 20234 end: i - lower + size - 1 20235 }); 20236 if (Math.min(maximum, i - lower) === maximum) { 20237 break; 20238 } 20239 j = 0, ++k; 20240 } 20241 j += this._core.mergers(this._core.relative(i)); 20242 } 20243 } 20244 }; 20245 20246 /** 20247 * Draws the user interface. 20248 * @todo The option `dotsData` wont work. 20249 * @protected 20250 */ 20251 Navigation.prototype.draw = function() { 20252 var difference, 20253 settings = this._core.settings, 20254 disabled = this._core.items().length <= settings.items, 20255 index = this._core.relative(this._core.current()), 20256 loop = settings.loop || settings.rewind; 20257 20258 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 20259 20260 if (settings.nav) { 20261 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 20262 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 20263 } 20264 20265 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 20266 20267 if (settings.dots) { 20268 difference = this._pages.length - this._controls.$absolute.children().length; 20269 20270 if (settings.dotsData && difference !== 0) { 20271 this._controls.$absolute.html(this._templates.join('')); 20272 } else if (difference > 0) { 20273 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 20274 } else if (difference < 0) { 20275 this._controls.$absolute.children().slice(difference).remove(); 20276 } 20277 20278 this._controls.$absolute.find('.active').removeClass('active'); 20279 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 20280 } 20281 }; 20282 20283 /** 20284 * Extends event data. 20285 * @protected 20286 * @param {Event} event - The event object which gets thrown. 20287 */ 20288 Navigation.prototype.onTrigger = function(event) { 20289 var settings = this._core.settings; 20290 20291 event.page = { 20292 index: $.inArray(this.current(), this._pages), 20293 count: this._pages.length, 20294 size: settings && (settings.center || settings.autoWidth || settings.dotsData 20295 ? 1 : settings.dotsEach || settings.items) 20296 }; 20297 }; 20298 20299 /** 20300 * Gets the current page position of the carousel. 20301 * @protected 20302 * @returns {Number} 20303 */ 20304 Navigation.prototype.current = function() { 20305 var current = this._core.relative(this._core.current()); 20306 return $.grep(this._pages, $.proxy(function(page, index) { 20307 return page.start <= current && page.end >= current; 20308 }, this)).pop(); 20309 }; 20310 20311 /** 20312 * Gets the current succesor/predecessor position. 20313 * @protected 20314 * @returns {Number} 20315 */ 20316 Navigation.prototype.getPosition = function(successor) { 20317 var position, length, 20318 settings = this._core.settings; 20319 20320 if (settings.slideBy == 'page') { 20321 position = $.inArray(this.current(), this._pages); 20322 length = this._pages.length; 20323 successor ? ++position : --position; 20324 position = this._pages[((position % length) + length) % length].start; 20325 } else { 20326 position = this._core.relative(this._core.current()); 20327 length = this._core.items().length; 20328 successor ? position += settings.slideBy : position -= settings.slideBy; 20329 } 20330 20331 return position; 20332 }; 20333 20334 /** 20335 * Slides to the next item or page. 20336 * @public 20337 * @param {Number} [speed=false] - The time in milliseconds for the transition. 20338 */ 20339 Navigation.prototype.next = function(speed) { 20340 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 20341 }; 20342 20343 /** 20344 * Slides to the previous item or page. 20345 * @public 20346 * @param {Number} [speed=false] - The time in milliseconds for the transition. 20347 */ 20348 Navigation.prototype.prev = function(speed) { 20349 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 20350 }; 20351 20352 /** 20353 * Slides to the specified item or page. 20354 * @public 20355 * @param {Number} position - The position of the item or page. 20356 * @param {Number} [speed] - The time in milliseconds for the transition. 20357 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 20358 */ 20359 Navigation.prototype.to = function(position, speed, standard) { 20360 var length; 20361 20362 if (!standard && this._pages.length) { 20363 length = this._pages.length; 20364 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 20365 } else { 20366 $.proxy(this._overrides.to, this._core)(position, speed); 20367 } 20368 }; 20369 20370 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 20371 20372})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 20373 20374/** 20375 * Hash Plugin 20376 * @version 2.3.4 20377 * @author Artus Kolanowski 20378 * @author David Deutsch 20379 * @license The MIT License (MIT) 20380 */ 20381;(function($, window, document, undefined) { 20382 'use strict'; 20383 20384 /** 20385 * Creates the hash plugin. 20386 * @class The Hash Plugin 20387 * @param {Owl} carousel - The Owl Carousel 20388 */ 20389 var Hash = function(carousel) { 20390 /** 20391 * Reference to the core. 20392 * @protected 20393 * @type {Owl} 20394 */ 20395 this._core = carousel; 20396 20397 /** 20398 * Hash index for the items. 20399 * @protected 20400 * @type {Object} 20401 */ 20402 this._hashes = {}; 20403 20404 /** 20405 * The carousel element. 20406 * @type {jQuery} 20407 */ 20408 this.$element = this._core.$element; 20409 20410 /** 20411 * All event handlers. 20412 * @protected 20413 * @type {Object} 20414 */ 20415 this._handlers = { 20416 'initialized.owl.carousel': $.proxy(function(e) { 20417 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 20418 $(window).trigger('hashchange.owl.navigation'); 20419 } 20420 }, this), 20421 'prepared.owl.carousel': $.proxy(function(e) { 20422 if (e.namespace) { 20423 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 20424 20425 if (!hash) { 20426 return; 20427 } 20428 20429 this._hashes[hash] = e.content; 20430 } 20431 }, this), 20432 'changed.owl.carousel': $.proxy(function(e) { 20433 if (e.namespace && e.property.name === 'position') { 20434 var current = this._core.items(this._core.relative(this._core.current())), 20435 hash = $.map(this._hashes, function(item, hash) { 20436 return item === current ? hash : null; 20437 }).join(); 20438 20439 if (!hash || window.location.hash.slice(1) === hash) { 20440 return; 20441 } 20442 20443 window.location.hash = hash; 20444 } 20445 }, this) 20446 }; 20447 20448 // set default options 20449 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 20450 20451 // register the event handlers 20452 this.$element.on(this._handlers); 20453 20454 // register event listener for hash navigation 20455 $(window).on('hashchange.owl.navigation', $.proxy(function(e) { 20456 var hash = window.location.hash.substring(1), 20457 items = this._core.$stage.children(), 20458 position = this._hashes[hash] && items.index(this._hashes[hash]); 20459 20460 if (position === undefined || position === this._core.current()) { 20461 return; 20462 } 20463 20464 this._core.to(this._core.relative(position), false, true); 20465 }, this)); 20466 }; 20467 20468 /** 20469 * Default options. 20470 * @public 20471 */ 20472 Hash.Defaults = { 20473 URLhashListener: false 20474 }; 20475 20476 /** 20477 * Destroys the plugin. 20478 * @public 20479 */ 20480 Hash.prototype.destroy = function() { 20481 var handler, property; 20482 20483 $(window).off('hashchange.owl.navigation'); 20484 20485 for (handler in this._handlers) { 20486 this._core.$element.off(handler, this._handlers[handler]); 20487 } 20488 for (property in Object.getOwnPropertyNames(this)) { 20489 typeof this[property] != 'function' && (this[property] = null); 20490 } 20491 }; 20492 20493 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 20494 20495})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 20496 20497/** 20498 * Support Plugin 20499 * 20500 * @version 2.3.4 20501 * @author Vivid Planet Software GmbH 20502 * @author Artus Kolanowski 20503 * @author David Deutsch 20504 * @license The MIT License (MIT) 20505 */ 20506;(function($, window, document, undefined) { 20507 20508 var style = $('<support>').get(0).style, 20509 prefixes = 'Webkit Moz O ms'.split(' '), 20510 events = { 20511 transition: { 20512 end: { 20513 WebkitTransition: 'webkitTransitionEnd', 20514 MozTransition: 'transitionend', 20515 OTransition: 'oTransitionEnd', 20516 transition: 'transitionend' 20517 } 20518 }, 20519 animation: { 20520 end: { 20521 WebkitAnimation: 'webkitAnimationEnd', 20522 MozAnimation: 'animationend', 20523 OAnimation: 'oAnimationEnd', 20524 animation: 'animationend' 20525 } 20526 } 20527 }, 20528 tests = { 20529 csstransforms: function() { 20530 return !!test('transform'); 20531 }, 20532 csstransforms3d: function() { 20533 return !!test('perspective'); 20534 }, 20535 csstransitions: function() { 20536 return !!test('transition'); 20537 }, 20538 cssanimations: function() { 20539 return !!test('animation'); 20540 } 20541 }; 20542 20543 function test(property, prefixed) { 20544 var result = false, 20545 upper = property.charAt(0).toUpperCase() + property.slice(1); 20546 20547 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 20548 if (style[property] !== undefined) { 20549 result = prefixed ? property : true; 20550 return false; 20551 } 20552 }); 20553 20554 return result; 20555 } 20556 20557 function prefixed(property) { 20558 return test(property, true); 20559 } 20560 20561 if (tests.csstransitions()) { 20562 /* jshint -W053 */ 20563 $.support.transition = new String(prefixed('transition')) 20564 $.support.transition.end = events.transition.end[ $.support.transition ]; 20565 } 20566 20567 if (tests.cssanimations()) { 20568 /* jshint -W053 */ 20569 $.support.animation = new String(prefixed('animation')) 20570 $.support.animation.end = events.animation.end[ $.support.animation ]; 20571 } 20572 20573 if (tests.csstransforms()) { 20574 /* jshint -W053 */ 20575 $.support.transform = new String(prefixed('transform')); 20576 $.support.transform3d = tests.csstransforms3d(); 20577 } 20578 20579})(window.Zepto || __webpack_provided_window_dot_jQuery, window, document); 20580 20581 20582/***/ }), 20583
vendor: 2,356 bytes, lines 20584-20613
20584/***/ "./node_modules/owl.carousel/dist/assets/owl.carousel.css": 20585/*!****************************************************************!*\ 20586 !*** ./node_modules/owl.carousel/dist/assets/owl.carousel.css ***! 20587 \****************************************************************/ 20588/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 20589 20590"use strict"; 20591__webpack_require__.r(__webpack_exports__); 20592/* harmony export */ __webpack_require__.d(__webpack_exports__, { 20593/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 20594/* harmony export */ }); 20595/* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"); 20596/* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__); 20597/* harmony import */ var _css_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_1_postcss_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_2_owl_carousel_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !!../../../css-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[1]!../../../postcss-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[2]!./owl.carousel.css */ "./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[7].oneOf[1].use[2]!./node_modules/owl.carousel/dist/assets/owl.carousel.css"); 20598 20599 20600 20601var options = {}; 20602 20603options.insert = "head"; 20604options.singleton = false; 20605 20606var update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_1_postcss_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_2_owl_carousel_css__WEBPACK_IMPORTED_MODULE_1__["default"], options); 20607 20608 20609 20610/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_1_postcss_loader_dist_cjs_js_ruleSet_1_rules_7_oneOf_1_use_2_owl_carousel_css__WEBPACK_IMPORTED_MODULE_1__["default"].locals || {}); 20611 20612/***/ }), 20613
vendor: 7,474 bytes, lines 20614-20891
20614/***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": 20615/*!****************************************************************************!*\ 20616 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! 20617 \****************************************************************************/ 20618/***/ ((module, __unused_webpack_exports, __webpack_require__) => { 20619 20620"use strict"; 20621 20622 20623var isOldIE = function isOldIE() { 20624 var memo; 20625 return function memorize() { 20626 if (typeof memo === 'undefined') { 20627 // Test for IE <= 9 as proposed by Browserhacks 20628 // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 20629 // Tests for existence of standard globals is to allow style-loader 20630 // to operate correctly into non-standard environments 20631 // @see https://github.com/webpack-contrib/style-loader/issues/177 20632 memo = Boolean(window && document && document.all && !window.atob); 20633 } 20634 20635 return memo; 20636 }; 20637}(); 20638 20639var getTarget = function getTarget() { 20640 var memo = {}; 20641 return function memorize(target) { 20642 if (typeof memo[target] === 'undefined') { 20643 var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself 20644 20645 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { 20646 try { 20647 // This will throw an exception if access to iframe is blocked 20648 // due to cross-origin restrictions 20649 styleTarget = styleTarget.contentDocument.head; 20650 } catch (e) { 20651 // istanbul ignore next 20652 styleTarget = null; 20653 } 20654 } 20655 20656 memo[target] = styleTarget; 20657 } 20658 20659 return memo[target]; 20660 }; 20661}(); 20662 20663var stylesInDom = []; 20664 20665function getIndexByIdentifier(identifier) { 20666 var result = -1; 20667 20668 for (var i = 0; i < stylesInDom.length; i++) { 20669 if (stylesInDom[i].identifier === identifier) { 20670 result = i; 20671 break; 20672 } 20673 } 20674 20675 return result; 20676} 20677 20678function modulesToDom(list, options) { 20679 var idCountMap = {}; 20680 var identifiers = []; 20681 20682 for (var i = 0; i < list.length; i++) { 20683 var item = list[i]; 20684 var id = options.base ? item[0] + options.base : item[0]; 20685 var count = idCountMap[id] || 0; 20686 var identifier = "".concat(id, " ").concat(count); 20687 idCountMap[id] = count + 1; 20688 var index = getIndexByIdentifier(identifier); 20689 var obj = { 20690 css: item[1], 20691 media: item[2], 20692 sourceMap: item[3] 20693 }; 20694 20695 if (index !== -1) { 20696 stylesInDom[index].references++; 20697 stylesInDom[index].updater(obj); 20698 } else { 20699 stylesInDom.push({ 20700 identifier: identifier, 20701 updater: addStyle(obj, options), 20702 references: 1 20703 }); 20704 } 20705 20706 identifiers.push(identifier); 20707 } 20708 20709 return identifiers; 20710} 20711 20712function insertStyleElement(options) { 20713 var style = document.createElement('style'); 20714 var attributes = options.attributes || {}; 20715 20716 if (typeof attributes.nonce === 'undefined') { 20717 var nonce = true ? __webpack_require__.nc : 0; 20718 20719 if (nonce) { 20720 attributes.nonce = nonce; 20721 } 20722 } 20723 20724 Object.keys(attributes).forEach(function (key) { 20725 style.setAttribute(key, attributes[key]); 20726 }); 20727 20728 if (typeof options.insert === 'function') { 20729 options.insert(style); 20730 } else { 20731 var target = getTarget(options.insert || 'head'); 20732 20733 if (!target) { 20734 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); 20735 } 20736 20737 target.appendChild(style); 20738 } 20739 20740 return style; 20741} 20742 20743function removeStyleElement(style) { 20744 // istanbul ignore if 20745 if (style.parentNode === null) { 20746 return false; 20747 } 20748 20749 style.parentNode.removeChild(style); 20750} 20751/* istanbul ignore next */ 20752 20753 20754var replaceText = function replaceText() { 20755 var textStore = []; 20756 return function replace(index, replacement) { 20757 textStore[index] = replacement; 20758 return textStore.filter(Boolean).join('\n'); 20759 }; 20760}(); 20761 20762function applyToSingletonTag(style, index, remove, obj) { 20763 var css = remove ? '' : obj.media ? "@media ".concat(obj.media, " {").concat(obj.css, "}") : obj.css; // For old IE 20764 20765 /* istanbul ignore if */ 20766 20767 if (style.styleSheet) { 20768 style.styleSheet.cssText = replaceText(index, css); 20769 } else { 20770 var cssNode = document.createTextNode(css); 20771 var childNodes = style.childNodes; 20772 20773 if (childNodes[index]) { 20774 style.removeChild(childNodes[index]); 20775 } 20776 20777 if (childNodes.length) { 20778 style.insertBefore(cssNode, childNodes[index]); 20779 } else { 20780 style.appendChild(cssNode); 20781 } 20782 } 20783} 20784 20785function applyToTag(style, options, obj) { 20786 var css = obj.css; 20787 var media = obj.media; 20788 var sourceMap = obj.sourceMap; 20789 20790 if (media) { 20791 style.setAttribute('media', media); 20792 } else { 20793 style.removeAttribute('media'); 20794 } 20795 20796 if (sourceMap && typeof btoa !== 'undefined') { 20797 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */"); 20798 } // For old IE 20799 20800 /* istanbul ignore if */ 20801 20802 20803 if (style.styleSheet) { 20804 style.styleSheet.cssText = css; 20805 } else { 20806 while (style.firstChild) { 20807 style.removeChild(style.firstChild); 20808 } 20809 20810 style.appendChild(document.createTextNode(css)); 20811 } 20812} 20813 20814var singleton = null; 20815var singletonCounter = 0; 20816 20817function addStyle(obj, options) { 20818 var style; 20819 var update; 20820 var remove; 20821 20822 if (options.singleton) { 20823 var styleIndex = singletonCounter++; 20824 style = singleton || (singleton = insertStyleElement(options)); 20825 update = applyToSingletonTag.bind(null, style, styleIndex, false); 20826 remove = applyToSingletonTag.bind(null, style, styleIndex, true); 20827 } else { 20828 style = insertStyleElement(options); 20829 update = applyToTag.bind(null, style, options); 20830 20831 remove = function remove() { 20832 removeStyleElement(style); 20833 }; 20834 } 20835 20836 update(obj); 20837 return function updateStyle(newObj) { 20838 if (newObj) { 20839 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) { 20840 return; 20841 } 20842 20843 update(obj = newObj); 20844 } else { 20845 remove(); 20846 } 20847 }; 20848} 20849 20850module.exports = function (list, options) { 20851 options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style> 20852 // tags it will allow on a page 20853 20854 if (!options.singleton && typeof options.singleton !== 'boolean') { 20855 options.singleton = isOldIE(); 20856 } 20857 20858 list = list || []; 20859 var lastIdentifiers = modulesToDom(list, options); 20860 return function update(newList) { 20861 newList = newList || []; 20862 20863 if (Object.prototype.toString.call(newList) !== '[object Array]') { 20864 return; 20865 } 20866 20867 for (var i = 0; i < lastIdentifiers.length; i++) { 20868 var identifier = lastIdentifiers[i]; 20869 var index = getIndexByIdentifier(identifier); 20870 stylesInDom[index].references--; 20871 } 20872 20873 var newLastIdentifiers = modulesToDom(newList, options); 20874 20875 for (var _i = 0; _i < lastIdentifiers.length; _i++) { 20876 var _identifier = lastIdentifiers[_i]; 20877 20878 var _index = getIndexByIdentifier(_identifier); 20879 20880 if (stylesInDom[_index].references === 0) { 20881 stylesInDom[_index].updater(); 20882 20883 stylesInDom.splice(_index, 1); 20884 } 20885 } 20886 20887 lastIdentifiers = newLastIdentifiers; 20888 }; 20889}; 20890 20891/***/ })
vendor: 4,135 bytes, lines 20891-20991
20891 20892 20893/******/ }); 20894/************************************************************************/ 20895/******/ // The module cache 20896/******/ var __webpack_module_cache__ = {}; 20897/******/ 20898/******/ // The require function 20899/******/ function __webpack_require__(moduleId) { 20900/******/ // Check if module is in cache 20901/******/ var cachedModule = __webpack_module_cache__[moduleId]; 20902/******/ if (cachedModule !== undefined) { 20903/******/ return cachedModule.exports; 20904/******/ } 20905/******/ // Create a new module (and put it into the cache) 20906/******/ var module = __webpack_module_cache__[moduleId] = { 20907/******/ id: moduleId, 20908/******/ // no module.loaded needed 20909/******/ exports: {} 20910/******/ }; 20911/******/ 20912/******/ // Execute the module function 20913/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 20914/******/ 20915/******/ // Return the exports of the module 20916/******/ return module.exports; 20917/******/ } 20918/******/ 20919/******/ // expose the modules object (__webpack_modules__) 20920/******/ __webpack_require__.m = __webpack_modules__; 20921/******/ 20922/************************************************************************/ 20923/******/ /* webpack/runtime/chunk loaded */ 20924/******/ (() => { 20925/******/ var deferred = []; 20926/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { 20927/******/ if(chunkIds) { 20928/******/ priority = priority || 0; 20929/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; 20930/******/ deferred[i] = [chunkIds, fn, priority]; 20931/******/ return; 20932/******/ } 20933/******/ var notFulfilled = Infinity; 20934/******/ for (var i = 0; i < deferred.length; i++) { 20935/******/ var [chunkIds, fn, priority] = deferred[i]; 20936/******/ var fulfilled = true; 20937/******/ for (var j = 0; j < chunkIds.length; j++) { 20938/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { 20939/******/ chunkIds.splice(j--, 1); 20940/******/ } else { 20941/******/ fulfilled = false; 20942/******/ if(priority < notFulfilled) notFulfilled = priority; 20943/******/ } 20944/******/ } 20945/******/ if(fulfilled) { 20946/******/ deferred.splice(i--, 1) 20947/******/ var r = fn(); 20948/******/ if (r !== undefined) result = r; 20949/******/ } 20950/******/ } 20951/******/ return result; 20952/******/ }; 20953/******/ })(); 20954/******/ 20955/******/ /* webpack/runtime/compat get default export */ 20956/******/ (() => { 20957/******/ // getDefaultExport function for compatibility with non-harmony modules 20958/******/ __webpack_require__.n = (module) => { 20959/******/ var getter = module && module.__esModule ? 20960/******/ () => (module['default']) : 20961/******/ () => (module); 20962/******/ __webpack_require__.d(getter, { a: getter }); 20963/******/ return getter; 20964/******/ }; 20965/******/ })(); 20966/******/ 20967/******/ /* webpack/runtime/define property getters */ 20968/******/ (() => { 20969/******/ // define getter functions for harmony exports 20970/******/ __webpack_require__.d = (exports, definition) => { 20971/******/ for(var key in definition) { 20972/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 20973/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 20974/******/ } 20975/******/ } 20976/******/ }; 20977/******/ })(); 20978/******/ 20979/******/ /* webpack/runtime/hasOwnProperty shorthand */ 20980/******/ (() => { 20981/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 20982/******/ })(); 20983/******/ 20984/******/ /* webpack/runtime/make namespace object */ 20985/******/ (() => { 20986/******/ // define __esModule on exports 20987/******/ __webpack_require__.r = (exports) => { 20988/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 20989/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 20990/******/ } 20991/******/ Object.defineProperty(exports, '__esModule', { value: true });
20992/******/ }; 20993/******/ })(); 20994/******/ 20995/******/ /* webpack/runtime/jsonp chunk loading */ 20996/******/ (() => { 20997/******/ // no baseURI 20998/******/ 20999/******/ // object to store loaded and loading chunks 21000/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 21001/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded 21002/******/ var installedChunks = { 21003/******/ "/dist/scripts/main": 0, 21004/******/ "dist/styles/main": 0, 21005/******/ "dist/styles/admin-main": 0 21006/******/ }; 21007/******/ 21008/******/ // no chunk on demand loading 21009/******/ 21010/******/ // no prefetching 21011/******/ 21012/******/ // no preloaded 21013/******/ 21014/******/ // no HMR 21015/******/ 21016/******/ // no HMR manifest 21017/******/ 21018/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); 21019/******/ 21020/******/ // install a JSONP callback for chunk loading 21021/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { 21022/******/ var [chunkIds, moreModules, runtime] = data; 21023/******/ // add "moreModules" to the modules object, 21024/******/ // then flag all "chunkIds" as loaded and fire callback 21025/******/ var moduleId, chunkId, i = 0;
21026/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { 21027/******/ for(moduleId in moreModules) { 21028/******/ if(__webpack_require__.o(moreModules, moduleId)) { 21029/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; 21030/******/ } 21031/******/ } 21032/******/ if(runtime) var result = runtime(__webpack_require__); 21033/******/ } 21034/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); 21035/******/ for(;i < chunkIds.length; i++) { 21036/******/ chunkId = chunkIds[i]; 21037/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { 21038/******/ installedChunks[chunkId][0](); 21039/******/ } 21040/******/ installedChunks[chunkIds[i]] = 0; 21041/******/ } 21042/******/ return __webpack_require__.O(result); 21043/******/ } 21044/******/ 21045/******/ var chunkLoadingGlobal = self["webpackChunkstl_partners"] = self["webpackChunkstl_partners"] || []; 21046/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); 21047/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); 21048/******/ })(); 21049/******/ 21050/************************************************************************/ 21051/******/ 21052/******/ // startup 21053/******/ // Load entry module and return exports 21054/******/ // This entry module depends on other loaded chunks and execution need to be delayed 21055/******/ __webpack_require__.O(undefined, ["dist/styles/main","dist/styles/admin-main"], () => (__webpack_require__("./assets/scripts/main.js"))) 21056/******/ __webpack_require__.O(undefined, ["dist/styles/main","dist/styles/admin-main"], () => (__webpack_require__("./assets/styles/main.scss"))) 21057/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["dist/styles/main","dist/styles/admin-main"], () => (__webpack_require__("./assets/styles/admin-main.scss"))) 21058/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); 21059/******/ 21060/******/ })() 21061; 21062 21063(function() { 21064 const $header = document.querySelector("#resource__form"); 21065 21066 const elementOffset = $header.offsetTop + 100; 21067 let prevScrollY = 0; 21068 21069 window.addEventListener("scroll", function(e) { 21070 if (window.scrollY < elementOffset) { 21071 $header.classList.add("header--visible"); 21072 } else if (window.scrollY < prevScrollY ) { 21073 $header.classList.add("header--visible"); 21074 } else if (window.scrollY > prevScrollY) { 21075 $header.classList.remove("header--visible"); 21076 } 21077 prevScrollY = window.scrollY; 21078 }); 21079})();
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.