vendor: 4,824 bytes, lines 1-125
1/******/ (function(modules) { // webpackBootstrap 2/******/ // install a JSONP callback for chunk loading 3/******/ function webpackJsonpCallback(data) { 4/******/ var chunkIds = data[0]; 5/******/ var moreModules = data[1]; 6/******/ 7/******/ 8/******/ // add "moreModules" to the modules object, 9/******/ // then flag all "chunkIds" as loaded and fire callback 10/******/ var moduleId, chunkId, i = 0, resolves = []; 11/******/ for(;i < chunkIds.length; i++) { 12/******/ chunkId = chunkIds[i]; 13/******/ if(installedChunks[chunkId]) { 14/******/ resolves.push(installedChunks[chunkId][0]); 15/******/ } 16/******/ installedChunks[chunkId] = 0; 17/******/ } 18/******/ for(moduleId in moreModules) { 19/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 20/******/ modules[moduleId] = moreModules[moduleId]; 21/******/ } 22/******/ } 23/******/ if(parentJsonpFunction) parentJsonpFunction(data); 24/******/ 25/******/ while(resolves.length) { 26/******/ resolves.shift()(); 27/******/ } 28/******/ 29/******/ }; 30/******/ 31/******/ 32/******/ // The module cache 33/******/ var installedModules = {}; 34/******/ 35/******/ // object to store loaded and loading chunks 36/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 37/******/ // Promise = chunk loading, 0 = chunk loaded 38/******/ var installedChunks = { 39/******/ "app": 0 40/******/ }; 41/******/ 42/******/ 43/******/ 44/******/ // script path function 45/******/ function jsonpScriptSrc(chunkId) { 46/******/ return __webpack_require__.p + "" + ({"svg4everybody":"svg4everybody"}[chunkId]||chunkId) + ".chunk.js" 47/******/ } 48/******/ 49/******/ // The require function 50/******/ function __webpack_require__(moduleId) { 51/******/ 52/******/ // Check if module is in cache 53/******/ if(installedModules[moduleId]) { 54/******/ return installedModules[moduleId].exports; 55/******/ } 56/******/ // Create a new module (and put it into the cache) 57/******/ var module = installedModules[moduleId] = { 58/******/ i: moduleId, 59/******/ l: false, 60/******/ exports: {} 61/******/ }; 62/******/ 63/******/ // Execute the module function 64/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 65/******/ 66/******/ // Flag the module as loaded 67/******/ module.l = true; 68/******/ 69/******/ // Return the exports of the module 70/******/ return module.exports; 71/******/ } 72/******/ 73/******/ // This file contains only the entry chunk. 74/******/ // The chunk loading function for additional chunks 75/******/ __webpack_require__.e = function requireEnsure(chunkId) { 76/******/ var promises = []; 77/******/ 78/******/ 79/******/ // JSONP chunk loading for javascript 80/******/ 81/******/ var installedChunkData = installedChunks[chunkId]; 82/******/ if(installedChunkData !== 0) { // 0 means "already installed". 83/******/ 84/******/ // a Promise means "currently loading". 85/******/ if(installedChunkData) { 86/******/ promises.push(installedChunkData[2]); 87/******/ } else { 88/******/ // setup Promise in chunk cache 89/******/ var promise = new Promise(function(resolve, reject) { 90/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; 91/******/ }); 92/******/ promises.push(installedChunkData[2] = promise); 93/******/ 94/******/ // start chunk loading 95/******/ var head = document.getElementsByTagName('head')[0]; 96/******/ var script = document.createElement('script'); 97/******/ var onScriptComplete; 98/******/ 99/******/ script.charset = 'utf-8'; 100/******/ script.timeout = 120; 101/******/ if (__webpack_require__.nc) { 102/******/ script.setAttribute("nonce", __webpack_require__.nc); 103/******/ } 104/******/ script.src = jsonpScriptSrc(chunkId); 105/******/ 106/******/ onScriptComplete = function (event) { 107/******/ // avoid mem leaks in IE. 108/******/ script.onerror = script.onload = null; 109/******/ clearTimeout(timeout); 110/******/ var chunk = installedChunks[chunkId]; 111/******/ if(chunk !== 0) { 112/******/ if(chunk) { 113/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); 114/******/ var realSrc = event && event.target && event.target.src; 115/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'); 116/******/ error.type = errorType; 117/******/ error.request = realSrc; 118/******/ chunk[1](error); 119/******/ } 120/******/ installedChunks[chunkId] = undefined; 121/******/ } 122/******/ }; 123/******/ var timeout = setTimeout(function(){ 124/******/ onScriptComplete({ type: 'timeout', target: script }); 125/******/ }, 120000);
vendor: 3,005 bytes, lines 126-189
126/******/ script.onerror = script.onload = onScriptComplete; 127/******/ head.appendChild(script); 128/******/ } 129/******/ } 130/******/ return Promise.all(promises); 131/******/ }; 132/******/ 133/******/ // expose the modules object (__webpack_modules__) 134/******/ __webpack_require__.m = modules; 135/******/ 136/******/ // expose the module cache 137/******/ __webpack_require__.c = installedModules; 138/******/ 139/******/ // define getter function for harmony exports 140/******/ __webpack_require__.d = function(exports, name, getter) { 141/******/ if(!__webpack_require__.o(exports, name)) { 142/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 143/******/ } 144/******/ }; 145/******/ 146/******/ // define __esModule on exports 147/******/ __webpack_require__.r = function(exports) { 148/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 149/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 150/******/ } 151/******/ Object.defineProperty(exports, '__esModule', { value: true }); 152/******/ }; 153/******/ 154/******/ // create a fake namespace object 155/******/ // mode & 1: value is a module id, require it 156/******/ // mode & 2: merge all properties of value into the ns 157/******/ // mode & 4: return value when already ns object 158/******/ // mode & 8|1: behave like require 159/******/ __webpack_require__.t = function(value, mode) { 160/******/ if(mode & 1) value = __webpack_require__(value); 161/******/ if(mode & 8) return value; 162/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 163/******/ var ns = Object.create(null); 164/******/ __webpack_require__.r(ns); 165/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 166/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 167/******/ return ns; 168/******/ }; 169/******/ 170/******/ // getDefaultExport function for compatibility with non-harmony modules 171/******/ __webpack_require__.n = function(module) { 172/******/ var getter = module && module.__esModule ? 173/******/ function getDefault() { return module['default']; } : 174/******/ function getModuleExports() { return module; }; 175/******/ __webpack_require__.d(getter, 'a', getter); 176/******/ return getter; 177/******/ }; 178/******/ 179/******/ // Object.prototype.hasOwnProperty.call 180/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 181/******/ 182/******/ // __webpack_public_path__ 183/******/ __webpack_require__.p = "../js/"; 184/******/ 185/******/ // on error function for async loading 186/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; 187/******/ 188/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; 189/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
190/******/ jsonpArray.push = webpackJsonpCallback; 191/******/ jsonpArray = jsonpArray.slice(); 192/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); 193/******/ var parentJsonpFunction = oldJsonpFunction; 194/******/ 195/******/ 196/******/ // Load entry module and return exports 197/******/ return __webpack_require__(__webpack_require__.s = "./src/js/app.js"); 198/******/ }) 199/************************************************************************/ 200/******/ ({ 201
vendor: 151,327 bytes, lines 202-5350
202/***/ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js": 203/*!******************************************************************!*\ 204 !*** ./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js ***! 205 \******************************************************************/ 206/*! no static exports found */ 207/***/ (function(module, exports) { 208 209// ================================================== 210// fancyBox v3.3.5 211// 212// Licensed GPLv3 for open source use 213// or fancyBox Commercial License for commercial use 214// 215// http://fancyapps.com/fancybox/ 216// Copyright 2018 fancyApps 217// 218// ================================================== 219(function(window, document, $, undefined) { 220 "use strict"; 221 222 window.console = window.console || { 223 info: function(stuff) {} 224 }; 225 226 // If there's no jQuery, fancyBox can't work 227 // ========================================= 228 229 if (!$) { 230 return; 231 } 232 233 // Check if fancyBox is already initialized 234 // ======================================== 235 236 if ($.fn.fancybox) { 237 console.info("fancyBox already initialized"); 238 239 return; 240 } 241 242 // Private default settings 243 // ======================== 244 245 var defaults = { 246 // Enable infinite gallery navigation 247 loop: false, 248 249 // Horizontal space between slides 250 gutter: 50, 251 252 // Enable keyboard navigation 253 keyboard: true, 254 255 // Should display navigation arrows at the screen edges 256 arrows: true, 257 258 // Should display counter at the top left corner 259 infobar: true, 260 261 // Should display close button (using `btnTpl.smallBtn` template) over the content 262 // Can be true, false, "auto" 263 // If "auto" - will be automatically enabled for "html", "inline" or "ajax" items 264 smallBtn: "auto", 265 266 // Should display toolbar (buttons at the top) 267 // Can be true, false, "auto" 268 // If "auto" - will be automatically hidden if "smallBtn" is enabled 269 toolbar: "auto", 270 271 // What buttons should appear in the top right corner. 272 // Buttons will be created using templates from `btnTpl` option 273 // and they will be placed into toolbar (class="fancybox-toolbar"` element) 274 buttons: [ 275 "zoom", 276 //"share", 277 //"slideShow", 278 //"fullScreen", 279 //"download", 280 "thumbs", 281 "close" 282 ], 283 284 // Detect "idle" time in seconds 285 idleTime: 3, 286 287 // Disable right-click and use simple image protection for images 288 protect: false, 289 290 // Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc 291 modal: false, 292 293 image: { 294 // Wait for images to load before displaying 295 // true - wait for image to load and then display; 296 // false - display thumbnail and load the full-sized image over top, 297 // requires predefined image dimensions (`data-width` and `data-height` attributes) 298 preload: false 299 }, 300 301 ajax: { 302 // Object containing settings for ajax request 303 settings: { 304 // This helps to indicate that request comes from the modal 305 // Feel free to change naming 306 data: { 307 fancybox: true 308 } 309 } 310 }, 311 312 iframe: { 313 // Iframe template 314 tpl: 315 '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen allowtransparency="true" src=""></iframe>', 316 317 // Preload iframe before displaying it 318 // This allows to calculate iframe content width and height 319 // (note: Due to "Same Origin Policy", you can't get cross domain data). 320 preload: true, 321 322 // Custom CSS styling for iframe wrapping element 323 // You can use this to set custom iframe dimensions 324 css: {}, 325 326 // Iframe tag attributes 327 attr: { 328 scrolling: "auto" 329 } 330 }, 331 332 // Default content type if cannot be detected automatically 333 defaultType: "image", 334 335 // Open/close animation type 336 // Possible values: 337 // false - disable 338 // "zoom" - zoom images from/to thumbnail 339 // "fade" 340 // "zoom-in-out" 341 // 342 animationEffect: "zoom", 343 344 // Duration in ms for open/close animation 345 animationDuration: 366, 346 347 // Should image change opacity while zooming 348 // If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios 349 zoomOpacity: "auto", 350 351 // Transition effect between slides 352 // 353 // Possible values: 354 // false - disable 355 // "fade' 356 // "slide' 357 // "circular' 358 // "tube' 359 // "zoom-in-out' 360 // "rotate' 361 // 362 transitionEffect: "fade", 363 364 // Duration in ms for transition animation 365 transitionDuration: 366, 366 367 // Custom CSS class for slide element 368 slideClass: "", 369 370 // Custom CSS class for layout 371 baseClass: "", 372 373 // Base template for layout 374 baseTpl: 375 '<div class="fancybox-container" role="dialog" tabindex="-1">' + 376 '<div class="fancybox-bg"></div>' + 377 '<div class="fancybox-inner">' + 378 '<div class="fancybox-infobar">' + 379 "<span data-fancybox-index></span> / <span data-fancybox-count></span>" + 380 "</div>" + 381 '<div class="fancybox-toolbar">{{buttons}}</div>' + 382 '<div class="fancybox-navigation">{{arrows}}</div>' + 383 '<div class="fancybox-stage"></div>' + 384 '<div class="fancybox-caption"></div>' + 385 "</div>" + 386 "</div>", 387 388 // Loading indicator template 389 spinnerTpl: '<div class="fancybox-loading"></div>', 390 391 // Error message template 392 errorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>', 393 394 btnTpl: { 395 download: 396 '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' + 397 '<svg viewBox="0 0 40 40">' + 398 '<path d="M13,16 L20,23 L27,16 M20,7 L20,23 M10,24 L10,28 L30,28 L30,24" />' + 399 "</svg>" + 400 "</a>", 401 402 zoom: 403 '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' + 404 '<svg viewBox="0 0 40 40">' + 405 '<path d="M18,17 m-8,0 a8,8 0 1,0 16,0 a8,8 0 1,0 -16,0 M24,22 L31,29" />' + 406 "</svg>" + 407 "</button>", 408 409 close: 410 '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' + 411 '<svg viewBox="0 0 40 40">' + 412 '<path d="M10,10 L30,30 M30,10 L10,30" />' + 413 "</svg>" + 414 "</button>", 415 416 // This small close button will be appended to your html/inline/ajax content by default, 417 // if "smallBtn" option is not set to false 418 smallBtn: 419 '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"><svg viewBox="0 0 32 32"><path d="M10,10 L22,22 M22,10 L10,22"></path></svg></button>', 420 421 // Arrows 422 arrowLeft: 423 '<a data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}" href="javascript:;">' + 424 '<svg viewBox="0 0 40 40">' + 425 '<path d="M18,12 L10,20 L18,28 M10,20 L30,20"></path>' + 426 "</svg>" + 427 "</a>", 428 429 arrowRight: 430 '<a data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}" href="javascript:;">' + 431 '<svg viewBox="0 0 40 40">' + 432 '<path d="M10,20 L30,20 M22,12 L30,20 L22,28"></path>' + 433 "</svg>" + 434 "</a>" 435 }, 436 437 // Container is injected into this element 438 parentEl: "body", 439 440 // Focus handling 441 // ============== 442 443 // Try to focus on the first focusable element after opening 444 autoFocus: false, 445 446 // Put focus back to active element after closing 447 backFocus: true, 448 449 // Do not let user to focus on element outside modal content 450 trapFocus: true, 451 452 // Module specific options 453 // ======================= 454 455 fullScreen: { 456 autoStart: false 457 }, 458 459 // Set `touch: false` to disable dragging/swiping 460 touch: { 461 vertical: true, // Allow to drag content vertically 462 momentum: true // Continue movement after releasing mouse/touch when panning 463 }, 464 465 // Hash value when initializing manually, 466 // set `false` to disable hash change 467 hash: null, 468 469 // Customize or add new media types 470 // Example: 471 /* 472 media : { 473 youtube : { 474 params : { 475 autoplay : 0 476 } 477 } 478 } 479 */ 480 media: {}, 481 482 slideShow: { 483 autoStart: false, 484 speed: 4000 485 }, 486 487 thumbs: { 488 autoStart: false, // Display thumbnails on opening 489 hideOnClose: true, // Hide thumbnail grid when closing animation starts 490 parentEl: ".fancybox-container", // Container is injected into this element 491 axis: "y" // Vertical (y) or horizontal (x) scrolling 492 }, 493 494 // Use mousewheel to navigate gallery 495 // If 'auto' - enabled for images only 496 wheel: "auto", 497 498 // Callbacks 499 //========== 500 501 // See Documentation/API/Events for more information 502 // Example: 503 /* 504 afterShow: function( instance, current ) { 505 console.info( 'Clicked element:' ); 506 console.info( current.opts.$orig ); 507 } 508 */ 509 510 onInit: $.noop, // When instance has been initialized 511 512 beforeLoad: $.noop, // Before the content of a slide is being loaded 513 afterLoad: $.noop, // When the content of a slide is done loading 514 515 beforeShow: $.noop, // Before open animation starts 516 afterShow: $.noop, // When content is done loading and animating 517 518 beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close. 519 afterClose: $.noop, // After instance has been closed 520 521 onActivate: $.noop, // When instance is brought to front 522 onDeactivate: $.noop, // When other instance has been activated 523 524 // Interaction 525 // =========== 526 527 // Use options below to customize taken action when user clicks or double clicks on the fancyBox area, 528 // each option can be string or method that returns value. 529 // 530 // Possible values: 531 // "close" - close instance 532 // "next" - move to next gallery item 533 // "nextOrClose" - move to next gallery item or close if gallery has only one item 534 // "toggleControls" - show/hide controls 535 // "zoom" - zoom image (if loaded) 536 // false - do nothing 537 538 // Clicked on the content 539 clickContent: function(current, event) { 540 return current.type === "image" ? "zoom" : false; 541 }, 542 543 // Clicked on the slide 544 clickSlide: "close", 545 546 // Clicked on the background (backdrop) element; 547 // if you have not changed the layout, then most likely you need to use `clickSlide` option 548 clickOutside: "close", 549 550 // Same as previous two, but for double click 551 dblclickContent: false, 552 dblclickSlide: false, 553 dblclickOutside: false, 554 555 // Custom options when mobile device is detected 556 // ============================================= 557 558 mobile: { 559 idleTime: false, 560 clickContent: function(current, event) { 561 return current.type === "image" ? "toggleControls" : false; 562 }, 563 clickSlide: function(current, event) { 564 return current.type === "image" ? "toggleControls" : "close"; 565 }, 566 dblclickContent: function(current, event) { 567 return current.type === "image" ? "zoom" : false; 568 }, 569 dblclickSlide: function(current, event) { 570 return current.type === "image" ? "zoom" : false; 571 } 572 }, 573 574 // Internationalization 575 // ==================== 576 577 lang: "en", 578 i18n: { 579 en: { 580 CLOSE: "Close", 581 NEXT: "Next", 582 PREV: "Previous", 583 ERROR: "The requested content cannot be loaded. <br/> Please try again later.", 584 PLAY_START: "Start slideshow", 585 PLAY_STOP: "Pause slideshow", 586 FULL_SCREEN: "Full screen", 587 THUMBS: "Thumbnails", 588 DOWNLOAD: "Download", 589 SHARE: "Share", 590 ZOOM: "Zoom" 591 }, 592 de: { 593 CLOSE: "Schliessen", 594 NEXT: "Weiter", 595 PREV: "Zurück", 596 ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es später nochmal.", 597 PLAY_START: "Diaschau starten", 598 PLAY_STOP: "Diaschau beenden", 599 FULL_SCREEN: "Vollbild", 600 THUMBS: "Vorschaubilder", 601 DOWNLOAD: "Herunterladen", 602 SHARE: "Teilen", 603 ZOOM: "MaÃstab" 604 } 605 } 606 }; 607 608 // Few useful variables and methods 609 // ================================ 610 611 var $W = $(window); 612 var $D = $(document); 613 614 var called = 0; 615 616 // Check if an object is a jQuery object and not a native JavaScript object 617 // ======================================================================== 618 var isQuery = function(obj) { 619 return obj && obj.hasOwnProperty && obj instanceof $; 620 }; 621 622 // Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame" 623 // =============================================================================== 624 var requestAFrame = (function() { 625 return ( 626 window.requestAnimationFrame || 627 window.webkitRequestAnimationFrame || 628 window.mozRequestAnimationFrame || 629 window.oRequestAnimationFrame || 630 // if all else fails, use setTimeout 631 function(callback) { 632 return window.setTimeout(callback, 1000 / 60); 633 } 634 ); 635 })(); 636 637 // Detect the supported transition-end event property name 638 // ======================================================= 639 var transitionEnd = (function() { 640 var el = document.createElement("fakeelement"), 641 t; 642 643 var transitions = { 644 transition: "transitionend", 645 OTransition: "oTransitionEnd", 646 MozTransition: "transitionend", 647 WebkitTransition: "webkitTransitionEnd" 648 }; 649 650 for (t in transitions) { 651 if (el.style[t] !== undefined) { 652 return transitions[t]; 653 } 654 } 655 656 return "transitionend"; 657 })(); 658 659 // Force redraw on an element. 660 // This helps in cases where the browser doesn't redraw an updated element properly 661 // ================================================================================ 662 var forceRedraw = function($el) { 663 return $el && $el.length && $el[0].offsetHeight; 664 }; 665 666 // Exclude array (`buttons`) options from deep merging 667 // =================================================== 668 var mergeOpts = function(opts1, opts2) { 669 var rez = $.extend(true, {}, opts1, opts2); 670 671 $.each(opts2, function(key, value) { 672 if ($.isArray(value)) { 673 rez[key] = value; 674 } 675 }); 676 677 return rez; 678 }; 679 680 // Class definition 681 // ================ 682 683 var FancyBox = function(content, opts, index) { 684 var self = this; 685 686 self.opts = mergeOpts({index: index}, $.fancybox.defaults); 687 688 if ($.isPlainObject(opts)) { 689 self.opts = mergeOpts(self.opts, opts); 690 } 691 692 if ($.fancybox.isMobile) { 693 self.opts = mergeOpts(self.opts, self.opts.mobile); 694 } 695 696 self.id = self.opts.id || ++called; 697 698 self.currIndex = parseInt(self.opts.index, 10) || 0; 699 self.prevIndex = null; 700 701 self.prevPos = null; 702 self.currPos = 0; 703 704 self.firstRun = true; 705 706 // All group items 707 self.group = []; 708 709 // Existing slides (for current, next and previous gallery items) 710 self.slides = {}; 711 712 // Create group elements 713 self.addContent(content); 714 715 if (!self.group.length) { 716 return; 717 } 718 719 // Save last active element 720 self.$lastFocus = $(document.activeElement).trigger("blur"); 721 722 self.init(); 723 }; 724 725 $.extend(FancyBox.prototype, { 726 // Create DOM structure 727 // ==================== 728 729 init: function() { 730 var self = this, 731 firstItem = self.group[self.currIndex], 732 firstItemOpts = firstItem.opts, 733 scrollbarWidth = $.fancybox.scrollbarWidth, 734 $scrollDiv, 735 $container, 736 buttonStr; 737 738 // Hide scrollbars 739 // =============== 740 741 if (!$.fancybox.getInstance() && firstItemOpts.hideScrollbar !== false) { 742 $("body").addClass("fancybox-active"); 743 744 if (!$.fancybox.isMobile && document.body.scrollHeight > window.innerHeight) { 745 if (scrollbarWidth === undefined) { 746 $scrollDiv = $('<div style="width:100px;height:100px;overflow:scroll;" />').appendTo("body"); 747 748 scrollbarWidth = $.fancybox.scrollbarWidth = $scrollDiv[0].offsetWidth - $scrollDiv[0].clientWidth; 749 750 $scrollDiv.remove(); 751 } 752 753 $("head").append( 754 '<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar { margin-right: ' + 755 scrollbarWidth + 756 "px; }</style>" 757 ); 758 759 $("body").addClass("compensate-for-scrollbar"); 760 } 761 } 762 763 // Build html markup and set references 764 // ==================================== 765 766 // Build html code for buttons and insert into main template 767 buttonStr = ""; 768 769 $.each(firstItemOpts.buttons, function(index, value) { 770 buttonStr += firstItemOpts.btnTpl[value] || ""; 771 }); 772 773 // Create markup from base template, it will be initially hidden to 774 // avoid unnecessary work like painting while initializing is not complete 775 $container = $( 776 self.translate( 777 self, 778 firstItemOpts.baseTpl 779 .replace("{{buttons}}", buttonStr) 780 .replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight) 781 ) 782 ) 783 .attr("id", "fancybox-container-" + self.id) 784 .addClass("fancybox-is-hidden") 785 .addClass(firstItemOpts.baseClass) 786 .data("FancyBox", self) 787 .appendTo(firstItemOpts.parentEl); 788 789 // Create object holding references to jQuery wrapped nodes 790 self.$refs = { 791 container: $container 792 }; 793 794 ["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function(item) { 795 self.$refs[item] = $container.find(".fancybox-" + item); 796 }); 797 798 self.trigger("onInit"); 799 800 // Enable events, deactive previous instances 801 self.activate(); 802 803 // Build slides, load and reveal content 804 self.jumpTo(self.currIndex); 805 }, 806 807 // Simple i18n support - replaces object keys found in template 808 // with corresponding values 809 // ============================================================ 810 811 translate: function(obj, str) { 812 var arr = obj.opts.i18n[obj.opts.lang]; 813 814 return str.replace(/\{\{(\w+)\}\}/g, function(match, n) { 815 var value = arr[n]; 816 817 if (value === undefined) { 818 return match; 819 } 820 821 return value; 822 }); 823 }, 824 825 // Populate current group with fresh content 826 // Check if each object has valid type and content 827 // =============================================== 828 829 addContent: function(content) { 830 var self = this, 831 items = $.makeArray(content), 832 thumbs; 833 834 $.each(items, function(i, item) { 835 var obj = {}, 836 opts = {}, 837 $item, 838 type, 839 found, 840 src, 841 srcParts; 842 843 // Step 1 - Make sure we have an object 844 // ==================================== 845 846 if ($.isPlainObject(item)) { 847 // We probably have manual usage here, something like 848 // $.fancybox.open( [ { src : "image.jpg", type : "image" } ] ) 849 850 obj = item; 851 opts = item.opts || item; 852 } else if ($.type(item) === "object" && $(item).length) { 853 // Here we probably have jQuery collection returned by some selector 854 $item = $(item); 855 856 // Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'` 857 opts = $item.data() || {}; 858 opts = $.extend(true, {}, opts, opts.options); 859 860 // Here we store clicked element 861 opts.$orig = $item; 862 863 obj.src = self.opts.src || opts.src || $item.attr("href"); 864 865 // Assume that simple syntax is used, for example: 866 // `$.fancybox.open( $("#test"), {} );` 867 if (!obj.type && !obj.src) { 868 obj.type = "inline"; 869 obj.src = item; 870 } 871 } else { 872 // Assume we have a simple html code, for example: 873 // $.fancybox.open( '<div><h1>Hi!</h1></div>' ); 874 obj = { 875 type: "html", 876 src: item + "" 877 }; 878 } 879 880 // Each gallery object has full collection of options 881 obj.opts = $.extend(true, {}, self.opts, opts); 882 883 // Do not merge buttons array 884 if ($.isArray(opts.buttons)) { 885 obj.opts.buttons = opts.buttons; 886 } 887 888 // Step 2 - Make sure we have content type, if not - try to guess 889 // ============================================================== 890 891 type = obj.type || obj.opts.type; 892 src = obj.src || ""; 893 894 if (!type && src) { 895 if ((found = src.match(/\.(mp4|mov|ogv)((\?|#).*)?$/i))) { 896 type = "video"; 897 898 if (!obj.opts.videoFormat) { 899 obj.opts.videoFormat = "video/" + (found[1] === "ogv" ? "ogg" : found[1]); 900 } 901 } else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) { 902 type = "image"; 903 } else if (src.match(/\.(pdf)((\?|#).*)?$/i)) { 904 type = "iframe"; 905 } else if (src.charAt(0) === "#") { 906 type = "inline"; 907 } 908 } 909 910 if (type) { 911 obj.type = type; 912 } else { 913 self.trigger("objectNeedsType", obj); 914 } 915 916 if (!obj.contentType) { 917 obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type; 918 } 919 920 // Step 3 - Some adjustments 921 // ========================= 922 923 obj.index = self.group.length; 924 925 if (obj.opts.smallBtn == "auto") { 926 obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1; 927 } 928 929 if (obj.opts.toolbar === "auto") { 930 obj.opts.toolbar = !obj.opts.smallBtn; 931 } 932 933 // Find thumbnail image 934 if (obj.opts.$trigger && obj.index === self.opts.index) { 935 obj.opts.$thumb = obj.opts.$trigger.find("img:first"); 936 } 937 938 if ((!obj.opts.$thumb || !obj.opts.$thumb.length) && obj.opts.$orig) { 939 obj.opts.$thumb = obj.opts.$orig.find("img:first"); 940 } 941 942 // "caption" is a "special" option, it can be used to customize caption per gallery item .. 943 if ($.type(obj.opts.caption) === "function") { 944 obj.opts.caption = obj.opts.caption.apply(item, [self, obj]); 945 } 946 947 if ($.type(self.opts.caption) === "function") { 948 obj.opts.caption = self.opts.caption.apply(item, [self, obj]); 949 } 950 951 // Make sure we have caption as a string or jQuery object 952 if (!(obj.opts.caption instanceof $)) { 953 obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + ""; 954 } 955 956 // Check if url contains "filter" used to filter the content 957 // Example: "ajax.html #something" 958 if (obj.type === "ajax") { 959 srcParts = src.split(/\s+/, 2); 960 961 if (srcParts.length > 1) { 962 obj.src = srcParts.shift(); 963 964 obj.opts.filter = srcParts.shift(); 965 } 966 } 967 968 // Hide all buttons and disable interactivity for modal items 969 if (obj.opts.modal) { 970 obj.opts = $.extend(true, obj.opts, { 971 // Remove buttons 972 infobar: 0, 973 toolbar: 0, 974 975 smallBtn: 0, 976 977 // Disable keyboard navigation 978 keyboard: 0, 979 980 // Disable some modules 981 slideShow: 0, 982 fullScreen: 0, 983 thumbs: 0, 984 touch: 0, 985 986 // Disable click event handlers 987 clickContent: false, 988 clickSlide: false, 989 clickOutside: false, 990 dblclickContent: false, 991 dblclickSlide: false, 992 dblclickOutside: false 993 }); 994 } 995 996 // Step 4 - Add processed object to group 997 // ====================================== 998 999 self.group.push(obj); 1000 }); 1001 1002 // Update controls if gallery is already opened 1003 if (Object.keys(self.slides).length) { 1004 self.updateControls(); 1005 1006 // Update thumbnails, if needed 1007 thumbs = self.Thumbs; 1008 1009 if (thumbs && thumbs.isActive) { 1010 thumbs.create(); 1011 1012 thumbs.focus(); 1013 } 1014 } 1015 }, 1016 1017 // Attach an event handler functions for: 1018 // - navigation buttons 1019 // - browser scrolling, resizing; 1020 // - focusing 1021 // - keyboard 1022 // - detect idle 1023 // ====================================== 1024 1025 addEvents: function() { 1026 var self = this; 1027 1028 self.removeEvents(); 1029 1030 // Make navigation elements clickable 1031 self.$refs.container 1032 .on("click.fb-close", "[data-fancybox-close]", function(e) { 1033 e.stopPropagation(); 1034 e.preventDefault(); 1035 1036 self.close(e); 1037 }) 1038 .on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function(e) { 1039 e.stopPropagation(); 1040 e.preventDefault(); 1041 1042 self.previous(); 1043 }) 1044 .on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function(e) { 1045 e.stopPropagation(); 1046 e.preventDefault(); 1047 1048 self.next(); 1049 }) 1050 .on("click.fb", "[data-fancybox-zoom]", function(e) { 1051 // Click handler for zoom button 1052 self[self.isScaledDown() ? "scaleToActual" : "scaleToFit"](); 1053 }); 1054 1055 // Handle page scrolling and browser resizing 1056 $W.on("orientationchange.fb resize.fb", function(e) { 1057 if (e && e.originalEvent && e.originalEvent.type === "resize") { 1058 requestAFrame(function() { 1059 self.update(); 1060 }); 1061 } else { 1062 self.$refs.stage.hide(); 1063 1064 setTimeout(function() { 1065 self.$refs.stage.show(); 1066 1067 self.update(); 1068 }, $.fancybox.isMobile ? 600 : 250); 1069 } 1070 }); 1071 1072 // Trap keyboard focus inside of the modal, so the user does not accidentally tab outside of the modal 1073 // (a.k.a. "escaping the modal") 1074 $D.on("focusin.fb", function(e) { 1075 var instance = $.fancybox ? $.fancybox.getInstance() : null; 1076 1077 if ( 1078 instance.isClosing || 1079 !instance.current || 1080 !instance.current.opts.trapFocus || 1081 $(e.target).hasClass("fancybox-container") || 1082 $(e.target).is(document) 1083 ) { 1084 return; 1085 } 1086 1087 if (instance && $(e.target).css("position") !== "fixed" && !instance.$refs.container.has(e.target).length) { 1088 e.stopPropagation(); 1089 1090 instance.focus(); 1091 } 1092 }); 1093 1094 // Enable keyboard navigation 1095 $D.on("keydown.fb", function(e) { 1096 var current = self.current, 1097 keycode = e.keyCode || e.which; 1098 1099 if (!current || !current.opts.keyboard) { 1100 return; 1101 } 1102 1103 if (e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input") || $(e.target).is("textarea")) { 1104 return; 1105 } 1106 1107 // Backspace and Esc keys 1108 if (keycode === 8 || keycode === 27) { 1109 e.preventDefault(); 1110 1111 self.close(e); 1112 1113 return; 1114 } 1115 1116 // Left arrow and Up arrow 1117 if (keycode === 37 || keycode === 38) { 1118 e.preventDefault(); 1119 1120 self.previous(); 1121 1122 return; 1123 } 1124 1125 // Righ arrow and Down arrow 1126 if (keycode === 39 || keycode === 40) { 1127 e.preventDefault(); 1128 1129 self.next(); 1130 1131 return; 1132 } 1133 1134 self.trigger("afterKeydown", e, keycode); 1135 }); 1136 1137 // Hide controls after some inactivity period 1138 if (self.group[self.currIndex].opts.idleTime) { 1139 self.idleSecondsCounter = 0; 1140 1141 $D.on( 1142 "mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle", 1143 function(e) { 1144 self.idleSecondsCounter = 0; 1145 1146 if (self.isIdle) { 1147 self.showControls(); 1148 } 1149 1150 self.isIdle = false; 1151 } 1152 ); 1153 1154 self.idleInterval = window.setInterval(function() { 1155 self.idleSecondsCounter++; 1156 1157 if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) { 1158 self.isIdle = true; 1159 self.idleSecondsCounter = 0; 1160 1161 self.hideControls(); 1162 } 1163 }, 1000); 1164 } 1165 }, 1166 1167 // Remove events added by the core 1168 // =============================== 1169 1170 removeEvents: function() { 1171 var self = this; 1172 1173 $W.off("orientationchange.fb resize.fb"); 1174 $D.off("focusin.fb keydown.fb .fb-idle"); 1175 1176 this.$refs.container.off(".fb-close .fb-prev .fb-next"); 1177 1178 if (self.idleInterval) { 1179 window.clearInterval(self.idleInterval); 1180 1181 self.idleInterval = null; 1182 } 1183 }, 1184 1185 // Change to previous gallery item 1186 // =============================== 1187 1188 previous: function(duration) { 1189 return this.jumpTo(this.currPos - 1, duration); 1190 }, 1191 1192 // Change to next gallery item 1193 // =========================== 1194 1195 next: function(duration) { 1196 return this.jumpTo(this.currPos + 1, duration); 1197 }, 1198 1199 // Switch to selected gallery item 1200 // =============================== 1201 1202 jumpTo: function(pos, duration) { 1203 var self = this, 1204 groupLen = self.group.length, 1205 firstRun, 1206 loop, 1207 current, 1208 previous, 1209 canvasWidth, 1210 currentPos, 1211 transitionProps; 1212 1213 if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) { 1214 return; 1215 } 1216 1217 pos = parseInt(pos, 10); 1218 1219 // Should loop? 1220 loop = self.current ? self.current.opts.loop : self.opts.loop; 1221 1222 if (!loop && (pos < 0 || pos >= groupLen)) { 1223 return false; 1224 } 1225 1226 firstRun = self.firstRun = !Object.keys(self.slides).length; 1227 1228 if (groupLen < 2 && !firstRun && !!self.isDragging) { 1229 return; 1230 } 1231 1232 previous = self.current; 1233 1234 self.prevIndex = self.currIndex; 1235 self.prevPos = self.currPos; 1236 1237 // Create slides 1238 current = self.createSlide(pos); 1239 1240 if (groupLen > 1) { 1241 if (loop || current.index > 0) { 1242 self.createSlide(pos - 1); 1243 } 1244 1245 if (loop || current.index < groupLen - 1) { 1246 self.createSlide(pos + 1); 1247 } 1248 } 1249 1250 self.current = current; 1251 self.currIndex = current.index; 1252 self.currPos = current.pos; 1253 1254 self.trigger("beforeShow", firstRun); 1255 1256 self.updateControls(); 1257 1258 currentPos = $.fancybox.getTranslate(current.$slide); 1259 1260 current.isMoved = (currentPos.left !== 0 || currentPos.top !== 0) && !current.$slide.hasClass("fancybox-animated"); 1261 1262 // Validate duration length 1263 current.forcedDuration = undefined; 1264 1265 if ($.isNumeric(duration)) { 1266 current.forcedDuration = duration; 1267 } else { 1268 duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"]; 1269 } 1270 1271 duration = parseInt(duration, 10); 1272 1273 // Fresh start - reveal container, current slide and start loading content 1274 if (firstRun) { 1275 if (current.opts.animationEffect && duration) { 1276 self.$refs.container.css("transition-duration", duration + "ms"); 1277 } 1278 1279 self.$refs.container.removeClass("fancybox-is-hidden"); 1280 1281 forceRedraw(self.$refs.container); 1282 1283 self.$refs.container.addClass("fancybox-is-open"); 1284 1285 forceRedraw(self.$refs.container); 1286 1287 // Make current slide visible 1288 current.$slide.addClass("fancybox-slide--previous"); 1289 1290 // Attempt to load content into slide; 1291 // at this point image would start loading, but inline/html content would load immediately 1292 self.loadSlide(current); 1293 1294 current.$slide.removeClass("fancybox-slide--previous").addClass("fancybox-slide--current"); 1295 1296 self.preload("image"); 1297 1298 return; 1299 } 1300 1301 // Clean up 1302 $.each(self.slides, function(index, slide) { 1303 $.fancybox.stop(slide.$slide); 1304 }); 1305 1306 // Make current that slide is visible even if content is still loading 1307 current.$slide.removeClass("fancybox-slide--next fancybox-slide--previous").addClass("fancybox-slide--current"); 1308 1309 // If slides have been dragged, animate them to correct position 1310 if (current.isMoved) { 1311 canvasWidth = Math.round(current.$slide.width()); 1312 1313 $.each(self.slides, function(index, slide) { 1314 var pos = slide.pos - current.pos; 1315 1316 $.fancybox.animate( 1317 slide.$slide, 1318 { 1319 top: 0, 1320 left: pos * canvasWidth + pos * slide.opts.gutter 1321 }, 1322 duration, 1323 function() { 1324 slide.$slide.removeAttr("style").removeClass("fancybox-slide--next fancybox-slide--previous"); 1325 1326 if (slide.pos === self.currPos) { 1327 current.isMoved = false; 1328 1329 self.complete(); 1330 } 1331 } 1332 ); 1333 }); 1334 } else { 1335 self.$refs.stage.children().removeAttr("style"); 1336 } 1337 1338 // Start transition that reveals current content 1339 // or wait when it will be loaded 1340 1341 if (current.isLoaded) { 1342 self.revealContent(current); 1343 } else { 1344 self.loadSlide(current); 1345 } 1346 1347 self.preload("image"); 1348 1349 if (previous.pos === current.pos) { 1350 return; 1351 } 1352 1353 // Handle previous slide 1354 // ===================== 1355 1356 transitionProps = "fancybox-slide--" + (previous.pos > current.pos ? "next" : "previous"); 1357 1358 previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current fancybox-slide--next fancybox-slide--previous"); 1359 1360 previous.isComplete = false; 1361 1362 if (!duration || (!current.isMoved && !current.opts.transitionEffect)) { 1363 return; 1364 } 1365 1366 if (current.isMoved) { 1367 previous.$slide.addClass(transitionProps); 1368 } else { 1369 transitionProps = "fancybox-animated " + transitionProps + " fancybox-fx-" + current.opts.transitionEffect; 1370 1371 $.fancybox.animate(previous.$slide, transitionProps, duration, function() { 1372 previous.$slide.removeClass(transitionProps).removeAttr("style"); 1373 }); 1374 } 1375 }, 1376 1377 // Create new "slide" element 1378 // These are gallery items that are actually added to DOM 1379 // ======================================================= 1380 1381 createSlide: function(pos) { 1382 var self = this, 1383 $slide, 1384 index; 1385 1386 index = pos % self.group.length; 1387 index = index < 0 ? self.group.length + index : index; 1388 1389 if (!self.slides[pos] && self.group[index]) { 1390 $slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage); 1391 1392 self.slides[pos] = $.extend(true, {}, self.group[index], { 1393 pos: pos, 1394 $slide: $slide, 1395 isLoaded: false 1396 }); 1397 1398 self.updateSlide(self.slides[pos]); 1399 } 1400 1401 return self.slides[pos]; 1402 }, 1403 1404 // Scale image to the actual size of the image; 1405 // x and y values should be relative to the slide 1406 // ============================================== 1407 1408 scaleToActual: function(x, y, duration) { 1409 var self = this, 1410 current = self.current, 1411 $content = current.$content, 1412 canvasWidth = $.fancybox.getTranslate(current.$slide).width, 1413 canvasHeight = $.fancybox.getTranslate(current.$slide).height, 1414 newImgWidth = current.width, 1415 newImgHeight = current.height, 1416 imgPos, 1417 posX, 1418 posY, 1419 scaleX, 1420 scaleY; 1421 1422 if (self.isAnimating || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) { 1423 return; 1424 } 1425 1426 $.fancybox.stop($content); 1427 1428 self.isAnimating = true; 1429 1430 x = x === undefined ? canvasWidth * 0.5 : x; 1431 y = y === undefined ? canvasHeight * 0.5 : y; 1432 1433 imgPos = $.fancybox.getTranslate($content); 1434 1435 imgPos.top -= $.fancybox.getTranslate(current.$slide).top; 1436 imgPos.left -= $.fancybox.getTranslate(current.$slide).left; 1437 1438 scaleX = newImgWidth / imgPos.width; 1439 scaleY = newImgHeight / imgPos.height; 1440 1441 // Get center position for original image 1442 posX = canvasWidth * 0.5 - newImgWidth * 0.5; 1443 posY = canvasHeight * 0.5 - newImgHeight * 0.5; 1444 1445 // Make sure image does not move away from edges 1446 if (newImgWidth > canvasWidth) { 1447 posX = imgPos.left * scaleX - (x * scaleX - x); 1448 1449 if (posX > 0) { 1450 posX = 0; 1451 } 1452 1453 if (posX < canvasWidth - newImgWidth) { 1454 posX = canvasWidth - newImgWidth; 1455 } 1456 } 1457 1458 if (newImgHeight > canvasHeight) { 1459 posY = imgPos.top * scaleY - (y * scaleY - y); 1460 1461 if (posY > 0) { 1462 posY = 0; 1463 } 1464 1465 if (posY < canvasHeight - newImgHeight) { 1466 posY = canvasHeight - newImgHeight; 1467 } 1468 } 1469 1470 self.updateCursor(newImgWidth, newImgHeight); 1471 1472 $.fancybox.animate( 1473 $content, 1474 { 1475 top: posY, 1476 left: posX, 1477 scaleX: scaleX, 1478 scaleY: scaleY 1479 }, 1480 duration || 330, 1481 function() { 1482 self.isAnimating = false; 1483 } 1484 ); 1485 1486 // Stop slideshow 1487 if (self.SlideShow && self.SlideShow.isActive) { 1488 self.SlideShow.stop(); 1489 } 1490 }, 1491 1492 // Scale image to fit inside parent element 1493 // ======================================== 1494 1495 scaleToFit: function(duration) { 1496 var self = this, 1497 current = self.current, 1498 $content = current.$content, 1499 end; 1500 1501 if (self.isAnimating || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) { 1502 return; 1503 } 1504 1505 $.fancybox.stop($content); 1506 1507 self.isAnimating = true; 1508 1509 end = self.getFitPos(current); 1510 1511 self.updateCursor(end.width, end.height); 1512 1513 $.fancybox.animate( 1514 $content, 1515 { 1516 top: end.top, 1517 left: end.left, 1518 scaleX: end.width / $content.width(), 1519 scaleY: end.height / $content.height() 1520 }, 1521 duration || 330, 1522 function() { 1523 self.isAnimating = false; 1524 } 1525 ); 1526 }, 1527 1528 // Calculate image size to fit inside viewport 1529 // =========================================== 1530 1531 getFitPos: function(slide) { 1532 var self = this, 1533 $content = slide.$content, 1534 width = slide.width || slide.opts.width, 1535 height = slide.height || slide.opts.height, 1536 maxWidth, 1537 maxHeight, 1538 minRatio, 1539 margin, 1540 aspectRatio, 1541 rez = {}; 1542 1543 if (!slide.isLoaded || !$content || !$content.length) { 1544 return false; 1545 } 1546 1547 margin = { 1548 top: parseInt(slide.$slide.css("paddingTop"), 10), 1549 right: parseInt(slide.$slide.css("paddingRight"), 10), 1550 bottom: parseInt(slide.$slide.css("paddingBottom"), 10), 1551 left: parseInt(slide.$slide.css("paddingLeft"), 10) 1552 }; 1553 1554 // We can not use $slide width here, because it can have different diemensions while in transiton 1555 maxWidth = parseInt(self.$refs.stage.width(), 10) - (margin.left + margin.right); 1556 maxHeight = parseInt(self.$refs.stage.height(), 10) - (margin.top + margin.bottom); 1557 1558 if (!width || !height) { 1559 width = maxWidth; 1560 height = maxHeight; 1561 } 1562 1563 minRatio = Math.min(1, maxWidth / width, maxHeight / height); 1564 1565 // Use floor rounding to make sure it really fits 1566 width = Math.floor(minRatio * width); 1567 height = Math.floor(minRatio * height); 1568 1569 if (slide.type === "image") { 1570 rez.top = Math.floor((maxHeight - height) * 0.5) + margin.top; 1571 rez.left = Math.floor((maxWidth - width) * 0.5) + margin.left; 1572 } else if (slide.contentType === "video") { 1573 // Force aspect ratio for the video 1574 // "I say the whole world must learn of our peaceful ways⦠by force!" 1575 aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9; 1576 1577 if (height > width / aspectRatio) { 1578 height = width / aspectRatio; 1579 } else if (width > height * aspectRatio) { 1580 width = height * aspectRatio; 1581 } 1582 } 1583 1584 rez.width = width; 1585 rez.height = height; 1586 1587 return rez; 1588 }, 1589 1590 // Update content size and position for all slides 1591 // ============================================== 1592 1593 update: function() { 1594 var self = this; 1595 1596 $.each(self.slides, function(key, slide) { 1597 self.updateSlide(slide); 1598 }); 1599 }, 1600 1601 // Update slide content position and size 1602 // ====================================== 1603 1604 updateSlide: function(slide, duration) { 1605 var self = this, 1606 $content = slide && slide.$content, 1607 width = slide.width || slide.opts.width, 1608 height = slide.height || slide.opts.height; 1609 1610 if ($content && (width || height || slide.contentType === "video") && !slide.hasError) { 1611 $.fancybox.stop($content); 1612 1613 $.fancybox.setTranslate($content, self.getFitPos(slide)); 1614 1615 if (slide.pos === self.currPos) { 1616 self.isAnimating = false; 1617 1618 self.updateCursor(); 1619 } 1620 } 1621 1622 slide.$slide.trigger("refresh"); 1623 1624 self.$refs.toolbar.toggleClass("compensate-for-scrollbar", slide.$slide.get(0).scrollHeight > slide.$slide.get(0).clientHeight); 1625 1626 self.trigger("onUpdate", slide); 1627 }, 1628 1629 // Horizontally center slide 1630 // ========================= 1631 1632 centerSlide: function(slide, duration) { 1633 var self = this, 1634 canvasWidth, 1635 pos; 1636 1637 if (self.current) { 1638 canvasWidth = Math.round(slide.$slide.width()); 1639 pos = slide.pos - self.current.pos; 1640 1641 $.fancybox.animate( 1642 slide.$slide, 1643 { 1644 top: 0, 1645 left: pos * canvasWidth + pos * slide.opts.gutter, 1646 opacity: 1 1647 }, 1648 duration === undefined ? 0 : duration, 1649 null, 1650 false 1651 ); 1652 } 1653 }, 1654 1655 // Update cursor style depending if content can be zoomed 1656 // ====================================================== 1657 1658 updateCursor: function(nextWidth, nextHeight) { 1659 var self = this, 1660 current = self.current, 1661 $container = self.$refs.container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-drag fancybox-can-zoomOut"), 1662 isZoomable; 1663 1664 if (!current || self.isClosing) { 1665 return; 1666 } 1667 1668 isZoomable = self.isZoomable(); 1669 1670 $container.toggleClass("fancybox-is-zoomable", isZoomable); 1671 1672 $("[data-fancybox-zoom]").prop("disabled", !isZoomable); 1673 1674 // Set cursor to zoom in/out if click event is 'zoom' 1675 if ( 1676 isZoomable && 1677 (current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) === "zoom")) 1678 ) { 1679 if (self.isScaledDown(nextWidth, nextHeight)) { 1680 // If image is scaled down, then, obviously, it can be zoomed to full size 1681 $container.addClass("fancybox-can-zoomIn"); 1682 } else { 1683 if (current.opts.touch) { 1684 // If image size ir largen than available available and touch module is not disable, 1685 // then user can do panning 1686 $container.addClass("fancybox-can-drag"); 1687 } else { 1688 $container.addClass("fancybox-can-zoomOut"); 1689 } 1690 } 1691 } else if (current.opts.touch && current.contentType !== "video") { 1692 $container.addClass("fancybox-can-drag"); 1693 } 1694 }, 1695 1696 // Check if current slide is zoomable 1697 // ================================== 1698 1699 isZoomable: function() { 1700 var self = this, 1701 current = self.current, 1702 fitPos; 1703 1704 // Assume that slide is zoomable if: 1705 // - image is still loading 1706 // - actual size of the image is smaller than available area 1707 if (current && !self.isClosing && current.type === "image" && !current.hasError) { 1708 if (!current.isLoaded) { 1709 return true; 1710 } 1711 1712 fitPos = self.getFitPos(current); 1713 1714 if (current.width > fitPos.width || current.height > fitPos.height) { 1715 return true; 1716 } 1717 } 1718 1719 return false; 1720 }, 1721 1722 // Check if current image dimensions are smaller than actual 1723 // ========================================================= 1724 1725 isScaledDown: function(nextWidth, nextHeight) { 1726 var self = this, 1727 rez = false, 1728 current = self.current, 1729 $content = current.$content; 1730 1731 if (nextWidth !== undefined && nextHeight !== undefined) { 1732 rez = nextWidth < current.width && nextHeight < current.height; 1733 } else if ($content) { 1734 rez = $.fancybox.getTranslate($content); 1735 rez = rez.width < current.width && rez.height < current.height; 1736 } 1737 1738 return rez; 1739 }, 1740 1741 // Check if image dimensions exceed parent element 1742 // =============================================== 1743 1744 canPan: function() { 1745 var self = this, 1746 rez = false, 1747 current = self.current, 1748 $content; 1749 1750 if (current.type === "image" && ($content = current.$content) && !current.hasError) { 1751 rez = self.getFitPos(current); 1752 rez = Math.abs($content.width() - rez.width) > 1 || Math.abs($content.height() - rez.height) > 1; 1753 } 1754 1755 return rez; 1756 }, 1757 1758 // Load content into the slide 1759 // =========================== 1760 1761 loadSlide: function(slide) { 1762 var self = this, 1763 type, 1764 $slide, 1765 ajaxLoad; 1766 1767 if (slide.isLoading || slide.isLoaded) { 1768 return; 1769 } 1770 1771 slide.isLoading = true; 1772 1773 self.trigger("beforeLoad", slide); 1774 1775 type = slide.type; 1776 $slide = slide.$slide; 1777 1778 $slide 1779 .off("refresh") 1780 .trigger("onReset") 1781 .addClass(slide.opts.slideClass); 1782 1783 // Create content depending on the type 1784 switch (type) { 1785 case "image": 1786 self.setImage(slide); 1787 1788 break; 1789 1790 case "iframe": 1791 self.setIframe(slide); 1792 1793 break; 1794 1795 case "html": 1796 self.setContent(slide, slide.src || slide.content); 1797 1798 break; 1799 1800 case "video": 1801 self.setContent( 1802 slide, 1803 '<video class="fancybox-video" controls controlsList="nodownload">' + 1804 '<source src="' + 1805 slide.src + 1806 '" type="' + 1807 slide.opts.videoFormat + 1808 '">' + 1809 "Your browser doesn't support HTML5 video" + 1810 "</video" 1811 ); 1812 1813 break; 1814 1815 case "inline": 1816 if ($(slide.src).length) { 1817 self.setContent(slide, $(slide.src)); 1818 } else { 1819 self.setError(slide); 1820 } 1821 1822 break; 1823 1824 case "ajax": 1825 self.showLoading(slide); 1826 1827 ajaxLoad = $.ajax( 1828 $.extend({}, slide.opts.ajax.settings, { 1829 url: slide.src, 1830 success: function(data, textStatus) { 1831 if (textStatus === "success") { 1832 self.setContent(slide, data); 1833 } 1834 }, 1835 error: function(jqXHR, textStatus) { 1836 if (jqXHR && textStatus !== "abort") { 1837 self.setError(slide); 1838 } 1839 } 1840 }) 1841 ); 1842 1843 $slide.one("onReset", function() { 1844 ajaxLoad.abort(); 1845 }); 1846 1847 break; 1848 1849 default: 1850 self.setError(slide); 1851 1852 break; 1853 } 1854 1855 return true; 1856 }, 1857 1858 // Use thumbnail image, if possible 1859 // ================================ 1860 1861 setImage: function(slide) { 1862 var self = this, 1863 srcset = slide.opts.srcset || slide.opts.image.srcset, 1864 thumbSrc, 1865 found, 1866 temp, 1867 pxRatio, 1868 windowWidth; 1869 1870 // Check if need to show loading icon 1871 slide.timouts = setTimeout(function() { 1872 var $img = slide.$image; 1873 1874 if (slide.isLoading && (!$img || !$img[0].complete) && !slide.hasError) { 1875 self.showLoading(slide); 1876 } 1877 }, 350); 1878 1879 // If we have "srcset", then we need to find first matching "src" value. 1880 // This is necessary, because when you set an src attribute, the browser will preload the image 1881 // before any javascript or even CSS is applied. 1882 if (srcset) { 1883 pxRatio = window.devicePixelRatio || 1; 1884 windowWidth = window.innerWidth * pxRatio; 1885 1886 temp = srcset.split(",").map(function(el) { 1887 var ret = {}; 1888 1889 el 1890 .trim() 1891 .split(/\s+/) 1892 .forEach(function(el, i) { 1893 var value = parseInt(el.substring(0, el.length - 1), 10); 1894 1895 if (i === 0) { 1896 return (ret.url = el); 1897 } 1898 1899 if (value) { 1900 ret.value = value; 1901 ret.postfix = el[el.length - 1]; 1902 } 1903 }); 1904 1905 return ret; 1906 }); 1907 1908 // Sort by value 1909 temp.sort(function(a, b) { 1910 return a.value - b.value; 1911 }); 1912 1913 // Ok, now we have an array of all srcset values 1914 for (var j = 0; j < temp.length; j++) { 1915 var el = temp[j]; 1916 1917 if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) { 1918 found = el; 1919 break; 1920 } 1921 } 1922 1923 // If not found, take the last one 1924 if (!found && temp.length) { 1925 found = temp[temp.length - 1]; 1926 } 1927 1928 if (found) { 1929 slide.src = found.url; 1930 1931 // If we have default width/height values, we can calculate height for matching source 1932 if (slide.width && slide.height && found.postfix == "w") { 1933 slide.height = slide.width / slide.height * found.value; 1934 slide.width = found.value; 1935 } 1936 1937 slide.opts.srcset = srcset; 1938 } 1939 } 1940 1941 // This will be wrapper containing both ghost and actual image 1942 slide.$content = $('<div class="fancybox-content"></div>') 1943 .addClass("fancybox-is-hidden") 1944 .appendTo(slide.$slide.addClass("fancybox-slide--image")); 1945 1946 // If we have a thumbnail, we can display it while actual image is loading 1947 // Users will not stare at black screen and actual image will appear gradually 1948 thumbSrc = slide.opts.thumb || (slide.opts.$thumb && slide.opts.$thumb.length ? slide.opts.$thumb.attr("src") : false); 1949 1950 if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && thumbSrc) { 1951 slide.width = slide.opts.width; 1952 slide.height = slide.opts.height; 1953 1954 slide.$ghost = $("<img />") 1955 .one("error", function() { 1956 $(this).remove(); 1957 1958 slide.$ghost = null; 1959 }) 1960 .one("load", function() { 1961 self.afterLoad(slide); 1962 }) 1963 .addClass("fancybox-image") 1964 .appendTo(slide.$content) 1965 .attr("src", thumbSrc); 1966 } 1967 1968 // Start loading actual image 1969 self.setBigImage(slide); 1970 }, 1971 1972 // Create full-size image 1973 // ====================== 1974 1975 setBigImage: function(slide) { 1976 var self = this, 1977 $img = $("<img />"); 1978 1979 slide.$image = $img 1980 .one("error", function() { 1981 self.setError(slide); 1982 }) 1983 .one("load", function() { 1984 var sizes; 1985 1986 if (!slide.$ghost) { 1987 self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight); 1988 1989 self.afterLoad(slide); 1990 } 1991 1992 // Clear timeout that checks if loading icon needs to be displayed 1993 if (slide.timouts) { 1994 clearTimeout(slide.timouts); 1995 slide.timouts = null; 1996 } 1997 1998 if (self.isClosing) { 1999 return; 2000 } 2001 2002 if (slide.opts.srcset) { 2003 sizes = slide.opts.sizes; 2004 2005 if (!sizes || sizes === "auto") { 2006 sizes = 2007 (slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round(slide.width / slide.height * 100)) + 2008 "vw"; 2009 } 2010 2011 $img.attr("sizes", sizes).attr("srcset", slide.opts.srcset); 2012 } 2013 2014 // Hide temporary image after some delay 2015 if (slide.$ghost) { 2016 setTimeout(function() { 2017 if (slide.$ghost && !self.isClosing) { 2018 slide.$ghost.hide(); 2019 } 2020 }, Math.min(300, Math.max(1000, slide.height / 1600))); 2021 } 2022 2023 self.hideLoading(slide); 2024 }) 2025 .addClass("fancybox-image") 2026 .attr("src", slide.src) 2027 .appendTo(slide.$content); 2028 2029 if (($img[0].complete || $img[0].readyState == "complete") && $img[0].naturalWidth && $img[0].naturalHeight) { 2030 $img.trigger("load"); 2031 } else if ($img[0].error) { 2032 $img.trigger("error"); 2033 } 2034 }, 2035 2036 // Computes the slide size from image size and maxWidth/maxHeight 2037 // ============================================================== 2038 2039 resolveImageSlideSize: function(slide, imgWidth, imgHeight) { 2040 var maxWidth = parseInt(slide.opts.width, 10), 2041 maxHeight = parseInt(slide.opts.height, 10); 2042 2043 // Sets the default values from the image 2044 slide.width = imgWidth; 2045 slide.height = imgHeight; 2046 2047 if (maxWidth > 0) { 2048 slide.width = maxWidth; 2049 slide.height = Math.floor(maxWidth * imgHeight / imgWidth); 2050 } 2051 2052 if (maxHeight > 0) { 2053 slide.width = Math.floor(maxHeight * imgWidth / imgHeight); 2054 slide.height = maxHeight; 2055 } 2056 }, 2057 2058 // Create iframe wrapper, iframe and bindings 2059 // ========================================== 2060 2061 setIframe: function(slide) { 2062 var self = this, 2063 opts = slide.opts.iframe, 2064 $slide = slide.$slide, 2065 $iframe; 2066 2067 slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>') 2068 .css(opts.css) 2069 .appendTo($slide); 2070 2071 $slide.addClass("fancybox-slide--" + slide.contentType); 2072 2073 slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime())) 2074 .attr(opts.attr) 2075 .appendTo(slide.$content); 2076 2077 if (opts.preload) { 2078 self.showLoading(slide); 2079 2080 // Unfortunately, it is not always possible to determine if iframe is successfully loaded 2081 // (due to browser security policy) 2082 2083 $iframe.on("load.fb error.fb", function(e) { 2084 this.isReady = 1; 2085 2086 slide.$slide.trigger("refresh"); 2087 2088 self.afterLoad(slide); 2089 }); 2090 2091 // Recalculate iframe content size 2092 // =============================== 2093 2094 $slide.on("refresh.fb", function() { 2095 var $content = slide.$content, 2096 frameWidth = opts.css.width, 2097 frameHeight = opts.css.height, 2098 $contents, 2099 $body; 2100 2101 if ($iframe[0].isReady !== 1) { 2102 return; 2103 } 2104 2105 try { 2106 $contents = $iframe.contents(); 2107 $body = $contents.find("body"); 2108 } catch (ignore) {} 2109 2110 // Calculate contnet dimensions if it is accessible 2111 if ($body && $body.length && $body.children().length) { 2112 $content.css({ 2113 width: "", 2114 height: "" 2115 }); 2116 2117 if (frameWidth === undefined) { 2118 frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true))); 2119 } 2120 2121 if (frameWidth) { 2122 $content.width(frameWidth); 2123 } 2124 2125 if (frameHeight === undefined) { 2126 frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true))); 2127 } 2128 2129 if (frameHeight) { 2130 $content.height(frameHeight); 2131 } 2132 } 2133 2134 $content.removeClass("fancybox-is-hidden"); 2135 }); 2136 } else { 2137 this.afterLoad(slide); 2138 } 2139 2140 $iframe.attr("src", slide.src); 2141 2142 // Remove iframe if closing or changing gallery item 2143 $slide.one("onReset", function() { 2144 // This helps IE not to throw errors when closing 2145 try { 2146 $(this) 2147 .find("iframe") 2148 .hide() 2149 .unbind() 2150 .attr("src", "//about:blank"); 2151 } catch (ignore) {} 2152 2153 $(this) 2154 .off("refresh.fb") 2155 .empty(); 2156 2157 slide.isLoaded = false; 2158 }); 2159 }, 2160 2161 // Wrap and append content to the slide 2162 // ====================================== 2163 2164 setContent: function(slide, content) { 2165 var self = this; 2166 2167 if (self.isClosing) { 2168 return; 2169 } 2170 2171 self.hideLoading(slide); 2172 2173 if (slide.$content) { 2174 $.fancybox.stop(slide.$content); 2175 } 2176 2177 slide.$slide.empty(); 2178 2179 // If content is a jQuery object, then it will be moved to the slide. 2180 // The placeholder is created so we will know where to put it back. 2181 if (isQuery(content) && content.parent().length) { 2182 // Make sure content is not already moved to fancyBox 2183 content 2184 .parent() 2185 .parent(".fancybox-slide--inline") 2186 .trigger("onReset"); 2187 2188 // Create temporary element marking original place of the content 2189 slide.$placeholder = $("<div>") 2190 .hide() 2191 .insertAfter(content); 2192 2193 // Make sure content is visible 2194 content.css("display", "inline-block"); 2195 } else if (!slide.hasError) { 2196 // If content is just a plain text, try to convert it to html 2197 if ($.type(content) === "string") { 2198 content = $("<div>") 2199 .append($.trim(content)) 2200 .contents(); 2201 2202 // If we have text node, then add wrapping element to make vertical alignment work 2203 if (content[0].nodeType === 3) { 2204 content = $("<div>").html(content); 2205 } 2206 } 2207 2208 // If "filter" option is provided, then filter content 2209 if (slide.opts.filter) { 2210 content = $("<div>") 2211 .html(content) 2212 .find(slide.opts.filter); 2213 } 2214 } 2215 2216 slide.$slide.one("onReset", function() { 2217 // Pause all html5 video/audio 2218 $(this) 2219 .find("video,audio") 2220 .trigger("pause"); 2221 2222 // Put content back 2223 if (slide.$placeholder) { 2224 slide.$placeholder.after(content.hide()).remove(); 2225 2226 slide.$placeholder = null; 2227 } 2228 2229 // Remove custom close button 2230 if (slide.$smallBtn) { 2231 slide.$smallBtn.remove(); 2232 2233 slide.$smallBtn = null; 2234 } 2235 2236 // Remove content and mark slide as not loaded 2237 if (!slide.hasError) { 2238 $(this).empty(); 2239 2240 slide.isLoaded = false; 2241 } 2242 }); 2243 2244 $(content).appendTo(slide.$slide); 2245 2246 if ($(content).is("video,audio")) { 2247 $(content).addClass("fancybox-video"); 2248 2249 $(content).wrap("<div></div>"); 2250 2251 slide.contentType = "video"; 2252 2253 slide.opts.width = slide.opts.width || $(content).attr("width"); 2254 slide.opts.height = slide.opts.height || $(content).attr("height"); 2255 } 2256 2257 slide.$content = slide.$slide 2258 .children() 2259 .filter("div,form,main,video,audio") 2260 .first() 2261 .addClass("fancybox-content"); 2262 2263 slide.$slide.addClass("fancybox-slide--" + slide.contentType); 2264 2265 this.afterLoad(slide); 2266 }, 2267 2268 // Display error message 2269 // ===================== 2270 2271 setError: function(slide) { 2272 slide.hasError = true; 2273 2274 slide.$slide 2275 .trigger("onReset") 2276 .removeClass("fancybox-slide--" + slide.contentType) 2277 .addClass("fancybox-slide--error"); 2278 2279 slide.contentType = "html"; 2280 2281 this.setContent(slide, this.translate(slide, slide.opts.errorTpl)); 2282 2283 if (slide.pos === this.currPos) { 2284 this.isAnimating = false; 2285 } 2286 }, 2287 2288 // Show loading icon inside the slide 2289 // ================================== 2290 2291 showLoading: function(slide) { 2292 var self = this; 2293 2294 slide = slide || self.current; 2295 2296 if (slide && !slide.$spinner) { 2297 slide.$spinner = $(self.translate(self, self.opts.spinnerTpl)).appendTo(slide.$slide); 2298 } 2299 }, 2300 2301 // Remove loading icon from the slide 2302 // ================================== 2303 2304 hideLoading: function(slide) { 2305 var self = this; 2306 2307 slide = slide || self.current; 2308 2309 if (slide && slide.$spinner) { 2310 slide.$spinner.remove(); 2311 2312 delete slide.$spinner; 2313 } 2314 }, 2315 2316 // Adjustments after slide content has been loaded 2317 // =============================================== 2318 2319 afterLoad: function(slide) { 2320 var self = this; 2321 2322 if (self.isClosing) { 2323 return; 2324 } 2325 2326 slide.isLoading = false; 2327 slide.isLoaded = true; 2328 2329 self.trigger("afterLoad", slide); 2330 2331 self.hideLoading(slide); 2332 2333 if (slide.pos === self.currPos) { 2334 self.updateCursor(); 2335 } 2336 2337 if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) { 2338 slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).prependTo(slide.$content); 2339 } 2340 2341 if (slide.opts.protect && slide.$content && !slide.hasError) { 2342 // Disable right click 2343 slide.$content.on("contextmenu.fb", function(e) { 2344 if (e.button == 2) { 2345 e.preventDefault(); 2346 } 2347 2348 return true; 2349 }); 2350 2351 // Add fake element on top of the image 2352 // This makes a bit harder for user to select image 2353 if (slide.type === "image") { 2354 $('<div class="fancybox-spaceball"></div>').appendTo(slide.$content); 2355 } 2356 } 2357 2358 self.revealContent(slide); 2359 }, 2360 2361 // Make content visible 2362 // This method is called right after content has been loaded or 2363 // user navigates gallery and transition should start 2364 // ============================================================ 2365 2366 revealContent: function(slide) { 2367 var self = this, 2368 $slide = slide.$slide, 2369 end = false, 2370 start = false, 2371 effect, 2372 effectClassName, 2373 duration, 2374 opacity; 2375 2376 effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"]; 2377 duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"]; 2378 2379 duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10); 2380 2381 // Do not animate if revealing the same slide 2382 if (slide.pos === self.currPos) { 2383 if (slide.isComplete) { 2384 effect = false; 2385 } else { 2386 self.isAnimating = true; 2387 } 2388 } 2389 2390 if (slide.isMoved || slide.pos !== self.currPos || !duration) { 2391 effect = false; 2392 } 2393 2394 // Check if can zoom 2395 if (effect === "zoom") { 2396 if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) { 2397 end = self.getFitPos(slide); 2398 } else { 2399 effect = "fade"; 2400 } 2401 } 2402 2403 // Zoom animation 2404 // ============== 2405 if (effect === "zoom") { 2406 end.scaleX = end.width / start.width; 2407 end.scaleY = end.height / start.height; 2408 2409 // Check if we need to animate opacity 2410 opacity = slide.opts.zoomOpacity; 2411 2412 if (opacity == "auto") { 2413 opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1; 2414 } 2415 2416 if (opacity) { 2417 start.opacity = 0.1; 2418 end.opacity = 1; 2419 } 2420 2421 // Draw image at start position 2422 $.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start); 2423 2424 forceRedraw(slide.$content); 2425 2426 // Start animation 2427 $.fancybox.animate(slide.$content, end, duration, function() { 2428 self.isAnimating = false; 2429 2430 self.complete(); 2431 }); 2432 2433 return; 2434 } 2435 2436 self.updateSlide(slide); 2437 2438 // Simply show content 2439 // =================== 2440 2441 if (!effect) { 2442 forceRedraw($slide); 2443 2444 slide.$content.removeClass("fancybox-is-hidden"); 2445 2446 if (slide.pos === self.currPos) { 2447 self.complete(); 2448 } 2449 2450 return; 2451 } 2452 2453 $.fancybox.stop($slide); 2454 2455 effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect; 2456 2457 $slide 2458 .removeAttr("style") 2459 .removeClass("fancybox-slide--current fancybox-slide--next fancybox-slide--previous") 2460 .addClass(effectClassName); 2461 2462 slide.$content.removeClass("fancybox-is-hidden"); 2463 2464 // Force reflow for CSS3 transitions 2465 forceRedraw($slide); 2466 2467 $.fancybox.animate( 2468 $slide, 2469 "fancybox-slide--current", 2470 duration, 2471 function(e) { 2472 $slide.removeClass(effectClassName).removeAttr("style"); 2473 2474 if (slide.pos === self.currPos) { 2475 self.complete(); 2476 } 2477 }, 2478 true 2479 ); 2480 }, 2481 2482 // Check if we can and have to zoom from thumbnail 2483 //================================================ 2484 2485 getThumbPos: function(slide) { 2486 var self = this, 2487 rez = false, 2488 $thumb = slide.opts.$thumb, 2489 thumbPos = $thumb && $thumb.length && $thumb[0].ownerDocument === document ? $thumb.offset() : 0, 2490 slidePos; 2491 2492 // Check if element is inside the viewport by at least 1 pixel 2493 var isElementVisible = function($el) { 2494 var element = $el[0], 2495 elementRect = element.getBoundingClientRect(), 2496 parentRects = [], 2497 visibleInAllParents; 2498 2499 while (element.parentElement !== null) { 2500 if ($(element.parentElement).css("overflow") === "hidden" || $(element.parentElement).css("overflow") === "auto") { 2501 parentRects.push(element.parentElement.getBoundingClientRect()); 2502 } 2503 2504 element = element.parentElement; 2505 } 2506 2507 visibleInAllParents = parentRects.every(function(parentRect) { 2508 var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left); 2509 var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top); 2510 2511 return visiblePixelX > 0 && visiblePixelY > 0; 2512 }); 2513 2514 return ( 2515 visibleInAllParents && 2516 elementRect.bottom > 0 && 2517 elementRect.right > 0 && 2518 elementRect.left < $(window).width() && 2519 elementRect.top < $(window).height() 2520 ); 2521 }; 2522 2523 if (thumbPos && isElementVisible($thumb)) { 2524 slidePos = self.$refs.stage.offset(); 2525 2526 rez = { 2527 top: thumbPos.top - slidePos.top + parseFloat($thumb.css("border-top-width") || 0), 2528 left: thumbPos.left - slidePos.left + parseFloat($thumb.css("border-left-width") || 0), 2529 width: $thumb.width(), 2530 height: $thumb.height(), 2531 scaleX: 1, 2532 scaleY: 1 2533 }; 2534 } 2535 2536 return rez; 2537 }, 2538 2539 // Final adjustments after current gallery item is moved to position 2540 // and it`s content is loaded 2541 // ================================================================== 2542 2543 complete: function() { 2544 var self = this, 2545 current = self.current, 2546 slides = {}; 2547 2548 if (current.isMoved || !current.isLoaded) { 2549 return; 2550 } 2551 2552 if (!current.isComplete) { 2553 current.isComplete = true; 2554 2555 current.$slide.siblings().trigger("onReset"); 2556 2557 self.preload("inline"); 2558 2559 // Trigger any CSS3 transiton inside the slide 2560 forceRedraw(current.$slide); 2561 2562 current.$slide.addClass("fancybox-slide--complete"); 2563 2564 // Remove unnecessary slides 2565 $.each(self.slides, function(key, slide) { 2566 if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) { 2567 slides[slide.pos] = slide; 2568 } else if (slide) { 2569 $.fancybox.stop(slide.$slide); 2570 2571 slide.$slide.off().remove(); 2572 } 2573 }); 2574 2575 self.slides = slides; 2576 } 2577 2578 self.isAnimating = false; 2579 2580 self.updateCursor(); 2581 2582 self.trigger("afterShow"); 2583 2584 // Play first html5 video/audio 2585 current.$slide 2586 .find("video,audio") 2587 .filter(":visible:first") 2588 .trigger("play"); 2589 2590 // Try to focus on the first focusable element 2591 if ( 2592 $(document.activeElement).is("[disabled]") || 2593 (current.opts.autoFocus && !(current.type == "image" || current.type === "iframe")) 2594 ) { 2595 self.focus(); 2596 } 2597 }, 2598 2599 // Preload next and previous slides 2600 // ================================ 2601 2602 preload: function(type) { 2603 var self = this, 2604 next = self.slides[self.currPos + 1], 2605 prev = self.slides[self.currPos - 1]; 2606 2607 if (next && next.type === type) { 2608 self.loadSlide(next); 2609 } 2610 2611 if (prev && prev.type === type) { 2612 self.loadSlide(prev); 2613 } 2614 }, 2615 2616 // Try to find and focus on the first focusable element 2617 // ==================================================== 2618 2619 focus: function() { 2620 var current = this.current, 2621 $el; 2622 2623 if (this.isClosing) { 2624 return; 2625 } 2626 2627 if (current && current.isComplete && current.$content) { 2628 // Look for first input with autofocus attribute 2629 $el = current.$content.find("input[autofocus]:enabled:visible:first"); 2630 2631 if (!$el.length) { 2632 $el = current.$content.find("button,:input,[tabindex],a").filter(":enabled:visible:first"); 2633 } 2634 2635 $el = $el && $el.length ? $el : current.$content; 2636 2637 $el.trigger("focus"); 2638 } 2639 }, 2640 2641 // Activates current instance - brings container to the front and enables keyboard, 2642 // notifies other instances about deactivating 2643 // ================================================================================= 2644 2645 activate: function() { 2646 var self = this; 2647 2648 // Deactivate all instances 2649 $(".fancybox-container").each(function() { 2650 var instance = $(this).data("FancyBox"); 2651 2652 // Skip self and closing instances 2653 if (instance && instance.id !== self.id && !instance.isClosing) { 2654 instance.trigger("onDeactivate"); 2655 2656 instance.removeEvents(); 2657 2658 instance.isVisible = false; 2659 } 2660 }); 2661 2662 self.isVisible = true; 2663 2664 if (self.current || self.isIdle) { 2665 self.update(); 2666 2667 self.updateControls(); 2668 } 2669 2670 self.trigger("onActivate"); 2671 2672 self.addEvents(); 2673 }, 2674 2675 // Start closing procedure 2676 // This will start "zoom-out" animation if needed and clean everything up afterwards 2677 // ================================================================================= 2678 2679 close: function(e, d) { 2680 var self = this, 2681 current = self.current, 2682 effect, 2683 duration, 2684 $content, 2685 domRect, 2686 opacity, 2687 start, 2688 end; 2689 2690 var done = function() { 2691 self.cleanUp(e); 2692 }; 2693 2694 if (self.isClosing) { 2695 return false; 2696 } 2697 2698 self.isClosing = true; 2699 2700 // If beforeClose callback prevents closing, make sure content is centered 2701 if (self.trigger("beforeClose", e) === false) { 2702 self.isClosing = false; 2703 2704 requestAFrame(function() { 2705 self.update(); 2706 }); 2707 2708 return false; 2709 } 2710 2711 // Remove all events 2712 // If there are multiple instances, they will be set again by "activate" method 2713 self.removeEvents(); 2714 2715 if (current.timouts) { 2716 clearTimeout(current.timouts); 2717 } 2718 2719 $content = current.$content; 2720 effect = current.opts.animationEffect; 2721 duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0; 2722 2723 // Remove other slides 2724 current.$slide 2725 .off(transitionEnd) 2726 .removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated"); 2727 2728 current.$slide 2729 .siblings() 2730 .trigger("onReset") 2731 .remove(); 2732 2733 // Trigger animations 2734 if (duration) { 2735 self.$refs.container.removeClass("fancybox-is-open").addClass("fancybox-is-closing"); 2736 } 2737 2738 // Clean up 2739 self.hideLoading(current); 2740 2741 self.hideControls(); 2742 2743 self.updateCursor(); 2744 2745 // Check if possible to zoom-out 2746 if ( 2747 effect === "zoom" && 2748 !(e !== true && $content && duration && current.type === "image" && !current.hasError && (end = self.getThumbPos(current))) 2749 ) { 2750 effect = "fade"; 2751 } 2752 2753 if (effect === "zoom") { 2754 $.fancybox.stop($content); 2755 2756 domRect = $.fancybox.getTranslate($content); 2757 2758 start = { 2759 top: domRect.top, 2760 left: domRect.left, 2761 scaleX: domRect.width / end.width, 2762 scaleY: domRect.height / end.height, 2763 width: end.width, 2764 height: end.height 2765 }; 2766 2767 // Check if we need to animate opacity 2768 opacity = current.opts.zoomOpacity; 2769 2770 if (opacity == "auto") { 2771 opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1; 2772 } 2773 2774 if (opacity) { 2775 end.opacity = 0; 2776 } 2777 2778 $.fancybox.setTranslate($content, start); 2779 2780 forceRedraw($content); 2781 2782 $.fancybox.animate($content, end, duration, done); 2783 2784 return true; 2785 } 2786 2787 if (effect && duration) { 2788 // If skip animation 2789 if (e === true) { 2790 setTimeout(done, duration); 2791 } else { 2792 $.fancybox.animate( 2793 current.$slide.removeClass("fancybox-slide--current"), 2794 "fancybox-animated fancybox-slide--previous fancybox-fx-" + effect, 2795 duration, 2796 done 2797 ); 2798 } 2799 } else { 2800 done(); 2801 } 2802 2803 return true; 2804 }, 2805 2806 // Final adjustments after removing the instance 2807 // ============================================= 2808 2809 cleanUp: function(e) { 2810 var self = this, 2811 $body = $("body"), 2812 instance, 2813 scrollTop; 2814 2815 self.current.$slide.trigger("onReset"); 2816 2817 self.$refs.container.empty().remove(); 2818 2819 self.trigger("afterClose", e); 2820 2821 // Place back focus 2822 if (self.$lastFocus && !!self.current.opts.backFocus) { 2823 self.$lastFocus.trigger("focus"); 2824 } 2825 2826 self.current = null; 2827 2828 // Check if there are other instances 2829 instance = $.fancybox.getInstance(); 2830 2831 if (instance) { 2832 instance.activate(); 2833 } else { 2834 $body.removeClass("fancybox-active compensate-for-scrollbar"); 2835 2836 $("#fancybox-style-noscroll").remove(); 2837 } 2838 }, 2839 2840 // Call callback and trigger an event 2841 // ================================== 2842 2843 trigger: function(name, slide) { 2844 var args = Array.prototype.slice.call(arguments, 1), 2845 self = this, 2846 obj = slide && slide.opts ? slide : self.current, 2847 rez; 2848 2849 if (obj) { 2850 args.unshift(obj); 2851 } else { 2852 obj = self; 2853 } 2854 2855 args.unshift(self); 2856 2857 if ($.isFunction(obj.opts[name])) { 2858 rez = obj.opts[name].apply(obj, args); 2859 } 2860 2861 if (rez === false) { 2862 return rez; 2863 } 2864 2865 if (name === "afterClose" || !self.$refs) { 2866 $D.trigger(name + ".fb", args); 2867 } else { 2868 self.$refs.container.trigger(name + ".fb", args); 2869 } 2870 }, 2871 2872 // Update infobar values, navigation button states and reveal caption 2873 // ================================================================== 2874 2875 updateControls: function(force) { 2876 var self = this, 2877 current = self.current, 2878 index = current.index, 2879 caption = current.opts.caption, 2880 $container = self.$refs.container, 2881 $caption = self.$refs.caption; 2882 2883 // Recalculate content dimensions 2884 current.$slide.trigger("refresh"); 2885 2886 self.$caption = caption && caption.length ? $caption.html(caption) : null; 2887 2888 if (!self.isHiddenControls && !self.isIdle) { 2889 self.showControls(); 2890 } 2891 2892 // Update info and navigation elements 2893 $container.find("[data-fancybox-count]").html(self.group.length); 2894 $container.find("[data-fancybox-index]").html(index + 1); 2895 2896 $container.find("[data-fancybox-prev]").toggleClass("disabled", !current.opts.loop && index <= 0); 2897 $container.find("[data-fancybox-next]").toggleClass("disabled", !current.opts.loop && index >= self.group.length - 1); 2898 2899 if (current.type === "image") { 2900 // Re-enable buttons; update download button source 2901 $container 2902 .find("[data-fancybox-zoom]") 2903 .show() 2904 .end() 2905 .find("[data-fancybox-download]") 2906 .attr("href", current.opts.image.src || current.src) 2907 .show(); 2908 } else if (current.opts.toolbar) { 2909 $container.find("[data-fancybox-download],[data-fancybox-zoom]").hide(); 2910 } 2911 }, 2912 2913 // Hide toolbar and caption 2914 // ======================== 2915 2916 hideControls: function() { 2917 this.isHiddenControls = true; 2918 2919 this.$refs.container.removeClass("fancybox-show-infobar fancybox-show-toolbar fancybox-show-caption fancybox-show-nav"); 2920 }, 2921 2922 showControls: function() { 2923 var self = this, 2924 opts = self.current ? self.current.opts : self.opts, 2925 $container = self.$refs.container; 2926 2927 self.isHiddenControls = false; 2928 self.idleSecondsCounter = 0; 2929 2930 $container 2931 .toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons)) 2932 .toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1)) 2933 .toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1)) 2934 .toggleClass("fancybox-is-modal", !!opts.modal); 2935 2936 if (self.$caption) { 2937 $container.addClass("fancybox-show-caption "); 2938 } else { 2939 $container.removeClass("fancybox-show-caption"); 2940 } 2941 }, 2942 2943 // Toggle toolbar and caption 2944 // ========================== 2945 2946 toggleControls: function() { 2947 if (this.isHiddenControls) { 2948 this.showControls(); 2949 } else { 2950 this.hideControls(); 2951 } 2952 } 2953 }); 2954 2955 $.fancybox = { 2956 version: "3.3.5", 2957 defaults: defaults, 2958 2959 // Get current instance and execute a command. 2960 // 2961 // Examples of usage: 2962 // 2963 // $instance = $.fancybox.getInstance(); 2964 // $.fancybox.getInstance().jumpTo( 1 ); 2965 // $.fancybox.getInstance( 'jumpTo', 1 ); 2966 // $.fancybox.getInstance( function() { 2967 // console.info( this.currIndex ); 2968 // }); 2969 // ====================================================== 2970 2971 getInstance: function(command) { 2972 var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"), 2973 args = Array.prototype.slice.call(arguments, 1); 2974 2975 if (instance instanceof FancyBox) { 2976 if ($.type(command) === "string") { 2977 instance[command].apply(instance, args); 2978 } else if ($.type(command) === "function") { 2979 command.apply(instance, args); 2980 } 2981 2982 return instance; 2983 } 2984 2985 return false; 2986 }, 2987 2988 // Create new instance 2989 // =================== 2990 2991 open: function(items, opts, index) { 2992 return new FancyBox(items, opts, index); 2993 }, 2994 2995 // Close current or all instances 2996 // ============================== 2997 2998 close: function(all) { 2999 var instance = this.getInstance(); 3000 3001 if (instance) { 3002 instance.close(); 3003 3004 // Try to find and close next instance 3005 3006 if (all === true) { 3007 this.close(); 3008 } 3009 } 3010 }, 3011 3012 // Close all instances and unbind all events 3013 // ========================================= 3014 3015 destroy: function() { 3016 this.close(true); 3017 3018 $D.add("body").off("click.fb-start", "**"); 3019 }, 3020 3021 // Try to detect mobile devices 3022 // ============================ 3023 3024 isMobile: 3025 document.createTouch !== undefined && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), 3026 3027 // Detect if 'translate3d' support is available 3028 // ============================================ 3029 3030 use3d: (function() { 3031 var div = document.createElement("div"); 3032 3033 return ( 3034 window.getComputedStyle && 3035 window.getComputedStyle(div) && 3036 window.getComputedStyle(div).getPropertyValue("transform") && 3037 !(document.documentMode && document.documentMode < 11) 3038 ); 3039 })(), 3040 3041 // Helper function to get current visual state of an element 3042 // returns array[ top, left, horizontal-scale, vertical-scale, opacity ] 3043 // ===================================================================== 3044 3045 getTranslate: function($el) { 3046 var domRect; 3047 3048 if (!$el || !$el.length) { 3049 return false; 3050 } 3051 3052 domRect = $el[0].getBoundingClientRect(); 3053 3054 return { 3055 top: domRect.top || 0, 3056 left: domRect.left || 0, 3057 width: domRect.width, 3058 height: domRect.height, 3059 opacity: parseFloat($el.css("opacity")) 3060 }; 3061 }, 3062 3063 // Shortcut for setting "translate3d" properties for element 3064 // Can set be used to set opacity, too 3065 // ======================================================== 3066 3067 setTranslate: function($el, props) { 3068 var str = "", 3069 css = {}; 3070 3071 if (!$el || !props) { 3072 return; 3073 } 3074 3075 if (props.left !== undefined || props.top !== undefined) { 3076 str = 3077 (props.left === undefined ? $el.position().left : props.left) + 3078 "px, " + 3079 (props.top === undefined ? $el.position().top : props.top) + 3080 "px"; 3081 3082 if (this.use3d) { 3083 str = "translate3d(" + str + ", 0px)"; 3084 } else { 3085 str = "translate(" + str + ")"; 3086 } 3087 } 3088 3089 if (props.scaleX !== undefined && props.scaleY !== undefined) { 3090 str = (str.length ? str + " " : "") + "scale(" + props.scaleX + ", " + props.scaleY + ")"; 3091 } 3092 3093 if (str.length) { 3094 css.transform = str; 3095 } 3096 3097 if (props.opacity !== undefined) { 3098 css.opacity = props.opacity; 3099 } 3100 3101 if (props.width !== undefined) { 3102 css.width = props.width; 3103 } 3104 3105 if (props.height !== undefined) { 3106 css.height = props.height; 3107 } 3108 3109 return $el.css(css); 3110 }, 3111 3112 // Simple CSS transition handler 3113 // ============================= 3114 3115 animate: function($el, to, duration, callback, leaveAnimationName) { 3116 var final = false; 3117 3118 if ($.isFunction(duration)) { 3119 callback = duration; 3120 duration = null; 3121 } 3122 3123 if (!$.isPlainObject(to)) { 3124 $el.removeAttr("style"); 3125 } 3126 3127 $.fancybox.stop($el); 3128 3129 $el.on(transitionEnd, function(e) { 3130 // Skip events from child elements and z-index change 3131 if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) { 3132 return; 3133 } 3134 3135 $.fancybox.stop($el); 3136 3137 if (final) { 3138 $.fancybox.setTranslate($el, final); 3139 } 3140 3141 if ($.isPlainObject(to)) { 3142 if (leaveAnimationName === false) { 3143 $el.removeAttr("style"); 3144 } 3145 } else if (leaveAnimationName !== true) { 3146 $el.removeClass(to); 3147 } 3148 3149 if ($.isFunction(callback)) { 3150 callback(e); 3151 } 3152 }); 3153 3154 if ($.isNumeric(duration)) { 3155 $el.css("transition-duration", duration + "ms"); 3156 } 3157 3158 // Start animation by changing CSS properties or class name 3159 if ($.isPlainObject(to)) { 3160 if (to.scaleX !== undefined && to.scaleY !== undefined) { 3161 final = $.extend({}, to, { 3162 width: $el.width() * to.scaleX, 3163 height: $el.height() * to.scaleY, 3164 scaleX: 1, 3165 scaleY: 1 3166 }); 3167 3168 delete to.width; 3169 delete to.height; 3170 3171 if ($el.parent().hasClass("fancybox-slide--image")) { 3172 $el.parent().addClass("fancybox-is-scaling"); 3173 } 3174 } 3175 3176 $.fancybox.setTranslate($el, to); 3177 } else { 3178 $el.addClass(to); 3179 } 3180 3181 // Make sure that `transitionend` callback gets fired 3182 $el.data( 3183 "timer", 3184 setTimeout(function() { 3185 $el.trigger("transitionend"); 3186 }, duration + 16) 3187 ); 3188 }, 3189 3190 stop: function($el) { 3191 if ($el && $el.length) { 3192 clearTimeout($el.data("timer")); 3193 3194 $el.off("transitionend").css("transition-duration", ""); 3195 3196 $el.parent().removeClass("fancybox-is-scaling"); 3197 } 3198 } 3199 }; 3200 3201 // Default click handler for "fancyboxed" links 3202 // ============================================ 3203 3204 function _run(e, opts) { 3205 var items = [], 3206 index = 0, 3207 $target, 3208 value; 3209 3210 // Avoid opening multiple times 3211 if (e && e.isDefaultPrevented()) { 3212 return; 3213 } 3214 3215 e.preventDefault(); 3216 3217 opts = e && e.data ? e.data.options : opts || {}; 3218 3219 $target = opts.$target || $(e.currentTarget); 3220 value = $target.attr("data-fancybox") || ""; 3221 3222 // Get all related items and find index for clicked one 3223 if (value) { 3224 items = opts.selector ? $(opts.selector) : e.data ? e.data.items : []; 3225 items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]'); 3226 3227 index = items.index($target); 3228 3229 // Sometimes current item can not be found (for example, if some script clones items) 3230 if (index < 0) { 3231 index = 0; 3232 } 3233 } else { 3234 items = [$target]; 3235 } 3236 3237 $.fancybox.open(items, opts, index); 3238 } 3239 3240 // Create a jQuery plugin 3241 // ====================== 3242 3243 $.fn.fancybox = function(options) { 3244 var selector; 3245 3246 options = options || {}; 3247 selector = options.selector || false; 3248 3249 if (selector) { 3250 // Use body element instead of document so it executes first 3251 $("body") 3252 .off("click.fb-start", selector) 3253 .on("click.fb-start", selector, {options: options}, _run); 3254 } else { 3255 this.off("click.fb-start").on( 3256 "click.fb-start", 3257 { 3258 items: this, 3259 options: options 3260 }, 3261 _run 3262 ); 3263 } 3264 3265 return this; 3266 }; 3267 3268 // Self initializing plugin for all elements having `data-fancybox` attribute 3269 // ========================================================================== 3270 3271 $D.on("click.fb-start", "[data-fancybox]", _run); 3272 3273 // Enable "trigger elements" 3274 // ========================= 3275 3276 $D.on("click.fb-start", "[data-trigger]", function(e) { 3277 _run(e, { 3278 $target: $('[data-fancybox="' + $(e.currentTarget).attr("data-trigger") + '"]').eq($(e.currentTarget).attr("data-index") || 0), 3279 $trigger: $(this) 3280 }); 3281 }); 3282})(window, document, window.jQuery || jQuery); 3283 3284// ========================================================================== 3285// 3286// Media 3287// Adds additional media type support 3288// 3289// ========================================================================== 3290(function($) { 3291 "use strict"; 3292 3293 // Formats matching url to final form 3294 3295 var format = function(url, rez, params) { 3296 if (!url) { 3297 return; 3298 } 3299 3300 params = params || ""; 3301 3302 if ($.type(params) === "object") { 3303 params = $.param(params, true); 3304 } 3305 3306 $.each(rez, function(key, value) { 3307 url = url.replace("$" + key, value || ""); 3308 }); 3309 3310 if (params.length) { 3311 url += (url.indexOf("?") > 0 ? "&" : "?") + params; 3312 } 3313 3314 return url; 3315 }; 3316 3317 // Object containing properties for each media type 3318 3319 var defaults = { 3320 youtube: { 3321 matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i, 3322 params: { 3323 autoplay: 1, 3324 autohide: 1, 3325 fs: 1, 3326 rel: 0, 3327 hd: 1, 3328 wmode: "transparent", 3329 enablejsapi: 1, 3330 html5: 1 3331 }, 3332 paramPlace: 8, 3333 type: "iframe", 3334 url: "//www.youtube.com/embed/$4", 3335 thumb: "//img.youtube.com/vi/$4/hqdefault.jpg" 3336 }, 3337 3338 vimeo: { 3339 matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/, 3340 params: { 3341 autoplay: 1, 3342 hd: 1, 3343 show_title: 1, 3344 show_byline: 1, 3345 show_portrait: 0, 3346 fullscreen: 1, 3347 api: 1 3348 }, 3349 paramPlace: 3, 3350 type: "iframe", 3351 url: "//player.vimeo.com/video/$2" 3352 }, 3353 3354 instagram: { 3355 matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, 3356 type: "image", 3357 url: "//$1/p/$2/media/?size=l" 3358 }, 3359 3360 // Examples: 3361 // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 3362 // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z 3363 // https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en 3364 // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572 3365 gmap_place: { 3366 matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i, 3367 type: "iframe", 3368 url: function(rez) { 3369 return ( 3370 "//maps.google." + 3371 rez[2] + 3372 "/?ll=" + 3373 (rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") + 3374 "&output=" + 3375 (rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed") 3376 ); 3377 } 3378 }, 3379 3380 // Examples: 3381 // https://www.google.com/maps/search/Empire+State+Building/ 3382 // https://www.google.com/maps/search/?api=1&query=centurylink+field 3383 // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393 3384 gmap_search: { 3385 matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i, 3386 type: "iframe", 3387 url: function(rez) { 3388 return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed"; 3389 } 3390 } 3391 }; 3392 3393 $(document).on("objectNeedsType.fb", function(e, instance, item) { 3394 var url = item.src || "", 3395 type = false, 3396 media, 3397 thumb, 3398 rez, 3399 params, 3400 urlParams, 3401 paramObj, 3402 provider; 3403 3404 media = $.extend(true, {}, defaults, item.opts.media); 3405 3406 // Look for any matching media type 3407 $.each(media, function(providerName, providerOpts) { 3408 rez = url.match(providerOpts.matcher); 3409 3410 if (!rez) { 3411 return; 3412 } 3413 3414 type = providerOpts.type; 3415 provider = providerName; 3416 paramObj = {}; 3417 3418 if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) { 3419 urlParams = rez[providerOpts.paramPlace]; 3420 3421 if (urlParams[0] == "?") { 3422 urlParams = urlParams.substring(1); 3423 } 3424 3425 urlParams = urlParams.split("&"); 3426 3427 for (var m = 0; m < urlParams.length; ++m) { 3428 var p = urlParams[m].split("=", 2); 3429 3430 if (p.length == 2) { 3431 paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " ")); 3432 } 3433 } 3434 } 3435 3436 params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj); 3437 3438 url = 3439 $.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params); 3440 3441 thumb = 3442 $.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez); 3443 3444 if (providerName === "youtube") { 3445 url = url.replace(/&t=((\d+)m)?(\d+)s/, function(match, p1, m, s) { 3446 return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10)); 3447 }); 3448 } else if (providerName === "vimeo") { 3449 url = url.replace("&%23", "#"); 3450 } 3451 3452 return false; 3453 }); 3454 3455 // If it is found, then change content type and update the url 3456 3457 if (type) { 3458 if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) { 3459 item.opts.thumb = thumb; 3460 } 3461 3462 if (type === "iframe") { 3463 item.opts = $.extend(true, item.opts, { 3464 iframe: { 3465 preload: false, 3466 attr: { 3467 scrolling: "no" 3468 } 3469 } 3470 }); 3471 } 3472 3473 $.extend(item, { 3474 type: type, 3475 src: url, 3476 origSrc: item.src, 3477 contentSource: provider, 3478 contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video" 3479 }); 3480 } else if (url) { 3481 item.type = item.opts.defaultType; 3482 } 3483 }); 3484})(window.jQuery || jQuery); 3485 3486// ========================================================================== 3487// 3488// Guestures 3489// Adds touch guestures, handles click and tap events 3490// 3491// ========================================================================== 3492(function(window, document, $) { 3493 "use strict"; 3494 3495 var requestAFrame = (function() { 3496 return ( 3497 window.requestAnimationFrame || 3498 window.webkitRequestAnimationFrame || 3499 window.mozRequestAnimationFrame || 3500 window.oRequestAnimationFrame || 3501 // if all else fails, use setTimeout 3502 function(callback) { 3503 return window.setTimeout(callback, 1000 / 60); 3504 } 3505 ); 3506 })(); 3507 3508 var cancelAFrame = (function() { 3509 return ( 3510 window.cancelAnimationFrame || 3511 window.webkitCancelAnimationFrame || 3512 window.mozCancelAnimationFrame || 3513 window.oCancelAnimationFrame || 3514 function(id) { 3515 window.clearTimeout(id); 3516 } 3517 ); 3518 })(); 3519 3520 var getPointerXY = function(e) { 3521 var result = []; 3522 3523 e = e.originalEvent || e || window.e; 3524 e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e]; 3525 3526 for (var key in e) { 3527 if (e[key].pageX) { 3528 result.push({ 3529 x: e[key].pageX, 3530 y: e[key].pageY 3531 }); 3532 } else if (e[key].clientX) { 3533 result.push({ 3534 x: e[key].clientX, 3535 y: e[key].clientY 3536 }); 3537 } 3538 } 3539 3540 return result; 3541 }; 3542 3543 var distance = function(point2, point1, what) { 3544 if (!point1 || !point2) { 3545 return 0; 3546 } 3547 3548 if (what === "x") { 3549 return point2.x - point1.x; 3550 } else if (what === "y") { 3551 return point2.y - point1.y; 3552 } 3553 3554 return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)); 3555 }; 3556 3557 var isClickable = function($el) { 3558 if ( 3559 $el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio') || 3560 $.isFunction($el.get(0).onclick) || 3561 $el.data("selectable") 3562 ) { 3563 return true; 3564 } 3565 3566 // Check for attributes like data-fancybox-next or data-fancybox-close 3567 for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) { 3568 if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") { 3569 return true; 3570 } 3571 } 3572 3573 return false; 3574 }; 3575 3576 var hasScrollbars = function(el) { 3577 var overflowY = window.getComputedStyle(el)["overflow-y"], 3578 overflowX = window.getComputedStyle(el)["overflow-x"], 3579 vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight, 3580 horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth; 3581 3582 return vertical || horizontal; 3583 }; 3584 3585 var isScrollable = function($el) { 3586 var rez = false; 3587 3588 while (true) { 3589 rez = hasScrollbars($el.get(0)); 3590 3591 if (rez) { 3592 break; 3593 } 3594 3595 $el = $el.parent(); 3596 3597 if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) { 3598 break; 3599 } 3600 } 3601 3602 return rez; 3603 }; 3604 3605 var Guestures = function(instance) { 3606 var self = this; 3607 3608 self.instance = instance; 3609 3610 self.$bg = instance.$refs.bg; 3611 self.$stage = instance.$refs.stage; 3612 self.$container = instance.$refs.container; 3613 3614 self.destroy(); 3615 3616 self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart")); 3617 }; 3618 3619 Guestures.prototype.destroy = function() { 3620 this.$container.off(".fb.touch"); 3621 }; 3622 3623 Guestures.prototype.ontouchstart = function(e) { 3624 var self = this, 3625 $target = $(e.target), 3626 instance = self.instance, 3627 current = instance.current, 3628 $content = current.$content, 3629 isTouchDevice = e.type == "touchstart"; 3630 3631 // Do not respond to both (touch and mouse) events 3632 if (isTouchDevice) { 3633 self.$container.off("mousedown.fb.touch"); 3634 } 3635 3636 // Ignore right click 3637 if (e.originalEvent && e.originalEvent.button == 2) { 3638 return; 3639 } 3640 3641 // Ignore taping on links, buttons, input elements 3642 if (!$target.length || isClickable($target) || isClickable($target.parent())) { 3643 return; 3644 } 3645 3646 // Ignore clicks on the scrollbar 3647 if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) { 3648 return; 3649 } 3650 3651 // Ignore clicks while zooming or closing 3652 if (!current || instance.isAnimating || instance.isClosing) { 3653 e.stopPropagation(); 3654 e.preventDefault(); 3655 3656 return; 3657 } 3658 3659 self.realPoints = self.startPoints = getPointerXY(e); 3660 3661 if (!self.startPoints.length) { 3662 return; 3663 } 3664 3665 e.stopPropagation(); 3666 3667 self.startEvent = e; 3668 3669 self.canTap = true; 3670 self.$target = $target; 3671 self.$content = $content; 3672 self.opts = current.opts.touch; 3673 3674 self.isPanning = false; 3675 self.isSwiping = false; 3676 self.isZooming = false; 3677 self.isScrolling = false; 3678 3679 self.startTime = new Date().getTime(); 3680 self.distanceX = self.distanceY = self.distance = 0; 3681 3682 self.canvasWidth = Math.round(current.$slide[0].clientWidth); 3683 self.canvasHeight = Math.round(current.$slide[0].clientHeight); 3684 3685 self.contentLastPos = null; 3686 self.contentStartPos = $.fancybox.getTranslate(self.$content) || {top: 0, left: 0}; 3687 self.sliderStartPos = self.sliderLastPos || $.fancybox.getTranslate(current.$slide); 3688 3689 // Since position will be absolute, but we need to make it relative to the stage 3690 self.stagePos = $.fancybox.getTranslate(instance.$refs.stage); 3691 3692 self.sliderStartPos.top -= self.stagePos.top; 3693 self.sliderStartPos.left -= self.stagePos.left; 3694 3695 self.contentStartPos.top -= self.stagePos.top; 3696 self.contentStartPos.left -= self.stagePos.left; 3697 3698 $(document) 3699 .off(".fb.touch") 3700 .on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend")) 3701 .on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove")); 3702 3703 if ($.fancybox.isMobile) { 3704 document.addEventListener("scroll", self.onscroll, true); 3705 } 3706 3707 if (!(self.opts || instance.canPan()) || !($target.is(self.$stage) || self.$stage.find($target).length)) { 3708 if ($target.is(".fancybox-image")) { 3709 e.preventDefault(); 3710 } 3711 3712 return; 3713 } 3714 3715 if (!($.fancybox.isMobile && (isScrollable($target) || isScrollable($target.parent())))) { 3716 e.preventDefault(); 3717 } 3718 3719 if (self.startPoints.length === 1 || current.hasError) { 3720 if (self.instance.canPan()) { 3721 $.fancybox.stop(self.$content); 3722 3723 self.$content.css("transition-duration", ""); 3724 3725 self.isPanning = true; 3726 } else { 3727 self.isSwiping = true; 3728 } 3729 3730 self.$container.addClass("fancybox-controls--isGrabbing"); 3731 } 3732 3733 if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) { 3734 self.canTap = false; 3735 self.isSwiping = false; 3736 self.isPanning = false; 3737 3738 self.isZooming = true; 3739 3740 $.fancybox.stop(self.$content); 3741 3742 self.$content.css("transition-duration", ""); 3743 3744 self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft(); 3745 self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop(); 3746 3747 self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width; 3748 self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height; 3749 3750 self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]); 3751 } 3752 }; 3753 3754 Guestures.prototype.onscroll = function(e) { 3755 var self = this; 3756 3757 self.isScrolling = true; 3758 3759 document.removeEventListener("scroll", self.onscroll, true); 3760 }; 3761 3762 Guestures.prototype.ontouchmove = function(e) { 3763 var self = this, 3764 $target = $(e.target); 3765 3766 // Make sure user has not released over iframe or disabled element 3767 if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) { 3768 self.ontouchend(e); 3769 return; 3770 } 3771 3772 if (self.isScrolling || !($target.is(self.$stage) || self.$stage.find($target).length)) { 3773 self.canTap = false; 3774 3775 return; 3776 } 3777 3778 self.newPoints = getPointerXY(e); 3779 3780 if (!(self.opts || self.instance.canPan()) || !self.newPoints.length || !self.newPoints.length) { 3781 return; 3782 } 3783 3784 if (!(self.isSwiping && self.isSwiping === true)) { 3785 e.preventDefault(); 3786 } 3787 3788 self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x"); 3789 self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y"); 3790 3791 self.distance = distance(self.newPoints[0], self.startPoints[0]); 3792 3793 // Skip false ontouchmove events (Chrome) 3794 if (self.distance > 0) { 3795 if (self.isSwiping) { 3796 self.onSwipe(e); 3797 } else if (self.isPanning) { 3798 self.onPan(); 3799 } else if (self.isZooming) { 3800 self.onZoom(); 3801 } 3802 } 3803 }; 3804 3805 Guestures.prototype.onSwipe = function(e) { 3806 var self = this, 3807 swiping = self.isSwiping, 3808 left = self.sliderStartPos.left || 0, 3809 angle; 3810 3811 // If direction is not yet determined 3812 if (swiping === true) { 3813 // We need at least 10px distance to correctly calculate an angle 3814 if (Math.abs(self.distance) > 10) { 3815 self.canTap = false; 3816 3817 if (self.instance.group.length < 2 && self.opts.vertical) { 3818 self.isSwiping = "y"; 3819 } else if (self.instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) { 3820 self.isSwiping = "x"; 3821 } else { 3822 angle = Math.abs(Math.atan2(self.distanceY, self.distanceX) * 180 / Math.PI); 3823 3824 self.isSwiping = angle > 45 && angle < 135 ? "y" : "x"; 3825 } 3826 3827 self.canTap = false; 3828 3829 if (self.isSwiping === "y" && $.fancybox.isMobile && (isScrollable(self.$target) || isScrollable(self.$target.parent()))) { 3830 self.isScrolling = true; 3831 3832 return; 3833 } 3834 3835 self.instance.isDragging = self.isSwiping; 3836 3837 // Reset points to avoid jumping, because we dropped first swipes to calculate the angle 3838 self.startPoints = self.newPoints; 3839 3840 $.each(self.instance.slides, function(index, slide) { 3841 $.fancybox.stop(slide.$slide); 3842 3843 slide.$slide.css("transition-duration", ""); 3844 3845 slide.inTransition = false; 3846 3847 if (slide.pos === self.instance.current.pos) { 3848 self.sliderStartPos.left = $.fancybox.getTranslate(slide.$slide).left - $.fancybox.getTranslate(self.instance.$refs.stage).left; 3849 } 3850 }); 3851 3852 // Stop slideshow 3853 if (self.instance.SlideShow && self.instance.SlideShow.isActive) { 3854 self.instance.SlideShow.stop(); 3855 } 3856 } 3857 3858 return; 3859 } 3860 3861 // Sticky edges 3862 if (swiping == "x") { 3863 if ( 3864 self.distanceX > 0 && 3865 (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop)) 3866 ) { 3867 left = left + Math.pow(self.distanceX, 0.8); 3868 } else if ( 3869 self.distanceX < 0 && 3870 (self.instance.group.length < 2 || 3871 (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop)) 3872 ) { 3873 left = left - Math.pow(-self.distanceX, 0.8); 3874 } else { 3875 left = left + self.distanceX; 3876 } 3877 } 3878 3879 self.sliderLastPos = { 3880 top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY, 3881 left: left 3882 }; 3883 3884 if (self.requestId) { 3885 cancelAFrame(self.requestId); 3886 3887 self.requestId = null; 3888 } 3889 3890 self.requestId = requestAFrame(function() { 3891 if (self.sliderLastPos) { 3892 $.each(self.instance.slides, function(index, slide) { 3893 var pos = slide.pos - self.instance.currPos; 3894 3895 $.fancybox.setTranslate(slide.$slide, { 3896 top: self.sliderLastPos.top, 3897 left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter 3898 }); 3899 }); 3900 3901 self.$container.addClass("fancybox-is-sliding"); 3902 } 3903 }); 3904 }; 3905 3906 Guestures.prototype.onPan = function() { 3907 var self = this; 3908 3909 // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit) 3910 if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) { 3911 self.startPoints = self.newPoints; 3912 return; 3913 } 3914 3915 self.canTap = false; 3916 3917 self.contentLastPos = self.limitMovement(); 3918 3919 if (self.requestId) { 3920 cancelAFrame(self.requestId); 3921 3922 self.requestId = null; 3923 } 3924 3925 self.requestId = requestAFrame(function() { 3926 $.fancybox.setTranslate(self.$content, self.contentLastPos); 3927 }); 3928 }; 3929 3930 // Make panning sticky to the edges 3931 Guestures.prototype.limitMovement = function() { 3932 var self = this; 3933 3934 var canvasWidth = self.canvasWidth; 3935 var canvasHeight = self.canvasHeight; 3936 3937 var distanceX = self.distanceX; 3938 var distanceY = self.distanceY; 3939 3940 var contentStartPos = self.contentStartPos; 3941 3942 var currentOffsetX = contentStartPos.left; 3943 var currentOffsetY = contentStartPos.top; 3944 3945 var currentWidth = contentStartPos.width; 3946 var currentHeight = contentStartPos.height; 3947 3948 var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY; 3949 3950 if (currentWidth > canvasWidth) { 3951 newOffsetX = currentOffsetX + distanceX; 3952 } else { 3953 newOffsetX = currentOffsetX; 3954 } 3955 3956 newOffsetY = currentOffsetY + distanceY; 3957 3958 // Slow down proportionally to traveled distance 3959 minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5); 3960 minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5); 3961 3962 maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5); 3963 maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5); 3964 3965 // -> 3966 if (distanceX > 0 && newOffsetX > minTranslateX) { 3967 newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0; 3968 } 3969 3970 // <- 3971 if (distanceX < 0 && newOffsetX < maxTranslateX) { 3972 newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0; 3973 } 3974 3975 // \/ 3976 if (distanceY > 0 && newOffsetY > minTranslateY) { 3977 newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0; 3978 } 3979 3980 // /\ 3981 if (distanceY < 0 && newOffsetY < maxTranslateY) { 3982 newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0; 3983 } 3984 3985 return { 3986 top: newOffsetY, 3987 left: newOffsetX 3988 }; 3989 }; 3990 3991 Guestures.prototype.limitPosition = function(newOffsetX, newOffsetY, newWidth, newHeight) { 3992 var self = this; 3993 3994 var canvasWidth = self.canvasWidth; 3995 var canvasHeight = self.canvasHeight; 3996 3997 if (newWidth > canvasWidth) { 3998 newOffsetX = newOffsetX > 0 ? 0 : newOffsetX; 3999 newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX; 4000 } else { 4001 // Center horizontally 4002 newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2); 4003 } 4004 4005 if (newHeight > canvasHeight) { 4006 newOffsetY = newOffsetY > 0 ? 0 : newOffsetY; 4007 newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY; 4008 } else { 4009 // Center vertically 4010 newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2); 4011 } 4012 4013 return { 4014 top: newOffsetY, 4015 left: newOffsetX 4016 }; 4017 }; 4018 4019 Guestures.prototype.onZoom = function() { 4020 var self = this; 4021 4022 // Calculate current distance between points to get pinch ratio and new width and height 4023 var contentStartPos = self.contentStartPos; 4024 4025 var currentWidth = contentStartPos.width; 4026 var currentHeight = contentStartPos.height; 4027 4028 var currentOffsetX = contentStartPos.left; 4029 var currentOffsetY = contentStartPos.top; 4030 4031 var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]); 4032 4033 var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers; 4034 4035 var newWidth = Math.floor(currentWidth * pinchRatio); 4036 var newHeight = Math.floor(currentHeight * pinchRatio); 4037 4038 // This is the translation due to pinch-zooming 4039 var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX; 4040 var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY; 4041 4042 // Point between the two touches 4043 var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft(); 4044 var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop(); 4045 4046 // And this is the translation due to translation of the centerpoint 4047 // between the two fingers 4048 var translateFromTranslatingX = centerPointEndX - self.centerPointStartX; 4049 var translateFromTranslatingY = centerPointEndY - self.centerPointStartY; 4050 4051 // The new offset is the old/current one plus the total translation 4052 var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX); 4053 var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY); 4054 4055 var newPos = { 4056 top: newOffsetY, 4057 left: newOffsetX, 4058 scaleX: pinchRatio, 4059 scaleY: pinchRatio 4060 }; 4061 4062 self.canTap = false; 4063 4064 self.newWidth = newWidth; 4065 self.newHeight = newHeight; 4066 4067 self.contentLastPos = newPos; 4068 4069 if (self.requestId) { 4070 cancelAFrame(self.requestId); 4071 4072 self.requestId = null; 4073 } 4074 4075 self.requestId = requestAFrame(function() { 4076 $.fancybox.setTranslate(self.$content, self.contentLastPos); 4077 }); 4078 }; 4079 4080 Guestures.prototype.ontouchend = function(e) { 4081 var self = this; 4082 var dMs = Math.max(new Date().getTime() - self.startTime, 1); 4083 4084 var swiping = self.isSwiping; 4085 var panning = self.isPanning; 4086 var zooming = self.isZooming; 4087 var scrolling = self.isScrolling; 4088 4089 self.endPoints = getPointerXY(e); 4090 4091 self.$container.removeClass("fancybox-controls--isGrabbing"); 4092 4093 $(document).off(".fb.touch"); 4094 4095 document.removeEventListener("scroll", self.onscroll, true); 4096 4097 if (self.requestId) { 4098 cancelAFrame(self.requestId); 4099 4100 self.requestId = null; 4101 } 4102 4103 self.isSwiping = false; 4104 self.isPanning = false; 4105 self.isZooming = false; 4106 self.isScrolling = false; 4107 4108 self.instance.isDragging = false; 4109 4110 if (self.canTap) { 4111 return self.onTap(e); 4112 } 4113 4114 self.speed = 366; 4115 4116 // Speed in px/ms 4117 self.velocityX = self.distanceX / dMs * 0.5; 4118 self.velocityY = self.distanceY / dMs * 0.5; 4119 4120 self.speedX = Math.max(self.speed * 0.5, Math.min(self.speed * 1.5, 1 / Math.abs(self.velocityX) * self.speed)); 4121 4122 if (panning) { 4123 self.endPanning(); 4124 } else if (zooming) { 4125 self.endZooming(); 4126 } else { 4127 self.endSwiping(swiping, scrolling); 4128 } 4129 4130 return; 4131 }; 4132 4133 Guestures.prototype.endSwiping = function(swiping, scrolling) { 4134 var self = this, 4135 ret = false, 4136 len = self.instance.group.length; 4137 4138 self.sliderLastPos = null; 4139 4140 // Close if swiped vertically / navigate if horizontally 4141 if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) { 4142 // Continue vertical movement 4143 $.fancybox.animate( 4144 self.instance.current.$slide, 4145 { 4146 top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150, 4147 opacity: 0 4148 }, 4149 200 4150 ); 4151 4152 ret = self.instance.close(true, 200); 4153 } else if (swiping == "x" && self.distanceX > 50 && len > 1) { 4154 ret = self.instance.previous(self.speedX); 4155 } else if (swiping == "x" && self.distanceX < -50 && len > 1) { 4156 ret = self.instance.next(self.speedX); 4157 } 4158 4159 if (ret === false && (swiping == "x" || swiping == "y")) { 4160 if (scrolling || len < 2) { 4161 self.instance.centerSlide(self.instance.current, 150); 4162 } else { 4163 self.instance.jumpTo(self.instance.current.index); 4164 } 4165 } 4166 4167 self.$container.removeClass("fancybox-is-sliding"); 4168 }; 4169 4170 // Limit panning from edges 4171 // ======================== 4172 Guestures.prototype.endPanning = function() { 4173 var self = this; 4174 var newOffsetX, newOffsetY, newPos; 4175 4176 if (!self.contentLastPos) { 4177 return; 4178 } 4179 4180 if (self.opts.momentum === false) { 4181 newOffsetX = self.contentLastPos.left; 4182 newOffsetY = self.contentLastPos.top; 4183 } else { 4184 // Continue movement 4185 newOffsetX = self.contentLastPos.left + self.velocityX * self.speed; 4186 newOffsetY = self.contentLastPos.top + self.velocityY * self.speed; 4187 } 4188 4189 newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height); 4190 4191 newPos.width = self.contentStartPos.width; 4192 newPos.height = self.contentStartPos.height; 4193 4194 $.fancybox.animate(self.$content, newPos, 330); 4195 }; 4196 4197 Guestures.prototype.endZooming = function() { 4198 var self = this; 4199 4200 var current = self.instance.current; 4201 4202 var newOffsetX, newOffsetY, newPos, reset; 4203 4204 var newWidth = self.newWidth; 4205 var newHeight = self.newHeight; 4206 4207 if (!self.contentLastPos) { 4208 return; 4209 } 4210 4211 newOffsetX = self.contentLastPos.left; 4212 newOffsetY = self.contentLastPos.top; 4213 4214 reset = { 4215 top: newOffsetY, 4216 left: newOffsetX, 4217 width: newWidth, 4218 height: newHeight, 4219 scaleX: 1, 4220 scaleY: 1 4221 }; 4222 4223 // Reset scalex/scaleY values; this helps for perfomance and does not break animation 4224 $.fancybox.setTranslate(self.$content, reset); 4225 4226 if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) { 4227 self.instance.scaleToFit(150); 4228 } else if (newWidth > current.width || newHeight > current.height) { 4229 self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150); 4230 } else { 4231 newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight); 4232 4233 // Switch from scale() to width/height or animation will not work correctly 4234 $.fancybox.setTranslate(self.$content, $.fancybox.getTranslate(self.$content)); 4235 4236 $.fancybox.animate(self.$content, newPos, 150); 4237 } 4238 }; 4239 4240 Guestures.prototype.onTap = function(e) { 4241 var self = this; 4242 var $target = $(e.target); 4243 4244 var instance = self.instance; 4245 var current = instance.current; 4246 4247 var endPoints = (e && getPointerXY(e)) || self.startPoints; 4248 4249 var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0; 4250 var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0; 4251 4252 var where; 4253 4254 var process = function(prefix) { 4255 var action = current.opts[prefix]; 4256 4257 if ($.isFunction(action)) { 4258 action = action.apply(instance, [current, e]); 4259 } 4260 4261 if (!action) { 4262 return; 4263 } 4264 4265 switch (action) { 4266 case "close": 4267 instance.close(self.startEvent); 4268 4269 break; 4270 4271 case "toggleControls": 4272 instance.toggleControls(true); 4273 4274 break; 4275 4276 case "next": 4277 instance.next(); 4278 4279 break; 4280 4281 case "nextOrClose": 4282 if (instance.group.length > 1) { 4283 instance.next(); 4284 } else { 4285 instance.close(self.startEvent); 4286 } 4287 4288 break; 4289 4290 case "zoom": 4291 if (current.type == "image" && (current.isLoaded || current.$ghost)) { 4292 if (instance.canPan()) { 4293 instance.scaleToFit(); 4294 } else if (instance.isScaledDown()) { 4295 instance.scaleToActual(tapX, tapY); 4296 } else if (instance.group.length < 2) { 4297 instance.close(self.startEvent); 4298 } 4299 } 4300 4301 break; 4302 } 4303 }; 4304 4305 // Ignore right click 4306 if (e.originalEvent && e.originalEvent.button == 2) { 4307 return; 4308 } 4309 4310 // Skip if clicked on the scrollbar 4311 if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) { 4312 return; 4313 } 4314 4315 // Check where is clicked 4316 if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) { 4317 where = "Outside"; 4318 } else if ($target.is(".fancybox-slide")) { 4319 where = "Slide"; 4320 } else if ( 4321 instance.current.$content && 4322 instance.current.$content 4323 .find($target) 4324 .addBack() 4325 .filter($target).length 4326 ) { 4327 where = "Content"; 4328 } else { 4329 return; 4330 } 4331 4332 // Check if this is a double tap 4333 if (self.tapped) { 4334 // Stop previously created single tap 4335 clearTimeout(self.tapped); 4336 self.tapped = null; 4337 4338 // Skip if distance between taps is too big 4339 if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) { 4340 return this; 4341 } 4342 4343 // OK, now we assume that this is a double-tap 4344 process("dblclick" + where); 4345 } else { 4346 // Single tap will be processed if user has not clicked second time within 300ms 4347 // or there is no need to wait for double-tap 4348 self.tapX = tapX; 4349 self.tapY = tapY; 4350 4351 if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) { 4352 self.tapped = setTimeout(function() { 4353 self.tapped = null; 4354 4355 process("click" + where); 4356 }, 500); 4357 } else { 4358 process("click" + where); 4359 } 4360 } 4361 4362 return this; 4363 }; 4364 4365 $(document).on("onActivate.fb", function(e, instance) { 4366 if (instance && !instance.Guestures) { 4367 instance.Guestures = new Guestures(instance); 4368 } 4369 }); 4370})(window, document, window.jQuery || jQuery); 4371 4372// ========================================================================== 4373// 4374// SlideShow 4375// Enables slideshow functionality 4376// 4377// Example of usage: 4378// $.fancybox.getInstance().SlideShow.start() 4379// 4380// ========================================================================== 4381(function(document, $) { 4382 "use strict"; 4383 4384 $.extend(true, $.fancybox.defaults, { 4385 btnTpl: { 4386 slideShow: 4387 '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' + 4388 '<svg viewBox="0 0 40 40">' + 4389 '<path d="M13,12 L27,20 L13,27 Z" />' + 4390 '<path d="M15,10 v19 M23,10 v19" />' + 4391 "</svg>" + 4392 "</button>" 4393 }, 4394 slideShow: { 4395 autoStart: false, 4396 speed: 3000 4397 } 4398 }); 4399 4400 var SlideShow = function(instance) { 4401 this.instance = instance; 4402 this.init(); 4403 }; 4404 4405 $.extend(SlideShow.prototype, { 4406 timer: null, 4407 isActive: false, 4408 $button: null, 4409 4410 init: function() { 4411 var self = this; 4412 4413 self.$button = self.instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function() { 4414 self.toggle(); 4415 }); 4416 4417 if (self.instance.group.length < 2 || !self.instance.group[self.instance.currIndex].opts.slideShow) { 4418 self.$button.hide(); 4419 } 4420 }, 4421 4422 set: function(force) { 4423 var self = this; 4424 4425 // Check if reached last element 4426 if ( 4427 self.instance && 4428 self.instance.current && 4429 (force === true || self.instance.current.opts.loop || self.instance.currIndex < self.instance.group.length - 1) 4430 ) { 4431 self.timer = setTimeout(function() { 4432 if (self.isActive) { 4433 self.instance.jumpTo((self.instance.currIndex + 1) % self.instance.group.length); 4434 } 4435 }, self.instance.current.opts.slideShow.speed); 4436 } else { 4437 self.stop(); 4438 self.instance.idleSecondsCounter = 0; 4439 self.instance.showControls(); 4440 } 4441 }, 4442 4443 clear: function() { 4444 var self = this; 4445 4446 clearTimeout(self.timer); 4447 4448 self.timer = null; 4449 }, 4450 4451 start: function() { 4452 var self = this; 4453 var current = self.instance.current; 4454 4455 if (current) { 4456 self.isActive = true; 4457 4458 self.$button 4459 .attr("title", current.opts.i18n[current.opts.lang].PLAY_STOP) 4460 .removeClass("fancybox-button--play") 4461 .addClass("fancybox-button--pause"); 4462 4463 self.set(true); 4464 } 4465 }, 4466 4467 stop: function() { 4468 var self = this; 4469 var current = self.instance.current; 4470 4471 self.clear(); 4472 4473 self.$button 4474 .attr("title", current.opts.i18n[current.opts.lang].PLAY_START) 4475 .removeClass("fancybox-button--pause") 4476 .addClass("fancybox-button--play"); 4477 4478 self.isActive = false; 4479 }, 4480 4481 toggle: function() { 4482 var self = this; 4483 4484 if (self.isActive) { 4485 self.stop(); 4486 } else { 4487 self.start(); 4488 } 4489 } 4490 }); 4491 4492 $(document).on({ 4493 "onInit.fb": function(e, instance) { 4494 if (instance && !instance.SlideShow) { 4495 instance.SlideShow = new SlideShow(instance); 4496 } 4497 }, 4498 4499 "beforeShow.fb": function(e, instance, current, firstRun) { 4500 var SlideShow = instance && instance.SlideShow; 4501 4502 if (firstRun) { 4503 if (SlideShow && current.opts.slideShow.autoStart) { 4504 SlideShow.start(); 4505 } 4506 } else if (SlideShow && SlideShow.isActive) { 4507 SlideShow.clear(); 4508 } 4509 }, 4510 4511 "afterShow.fb": function(e, instance, current) { 4512 var SlideShow = instance && instance.SlideShow; 4513 4514 if (SlideShow && SlideShow.isActive) { 4515 SlideShow.set(); 4516 } 4517 }, 4518 4519 "afterKeydown.fb": function(e, instance, current, keypress, keycode) { 4520 var SlideShow = instance && instance.SlideShow; 4521 4522 // "P" or Spacebar 4523 if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) { 4524 keypress.preventDefault(); 4525 4526 SlideShow.toggle(); 4527 } 4528 }, 4529 4530 "beforeClose.fb onDeactivate.fb": function(e, instance) { 4531 var SlideShow = instance && instance.SlideShow; 4532 4533 if (SlideShow) { 4534 SlideShow.stop(); 4535 } 4536 } 4537 }); 4538 4539 // Page Visibility API to pause slideshow when window is not active 4540 $(document).on("visibilitychange", function() { 4541 var instance = $.fancybox.getInstance(); 4542 var SlideShow = instance && instance.SlideShow; 4543 4544 if (SlideShow && SlideShow.isActive) { 4545 if (document.hidden) { 4546 SlideShow.clear(); 4547 } else { 4548 SlideShow.set(); 4549 } 4550 } 4551 }); 4552})(document, window.jQuery || jQuery); 4553 4554// ========================================================================== 4555// 4556// FullScreen 4557// Adds fullscreen functionality 4558// 4559// ========================================================================== 4560(function(document, $) { 4561 "use strict"; 4562 4563 // Collection of methods supported by user browser 4564 var fn = (function() { 4565 var fnMap = [ 4566 ["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"], 4567 // new WebKit 4568 [ 4569 "webkitRequestFullscreen", 4570 "webkitExitFullscreen", 4571 "webkitFullscreenElement", 4572 "webkitFullscreenEnabled", 4573 "webkitfullscreenchange", 4574 "webkitfullscreenerror" 4575 ], 4576 // old WebKit (Safari 5.1) 4577 [ 4578 "webkitRequestFullScreen", 4579 "webkitCancelFullScreen", 4580 "webkitCurrentFullScreenElement", 4581 "webkitCancelFullScreen", 4582 "webkitfullscreenchange", 4583 "webkitfullscreenerror" 4584 ], 4585 [ 4586 "mozRequestFullScreen", 4587 "mozCancelFullScreen", 4588 "mozFullScreenElement", 4589 "mozFullScreenEnabled", 4590 "mozfullscreenchange", 4591 "mozfullscreenerror" 4592 ], 4593 ["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"] 4594 ]; 4595 4596 var ret = {}; 4597 4598 for (var i = 0; i < fnMap.length; i++) { 4599 var val = fnMap[i]; 4600 4601 if (val && val[1] in document) { 4602 for (var j = 0; j < val.length; j++) { 4603 ret[fnMap[0][j]] = val[j]; 4604 } 4605 4606 return ret; 4607 } 4608 } 4609 4610 return false; 4611 })(); 4612 4613 // If browser does not have Full Screen API, then simply unset default button template and stop 4614 if (!fn) { 4615 if ($ && $.fancybox) { 4616 $.fancybox.defaults.btnTpl.fullScreen = false; 4617 } 4618 4619 return; 4620 } 4621 4622 var FullScreen = { 4623 request: function(elem) { 4624 elem = elem || document.documentElement; 4625 4626 elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT); 4627 }, 4628 exit: function() { 4629 document[fn.exitFullscreen](); 4630 }, 4631 toggle: function(elem) { 4632 elem = elem || document.documentElement; 4633 4634 if (this.isFullscreen()) { 4635 this.exit(); 4636 } else { 4637 this.request(elem); 4638 } 4639 }, 4640 isFullscreen: function() { 4641 return Boolean(document[fn.fullscreenElement]); 4642 }, 4643 enabled: function() { 4644 return Boolean(document[fn.fullscreenEnabled]); 4645 } 4646 }; 4647 4648 $.extend(true, $.fancybox.defaults, { 4649 btnTpl: { 4650 fullScreen: 4651 '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fullscreen" title="{{FULL_SCREEN}}">' + 4652 '<svg viewBox="0 0 40 40">' + 4653 '<path d="M9,12 v16 h22 v-16 h-22 v8" />' + 4654 "</svg>" + 4655 "</button>" 4656 }, 4657 fullScreen: { 4658 autoStart: false 4659 } 4660 }); 4661 4662 $(document).on({ 4663 "onInit.fb": function(e, instance) { 4664 var $container; 4665 4666 if (instance && instance.group[instance.currIndex].opts.fullScreen) { 4667 $container = instance.$refs.container; 4668 4669 $container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function(e) { 4670 e.stopPropagation(); 4671 e.preventDefault(); 4672 4673 FullScreen.toggle(); 4674 }); 4675 4676 if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) { 4677 FullScreen.request(); 4678 } 4679 4680 // Expose API 4681 instance.FullScreen = FullScreen; 4682 } else if (instance) { 4683 instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide(); 4684 } 4685 }, 4686 4687 "afterKeydown.fb": function(e, instance, current, keypress, keycode) { 4688 // "F" 4689 if (instance && instance.FullScreen && keycode === 70) { 4690 keypress.preventDefault(); 4691 4692 instance.FullScreen.toggle(); 4693 } 4694 }, 4695 4696 "beforeClose.fb": function(e, instance) { 4697 if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) { 4698 FullScreen.exit(); 4699 } 4700 } 4701 }); 4702 4703 $(document).on(fn.fullscreenchange, function() { 4704 var isFullscreen = FullScreen.isFullscreen(), 4705 instance = $.fancybox.getInstance(); 4706 4707 if (instance) { 4708 // If image is zooming, then force to stop and reposition properly 4709 if (instance.current && instance.current.type === "image" && instance.isAnimating) { 4710 instance.current.$content.css("transition", "none"); 4711 4712 instance.isAnimating = false; 4713 4714 instance.update(true, true, 0); 4715 } 4716 4717 instance.trigger("onFullscreenChange", isFullscreen); 4718 4719 instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen); 4720 } 4721 }); 4722})(document, window.jQuery || jQuery); 4723 4724// ========================================================================== 4725// 4726// Thumbs 4727// Displays thumbnails in a grid 4728// 4729// ========================================================================== 4730(function(document, $) { 4731 "use strict"; 4732 4733 var CLASS = "fancybox-thumbs", 4734 CLASS_ACTIVE = CLASS + "-active", 4735 CLASS_LOAD = CLASS + "-loading"; 4736 4737 // Make sure there are default values 4738 $.fancybox.defaults = $.extend( 4739 true, 4740 { 4741 btnTpl: { 4742 thumbs: 4743 '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' + 4744 '<svg viewBox="0 0 120 120">' + 4745 '<path d="M30,30 h14 v14 h-14 Z M50,30 h14 v14 h-14 Z M70,30 h14 v14 h-14 Z M30,50 h14 v14 h-14 Z M50,50 h14 v14 h-14 Z M70,50 h14 v14 h-14 Z M30,70 h14 v14 h-14 Z M50,70 h14 v14 h-14 Z M70,70 h14 v14 h-14 Z" />' + 4746 "</svg>" + 4747 "</button>" 4748 }, 4749 thumbs: { 4750 autoStart: false, // Display thumbnails on opening 4751 hideOnClose: true, // Hide thumbnail grid when closing animation starts 4752 parentEl: ".fancybox-container", // Container is injected into this element 4753 axis: "y" // Vertical (y) or horizontal (x) scrolling 4754 } 4755 }, 4756 $.fancybox.defaults 4757 ); 4758 4759 var FancyThumbs = function(instance) { 4760 this.init(instance); 4761 }; 4762 4763 $.extend(FancyThumbs.prototype, { 4764 $button: null, 4765 $grid: null, 4766 $list: null, 4767 isVisible: false, 4768 isActive: false, 4769 4770 init: function(instance) { 4771 var self = this, 4772 first, 4773 second; 4774 4775 self.instance = instance; 4776 4777 instance.Thumbs = self; 4778 4779 self.opts = instance.group[instance.currIndex].opts.thumbs; 4780 4781 // Enable thumbs if at least two group items have thumbnails 4782 first = instance.group[0]; 4783 first = first.opts.thumb || (first.opts.$thumb && first.opts.$thumb.length ? first.opts.$thumb.attr("src") : false); 4784 4785 if (instance.group.length > 1) { 4786 second = instance.group[1]; 4787 second = second.opts.thumb || (second.opts.$thumb && second.opts.$thumb.length ? second.opts.$thumb.attr("src") : false); 4788 } 4789 4790 self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]"); 4791 4792 if (self.opts && first && second && first && second) { 4793 self.$button.show().on("click", function() { 4794 self.toggle(); 4795 }); 4796 4797 self.isActive = true; 4798 } else { 4799 self.$button.hide(); 4800 } 4801 }, 4802 4803 create: function() { 4804 var self = this, 4805 instance = self.instance, 4806 parentEl = self.opts.parentEl, 4807 list = [], 4808 src; 4809 4810 if (!self.$grid) { 4811 // Create main element 4812 self.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo( 4813 instance.$refs.container 4814 .find(parentEl) 4815 .addBack() 4816 .filter(parentEl) 4817 ); 4818 4819 // Add "click" event that performs gallery navigation 4820 self.$grid.on("click", "li", function() { 4821 instance.jumpTo($(this).attr("data-index")); 4822 }); 4823 } 4824 4825 // Build the list 4826 if (!self.$list) { 4827 self.$list = $("<ul>").appendTo(self.$grid); 4828 } 4829 4830 $.each(instance.group, function(i, item) { 4831 src = item.opts.thumb || (item.opts.$thumb ? item.opts.$thumb.attr("src") : null); 4832 4833 if (!src && item.type === "image") { 4834 src = item.src; 4835 } 4836 4837 list.push( 4838 '<li data-index="' + 4839 i + 4840 '" tabindex="0" class="' + 4841 CLASS_LOAD + 4842 '"' + 4843 (src && src.length ? ' style="background-image:url(' + src + ')" />' : "") + 4844 "></li>" 4845 ); 4846 }); 4847 4848 self.$list[0].innerHTML = list.join(""); 4849 4850 if (self.opts.axis === "x") { 4851 // Set fixed width for list element to enable horizontal scrolling 4852 self.$list.width( 4853 parseInt(self.$grid.css("padding-right"), 10) + 4854 instance.group.length * 4855 self.$list 4856 .children() 4857 .eq(0) 4858 .outerWidth(true) 4859 ); 4860 } 4861 }, 4862 4863 focus: function(duration) { 4864 var self = this, 4865 $list = self.$list, 4866 $grid = self.$grid, 4867 thumb, 4868 thumbPos; 4869 4870 if (!self.instance.current) { 4871 return; 4872 } 4873 4874 thumb = $list 4875 .children() 4876 .removeClass(CLASS_ACTIVE) 4877 .filter('[data-index="' + self.instance.current.index + '"]') 4878 .addClass(CLASS_ACTIVE); 4879 4880 thumbPos = thumb.position(); 4881 4882 // Check if need to scroll to make current thumb visible 4883 if (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) { 4884 $list.stop().animate( 4885 { 4886 scrollTop: $list.scrollTop() + thumbPos.top 4887 }, 4888 duration 4889 ); 4890 } else if ( 4891 self.opts.axis === "x" && 4892 (thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth())) 4893 ) { 4894 $list 4895 .parent() 4896 .stop() 4897 .animate( 4898 { 4899 scrollLeft: thumbPos.left 4900 }, 4901 duration 4902 ); 4903 } 4904 }, 4905 4906 update: function() { 4907 var that = this; 4908 that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible); 4909 4910 if (that.isVisible) { 4911 if (!that.$grid) { 4912 that.create(); 4913 } 4914 4915 that.instance.trigger("onThumbsShow"); 4916 4917 that.focus(0); 4918 } else if (that.$grid) { 4919 that.instance.trigger("onThumbsHide"); 4920 } 4921 4922 // Update content position 4923 that.instance.update(); 4924 }, 4925 4926 hide: function() { 4927 this.isVisible = false; 4928 this.update(); 4929 }, 4930 4931 show: function() { 4932 this.isVisible = true; 4933 this.update(); 4934 }, 4935 4936 toggle: function() { 4937 this.isVisible = !this.isVisible; 4938 this.update(); 4939 } 4940 }); 4941 4942 $(document).on({ 4943 "onInit.fb": function(e, instance) { 4944 var Thumbs; 4945 4946 if (instance && !instance.Thumbs) { 4947 Thumbs = new FancyThumbs(instance); 4948 4949 if (Thumbs.isActive && Thumbs.opts.autoStart === true) { 4950 Thumbs.show(); 4951 } 4952 } 4953 }, 4954 4955 "beforeShow.fb": function(e, instance, item, firstRun) { 4956 var Thumbs = instance && instance.Thumbs; 4957 4958 if (Thumbs && Thumbs.isVisible) { 4959 Thumbs.focus(firstRun ? 0 : 250); 4960 } 4961 }, 4962 4963 "afterKeydown.fb": function(e, instance, current, keypress, keycode) { 4964 var Thumbs = instance && instance.Thumbs; 4965 4966 // "G" 4967 if (Thumbs && Thumbs.isActive && keycode === 71) { 4968 keypress.preventDefault(); 4969 4970 Thumbs.toggle(); 4971 } 4972 }, 4973 4974 "beforeClose.fb": function(e, instance) { 4975 var Thumbs = instance && instance.Thumbs; 4976 4977 if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) { 4978 Thumbs.$grid.hide(); 4979 } 4980 } 4981 }); 4982})(document, window.jQuery || jQuery); 4983 4984//// ========================================================================== 4985// 4986// Share 4987// Displays simple form for sharing current url 4988// 4989// ========================================================================== 4990(function(document, $) { 4991 "use strict"; 4992 4993 $.extend(true, $.fancybox.defaults, { 4994 btnTpl: { 4995 share: 4996 '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' + 4997 '<svg viewBox="0 0 40 40">' + 4998 '<path d="M6,30 C8,18 19,16 23,16 L23,16 L23,10 L33,20 L23,29 L23,24 C19,24 8,27 6,30 Z">' + 4999 "</svg>" + 5000 "</button>" 5001 }, 5002 share: { 5003 url: function(instance, item) { 5004 return ( 5005 (!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location 5006 ); 5007 }, 5008 tpl: 5009 '<div class="fancybox-share">' + 5010 "<h1>{{SHARE}}</h1>" + 5011 "<p>" + 5012 '<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' + 5013 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' + 5014 "<span>Facebook</span>" + 5015 "</a>" + 5016 '<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' + 5017 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' + 5018 "<span>Twitter</span>" + 5019 "</a>" + 5020 '<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' + 5021 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' + 5022 "<span>Pinterest</span>" + 5023 "</a>" + 5024 "</p>" + 5025 '<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" /></p>' + 5026 "</div>" 5027 } 5028 }); 5029 5030 function escapeHtml(string) { 5031 var entityMap = { 5032 "&": "&", 5033 "<": "<", 5034 ">": ">", 5035 '"': """, 5036 "'": "'", 5037 "/": "/", 5038 "`": "`", 5039 "=": "=" 5040 }; 5041 5042 return String(string).replace(/[&<>"'`=\/]/g, function(s) { 5043 return entityMap[s]; 5044 }); 5045 } 5046 5047 $(document).on("click", "[data-fancybox-share]", function() { 5048 var instance = $.fancybox.getInstance(), 5049 current = instance.current || null, 5050 url, 5051 tpl; 5052 5053 if (!current) { 5054 return; 5055 } 5056 5057 if ($.type(current.opts.share.url) === "function") { 5058 url = current.opts.share.url.apply(current, [instance, current]); 5059 } 5060 5061 tpl = current.opts.share.tpl 5062 .replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "") 5063 .replace(/\{\{url\}\}/g, encodeURIComponent(url)) 5064 .replace(/\{\{url_raw\}\}/g, escapeHtml(url)) 5065 .replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : ""); 5066 5067 $.fancybox.open({ 5068 src: instance.translate(instance, tpl), 5069 type: "html", 5070 opts: { 5071 animationEffect: false, 5072 afterLoad: function(shareInstance, shareCurrent) { 5073 // Close self if parent instance is closing 5074 instance.$refs.container.one("beforeClose.fb", function() { 5075 shareInstance.close(null, 0); 5076 }); 5077 5078 // Opening links in a popup window 5079 shareCurrent.$content.find(".fancybox-share__links a").click(function() { 5080 window.open(this.href, "Share", "width=550, height=450"); 5081 return false; 5082 }); 5083 } 5084 } 5085 }); 5086 }); 5087})(document, window.jQuery || jQuery); 5088 5089// ========================================================================== 5090// 5091// Hash 5092// Enables linking to each modal 5093// 5094// ========================================================================== 5095(function(document, window, $) { 5096 "use strict"; 5097 5098 // Simple $.escapeSelector polyfill (for jQuery prior v3) 5099 if (!$.escapeSelector) { 5100 $.escapeSelector = function(sel) { 5101 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 5102 var fcssescape = function(ch, asCodePoint) { 5103 if (asCodePoint) { 5104 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 5105 if (ch === "\0") { 5106 return "\uFFFD"; 5107 } 5108 5109 // Control characters and (dependent upon position) numbers get escaped as code points 5110 return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; 5111 } 5112 5113 // Other potentially-special ASCII characters get backslash-escaped 5114 return "\\" + ch; 5115 }; 5116 5117 return (sel + "").replace(rcssescape, fcssescape); 5118 }; 5119 } 5120 5121 // Get info about gallery name and current index from url 5122 function parseUrl() { 5123 var hash = window.location.hash.substr(1), 5124 rez = hash.split("-"), 5125 index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1, 5126 gallery = rez.join("-"); 5127 5128 return { 5129 hash: hash, 5130 /* Index is starting from 1 */ 5131 index: index < 1 ? 1 : index, 5132 gallery: gallery 5133 }; 5134 } 5135 5136 // Trigger click evnt on links to open new fancyBox instance 5137 function triggerFromUrl(url) { 5138 var $el; 5139 5140 if (url.gallery !== "") { 5141 // If we can find element matching 'data-fancybox' atribute, then trigger click event for that. 5142 // It should start fancyBox 5143 $el = $("[data-fancybox='" + $.escapeSelector(url.gallery) + "']") 5144 .eq(url.index - 1) 5145 .trigger("click.fb-start"); 5146 } 5147 } 5148 5149 // Get gallery name from current instance 5150 function getGalleryID(instance) { 5151 var opts, ret; 5152 5153 if (!instance) { 5154 return false; 5155 } 5156 5157 opts = instance.current ? instance.current.opts : instance.opts; 5158 ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") : ""); 5159 5160 return ret === "" ? false : ret; 5161 } 5162 5163 // Start when DOM becomes ready 5164 $(function() { 5165 // Check if user has disabled this module 5166 if ($.fancybox.defaults.hash === false) { 5167 return; 5168 } 5169 5170 // Update hash when opening/closing fancyBox 5171 $(document).on({ 5172 "onInit.fb": function(e, instance) { 5173 var url, gallery; 5174 5175 if (instance.group[instance.currIndex].opts.hash === false) { 5176 return; 5177 } 5178 5179 url = parseUrl(); 5180 gallery = getGalleryID(instance); 5181 5182 // Make sure gallery start index matches index from hash 5183 if (gallery && url.gallery && gallery == url.gallery) { 5184 instance.currIndex = url.index - 1; 5185 } 5186 }, 5187 5188 "beforeShow.fb": function(e, instance, current, firstRun) { 5189 var gallery; 5190 5191 if (!current || current.opts.hash === false) { 5192 return; 5193 } 5194 5195 // Check if need to update window hash 5196 gallery = getGalleryID(instance); 5197 5198 if (!gallery) { 5199 return; 5200 } 5201 5202 // Variable containing last hash value set by fancyBox 5203 // It will be used to determine if fancyBox needs to close after hash change is detected 5204 instance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : ""); 5205 5206 // If current hash is the same (this instance most likely is opened by hashchange), then do nothing 5207 if (window.location.hash === "#" + instance.currentHash) { 5208 return; 5209 } 5210 5211 if (!instance.origHash) { 5212 instance.origHash = window.location.hash; 5213 } 5214 5215 if (instance.hashTimer) { 5216 clearTimeout(instance.hashTimer); 5217 } 5218 5219 // Update hash 5220 instance.hashTimer = setTimeout(function() { 5221 if ("replaceState" in window.history) { 5222 window.history[firstRun ? "pushState" : "replaceState"]( 5223 {}, 5224 document.title, 5225 window.location.pathname + window.location.search + "#" + instance.currentHash 5226 ); 5227 5228 if (firstRun) { 5229 instance.hasCreatedHistory = true; 5230 } 5231 } else { 5232 window.location.hash = instance.currentHash; 5233 } 5234 5235 instance.hashTimer = null; 5236 }, 300); 5237 }, 5238 5239 "beforeClose.fb": function(e, instance, current) { 5240 var gallery; 5241 5242 if (current.opts.hash === false) { 5243 return; 5244 } 5245 5246 gallery = getGalleryID(instance); 5247 5248 // Goto previous history entry 5249 if (instance.currentHash && instance.hasCreatedHistory) { 5250 window.history.back(); 5251 } else if (instance.currentHash) { 5252 if ("replaceState" in window.history) { 5253 window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || "")); 5254 } else { 5255 window.location.hash = instance.origHash; 5256 } 5257 } 5258 5259 instance.currentHash = null; 5260 5261 clearTimeout(instance.hashTimer); 5262 } 5263 }); 5264 5265 // Check if need to start/close after url has changed 5266 $(window).on("hashchange.fb", function() { 5267 var url = parseUrl(), 5268 fb; 5269 5270 // Find last fancyBox instance that has "hash" 5271 $.each( 5272 $(".fancybox-container") 5273 .get() 5274 .reverse(), 5275 function(index, value) { 5276 var tmp = $(value).data("FancyBox"); 5277 //isClosing 5278 if (tmp.currentHash) { 5279 fb = tmp; 5280 return false; 5281 } 5282 } 5283 ); 5284 5285 if (fb) { 5286 // Now, compare hash values 5287 if (fb.currentHash && fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) { 5288 fb.currentHash = null; 5289 5290 fb.close(); 5291 } 5292 } else if (url.gallery !== "") { 5293 triggerFromUrl(url); 5294 } 5295 }); 5296 5297 // Check current hash and trigger click event on matching element to start fancyBox, if needed 5298 setTimeout(function() { 5299 if (!$.fancybox.getInstance()) { 5300 triggerFromUrl(parseUrl()); 5301 } 5302 }, 50); 5303 }); 5304})(document, window, window.jQuery || jQuery); 5305 5306// ========================================================================== 5307// 5308// Wheel 5309// Basic mouse weheel support for gallery navigation 5310// 5311// ========================================================================== 5312(function(document, $) { 5313 "use strict"; 5314 5315 var prevTime = new Date().getTime(); 5316 5317 $(document).on({ 5318 "onInit.fb": function(e, instance, current) { 5319 instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function(e) { 5320 var current = instance.current, 5321 currTime = new Date().getTime(); 5322 5323 if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) { 5324 return; 5325 } 5326 5327 e.preventDefault(); 5328 e.stopPropagation(); 5329 5330 if (current.$slide.hasClass("fancybox-animated")) { 5331 return; 5332 } 5333 5334 e = e.originalEvent || e; 5335 5336 if (currTime - prevTime < 250) { 5337 return; 5338 } 5339 5340 prevTime = currTime; 5341 5342 instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"](); 5343 }); 5344 } 5345 }); 5346})(document, window.jQuery || jQuery); 5347 5348 5349/***/ }), 5350
vendor: 1,022 bytes, lines 5351-5379
5351/***/ "./node_modules/detect-hover/lib/index.js": 5352/*!************************************************!*\ 5353 !*** ./node_modules/detect-hover/lib/index.js ***! 5354 \************************************************/ 5355/*! no static exports found */ 5356/***/ (function(module, exports, __webpack_require__) { 5357 5358"use strict"; 5359 5360 5361Object.defineProperty(exports, "__esModule", { 5362 value: true 5363}); 5364var detectHover = { 5365 update: function update() { 5366 if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') { 5367 detectHover.hover = window.matchMedia('(hover: hover)').matches; 5368 detectHover.none = window.matchMedia('(hover: none)').matches || window.matchMedia('(hover: on-demand)').matches; 5369 detectHover.anyHover = window.matchMedia('(any-hover: hover)').matches; 5370 detectHover.anyNone = window.matchMedia('(any-hover: none)').matches || window.matchMedia('(any-hover: on-demand)').matches; 5371 } 5372 } 5373}; 5374 5375detectHover.update(); 5376exports.default = detectHover; 5377 5378/***/ }), 5379
vendor: 5,704 bytes, lines 5380-5519
5380/***/ "./node_modules/detect-it/lib/index.js": 5381/*!*********************************************!*\ 5382 !*** ./node_modules/detect-it/lib/index.js ***! 5383 \*********************************************/ 5384/*! no static exports found */ 5385/***/ (function(module, exports, __webpack_require__) { 5386 5387"use strict"; 5388 5389 5390Object.defineProperty(exports, "__esModule", { 5391 value: true 5392}); 5393 5394var _detectHover = __webpack_require__(/*! detect-hover */ "./node_modules/detect-hover/lib/index.js"); 5395 5396var _detectHover2 = _interopRequireDefault(_detectHover); 5397 5398var _detectPointer = __webpack_require__(/*! detect-pointer */ "./node_modules/detect-pointer/lib/index.js"); 5399 5400var _detectPointer2 = _interopRequireDefault(_detectPointer); 5401 5402var _detectTouchEvents = __webpack_require__(/*! detect-touch-events */ "./node_modules/detect-touch-events/lib/index.js"); 5403 5404var _detectTouchEvents2 = _interopRequireDefault(_detectTouchEvents); 5405 5406var _detectPassiveEvents = __webpack_require__(/*! detect-passive-events */ "./node_modules/detect-passive-events/lib/index.js"); 5407 5408var _detectPassiveEvents2 = _interopRequireDefault(_detectPassiveEvents); 5409 5410function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 5411 5412/* 5413 * detectIt object structure 5414 * const detectIt = { 5415 * deviceType: 'mouseOnly' / 'touchOnly' / 'hybrid', 5416 * passiveEvents: boolean, 5417 * hasTouch: boolean, 5418 * hasMouse: boolean, 5419 * maxTouchPoints: number, 5420 * primaryHover: 'hover' / 'none', 5421 * primaryPointer: 'fine' / 'coarse' / 'none', 5422 * state: { 5423 * detectHover, 5424 * detectPointer, 5425 * detectTouchEvents, 5426 * detectPassiveEvents, 5427 * }, 5428 * update() {...}, 5429 * } 5430 */ 5431 5432function determineDeviceType(hasTouch, anyHover, anyFine, state) { 5433 // A hybrid device is one that both hasTouch and any input device can hover 5434 // or has a fine pointer. 5435 if (hasTouch && (anyHover || anyFine)) return 'hybrid'; 5436 5437 // workaround for browsers that have the touch events api, 5438 // and have implemented Level 4 media queries but not the 5439 // hover and pointer media queries, so the tests are all false (notable Firefox) 5440 // if it hasTouch, no pointer and hover support, and on an android assume it's touchOnly 5441 // if it hasTouch, no pointer and hover support, and not on an android assume it's a hybrid 5442 if (hasTouch && Object.keys(state.detectHover).filter(function (key) { 5443 return key !== 'update'; 5444 }).every(function (key) { 5445 return state.detectHover[key] === false; 5446 }) && Object.keys(state.detectPointer).filter(function (key) { 5447 return key !== 'update'; 5448 }).every(function (key) { 5449 return state.detectPointer[key] === false; 5450 })) { 5451 if (window.navigator && /android/.test(window.navigator.userAgent.toLowerCase())) { 5452 return 'touchOnly'; 5453 } 5454 return 'hybrid'; 5455 } 5456 5457 // In almost all cases a device that doesnât support touch will have a mouse, 5458 // but there may be rare exceptions. Note that it doesnât work to do additional tests 5459 // based on hover and pointer media queries as older browsers donât support these. 5460 // Essentially, 'mouseOnly' is the default. 5461 return hasTouch ? 'touchOnly' : 'mouseOnly'; 5462} 5463 5464var detectIt = { 5465 state: { 5466 detectHover: _detectHover2.default, 5467 detectPointer: _detectPointer2.default, 5468 detectTouchEvents: _detectTouchEvents2.default, 5469 detectPassiveEvents: _detectPassiveEvents2.default 5470 }, 5471 update: function update() { 5472 detectIt.state.detectHover.update(); 5473 detectIt.state.detectPointer.update(); 5474 detectIt.state.detectTouchEvents.update(); 5475 detectIt.state.detectPassiveEvents.update(); 5476 detectIt.updateOnlyOwnProperties(); 5477 }, 5478 updateOnlyOwnProperties: function updateOnlyOwnProperties() { 5479 if (typeof window !== 'undefined') { 5480 detectIt.passiveEvents = detectIt.state.detectPassiveEvents.hasSupport || false; 5481 5482 detectIt.hasTouch = detectIt.state.detectTouchEvents.hasSupport || false; 5483 5484 detectIt.deviceType = determineDeviceType(detectIt.hasTouch, detectIt.state.detectHover.anyHover, detectIt.state.detectPointer.anyFine, detectIt.state); 5485 5486 detectIt.hasMouse = detectIt.deviceType !== 'touchOnly'; 5487 5488 detectIt.primaryInput = detectIt.deviceType === 'mouseOnly' && 'mouse' || detectIt.deviceType === 'touchOnly' && 'touch' || 5489 // deviceType is hybrid: 5490 detectIt.state.detectPointer.fine && 'mouse' || detectIt.state.detectPointer.coarse && 'touch' || 5491 // if there's no support for hover media queries but detectIt determined it's 5492 // a hybrid device, then assume it's a mouse first device 5493 'mouse'; 5494 5495 // issue with Windows Chrome on hybrid devices starting in version 59 where 5496 // media queries represent a touch only device, so if the browser is an 5497 // affected Windows Chrome version and hasTouch, 5498 // then assume it's a hybrid with primaryInput mouse 5499 // note that version 62 of Chrome fixes this issue 5500 // see https://github.com/rafrex/detect-it/issues/8 5501 var inVersionRange = function inVersionRange(version) { 5502 return version >= 59 && version < 62; 5503 }; 5504 var isAffectedWindowsChromeVersion = /windows/.test(window.navigator.userAgent.toLowerCase()) && /chrome/.test(window.navigator.userAgent.toLowerCase()) && inVersionRange(parseInt(/Chrome\/([0-9.]+)/.exec(navigator.userAgent)[1], 10)); 5505 5506 if (isAffectedWindowsChromeVersion && detectIt.hasTouch) { 5507 detectIt.deviceType = 'hybrid'; 5508 detectIt.hasMouse = true; 5509 detectIt.primaryInput = 'mouse'; 5510 } 5511 } 5512 } 5513}; 5514 5515detectIt.updateOnlyOwnProperties(); 5516exports.default = detectIt; 5517 5518/***/ }), 5519
vendor: 1,430 bytes, lines 5520-5559
5520/***/ "./node_modules/detect-passive-events/lib/index.js": 5521/*!*********************************************************!*\ 5522 !*** ./node_modules/detect-passive-events/lib/index.js ***! 5523 \*********************************************************/ 5524/*! no static exports found */ 5525/***/ (function(module, exports, __webpack_require__) { 5526 5527"use strict"; 5528 5529 5530Object.defineProperty(exports, "__esModule", { 5531 value: true 5532}); 5533// adapted from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md 5534var detectPassiveEvents = { 5535 update: function update() { 5536 if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') { 5537 var passive = false; 5538 var options = Object.defineProperty({}, 'passive', { 5539 get: function get() { 5540 passive = true; 5541 } 5542 }); 5543 // note: have to set and remove a no-op listener instead of null 5544 // (which was used previously), becasue Edge v15 throws an error 5545 // when providing a null callback. 5546 // https://github.com/rafrex/detect-passive-events/pull/3 5547 var noop = function noop() {}; 5548 window.addEventListener('testPassiveEventSupport', noop, options); 5549 window.removeEventListener('testPassiveEventSupport', noop, options); 5550 detectPassiveEvents.hasSupport = passive; 5551 } 5552 } 5553}; 5554 5555detectPassiveEvents.update(); 5556exports.default = detectPassiveEvents; 5557 5558/***/ }), 5559
vendor: 1,105 bytes, lines 5560-5590
5560/***/ "./node_modules/detect-pointer/lib/index.js": 5561/*!**************************************************!*\ 5562 !*** ./node_modules/detect-pointer/lib/index.js ***! 5563 \**************************************************/ 5564/*! no static exports found */ 5565/***/ (function(module, exports, __webpack_require__) { 5566 5567"use strict"; 5568 5569 5570Object.defineProperty(exports, "__esModule", { 5571 value: true 5572}); 5573var detectPointer = { 5574 update: function update() { 5575 if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') { 5576 detectPointer.fine = window.matchMedia('(pointer: fine)').matches; 5577 detectPointer.coarse = window.matchMedia('(pointer: coarse)').matches; 5578 detectPointer.none = window.matchMedia('(pointer: none)').matches; 5579 detectPointer.anyFine = window.matchMedia('(any-pointer: fine)').matches; 5580 detectPointer.anyCoarse = window.matchMedia('(any-pointer: coarse)').matches; 5581 detectPointer.anyNone = window.matchMedia('(any-pointer: none)').matches; 5582 } 5583 } 5584}; 5585 5586detectPointer.update(); 5587exports.default = detectPointer; 5588 5589/***/ }), 5590
vendor: 759 bytes, lines 5591-5617
5591/***/ "./node_modules/detect-touch-events/lib/index.js": 5592/*!*******************************************************!*\ 5593 !*** ./node_modules/detect-touch-events/lib/index.js ***! 5594 \*******************************************************/ 5595/*! no static exports found */ 5596/***/ (function(module, exports, __webpack_require__) { 5597 5598"use strict"; 5599 5600 5601Object.defineProperty(exports, "__esModule", { 5602 value: true 5603}); 5604var detectTouchEvents = { 5605 update: function update() { 5606 if (typeof window !== 'undefined') { 5607 detectTouchEvents.hasSupport = 'ontouchstart' in window; 5608 detectTouchEvents.browserSupportsApi = Boolean(window.TouchEvent); 5609 } 5610 } 5611}; 5612 5613detectTouchEvents.update(); 5614exports.default = detectTouchEvents; 5615 5616/***/ }), 5617
vendor: 68,518 bytes, lines 5618-7968
5618/***/ "./node_modules/nouislider/distribute/nouislider.js": 5619/*!**********************************************************!*\ 5620 !*** ./node_modules/nouislider/distribute/nouislider.js ***! 5621 \**********************************************************/ 5622/*! no static exports found */ 5623/***/ (function(module, exports, __webpack_require__) { 5624 5625var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! nouislider - 11.1.0 - 2018-04-02 11:18:13 */ 5626 5627(function (factory) { 5628 5629 if ( true ) { 5630 5631 // AMD. Register as an anonymous module. 5632 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 5633 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 5634 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 5635 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5636 5637 } else {} 5638 5639}(function( ){ 5640 5641 'use strict'; 5642 5643 var VERSION = '11.1.0'; 5644 5645 5646 function isValidFormatter ( entry ) { 5647 return typeof entry === 'object' && typeof entry.to === 'function' && typeof entry.from === 'function'; 5648 } 5649 5650 function removeElement ( el ) { 5651 el.parentElement.removeChild(el); 5652 } 5653 5654 function isSet ( value ) { 5655 return value !== null && value !== undefined; 5656 } 5657 5658 // Bindable version 5659 function preventDefault ( e ) { 5660 e.preventDefault(); 5661 } 5662 5663 // Removes duplicates from an array. 5664 function unique ( array ) { 5665 return array.filter(function(a){ 5666 return !this[a] ? this[a] = true : false; 5667 }, {}); 5668 } 5669 5670 // Round a value to the closest 'to'. 5671 function closest ( value, to ) { 5672 return Math.round(value / to) * to; 5673 } 5674 5675 // Current position of an element relative to the document. 5676 function offset ( elem, orientation ) { 5677 5678 var rect = elem.getBoundingClientRect(); 5679 var doc = elem.ownerDocument; 5680 var docElem = doc.documentElement; 5681 var pageOffset = getPageOffset(doc); 5682 5683 // getBoundingClientRect contains left scroll in Chrome on Android. 5684 // I haven't found a feature detection that proves this. Worst case 5685 // scenario on mis-match: the 'tap' feature on horizontal sliders breaks. 5686 if ( /webkit.*Chrome.*Mobile/i.test(navigator.userAgent) ) { 5687 pageOffset.x = 0; 5688 } 5689 5690 return orientation ? (rect.top + pageOffset.y - docElem.clientTop) : (rect.left + pageOffset.x - docElem.clientLeft); 5691 } 5692 5693 // Checks whether a value is numerical. 5694 function isNumeric ( a ) { 5695 return typeof a === 'number' && !isNaN( a ) && isFinite( a ); 5696 } 5697 5698 // Sets a class and removes it after [duration] ms. 5699 function addClassFor ( element, className, duration ) { 5700 if (duration > 0) { 5701 addClass(element, className); 5702 setTimeout(function(){ 5703 removeClass(element, className); 5704 }, duration); 5705 } 5706 } 5707 5708 // Limits a value to 0 - 100 5709 function limit ( a ) { 5710 return Math.max(Math.min(a, 100), 0); 5711 } 5712 5713 // Wraps a variable as an array, if it isn't one yet. 5714 // Note that an input array is returned by reference! 5715 function asArray ( a ) { 5716 return Array.isArray(a) ? a : [a]; 5717 } 5718 5719 // Counts decimals 5720 function countDecimals ( numStr ) { 5721 numStr = String(numStr); 5722 var pieces = numStr.split("."); 5723 return pieces.length > 1 ? pieces[1].length : 0; 5724 } 5725 5726 // http://youmightnotneedjquery.com/#add_class 5727 function addClass ( el, className ) { 5728 if ( el.classList ) { 5729 el.classList.add(className); 5730 } else { 5731 el.className += ' ' + className; 5732 } 5733 } 5734 5735 // http://youmightnotneedjquery.com/#remove_class 5736 function removeClass ( el, className ) { 5737 if ( el.classList ) { 5738 el.classList.remove(className); 5739 } else { 5740 el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 5741 } 5742 } 5743 5744 // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/ 5745 function hasClass ( el, className ) { 5746 return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className); 5747 } 5748 5749 // https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes 5750 function getPageOffset ( doc ) { 5751 5752 var supportPageOffset = window.pageXOffset !== undefined; 5753 var isCSS1Compat = ((doc.compatMode || "") === "CSS1Compat"); 5754 var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? doc.documentElement.scrollLeft : doc.body.scrollLeft; 5755 var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? doc.documentElement.scrollTop : doc.body.scrollTop; 5756 5757 return { 5758 x: x, 5759 y: y 5760 }; 5761 } 5762 5763 // we provide a function to compute constants instead 5764 // of accessing window.* as soon as the module needs it 5765 // so that we do not compute anything if not needed 5766 function getActions ( ) { 5767 5768 // Determine the events to bind. IE11 implements pointerEvents without 5769 // a prefix, which breaks compatibility with the IE10 implementation. 5770 return window.navigator.pointerEnabled ? { 5771 start: 'pointerdown', 5772 move: 'pointermove', 5773 end: 'pointerup' 5774 } : window.navigator.msPointerEnabled ? { 5775 start: 'MSPointerDown', 5776 move: 'MSPointerMove', 5777 end: 'MSPointerUp' 5778 } : { 5779 start: 'mousedown touchstart', 5780 move: 'mousemove touchmove', 5781 end: 'mouseup touchend' 5782 }; 5783 } 5784 5785 // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md 5786 // Issue #785 5787 function getSupportsPassive ( ) { 5788 5789 var supportsPassive = false; 5790 5791 try { 5792 5793 var opts = Object.defineProperty({}, 'passive', { 5794 get: function() { 5795 supportsPassive = true; 5796 } 5797 }); 5798 5799 window.addEventListener('test', null, opts); 5800 5801 } catch (e) {} 5802 5803 return supportsPassive; 5804 } 5805 5806 function getSupportsTouchActionNone ( ) { 5807 return window.CSS && CSS.supports && CSS.supports('touch-action', 'none'); 5808 } 5809 5810 5811// Value calculation 5812 5813 // Determine the size of a sub-range in relation to a full range. 5814 function subRangeRatio ( pa, pb ) { 5815 return (100 / (pb - pa)); 5816 } 5817 5818 // (percentage) How many percent is this value of this range? 5819 function fromPercentage ( range, value ) { 5820 return (value * 100) / ( range[1] - range[0] ); 5821 } 5822 5823 // (percentage) Where is this value on this range? 5824 function toPercentage ( range, value ) { 5825 return fromPercentage( range, range[0] < 0 ? 5826 value + Math.abs(range[0]) : 5827 value - range[0] ); 5828 } 5829 5830 // (value) How much is this percentage on this range? 5831 function isPercentage ( range, value ) { 5832 return ((value * ( range[1] - range[0] )) / 100) + range[0]; 5833 } 5834 5835 5836// Range conversion 5837 5838 function getJ ( value, arr ) { 5839 5840 var j = 1; 5841 5842 while ( value >= arr[j] ){ 5843 j += 1; 5844 } 5845 5846 return j; 5847 } 5848 5849 // (percentage) Input a value, find where, on a scale of 0-100, it applies. 5850 function toStepping ( xVal, xPct, value ) { 5851 5852 if ( value >= xVal.slice(-1)[0] ){ 5853 return 100; 5854 } 5855 5856 var j = getJ( value, xVal ); 5857 var va = xVal[j-1]; 5858 var vb = xVal[j]; 5859 var pa = xPct[j-1]; 5860 var pb = xPct[j]; 5861 5862 return pa + (toPercentage([va, vb], value) / subRangeRatio (pa, pb)); 5863 } 5864 5865 // (value) Input a percentage, find where it is on the specified range. 5866 function fromStepping ( xVal, xPct, value ) { 5867 5868 // There is no range group that fits 100 5869 if ( value >= 100 ){ 5870 return xVal.slice(-1)[0]; 5871 } 5872 5873 var j = getJ( value, xPct ); 5874 var va = xVal[j-1]; 5875 var vb = xVal[j]; 5876 var pa = xPct[j-1]; 5877 var pb = xPct[j]; 5878 5879 return isPercentage([va, vb], (value - pa) * subRangeRatio (pa, pb)); 5880 } 5881 5882 // (percentage) Get the step that applies at a certain value. 5883 function getStep ( xPct, xSteps, snap, value ) { 5884 5885 if ( value === 100 ) { 5886 return value; 5887 } 5888 5889 var j = getJ( value, xPct ); 5890 var a = xPct[j-1]; 5891 var b = xPct[j]; 5892 5893 // If 'snap' is set, steps are used as fixed points on the slider. 5894 if ( snap ) { 5895 5896 // Find the closest position, a or b. 5897 if ((value - a) > ((b-a)/2)){ 5898 return b; 5899 } 5900 5901 return a; 5902 } 5903 5904 if ( !xSteps[j-1] ){ 5905 return value; 5906 } 5907 5908 return xPct[j-1] + closest( 5909 value - xPct[j-1], 5910 xSteps[j-1] 5911 ); 5912 } 5913 5914 5915// Entry parsing 5916 5917 function handleEntryPoint ( index, value, that ) { 5918 5919 var percentage; 5920 5921 // Wrap numerical input in an array. 5922 if ( typeof value === "number" ) { 5923 value = [value]; 5924 } 5925 5926 // Reject any invalid input, by testing whether value is an array. 5927 if ( !Array.isArray(value) ){ 5928 throw new Error("noUiSlider (" + VERSION + "): 'range' contains invalid value."); 5929 } 5930 5931 // Covert min/max syntax to 0 and 100. 5932 if ( index === 'min' ) { 5933 percentage = 0; 5934 } else if ( index === 'max' ) { 5935 percentage = 100; 5936 } else { 5937 percentage = parseFloat( index ); 5938 } 5939 5940 // Check for correct input. 5941 if ( !isNumeric( percentage ) || !isNumeric( value[0] ) ) { 5942 throw new Error("noUiSlider (" + VERSION + "): 'range' value isn't numeric."); 5943 } 5944 5945 // Store values. 5946 that.xPct.push( percentage ); 5947 that.xVal.push( value[0] ); 5948 5949 // NaN will evaluate to false too, but to keep 5950 // logging clear, set step explicitly. Make sure 5951 // not to override the 'step' setting with false. 5952 if ( !percentage ) { 5953 if ( !isNaN( value[1] ) ) { 5954 that.xSteps[0] = value[1]; 5955 } 5956 } else { 5957 that.xSteps.push( isNaN(value[1]) ? false : value[1] ); 5958 } 5959 5960 that.xHighestCompleteStep.push(0); 5961 } 5962 5963 function handleStepPoint ( i, n, that ) { 5964 5965 // Ignore 'false' stepping. 5966 if ( !n ) { 5967 return true; 5968 } 5969 5970 // Factor to range ratio 5971 that.xSteps[i] = fromPercentage([that.xVal[i], that.xVal[i+1]], n) / subRangeRatio(that.xPct[i], that.xPct[i+1]); 5972 5973 var totalSteps = (that.xVal[i+1] - that.xVal[i]) / that.xNumSteps[i]; 5974 var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1); 5975 var step = that.xVal[i] + (that.xNumSteps[i] * highestStep); 5976 5977 that.xHighestCompleteStep[i] = step; 5978 } 5979 5980 5981// Interface 5982 5983 function Spectrum ( entry, snap, singleStep ) { 5984 5985 this.xPct = []; 5986 this.xVal = []; 5987 this.xSteps = [ singleStep || false ]; 5988 this.xNumSteps = [ false ]; 5989 this.xHighestCompleteStep = []; 5990 5991 this.snap = snap; 5992 5993 var index; 5994 var ordered = []; // [0, 'min'], [1, '50%'], [2, 'max'] 5995 5996 // Map the object keys to an array. 5997 for ( index in entry ) { 5998 if ( entry.hasOwnProperty(index) ) { 5999 ordered.push([entry[index], index]); 6000 } 6001 } 6002 6003 // Sort all entries by value (numeric sort). 6004 if ( ordered.length && typeof ordered[0][0] === "object" ) { 6005 ordered.sort(function(a, b) { return a[0][0] - b[0][0]; }); 6006 } else { 6007 ordered.sort(function(a, b) { return a[0] - b[0]; }); 6008 } 6009 6010 6011 // Convert all entries to subranges. 6012 for ( index = 0; index < ordered.length; index++ ) { 6013 handleEntryPoint(ordered[index][1], ordered[index][0], this); 6014 } 6015 6016 // Store the actual step values. 6017 // xSteps is sorted in the same order as xPct and xVal. 6018 this.xNumSteps = this.xSteps.slice(0); 6019 6020 // Convert all numeric steps to the percentage of the subrange they represent. 6021 for ( index = 0; index < this.xNumSteps.length; index++ ) { 6022 handleStepPoint(index, this.xNumSteps[index], this); 6023 } 6024 } 6025 6026 Spectrum.prototype.getMargin = function ( value ) { 6027 6028 var step = this.xNumSteps[0]; 6029 6030 if ( step && ((value / step) % 1) !== 0 ) { 6031 throw new Error("noUiSlider (" + VERSION + "): 'limit', 'margin' and 'padding' must be divisible by step."); 6032 } 6033 6034 return this.xPct.length === 2 ? fromPercentage(this.xVal, value) : false; 6035 }; 6036 6037 Spectrum.prototype.toStepping = function ( value ) { 6038 6039 value = toStepping( this.xVal, this.xPct, value ); 6040 6041 return value; 6042 }; 6043 6044 Spectrum.prototype.fromStepping = function ( value ) { 6045 6046 return fromStepping( this.xVal, this.xPct, value ); 6047 }; 6048 6049 Spectrum.prototype.getStep = function ( value ) { 6050 6051 value = getStep(this.xPct, this.xSteps, this.snap, value ); 6052 6053 return value; 6054 }; 6055 6056 Spectrum.prototype.getNearbySteps = function ( value ) { 6057 6058 var j = getJ(value, this.xPct); 6059 6060 return { 6061 stepBefore: { startValue: this.xVal[j-2], step: this.xNumSteps[j-2], highestStep: this.xHighestCompleteStep[j-2] }, 6062 thisStep: { startValue: this.xVal[j-1], step: this.xNumSteps[j-1], highestStep: this.xHighestCompleteStep[j-1] }, 6063 stepAfter: { startValue: this.xVal[j-0], step: this.xNumSteps[j-0], highestStep: this.xHighestCompleteStep[j-0] } 6064 }; 6065 }; 6066 6067 Spectrum.prototype.countStepDecimals = function () { 6068 var stepDecimals = this.xNumSteps.map(countDecimals); 6069 return Math.max.apply(null, stepDecimals); 6070 }; 6071 6072 // Outside testing 6073 Spectrum.prototype.convert = function ( value ) { 6074 return this.getStep(this.toStepping(value)); 6075 }; 6076 6077/* Every input option is tested and parsed. This'll prevent 6078 endless validation in internal methods. These tests are 6079 structured with an item for every option available. An 6080 option can be marked as required by setting the 'r' flag. 6081 The testing function is provided with three arguments: 6082 - The provided value for the option; 6083 - A reference to the options object; 6084 - The name for the option; 6085 6086 The testing function returns false when an error is detected, 6087 or true when everything is OK. It can also modify the option 6088 object, to make sure all values can be correctly looped elsewhere. */ 6089 6090 var defaultFormatter = { 'to': function( value ){ 6091 return value !== undefined && value.toFixed(2); 6092 }, 'from': Number }; 6093 6094 function validateFormat ( entry ) { 6095 6096 // Any object with a to and from method is supported. 6097 if ( isValidFormatter(entry) ) { 6098 return true; 6099 } 6100 6101 throw new Error("noUiSlider (" + VERSION + "): 'format' requires 'to' and 'from' methods."); 6102 } 6103 6104 function testStep ( parsed, entry ) { 6105 6106 if ( !isNumeric( entry ) ) { 6107 throw new Error("noUiSlider (" + VERSION + "): 'step' is not numeric."); 6108 } 6109 6110 // The step option can still be used to set stepping 6111 // for linear sliders. Overwritten if set in 'range'. 6112 parsed.singleStep = entry; 6113 } 6114 6115 function testRange ( parsed, entry ) { 6116 6117 // Filter incorrect input. 6118 if ( typeof entry !== 'object' || Array.isArray(entry) ) { 6119 throw new Error("noUiSlider (" + VERSION + "): 'range' is not an object."); 6120 } 6121 6122 // Catch missing start or end. 6123 if ( entry.min === undefined || entry.max === undefined ) { 6124 throw new Error("noUiSlider (" + VERSION + "): Missing 'min' or 'max' in 'range'."); 6125 } 6126 6127 // Catch equal start or end. 6128 if ( entry.min === entry.max ) { 6129 throw new Error("noUiSlider (" + VERSION + "): 'range' 'min' and 'max' cannot be equal."); 6130 } 6131 6132 parsed.spectrum = new Spectrum(entry, parsed.snap, parsed.singleStep); 6133 } 6134 6135 function testStart ( parsed, entry ) { 6136 6137 entry = asArray(entry); 6138 6139 // Validate input. Values aren't tested, as the public .val method 6140 // will always provide a valid location. 6141 if ( !Array.isArray( entry ) || !entry.length ) { 6142 throw new Error("noUiSlider (" + VERSION + "): 'start' option is incorrect."); 6143 } 6144 6145 // Store the number of handles. 6146 parsed.handles = entry.length; 6147 6148 // When the slider is initialized, the .val method will 6149 // be called with the start options. 6150 parsed.start = entry; 6151 } 6152 6153 function testSnap ( parsed, entry ) { 6154 6155 // Enforce 100% stepping within subranges. 6156 parsed.snap = entry; 6157 6158 if ( typeof entry !== 'boolean' ){ 6159 throw new Error("noUiSlider (" + VERSION + "): 'snap' option must be a boolean."); 6160 } 6161 } 6162 6163 function testAnimate ( parsed, entry ) { 6164 6165 // Enforce 100% stepping within subranges. 6166 parsed.animate = entry; 6167 6168 if ( typeof entry !== 'boolean' ){ 6169 throw new Error("noUiSlider (" + VERSION + "): 'animate' option must be a boolean."); 6170 } 6171 } 6172 6173 function testAnimationDuration ( parsed, entry ) { 6174 6175 parsed.animationDuration = entry; 6176 6177 if ( typeof entry !== 'number' ){ 6178 throw new Error("noUiSlider (" + VERSION + "): 'animationDuration' option must be a number."); 6179 } 6180 } 6181 6182 function testConnect ( parsed, entry ) { 6183 6184 var connect = [false]; 6185 var i; 6186 6187 // Map legacy options 6188 if ( entry === 'lower' ) { 6189 entry = [true, false]; 6190 } 6191 6192 else if ( entry === 'upper' ) { 6193 entry = [false, true]; 6194 } 6195 6196 // Handle boolean options 6197 if ( entry === true || entry === false ) { 6198 6199 for ( i = 1; i < parsed.handles; i++ ) { 6200 connect.push(entry); 6201 } 6202 6203 connect.push(false); 6204 } 6205 6206 // Reject invalid input 6207 else if ( !Array.isArray( entry ) || !entry.length || entry.length !== parsed.handles + 1 ) { 6208 throw new Error("noUiSlider (" + VERSION + "): 'connect' option doesn't match handle count."); 6209 } 6210 6211 else { 6212 connect = entry; 6213 } 6214 6215 parsed.connect = connect; 6216 } 6217 6218 function testOrientation ( parsed, entry ) { 6219 6220 // Set orientation to an a numerical value for easy 6221 // array selection. 6222 switch ( entry ){ 6223 case 'horizontal': 6224 parsed.ort = 0; 6225 break; 6226 case 'vertical': 6227 parsed.ort = 1; 6228 break; 6229 default: 6230 throw new Error("noUiSlider (" + VERSION + "): 'orientation' option is invalid."); 6231 } 6232 } 6233 6234 function testMargin ( parsed, entry ) { 6235 6236 if ( !isNumeric(entry) ){ 6237 throw new Error("noUiSlider (" + VERSION + "): 'margin' option must be numeric."); 6238 } 6239 6240 // Issue #582 6241 if ( entry === 0 ) { 6242 return; 6243 } 6244 6245 parsed.margin = parsed.spectrum.getMargin(entry); 6246 6247 if ( !parsed.margin ) { 6248 throw new Error("noUiSlider (" + VERSION + "): 'margin' option is only supported on linear sliders."); 6249 } 6250 } 6251 6252 function testLimit ( parsed, entry ) { 6253 6254 if ( !isNumeric(entry) ){ 6255 throw new Error("noUiSlider (" + VERSION + "): 'limit' option must be numeric."); 6256 } 6257 6258 parsed.limit = parsed.spectrum.getMargin(entry); 6259 6260 if ( !parsed.limit || parsed.handles < 2 ) { 6261 throw new Error("noUiSlider (" + VERSION + "): 'limit' option is only supported on linear sliders with 2 or more handles."); 6262 } 6263 } 6264 6265 function testPadding ( parsed, entry ) { 6266 6267 if ( !isNumeric(entry) && !Array.isArray(entry) ){ 6268 throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be numeric or array of exactly 2 numbers."); 6269 } 6270 6271 if ( Array.isArray(entry) && !(entry.length === 2 || isNumeric(entry[0]) || isNumeric(entry[1])) ) { 6272 throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be numeric or array of exactly 2 numbers."); 6273 } 6274 6275 if ( entry === 0 ) { 6276 return; 6277 } 6278 6279 if ( !Array.isArray(entry) ) { 6280 entry = [entry, entry]; 6281 } 6282 6283 // 'getMargin' returns false for invalid values. 6284 parsed.padding = [parsed.spectrum.getMargin(entry[0]), parsed.spectrum.getMargin(entry[1])]; 6285 6286 if ( parsed.padding[0] === false || parsed.padding[1] === false ) { 6287 throw new Error("noUiSlider (" + VERSION + "): 'padding' option is only supported on linear sliders."); 6288 } 6289 6290 if ( parsed.padding[0] < 0 || parsed.padding[1] < 0 ) { 6291 throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number(s)."); 6292 } 6293 6294 if ( parsed.padding[0] + parsed.padding[1] >= 100 ) { 6295 throw new Error("noUiSlider (" + VERSION + "): 'padding' option must not exceed 100% of the range."); 6296 } 6297 } 6298 6299 function testDirection ( parsed, entry ) { 6300 6301 // Set direction as a numerical value for easy parsing. 6302 // Invert connection for RTL sliders, so that the proper 6303 // handles get the connect/background classes. 6304 switch ( entry ) { 6305 case 'ltr': 6306 parsed.dir = 0; 6307 break; 6308 case 'rtl': 6309 parsed.dir = 1; 6310 break; 6311 default: 6312 throw new Error("noUiSlider (" + VERSION + "): 'direction' option was not recognized."); 6313 } 6314 } 6315 6316 function testBehaviour ( parsed, entry ) { 6317 6318 // Make sure the input is a string. 6319 if ( typeof entry !== 'string' ) { 6320 throw new Error("noUiSlider (" + VERSION + "): 'behaviour' must be a string containing options."); 6321 } 6322 6323 // Check if the string contains any keywords. 6324 // None are required. 6325 var tap = entry.indexOf('tap') >= 0; 6326 var drag = entry.indexOf('drag') >= 0; 6327 var fixed = entry.indexOf('fixed') >= 0; 6328 var snap = entry.indexOf('snap') >= 0; 6329 var hover = entry.indexOf('hover') >= 0; 6330 6331 if ( fixed ) { 6332 6333 if ( parsed.handles !== 2 ) { 6334 throw new Error("noUiSlider (" + VERSION + "): 'fixed' behaviour must be used with 2 handles"); 6335 } 6336 6337 // Use margin to enforce fixed state 6338 testMargin(parsed, parsed.start[1] - parsed.start[0]); 6339 } 6340 6341 parsed.events = { 6342 tap: tap || snap, 6343 drag: drag, 6344 fixed: fixed, 6345 snap: snap, 6346 hover: hover 6347 }; 6348 } 6349 6350 function testTooltips ( parsed, entry ) { 6351 6352 if ( entry === false ) { 6353 return; 6354 } 6355 6356 else if ( entry === true ) { 6357 6358 parsed.tooltips = []; 6359 6360 for ( var i = 0; i < parsed.handles; i++ ) { 6361 parsed.tooltips.push(true); 6362 } 6363 } 6364 6365 else { 6366 6367 parsed.tooltips = asArray(entry); 6368 6369 if ( parsed.tooltips.length !== parsed.handles ) { 6370 throw new Error("noUiSlider (" + VERSION + "): must pass a formatter for all handles."); 6371 } 6372 6373 parsed.tooltips.forEach(function(formatter){ 6374 if ( typeof formatter !== 'boolean' && (typeof formatter !== 'object' || typeof formatter.to !== 'function') ) { 6375 throw new Error("noUiSlider (" + VERSION + "): 'tooltips' must be passed a formatter or 'false'."); 6376 } 6377 }); 6378 } 6379 } 6380 6381 function testAriaFormat ( parsed, entry ) { 6382 parsed.ariaFormat = entry; 6383 validateFormat(entry); 6384 } 6385 6386 function testFormat ( parsed, entry ) { 6387 parsed.format = entry; 6388 validateFormat(entry); 6389 } 6390 6391 function testCssPrefix ( parsed, entry ) { 6392 6393 if ( typeof entry !== 'string' && entry !== false ) { 6394 throw new Error("noUiSlider (" + VERSION + "): 'cssPrefix' must be a string or `false`."); 6395 } 6396 6397 parsed.cssPrefix = entry; 6398 } 6399 6400 function testCssClasses ( parsed, entry ) { 6401 6402 if ( typeof entry !== 'object' ) { 6403 throw new Error("noUiSlider (" + VERSION + "): 'cssClasses' must be an object."); 6404 } 6405 6406 if ( typeof parsed.cssPrefix === 'string' ) { 6407 parsed.cssClasses = {}; 6408 6409 for ( var key in entry ) { 6410 if ( !entry.hasOwnProperty(key) ) { continue; } 6411 6412 parsed.cssClasses[key] = parsed.cssPrefix + entry[key]; 6413 } 6414 } else { 6415 parsed.cssClasses = entry; 6416 } 6417 } 6418 6419 // Test all developer settings and parse to assumption-safe values. 6420 function testOptions ( options ) { 6421 6422 // To prove a fix for #537, freeze options here. 6423 // If the object is modified, an error will be thrown. 6424 // Object.freeze(options); 6425 6426 var parsed = { 6427 margin: 0, 6428 limit: 0, 6429 padding: 0, 6430 animate: true, 6431 animationDuration: 300, 6432 ariaFormat: defaultFormatter, 6433 format: defaultFormatter 6434 }; 6435 6436 // Tests are executed in the order they are presented here. 6437 var tests = { 6438 'step': { r: false, t: testStep }, 6439 'start': { r: true, t: testStart }, 6440 'connect': { r: true, t: testConnect }, 6441 'direction': { r: true, t: testDirection }, 6442 'snap': { r: false, t: testSnap }, 6443 'animate': { r: false, t: testAnimate }, 6444 'animationDuration': { r: false, t: testAnimationDuration }, 6445 'range': { r: true, t: testRange }, 6446 'orientation': { r: false, t: testOrientation }, 6447 'margin': { r: false, t: testMargin }, 6448 'limit': { r: false, t: testLimit }, 6449 'padding': { r: false, t: testPadding }, 6450 'behaviour': { r: true, t: testBehaviour }, 6451 'ariaFormat': { r: false, t: testAriaFormat }, 6452 'format': { r: false, t: testFormat }, 6453 'tooltips': { r: false, t: testTooltips }, 6454 'cssPrefix': { r: true, t: testCssPrefix }, 6455 'cssClasses': { r: true, t: testCssClasses } 6456 }; 6457 6458 var defaults = { 6459 'connect': false, 6460 'direction': 'ltr', 6461 'behaviour': 'tap', 6462 'orientation': 'horizontal', 6463 'cssPrefix' : 'noUi-', 6464 'cssClasses': { 6465 target: 'target', 6466 base: 'base', 6467 origin: 'origin', 6468 handle: 'handle', 6469 handleLower: 'handle-lower', 6470 handleUpper: 'handle-upper', 6471 horizontal: 'horizontal', 6472 vertical: 'vertical', 6473 background: 'background', 6474 connect: 'connect', 6475 connects: 'connects', 6476 ltr: 'ltr', 6477 rtl: 'rtl', 6478 draggable: 'draggable', 6479 drag: 'state-drag', 6480 tap: 'state-tap', 6481 active: 'active', 6482 tooltip: 'tooltip', 6483 pips: 'pips', 6484 pipsHorizontal: 'pips-horizontal', 6485 pipsVertical: 'pips-vertical', 6486 marker: 'marker', 6487 markerHorizontal: 'marker-horizontal', 6488 markerVertical: 'marker-vertical', 6489 markerNormal: 'marker-normal', 6490 markerLarge: 'marker-large', 6491 markerSub: 'marker-sub', 6492 value: 'value', 6493 valueHorizontal: 'value-horizontal', 6494 valueVertical: 'value-vertical', 6495 valueNormal: 'value-normal', 6496 valueLarge: 'value-large', 6497 valueSub: 'value-sub' 6498 } 6499 }; 6500 6501 // AriaFormat defaults to regular format, if any. 6502 if ( options.format && !options.ariaFormat ) { 6503 options.ariaFormat = options.format; 6504 } 6505 6506 // Run all options through a testing mechanism to ensure correct 6507 // input. It should be noted that options might get modified to 6508 // be handled properly. E.g. wrapping integers in arrays. 6509 Object.keys(tests).forEach(function( name ){ 6510 6511 // If the option isn't set, but it is required, throw an error. 6512 if ( !isSet(options[name]) && defaults[name] === undefined ) { 6513 6514 if ( tests[name].r ) { 6515 throw new Error("noUiSlider (" + VERSION + "): '" + name + "' is required."); 6516 } 6517 6518 return true; 6519 } 6520 6521 tests[name].t( parsed, !isSet(options[name]) ? defaults[name] : options[name] ); 6522 }); 6523 6524 // Forward pips options 6525 parsed.pips = options.pips; 6526 6527 // All recent browsers accept unprefixed transform. 6528 // We need -ms- for IE9 and -webkit- for older Android; 6529 // Assume use of -webkit- if unprefixed and -ms- are not supported. 6530 // https://caniuse.com/#feat=transforms2d 6531 var d = document.createElement("div"); 6532 var msPrefix = d.style.msTransform !== undefined; 6533 var noPrefix = d.style.transform !== undefined; 6534 6535 parsed.transformRule = noPrefix ? 'transform' : (msPrefix ? 'msTransform' : 'webkitTransform'); 6536 6537 // Pips don't move, so we can place them using left/top. 6538 var styles = [['left', 'top'], ['right', 'bottom']]; 6539 6540 parsed.style = styles[parsed.dir][parsed.ort]; 6541 6542 return parsed; 6543 } 6544 6545 6546function scope ( target, options, originalOptions ){ 6547 6548 var actions = getActions(); 6549 var supportsTouchActionNone = getSupportsTouchActionNone(); 6550 var supportsPassive = supportsTouchActionNone && getSupportsPassive(); 6551 6552 // All variables local to 'scope' are prefixed with 'scope_' 6553 var scope_Target = target; 6554 var scope_Locations = []; 6555 var scope_Base; 6556 var scope_Handles; 6557 var scope_HandleNumbers = []; 6558 var scope_ActiveHandlesCount = 0; 6559 var scope_Connects; 6560 var scope_Spectrum = options.spectrum; 6561 var scope_Values = []; 6562 var scope_Events = {}; 6563 var scope_Self; 6564 var scope_Pips; 6565 var scope_Document = target.ownerDocument; 6566 var scope_DocumentElement = scope_Document.documentElement; 6567 var scope_Body = scope_Document.body; 6568 6569 6570 // For horizontal sliders in standard ltr documents, 6571 // make .noUi-origin overflow to the left so the document doesn't scroll. 6572 var scope_DirOffset = (scope_Document.dir === 'rtl') || (options.ort === 1) ? 0 : 100; 6573 6574/*! In this file: Construction of DOM elements; */ 6575 6576 // Creates a node, adds it to target, returns the new node. 6577 function addNodeTo ( addTarget, className ) { 6578 6579 var div = scope_Document.createElement('div'); 6580 6581 if ( className ) { 6582 addClass(div, className); 6583 } 6584 6585 addTarget.appendChild(div); 6586 6587 return div; 6588 } 6589 6590 // Append a origin to the base 6591 function addOrigin ( base, handleNumber ) { 6592 6593 var origin = addNodeTo(base, options.cssClasses.origin); 6594 var handle = addNodeTo(origin, options.cssClasses.handle); 6595 6596 handle.setAttribute('data-handle', handleNumber); 6597 6598 // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex 6599 // 0 = focusable and reachable 6600 handle.setAttribute('tabindex', '0'); 6601 handle.setAttribute('role', 'slider'); 6602 handle.setAttribute('aria-orientation', options.ort ? 'vertical' : 'horizontal'); 6603 6604 if ( handleNumber === 0 ) { 6605 addClass(handle, options.cssClasses.handleLower); 6606 } 6607 6608 else if ( handleNumber === options.handles - 1 ) { 6609 addClass(handle, options.cssClasses.handleUpper); 6610 } 6611 6612 return origin; 6613 } 6614 6615 // Insert nodes for connect elements 6616 function addConnect ( base, add ) { 6617 6618 if ( !add ) { 6619 return false; 6620 } 6621 6622 return addNodeTo(base, options.cssClasses.connect); 6623 } 6624 6625 // Add handles to the slider base. 6626 function addElements ( connectOptions, base ) { 6627 6628 var connectBase = addNodeTo(base, options.cssClasses.connects); 6629 6630 scope_Handles = []; 6631 scope_Connects = []; 6632 6633 scope_Connects.push(addConnect(connectBase, connectOptions[0])); 6634 6635 // [::::O====O====O====] 6636 // connectOptions = [0, 1, 1, 1] 6637 6638 for ( var i = 0; i < options.handles; i++ ) { 6639 // Keep a list of all added handles. 6640 scope_Handles.push(addOrigin(base, i)); 6641 scope_HandleNumbers[i] = i; 6642 scope_Connects.push(addConnect(connectBase, connectOptions[i + 1])); 6643 } 6644 } 6645 6646 // Initialize a single slider. 6647 function addSlider ( addTarget ) { 6648 6649 // Apply classes and data to the target. 6650 addClass(addTarget, options.cssClasses.target); 6651 6652 if ( options.dir === 0 ) { 6653 addClass(addTarget, options.cssClasses.ltr); 6654 } else { 6655 addClass(addTarget, options.cssClasses.rtl); 6656 } 6657 6658 if ( options.ort === 0 ) { 6659 addClass(addTarget, options.cssClasses.horizontal); 6660 } else { 6661 addClass(addTarget, options.cssClasses.vertical); 6662 } 6663 6664 scope_Base = addNodeTo(addTarget, options.cssClasses.base); 6665 } 6666 6667 6668 function addTooltip ( handle, handleNumber ) { 6669 6670 if ( !options.tooltips[handleNumber] ) { 6671 return false; 6672 } 6673 6674 return addNodeTo(handle.firstChild, options.cssClasses.tooltip); 6675 } 6676 6677 // The tooltips option is a shorthand for using the 'update' event. 6678 function tooltips ( ) { 6679 6680 // Tooltips are added with options.tooltips in original order. 6681 var tips = scope_Handles.map(addTooltip); 6682 6683 bindEvent('update', function(values, handleNumber, unencoded) { 6684 6685 if ( !tips[handleNumber] ) { 6686 return; 6687 } 6688 6689 var formattedValue = values[handleNumber]; 6690 6691 if ( options.tooltips[handleNumber] !== true ) { 6692 formattedValue = options.tooltips[handleNumber].to(unencoded[handleNumber]); 6693 } 6694 6695 tips[handleNumber].innerHTML = formattedValue; 6696 }); 6697 } 6698 6699 6700 function aria ( ) { 6701 6702 bindEvent('update', function ( values, handleNumber, unencoded, tap, positions ) { 6703 6704 // Update Aria Values for all handles, as a change in one changes min and max values for the next. 6705 scope_HandleNumbers.forEach(function( index ){ 6706 6707 var handle = scope_Handles[index]; 6708 6709 var min = checkHandlePosition(scope_Locations, index, 0, true, true, true); 6710 var max = checkHandlePosition(scope_Locations, index, 100, true, true, true); 6711 6712 var now = positions[index]; 6713 var text = options.ariaFormat.to(unencoded[index]); 6714 6715 handle.children[0].setAttribute('aria-valuemin', min.toFixed(1)); 6716 handle.children[0].setAttribute('aria-valuemax', max.toFixed(1)); 6717 handle.children[0].setAttribute('aria-valuenow', now.toFixed(1)); 6718 handle.children[0].setAttribute('aria-valuetext', text); 6719 }); 6720 }); 6721 } 6722 6723 6724 function getGroup ( mode, values, stepped ) { 6725 6726 // Use the range. 6727 if ( mode === 'range' || mode === 'steps' ) { 6728 return scope_Spectrum.xVal; 6729 } 6730 6731 if ( mode === 'count' ) { 6732 6733 if ( values < 2 ) { 6734 throw new Error("noUiSlider (" + VERSION + "): 'values' (>= 2) required for mode 'count'."); 6735 } 6736 6737 // Divide 0 - 100 in 'count' parts. 6738 var interval = values - 1; 6739 var spread = ( 100 / interval ); 6740 6741 values = []; 6742 6743 // List these parts and have them handled as 'positions'. 6744 while ( interval-- ) { 6745 values[ interval ] = ( interval * spread ); 6746 } 6747 6748 values.push(100); 6749 6750 mode = 'positions'; 6751 } 6752 6753 if ( mode === 'positions' ) { 6754 6755 // Map all percentages to on-range values. 6756 return values.map(function( value ){ 6757 return scope_Spectrum.fromStepping( stepped ? scope_Spectrum.getStep( value ) : value ); 6758 }); 6759 } 6760 6761 if ( mode === 'values' ) { 6762 6763 // If the value must be stepped, it needs to be converted to a percentage first. 6764 if ( stepped ) { 6765 6766 return values.map(function( value ){ 6767 6768 // Convert to percentage, apply step, return to value. 6769 return scope_Spectrum.fromStepping( scope_Spectrum.getStep( scope_Spectrum.toStepping( value ) ) ); 6770 }); 6771 6772 } 6773 6774 // Otherwise, we can simply use the values. 6775 return values; 6776 } 6777 } 6778 6779 function generateSpread ( density, mode, group ) { 6780 6781 function safeIncrement(value, increment) { 6782 // Avoid floating point variance by dropping the smallest decimal places. 6783 return (value + increment).toFixed(7) / 1; 6784 } 6785 6786 var indexes = {}; 6787 var firstInRange = scope_Spectrum.xVal[0]; 6788 var lastInRange = scope_Spectrum.xVal[scope_Spectrum.xVal.length-1]; 6789 var ignoreFirst = false; 6790 var ignoreLast = false; 6791 var prevPct = 0; 6792 6793 // Create a copy of the group, sort it and filter away all duplicates. 6794 group = unique(group.slice().sort(function(a, b){ return a - b; })); 6795 6796 // Make sure the range starts with the first element. 6797 if ( group[0] !== firstInRange ) { 6798 group.unshift(firstInRange); 6799 ignoreFirst = true; 6800 } 6801 6802 // Likewise for the last one. 6803 if ( group[group.length - 1] !== lastInRange ) { 6804 group.push(lastInRange); 6805 ignoreLast = true; 6806 } 6807 6808 group.forEach(function ( current, index ) { 6809 6810 // Get the current step and the lower + upper positions. 6811 var step; 6812 var i; 6813 var q; 6814 var low = current; 6815 var high = group[index+1]; 6816 var newPct; 6817 var pctDifference; 6818 var pctPos; 6819 var type; 6820 var steps; 6821 var realSteps; 6822 var stepsize; 6823 6824 // When using 'steps' mode, use the provided steps. 6825 // Otherwise, we'll step on to the next subrange. 6826 if ( mode === 'steps' ) { 6827 step = scope_Spectrum.xNumSteps[ index ]; 6828 } 6829 6830 // Default to a 'full' step. 6831 if ( !step ) { 6832 step = high-low; 6833 } 6834 6835 // Low can be 0, so test for false. If high is undefined, 6836 // we are at the last subrange. Index 0 is already handled. 6837 if ( low === false || high === undefined ) { 6838 return; 6839 } 6840 6841 // Make sure step isn't 0, which would cause an infinite loop (#654) 6842 step = Math.max(step, 0.0000001); 6843 6844 // Find all steps in the subrange. 6845 for ( i = low; i <= high; i = safeIncrement(i, step) ) { 6846 6847 // Get the percentage value for the current step, 6848 // calculate the size for the subrange. 6849 newPct = scope_Spectrum.toStepping( i ); 6850 pctDifference = newPct - prevPct; 6851 6852 steps = pctDifference / density; 6853 realSteps = Math.round(steps); 6854 6855 // This ratio represents the amount of percentage-space a point indicates. 6856 // For a density 1 the points/percentage = 1. For density 2, that percentage needs to be re-devided. 6857 // Round the percentage offset to an even number, then divide by two 6858 // to spread the offset on both sides of the range. 6859 stepsize = pctDifference/realSteps; 6860 6861 // Divide all points evenly, adding the correct number to this subrange. 6862 // Run up to <= so that 100% gets a point, event if ignoreLast is set. 6863 for ( q = 1; q <= realSteps; q += 1 ) { 6864 6865 // The ratio between the rounded value and the actual size might be ~1% off. 6866 // Correct the percentage offset by the number of points 6867 // per subrange. density = 1 will result in 100 points on the 6868 // full range, 2 for 50, 4 for 25, etc. 6869 pctPos = prevPct + ( q * stepsize ); 6870 indexes[pctPos.toFixed(5)] = ['x', 0]; 6871 } 6872 6873 // Determine the point type. 6874 type = (group.indexOf(i) > -1) ? 1 : ( mode === 'steps' ? 2 : 0 ); 6875 6876 // Enforce the 'ignoreFirst' option by overwriting the type for 0. 6877 if ( !index && ignoreFirst ) { 6878 type = 0; 6879 } 6880 6881 if ( !(i === high && ignoreLast)) { 6882 // Mark the 'type' of this point. 0 = plain, 1 = real value, 2 = step value. 6883 indexes[newPct.toFixed(5)] = [i, type]; 6884 } 6885 6886 // Update the percentage count. 6887 prevPct = newPct; 6888 } 6889 }); 6890 6891 return indexes; 6892 } 6893 6894 function addMarking ( spread, filterFunc, formatter ) { 6895 6896 var element = scope_Document.createElement('div'); 6897 6898 var valueSizeClasses = [ 6899 options.cssClasses.valueNormal, 6900 options.cssClasses.valueLarge, 6901 options.cssClasses.valueSub 6902 ]; 6903 var markerSizeClasses = [ 6904 options.cssClasses.markerNormal, 6905 options.cssClasses.markerLarge, 6906 options.cssClasses.markerSub 6907 ]; 6908 var valueOrientationClasses = [ 6909 options.cssClasses.valueHorizontal, 6910 options.cssClasses.valueVertical 6911 ]; 6912 var markerOrientationClasses = [ 6913 options.cssClasses.markerHorizontal, 6914 options.cssClasses.markerVertical 6915 ]; 6916 6917 addClass(element, options.cssClasses.pips); 6918 addClass(element, options.ort === 0 ? options.cssClasses.pipsHorizontal : options.cssClasses.pipsVertical); 6919 6920 function getClasses( type, source ){ 6921 var a = source === options.cssClasses.value; 6922 var orientationClasses = a ? valueOrientationClasses : markerOrientationClasses; 6923 var sizeClasses = a ? valueSizeClasses : markerSizeClasses; 6924 6925 return source + ' ' + orientationClasses[options.ort] + ' ' + sizeClasses[type]; 6926 } 6927 6928 function addSpread ( offset, values ){ 6929 6930 // Apply the filter function, if it is set. 6931 values[1] = (values[1] && filterFunc) ? filterFunc(values[0], values[1]) : values[1]; 6932 6933 // Add a marker for every point 6934 var node = addNodeTo(element, false); 6935 node.className = getClasses(values[1], options.cssClasses.marker); 6936 node.style[options.style] = offset + '%'; 6937 6938 // Values are only appended for points marked '1' or '2'. 6939 if ( values[1] ) { 6940 node = addNodeTo(element, false); 6941 node.className = getClasses(values[1], options.cssClasses.value); 6942 node.setAttribute('data-value', values[0]); 6943 node.style[options.style] = offset + '%'; 6944 node.innerText = formatter.to(values[0]); 6945 } 6946 } 6947 6948 // Append all points. 6949 Object.keys(spread).forEach(function(a){ 6950 addSpread(a, spread[a]); 6951 }); 6952 6953 return element; 6954 } 6955 6956 function removePips ( ) { 6957 if ( scope_Pips ) { 6958 removeElement(scope_Pips); 6959 scope_Pips = null; 6960 } 6961 } 6962 6963 function pips ( grid ) { 6964 6965 // Fix #669 6966 removePips(); 6967 6968 var mode = grid.mode; 6969 var density = grid.density || 1; 6970 var filter = grid.filter || false; 6971 var values = grid.values || false; 6972 var stepped = grid.stepped || false; 6973 var group = getGroup( mode, values, stepped ); 6974 var spread = generateSpread( density, mode, group ); 6975 var format = grid.format || { 6976 to: Math.round 6977 }; 6978 6979 scope_Pips = scope_Target.appendChild(addMarking( 6980 spread, 6981 filter, 6982 format 6983 )); 6984 6985 return scope_Pips; 6986 } 6987 6988/*! In this file: Browser events (not slider events like slide, change); */ 6989 6990 // Shorthand for base dimensions. 6991 function baseSize ( ) { 6992 var rect = scope_Base.getBoundingClientRect(); 6993 var alt = 'offset' + ['Width', 'Height'][options.ort]; 6994 return options.ort === 0 ? (rect.width||scope_Base[alt]) : (rect.height||scope_Base[alt]); 6995 } 6996 6997 // Handler for attaching events trough a proxy. 6998 function attachEvent ( events, element, callback, data ) { 6999 7000 // This function can be used to 'filter' events to the slider. 7001 // element is a node, not a nodeList 7002 7003 var method = function ( e ){ 7004 7005 e = fixEvent(e, data.pageOffset, data.target || element); 7006 7007 // fixEvent returns false if this event has a different target 7008 // when handling (multi-) touch events; 7009 if ( !e ) { 7010 return false; 7011 } 7012 7013 // doNotReject is passed by all end events to make sure released touches 7014 // are not rejected, leaving the slider "stuck" to the cursor; 7015 if ( scope_Target.hasAttribute('disabled') && !data.doNotReject ) { 7016 return false; 7017 } 7018 7019 // Stop if an active 'tap' transition is taking place. 7020 if ( hasClass(scope_Target, options.cssClasses.tap) && !data.doNotReject ) { 7021 return false; 7022 } 7023 7024 // Ignore right or middle clicks on start #454 7025 if ( events === actions.start && e.buttons !== undefined && e.buttons > 1 ) { 7026 return false; 7027 } 7028 7029 // Ignore right or middle clicks on start #454 7030 if ( data.hover && e.buttons ) { 7031 return false; 7032 } 7033 7034 // 'supportsPassive' is only true if a browser also supports touch-action: none in CSS. 7035 // iOS safari does not, so it doesn't get to benefit from passive scrolling. iOS does support 7036 // touch-action: manipulation, but that allows panning, which breaks 7037 // sliders after zooming/on non-responsive pages. 7038 // See: https://bugs.webkit.org/show_bug.cgi?id=133112 7039 if ( !supportsPassive ) { 7040 e.preventDefault(); 7041 } 7042 7043 e.calcPoint = e.points[ options.ort ]; 7044 7045 // Call the event handler with the event [ and additional data ]. 7046 callback ( e, data ); 7047 }; 7048 7049 var methods = []; 7050 7051 // Bind a closure on the target for every event type. 7052 events.split(' ').forEach(function( eventName ){ 7053 element.addEventListener(eventName, method, supportsPassive ? { passive: true } : false); 7054 methods.push([eventName, method]); 7055 }); 7056 7057 return methods; 7058 } 7059 7060 // Provide a clean event with standardized offset values. 7061 function fixEvent ( e, pageOffset, eventTarget ) { 7062 7063 // Filter the event to register the type, which can be 7064 // touch, mouse or pointer. Offset changes need to be 7065 // made on an event specific basis. 7066 var touch = e.type.indexOf('touch') === 0; 7067 var mouse = e.type.indexOf('mouse') === 0; 7068 var pointer = e.type.indexOf('pointer') === 0; 7069 7070 var x; 7071 var y; 7072 7073 // IE10 implemented pointer events with a prefix; 7074 if ( e.type.indexOf('MSPointer') === 0 ) { 7075 pointer = true; 7076 } 7077 7078 // In the event that multitouch is activated, the only thing one handle should be concerned 7079 // about is the touches that originated on top of it. 7080 if ( touch ) { 7081 7082 // Returns true if a touch originated on the target. 7083 var isTouchOnTarget = function (checkTouch) { 7084 return checkTouch.target === eventTarget || eventTarget.contains(checkTouch.target); 7085 }; 7086 7087 // In the case of touchstart events, we need to make sure there is still no more than one 7088 // touch on the target so we look amongst all touches. 7089 if (e.type === 'touchstart') { 7090 7091 var targetTouches = Array.prototype.filter.call(e.touches, isTouchOnTarget); 7092 7093 // Do not support more than one touch per handle. 7094 if ( targetTouches.length > 1 ) { 7095 return false; 7096 } 7097 7098 x = targetTouches[0].pageX; 7099 y = targetTouches[0].pageY; 7100 7101 } else { 7102 7103 // In the other cases, find on changedTouches is enough. 7104 var targetTouch = Array.prototype.find.call(e.changedTouches, isTouchOnTarget); 7105 7106 // Cancel if the target touch has not moved. 7107 if ( !targetTouch ) { 7108 return false; 7109 } 7110 7111 x = targetTouch.pageX; 7112 y = targetTouch.pageY; 7113 } 7114 } 7115 7116 pageOffset = pageOffset || getPageOffset(scope_Document); 7117 7118 if ( mouse || pointer ) { 7119 x = e.clientX + pageOffset.x; 7120 y = e.clientY + pageOffset.y; 7121 } 7122 7123 e.pageOffset = pageOffset; 7124 e.points = [x, y]; 7125 e.cursor = mouse || pointer; // Fix #435 7126 7127 return e; 7128 } 7129 7130 // Translate a coordinate in the document to a percentage on the slider 7131 function calcPointToPercentage ( calcPoint ) { 7132 var location = calcPoint - offset(scope_Base, options.ort); 7133 var proposal = ( location * 100 ) / baseSize(); 7134 7135 // Clamp proposal between 0% and 100% 7136 // Out-of-bound coordinates may occur when .noUi-base pseudo-elements 7137 // are used (e.g. contained handles feature) 7138 proposal = limit(proposal); 7139 7140 return options.dir ? 100 - proposal : proposal; 7141 } 7142 7143 // Find handle closest to a certain percentage on the slider 7144 function getClosestHandle ( proposal ) { 7145 7146 var closest = 100; 7147 var handleNumber = false; 7148 7149 scope_Handles.forEach(function(handle, index){ 7150 7151 // Disabled handles are ignored 7152 if ( handle.hasAttribute('disabled') ) { 7153 return; 7154 } 7155 7156 var pos = Math.abs(scope_Locations[index] - proposal); 7157 7158 if ( pos < closest || (pos === 100 && closest === 100) ) { 7159 handleNumber = index; 7160 closest = pos; 7161 } 7162 }); 7163 7164 return handleNumber; 7165 } 7166 7167 // Fire 'end' when a mouse or pen leaves the document. 7168 function documentLeave ( event, data ) { 7169 if ( event.type === "mouseout" && event.target.nodeName === "HTML" && event.relatedTarget === null ){ 7170 eventEnd (event, data); 7171 } 7172 } 7173 7174 // Handle movement on document for handle and range drag. 7175 function eventMove ( event, data ) { 7176 7177 // Fix #498 7178 // Check value of .buttons in 'start' to work around a bug in IE10 mobile (data.buttonsProperty). 7179 // https://connect.microsoft.com/IE/feedback/details/927005/mobile-ie10-windows-phone-buttons-property-of-pointermove-event-always-zero 7180 // IE9 has .buttons and .which zero on mousemove. 7181 // Firefox breaks the spec MDN defines. 7182 if ( navigator.appVersion.indexOf("MSIE 9") === -1 && event.buttons === 0 && data.buttonsProperty !== 0 ) { 7183 return eventEnd(event, data); 7184 } 7185 7186 // Check if we are moving up or down 7187 var movement = (options.dir ? -1 : 1) * (event.calcPoint - data.startCalcPoint); 7188 7189 // Convert the movement into a percentage of the slider width/height 7190 var proposal = (movement * 100) / data.baseSize; 7191 7192 moveHandles(movement > 0, proposal, data.locations, data.handleNumbers); 7193 } 7194 7195 // Unbind move events on document, call callbacks. 7196 function eventEnd ( event, data ) { 7197 7198 // The handle is no longer active, so remove the class. 7199 if ( data.handle ) { 7200 removeClass(data.handle, options.cssClasses.active); 7201 scope_ActiveHandlesCount -= 1; 7202 } 7203 7204 // Unbind the move and end events, which are added on 'start'. 7205 data.listeners.forEach(function( c ) { 7206 scope_DocumentElement.removeEventListener(c[0], c[1]); 7207 }); 7208 7209 if ( scope_ActiveHandlesCount === 0 ) { 7210 // Remove dragging class. 7211 removeClass(scope_Target, options.cssClasses.drag); 7212 setZindex(); 7213 7214 // Remove cursor styles and text-selection events bound to the body. 7215 if ( event.cursor ) { 7216 scope_Body.style.cursor = ''; 7217 scope_Body.removeEventListener('selectstart', preventDefault); 7218 } 7219 } 7220 7221 data.handleNumbers.forEach(function(handleNumber){ 7222 fireEvent('change', handleNumber); 7223 fireEvent('set', handleNumber); 7224 fireEvent('end', handleNumber); 7225 }); 7226 } 7227 7228 // Bind move events on document. 7229 function eventStart ( event, data ) { 7230 7231 var handle; 7232 if ( data.handleNumbers.length === 1 ) { 7233 7234 var handleOrigin = scope_Handles[data.handleNumbers[0]]; 7235 7236 // Ignore 'disabled' handles 7237 if ( handleOrigin.hasAttribute('disabled') ) { 7238 return false; 7239 } 7240 7241 handle = handleOrigin.children[0]; 7242 scope_ActiveHandlesCount += 1; 7243 7244 // Mark the handle as 'active' so it can be styled. 7245 addClass(handle, options.cssClasses.active); 7246 } 7247 7248 // A drag should never propagate up to the 'tap' event. 7249 event.stopPropagation(); 7250 7251 // Record the event listeners. 7252 var listeners = []; 7253 7254 // Attach the move and end events. 7255 var moveEvent = attachEvent(actions.move, scope_DocumentElement, eventMove, { 7256 // The event target has changed so we need to propagate the original one so that we keep 7257 // relying on it to extract target touches. 7258 target: event.target, 7259 handle: handle, 7260 listeners: listeners, 7261 startCalcPoint: event.calcPoint, 7262 baseSize: baseSize(), 7263 pageOffset: event.pageOffset, 7264 handleNumbers: data.handleNumbers, 7265 buttonsProperty: event.buttons, 7266 locations: scope_Locations.slice() 7267 }); 7268 7269 var endEvent = attachEvent(actions.end, scope_DocumentElement, eventEnd, { 7270 target: event.target, 7271 handle: handle, 7272 listeners: listeners, 7273 doNotReject: true, 7274 handleNumbers: data.handleNumbers 7275 }); 7276 7277 var outEvent = attachEvent("mouseout", scope_DocumentElement, documentLeave, { 7278 target: event.target, 7279 handle: handle, 7280 listeners: listeners, 7281 doNotReject: true, 7282 handleNumbers: data.handleNumbers 7283 }); 7284 7285 // We want to make sure we pushed the listeners in the listener list rather than creating 7286 // a new one as it has already been passed to the event handlers. 7287 listeners.push.apply(listeners, moveEvent.concat(endEvent, outEvent)); 7288 7289 // Text selection isn't an issue on touch devices, 7290 // so adding cursor styles can be skipped. 7291 if ( event.cursor ) { 7292 7293 // Prevent the 'I' cursor and extend the range-drag cursor. 7294 scope_Body.style.cursor = getComputedStyle(event.target).cursor; 7295 7296 // Mark the target with a dragging state. 7297 if ( scope_Handles.length > 1 ) { 7298 addClass(scope_Target, options.cssClasses.drag); 7299 } 7300 7301 // Prevent text selection when dragging the handles. 7302 // In noUiSlider <= 9.2.0, this was handled by calling preventDefault on mouse/touch start/move, 7303 // which is scroll blocking. The selectstart event is supported by FireFox starting from version 52, 7304 // meaning the only holdout is iOS Safari. This doesn't matter: text selection isn't triggered there. 7305 // The 'cursor' flag is false. 7306 // See: http://caniuse.com/#search=selectstart 7307 scope_Body.addEventListener('selectstart', preventDefault, false); 7308 } 7309 7310 data.handleNumbers.forEach(function(handleNumber){ 7311 fireEvent('start', handleNumber); 7312 }); 7313 } 7314 7315 // Move closest handle to tapped location. 7316 function eventTap ( event ) { 7317 7318 // The tap event shouldn't propagate up 7319 event.stopPropagation(); 7320 7321 var proposal = calcPointToPercentage(event.calcPoint); 7322 var handleNumber = getClosestHandle(proposal); 7323 7324 // Tackle the case that all handles are 'disabled'. 7325 if ( handleNumber === false ) { 7326 return false; 7327 } 7328 7329 // Flag the slider as it is now in a transitional state. 7330 // Transition takes a configurable amount of ms (default 300). Re-enable the slider after that. 7331 if ( !options.events.snap ) { 7332 addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration); 7333 } 7334 7335 setHandle(handleNumber, proposal, true, true); 7336 7337 setZindex(); 7338 7339 fireEvent('slide', handleNumber, true); 7340 fireEvent('update', handleNumber, true); 7341 fireEvent('change', handleNumber, true); 7342 fireEvent('set', handleNumber, true); 7343 7344 if ( options.events.snap ) { 7345 eventStart(event, { handleNumbers: [handleNumber] }); 7346 } 7347 } 7348 7349 // Fires a 'hover' event for a hovered mouse/pen position. 7350 function eventHover ( event ) { 7351 7352 var proposal = calcPointToPercentage(event.calcPoint); 7353 7354 var to = scope_Spectrum.getStep(proposal); 7355 var value = scope_Spectrum.fromStepping(to); 7356 7357 Object.keys(scope_Events).forEach(function( targetEvent ) { 7358 if ( 'hover' === targetEvent.split('.')[0] ) { 7359 scope_Events[targetEvent].forEach(function( callback ) { 7360 callback.call( scope_Self, value ); 7361 }); 7362 } 7363 }); 7364 } 7365 7366 // Attach events to several slider parts. 7367 function bindSliderEvents ( behaviour ) { 7368 7369 // Attach the standard drag event to the handles. 7370 if ( !behaviour.fixed ) { 7371 7372 scope_Handles.forEach(function( handle, index ){ 7373 7374 // These events are only bound to the visual handle 7375 // element, not the 'real' origin element. 7376 attachEvent ( actions.start, handle.children[0], eventStart, { 7377 handleNumbers: [index] 7378 }); 7379 }); 7380 } 7381 7382 // Attach the tap event to the slider base. 7383 if ( behaviour.tap ) { 7384 attachEvent (actions.start, scope_Base, eventTap, {}); 7385 } 7386 7387 // Fire hover events 7388 if ( behaviour.hover ) { 7389 attachEvent (actions.move, scope_Base, eventHover, { hover: true }); 7390 } 7391 7392 // Make the range draggable. 7393 if ( behaviour.drag ){ 7394 7395 scope_Connects.forEach(function( connect, index ){ 7396 7397 if ( connect === false || index === 0 || index === scope_Connects.length - 1 ) { 7398 return; 7399 } 7400 7401 var handleBefore = scope_Handles[index - 1]; 7402 var handleAfter = scope_Handles[index]; 7403 var eventHolders = [connect]; 7404 7405 addClass(connect, options.cssClasses.draggable); 7406 7407 // When the range is fixed, the entire range can 7408 // be dragged by the handles. The handle in the first 7409 // origin will propagate the start event upward, 7410 // but it needs to be bound manually on the other. 7411 if ( behaviour.fixed ) { 7412 eventHolders.push(handleBefore.children[0]); 7413 eventHolders.push(handleAfter.children[0]); 7414 } 7415 7416 eventHolders.forEach(function( eventHolder ) { 7417 attachEvent ( actions.start, eventHolder, eventStart, { 7418 handles: [handleBefore, handleAfter], 7419 handleNumbers: [index - 1, index] 7420 }); 7421 }); 7422 }); 7423 } 7424 } 7425 7426/*! In this file: Slider events (not browser events); */ 7427 7428 // Attach an event to this slider, possibly including a namespace 7429 function bindEvent ( namespacedEvent, callback ) { 7430 scope_Events[namespacedEvent] = scope_Events[namespacedEvent] || []; 7431 scope_Events[namespacedEvent].push(callback); 7432 7433 // If the event bound is 'update,' fire it immediately for all handles. 7434 if ( namespacedEvent.split('.')[0] === 'update' ) { 7435 scope_Handles.forEach(function(a, index){ 7436 fireEvent('update', index); 7437 }); 7438 } 7439 } 7440 7441 // Undo attachment of event 7442 function removeEvent ( namespacedEvent ) { 7443 7444 var event = namespacedEvent && namespacedEvent.split('.')[0]; 7445 var namespace = event && namespacedEvent.substring(event.length); 7446 7447 Object.keys(scope_Events).forEach(function( bind ){ 7448 7449 var tEvent = bind.split('.')[0]; 7450 var tNamespace = bind.substring(tEvent.length); 7451 7452 if ( (!event || event === tEvent) && (!namespace || namespace === tNamespace) ) { 7453 delete scope_Events[bind]; 7454 } 7455 }); 7456 } 7457 7458 // External event handling 7459 function fireEvent ( eventName, handleNumber, tap ) { 7460 7461 Object.keys(scope_Events).forEach(function( targetEvent ) { 7462 7463 var eventType = targetEvent.split('.')[0]; 7464 7465 if ( eventName === eventType ) { 7466 scope_Events[targetEvent].forEach(function( callback ) { 7467 7468 callback.call( 7469 // Use the slider public API as the scope ('this') 7470 scope_Self, 7471 // Return values as array, so arg_1[arg_2] is always valid. 7472 scope_Values.map(options.format.to), 7473 // Handle index, 0 or 1 7474 handleNumber, 7475 // Unformatted slider values 7476 scope_Values.slice(), 7477 // Event is fired by tap, true or false 7478 tap || false, 7479 // Left offset of the handle, in relation to the slider 7480 scope_Locations.slice() 7481 ); 7482 }); 7483 } 7484 }); 7485 } 7486 7487/*! In this file: Mechanics for slider operation */ 7488 7489 function toPct ( pct ) { 7490 return pct + '%'; 7491 } 7492 7493 // Split out the handle positioning logic so the Move event can use it, too 7494 function checkHandlePosition ( reference, handleNumber, to, lookBackward, lookForward, getValue ) { 7495 7496 // For sliders with multiple handles, limit movement to the other handle. 7497 // Apply the margin option by adding it to the handle positions. 7498 if ( scope_Handles.length > 1 ) { 7499 7500 if ( lookBackward && handleNumber > 0 ) { 7501 to = Math.max(to, reference[handleNumber - 1] + options.margin); 7502 } 7503 7504 if ( lookForward && handleNumber < scope_Handles.length - 1 ) { 7505 to = Math.min(to, reference[handleNumber + 1] - options.margin); 7506 } 7507 } 7508 7509 // The limit option has the opposite effect, limiting handles to a 7510 // maximum distance from another. Limit must be > 0, as otherwise 7511 // handles would be unmoveable. 7512 if ( scope_Handles.length > 1 && options.limit ) { 7513 7514 if ( lookBackward && handleNumber > 0 ) { 7515 to = Math.min(to, reference[handleNumber - 1] + options.limit); 7516 } 7517 7518 if ( lookForward && handleNumber < scope_Handles.length - 1 ) { 7519 to = Math.max(to, reference[handleNumber + 1] - options.limit); 7520 } 7521 } 7522 7523 // The padding option keeps the handles a certain distance from the 7524 // edges of the slider. Padding must be > 0. 7525 if ( options.padding ) { 7526 7527 if ( handleNumber === 0 ) { 7528 to = Math.max(to, options.padding[0]); 7529 } 7530 7531 if ( handleNumber === scope_Handles.length - 1 ) { 7532 to = Math.min(to, 100 - options.padding[1]); 7533 } 7534 } 7535 7536 to = scope_Spectrum.getStep(to); 7537 7538 // Limit percentage to the 0 - 100 range 7539 to = limit(to); 7540 7541 // Return false if handle can't move 7542 if ( to === reference[handleNumber] && !getValue ) { 7543 return false; 7544 } 7545 7546 return to; 7547 } 7548 7549 // Uses slider orientation to create CSS rules. a = base value; 7550 function inRuleOrder ( v, a ) { 7551 var o = options.ort; 7552 return (o?a:v) + ', ' + (o?v:a); 7553 } 7554 7555 // Moves handle(s) by a percentage 7556 // (bool, % to move, [% where handle started, ...], [index in scope_Handles, ...]) 7557 function moveHandles ( upward, proposal, locations, handleNumbers ) { 7558 7559 var proposals = locations.slice(); 7560 7561 var b = [!upward, upward]; 7562 var f = [upward, !upward]; 7563 7564 // Copy handleNumbers so we don't change the dataset 7565 handleNumbers = handleNumbers.slice(); 7566 7567 // Check to see which handle is 'leading'. 7568 // If that one can't move the second can't either. 7569 if ( upward ) { 7570 handleNumbers.reverse(); 7571 } 7572 7573 // Step 1: get the maximum percentage that any of the handles can move 7574 if ( handleNumbers.length > 1 ) { 7575 7576 handleNumbers.forEach(function(handleNumber, o) { 7577 7578 var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false); 7579 7580 // Stop if one of the handles can't move. 7581 if ( to === false ) { 7582 proposal = 0; 7583 } else { 7584 proposal = to - proposals[handleNumber]; 7585 proposals[handleNumber] = to; 7586 } 7587 }); 7588 } 7589 7590 // If using one handle, check backward AND forward 7591 else { 7592 b = f = [true]; 7593 } 7594 7595 var state = false; 7596 7597 // Step 2: Try to set the handles with the found percentage 7598 handleNumbers.forEach(function(handleNumber, o) { 7599 state = setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o]) || state; 7600 }); 7601 7602 // Step 3: If a handle moved, fire events 7603 if ( state ) { 7604 handleNumbers.forEach(function(handleNumber){ 7605 fireEvent('update', handleNumber); 7606 fireEvent('slide', handleNumber); 7607 }); 7608 } 7609 } 7610 7611 // Takes a base value and an offset. This offset is used for the connect bar size. 7612 // In the initial design for this feature, the origin element was 1% wide. 7613 // Unfortunately, a rounding bug in Chrome makes it impossible to implement this feature 7614 // in this manner: https://bugs.chromium.org/p/chromium/issues/detail?id=798223 7615 function transformDirection ( a, b ) { 7616 return options.dir ? 100 - a - b : a; 7617 } 7618 7619 // Updates scope_Locations and scope_Values, updates visual state 7620 function updateHandlePosition ( handleNumber, to ) { 7621 7622 // Update locations. 7623 scope_Locations[handleNumber] = to; 7624 7625 // Convert the value to the slider stepping/range. 7626 scope_Values[handleNumber] = scope_Spectrum.fromStepping(to); 7627 7628 var rule = 'translate(' + inRuleOrder(toPct(transformDirection(to, 0) - scope_DirOffset), '0') + ')'; 7629 scope_Handles[handleNumber].style[options.transformRule] = rule; 7630 7631 updateConnect(handleNumber); 7632 updateConnect(handleNumber + 1); 7633 } 7634 7635 // Handles before the slider middle are stacked later = higher, 7636 // Handles after the middle later is lower 7637 // [[7] [8] .......... | .......... [5] [4] 7638 function setZindex ( ) { 7639 7640 scope_HandleNumbers.forEach(function(handleNumber){ 7641 var dir = (scope_Locations[handleNumber] > 50 ? -1 : 1); 7642 var zIndex = 3 + (scope_Handles.length + (dir * handleNumber)); 7643 scope_Handles[handleNumber].style.zIndex = zIndex; 7644 }); 7645 } 7646 7647 // Test suggested values and apply margin, step. 7648 function setHandle ( handleNumber, to, lookBackward, lookForward ) { 7649 7650 to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false); 7651 7652 if ( to === false ) { 7653 return false; 7654 } 7655 7656 updateHandlePosition(handleNumber, to); 7657 7658 return true; 7659 } 7660 7661 // Updates style attribute for connect nodes 7662 function updateConnect ( index ) { 7663 7664 // Skip connects set to false 7665 if ( !scope_Connects[index] ) { 7666 return; 7667 } 7668 7669 var l = 0; 7670 var h = 100; 7671 7672 if ( index !== 0 ) { 7673 l = scope_Locations[index - 1]; 7674 } 7675 7676 if ( index !== scope_Connects.length - 1 ) { 7677 h = scope_Locations[index]; 7678 } 7679 7680 // We use two rules: 7681 // 'translate' to change the left/top offset; 7682 // 'scale' to change the width of the element; 7683 // As the element has a width of 100%, a translation of 100% is equal to 100% of the parent (.noUi-base) 7684 var connectWidth = h - l; 7685 var translateRule = 'translate(' + inRuleOrder(toPct(transformDirection(l, connectWidth)), '0') + ')'; 7686 var scaleRule = 'scale(' + inRuleOrder(connectWidth / 100, '1') + ')'; 7687 7688 scope_Connects[index].style[options.transformRule] = translateRule + ' ' + scaleRule; 7689 } 7690 7691/*! In this file: All methods eventually exposed in slider.noUiSlider... */ 7692 7693 // Parses value passed to .set method. Returns current value if not parse-able. 7694 function resolveToValue ( to, handleNumber ) { 7695 7696 // Setting with null indicates an 'ignore'. 7697 // Inputting 'false' is invalid. 7698 if ( to === null || to === false || to === undefined ) { 7699 return scope_Locations[handleNumber]; 7700 } 7701 7702 // If a formatted number was passed, attempt to decode it. 7703 if ( typeof to === 'number' ) { 7704 to = String(to); 7705 } 7706 7707 to = options.format.from(to); 7708 to = scope_Spectrum.toStepping(to); 7709 7710 // If parsing the number failed, use the current value. 7711 if ( to === false || isNaN(to) ) { 7712 return scope_Locations[handleNumber]; 7713 } 7714 7715 return to; 7716 } 7717 7718 // Set the slider value. 7719 function valueSet ( input, fireSetEvent ) { 7720 7721 var values = asArray(input); 7722 var isInit = scope_Locations[0] === undefined; 7723 7724 // Event fires by default 7725 fireSetEvent = (fireSetEvent === undefined ? true : !!fireSetEvent); 7726 7727 // Animation is optional. 7728 // Make sure the initial values were set before using animated placement. 7729 if ( options.animate && !isInit ) { 7730 addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration); 7731 } 7732 7733 // First pass, without lookAhead but with lookBackward. Values are set from left to right. 7734 scope_HandleNumbers.forEach(function(handleNumber){ 7735 setHandle(handleNumber, resolveToValue(values[handleNumber], handleNumber), true, false); 7736 }); 7737 7738 // Second pass. Now that all base values are set, apply constraints 7739 scope_HandleNumbers.forEach(function(handleNumber){ 7740 setHandle(handleNumber, scope_Locations[handleNumber], true, true); 7741 }); 7742 7743 setZindex(); 7744 7745 scope_HandleNumbers.forEach(function(handleNumber){ 7746 7747 fireEvent('update', handleNumber); 7748 7749 // Fire the event only for handles that received a new value, as per #579 7750 if ( values[handleNumber] !== null && fireSetEvent ) { 7751 fireEvent('set', handleNumber); 7752 } 7753 }); 7754 } 7755 7756 // Reset slider to initial values 7757 function valueReset ( fireSetEvent ) { 7758 valueSet(options.start, fireSetEvent); 7759 } 7760 7761 // Get the slider value. 7762 function valueGet ( ) { 7763 7764 var values = scope_Values.map(options.format.to); 7765 7766 // If only one handle is used, return a single value. 7767 if ( values.length === 1 ){ 7768 return values[0]; 7769 } 7770 7771 return values; 7772 } 7773 7774 // Removes classes from the root and empties it. 7775 function destroy ( ) { 7776 7777 for ( var key in options.cssClasses ) { 7778 if ( !options.cssClasses.hasOwnProperty(key) ) { continue; } 7779 removeClass(scope_Target, options.cssClasses[key]); 7780 } 7781 7782 while (scope_Target.firstChild) { 7783 scope_Target.removeChild(scope_Target.firstChild); 7784 } 7785 7786 delete scope_Target.noUiSlider; 7787 } 7788 7789 // Get the current step size for the slider. 7790 function getCurrentStep ( ) { 7791 7792 // Check all locations, map them to their stepping point. 7793 // Get the step point, then find it in the input list. 7794 return scope_Locations.map(function( location, index ){ 7795 7796 var nearbySteps = scope_Spectrum.getNearbySteps( location ); 7797 var value = scope_Values[index]; 7798 var increment = nearbySteps.thisStep.step; 7799 var decrement = null; 7800 7801 // If the next value in this step moves into the next step, 7802 // the increment is the start of the next step - the current value 7803 if ( increment !== false ) { 7804 if ( value + increment > nearbySteps.stepAfter.startValue ) { 7805 increment = nearbySteps.stepAfter.startValue - value; 7806 } 7807 } 7808 7809 7810 // If the value is beyond the starting point 7811 if ( value > nearbySteps.thisStep.startValue ) { 7812 decrement = nearbySteps.thisStep.step; 7813 } 7814 7815 else if ( nearbySteps.stepBefore.step === false ) { 7816 decrement = false; 7817 } 7818 7819 // If a handle is at the start of a step, it always steps back into the previous step first 7820 else { 7821 decrement = value - nearbySteps.stepBefore.highestStep; 7822 } 7823 7824 7825 // Now, if at the slider edges, there is not in/decrement 7826 if ( location === 100 ) { 7827 increment = null; 7828 } 7829 7830 else if ( location === 0 ) { 7831 decrement = null; 7832 } 7833 7834 // As per #391, the comparison for the decrement step can have some rounding issues. 7835 var stepDecimals = scope_Spectrum.countStepDecimals(); 7836 7837 // Round per #391 7838 if ( increment !== null && increment !== false ) { 7839 increment = Number(increment.toFixed(stepDecimals)); 7840 } 7841 7842 if ( decrement !== null && decrement !== false ) { 7843 decrement = Number(decrement.toFixed(stepDecimals)); 7844 } 7845 7846 return [decrement, increment]; 7847 }); 7848 } 7849 7850 // Updateable: margin, limit, padding, step, range, animate, snap 7851 function updateOptions ( optionsToUpdate, fireSetEvent ) { 7852 7853 // Spectrum is created using the range, snap, direction and step options. 7854 // 'snap' and 'step' can be updated. 7855 // If 'snap' and 'step' are not passed, they should remain unchanged. 7856 var v = valueGet(); 7857 7858 var updateAble = ['margin', 'limit', 'padding', 'range', 'animate', 'snap', 'step', 'format']; 7859 7860 // Only change options that we're actually passed to update. 7861 updateAble.forEach(function(name){ 7862 if ( optionsToUpdate[name] !== undefined ) { 7863 originalOptions[name] = optionsToUpdate[name]; 7864 } 7865 }); 7866 7867 var newOptions = testOptions(originalOptions); 7868 7869 // Load new options into the slider state 7870 updateAble.forEach(function(name){ 7871 if ( optionsToUpdate[name] !== undefined ) { 7872 options[name] = newOptions[name]; 7873 } 7874 }); 7875 7876 scope_Spectrum = newOptions.spectrum; 7877 7878 // Limit, margin and padding depend on the spectrum but are stored outside of it. (#677) 7879 options.margin = newOptions.margin; 7880 options.limit = newOptions.limit; 7881 options.padding = newOptions.padding; 7882 7883 // Update pips, removes existing. 7884 if ( options.pips ) { 7885 pips(options.pips); 7886 } 7887 7888 // Invalidate the current positioning so valueSet forces an update. 7889 scope_Locations = []; 7890 valueSet(optionsToUpdate.start || v, fireSetEvent); 7891 } 7892 7893/*! In this file: Calls to functions. All other scope_ files define functions only; */ 7894 7895 // Create the base element, initialize HTML and set classes. 7896 // Add handles and connect elements. 7897 addSlider(scope_Target); 7898 addElements(options.connect, scope_Base); 7899 7900 // Attach user events. 7901 bindSliderEvents(options.events); 7902 7903 // Use the public value method to set the start values. 7904 valueSet(options.start); 7905 7906 scope_Self = { 7907 destroy: destroy, 7908 steps: getCurrentStep, 7909 on: bindEvent, 7910 off: removeEvent, 7911 get: valueGet, 7912 set: valueSet, 7913 reset: valueReset, 7914 // Exposed for unit testing, don't use this in your application. 7915 __moveHandles: function(a, b, c) { moveHandles(a, b, scope_Locations, c); }, 7916 options: originalOptions, // Issue #600, #678 7917 updateOptions: updateOptions, 7918 target: scope_Target, // Issue #597 7919 removePips: removePips, 7920 pips: pips // Issue #594 7921 }; 7922 7923 if ( options.pips ) { 7924 pips(options.pips); 7925 } 7926 7927 if ( options.tooltips ) { 7928 tooltips(); 7929 } 7930 7931 aria(); 7932 7933 return scope_Self; 7934 7935} 7936 7937 7938 // Run the standard initializer 7939 function initialize ( target, originalOptions ) { 7940 7941 if ( !target || !target.nodeName ) { 7942 throw new Error("noUiSlider (" + VERSION + "): create requires a single element, got: " + target); 7943 } 7944 7945 // Throw an error if the slider was already initialized. 7946 if ( target.noUiSlider ) { 7947 throw new Error("noUiSlider (" + VERSION + "): Slider was already initialized."); 7948 } 7949 7950 // Test the options and create the slider environment; 7951 var options = testOptions( originalOptions, target ); 7952 var api = scope( target, options, originalOptions ); 7953 7954 target.noUiSlider = api; 7955 7956 return api; 7957 } 7958 7959 // Use an object instead of a function for future expandability; 7960 return { 7961 version: VERSION, 7962 create: initialize 7963 }; 7964 7965})); 7966 7967/***/ }), 7968
vendor: 92,636 bytes, lines 7969-10989
7969/***/ "./node_modules/slick-carousel/slick/slick.js": 7970/*!****************************************************!*\ 7971 !*** ./node_modules/slick-carousel/slick/slick.js ***! 7972 \****************************************************/ 7973/*! no static exports found */ 7974/***/ (function(module, exports, __webpack_require__) { 7975 7976var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* 7977 _ _ _ _ 7978 ___| (_) ___| | __ (_)___ 7979/ __| | |/ __| |/ / | / __| 7980\__ \ | | (__| < _ | \__ \ 7981|___/_|_|\___|_|\_(_)/ |___/ 7982 |__/ 7983 7984 Version: 1.8.1 7985 Author: Ken Wheeler 7986 Website: http://kenwheeler.github.io 7987 Docs: http://kenwheeler.github.io/slick 7988 Repo: http://github.com/kenwheeler/slick 7989 Issues: http://github.com/kenwheeler/slick/issues 7990 7991 */ 7992/* global window, document, define, jQuery, setInterval, clearInterval */ 7993;(function(factory) { 7994 'use strict'; 7995 if (true) { 7996 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 7997 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 7998 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 7999 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 8000 } else {} 8001 8002}(function($) { 8003 'use strict'; 8004 var Slick = window.Slick || {}; 8005 8006 Slick = (function() { 8007 8008 var instanceUid = 0; 8009 8010 function Slick(element, settings) { 8011 8012 var _ = this, dataSettings; 8013 8014 _.defaults = { 8015 accessibility: true, 8016 adaptiveHeight: false, 8017 appendArrows: $(element), 8018 appendDots: $(element), 8019 arrows: true, 8020 asNavFor: null, 8021 prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>', 8022 nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>', 8023 autoplay: false, 8024 autoplaySpeed: 3000, 8025 centerMode: false, 8026 centerPadding: '50px', 8027 cssEase: 'ease', 8028 customPaging: function(slider, i) { 8029 return $('<button type="button" />').text(i + 1); 8030 }, 8031 dots: false, 8032 dotsClass: 'slick-dots', 8033 draggable: true, 8034 easing: 'linear', 8035 edgeFriction: 0.35, 8036 fade: false, 8037 focusOnSelect: false, 8038 focusOnChange: false, 8039 infinite: true, 8040 initialSlide: 0, 8041 lazyLoad: 'ondemand', 8042 mobileFirst: false, 8043 pauseOnHover: true, 8044 pauseOnFocus: true, 8045 pauseOnDotsHover: false, 8046 respondTo: 'window', 8047 responsive: null, 8048 rows: 1, 8049 rtl: false, 8050 slide: '', 8051 slidesPerRow: 1, 8052 slidesToShow: 1, 8053 slidesToScroll: 1, 8054 speed: 500, 8055 swipe: true, 8056 swipeToSlide: false, 8057 touchMove: true, 8058 touchThreshold: 5, 8059 useCSS: true, 8060 useTransform: true, 8061 variableWidth: false, 8062 vertical: false, 8063 verticalSwiping: false, 8064 waitForAnimate: true, 8065 zIndex: 1000 8066 }; 8067 8068 _.initials = { 8069 animating: false, 8070 dragging: false, 8071 autoPlayTimer: null, 8072 currentDirection: 0, 8073 currentLeft: null, 8074 currentSlide: 0, 8075 direction: 1, 8076 $dots: null, 8077 listWidth: null, 8078 listHeight: null, 8079 loadIndex: 0, 8080 $nextArrow: null, 8081 $prevArrow: null, 8082 scrolling: false, 8083 slideCount: null, 8084 slideWidth: null, 8085 $slideTrack: null, 8086 $slides: null, 8087 sliding: false, 8088 slideOffset: 0, 8089 swipeLeft: null, 8090 swiping: false, 8091 $list: null, 8092 touchObject: {}, 8093 transformsEnabled: false, 8094 unslicked: false 8095 }; 8096 8097 $.extend(_, _.initials); 8098 8099 _.activeBreakpoint = null; 8100 _.animType = null; 8101 _.animProp = null; 8102 _.breakpoints = []; 8103 _.breakpointSettings = []; 8104 _.cssTransitions = false; 8105 _.focussed = false; 8106 _.interrupted = false; 8107 _.hidden = 'hidden'; 8108 _.paused = true; 8109 _.positionProp = null; 8110 _.respondTo = null; 8111 _.rowCount = 1; 8112 _.shouldClick = true; 8113 _.$slider = $(element); 8114 _.$slidesCache = null; 8115 _.transformType = null; 8116 _.transitionType = null; 8117 _.visibilityChange = 'visibilitychange'; 8118 _.windowWidth = 0; 8119 _.windowTimer = null; 8120 8121 dataSettings = $(element).data('slick') || {}; 8122 8123 _.options = $.extend({}, _.defaults, settings, dataSettings); 8124 8125 _.currentSlide = _.options.initialSlide; 8126 8127 _.originalSettings = _.options; 8128 8129 if (typeof document.mozHidden !== 'undefined') { 8130 _.hidden = 'mozHidden'; 8131 _.visibilityChange = 'mozvisibilitychange'; 8132 } else if (typeof document.webkitHidden !== 'undefined') { 8133 _.hidden = 'webkitHidden'; 8134 _.visibilityChange = 'webkitvisibilitychange'; 8135 } 8136 8137 _.autoPlay = $.proxy(_.autoPlay, _); 8138 _.autoPlayClear = $.proxy(_.autoPlayClear, _); 8139 _.autoPlayIterator = $.proxy(_.autoPlayIterator, _); 8140 _.changeSlide = $.proxy(_.changeSlide, _); 8141 _.clickHandler = $.proxy(_.clickHandler, _); 8142 _.selectHandler = $.proxy(_.selectHandler, _); 8143 _.setPosition = $.proxy(_.setPosition, _); 8144 _.swipeHandler = $.proxy(_.swipeHandler, _); 8145 _.dragHandler = $.proxy(_.dragHandler, _); 8146 _.keyHandler = $.proxy(_.keyHandler, _); 8147 8148 _.instanceUid = instanceUid++; 8149 8150 // A simple way to check for HTML strings 8151 // Strict HTML recognition (must start with <) 8152 // Extracted from jQuery v1.11 source 8153 _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/; 8154 8155 8156 _.registerBreakpoints(); 8157 _.init(true); 8158 8159 } 8160 8161 return Slick; 8162 8163 }()); 8164 8165 Slick.prototype.activateADA = function() { 8166 var _ = this; 8167 8168 _.$slideTrack.find('.slick-active').attr({ 8169 'aria-hidden': 'false' 8170 }).find('a, input, button, select').attr({ 8171 'tabindex': '0' 8172 }); 8173 8174 }; 8175 8176 Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) { 8177 8178 var _ = this; 8179 8180 if (typeof(index) === 'boolean') { 8181 addBefore = index; 8182 index = null; 8183 } else if (index < 0 || (index >= _.slideCount)) { 8184 return false; 8185 } 8186 8187 _.unload(); 8188 8189 if (typeof(index) === 'number') { 8190 if (index === 0 && _.$slides.length === 0) { 8191 $(markup).appendTo(_.$slideTrack); 8192 } else if (addBefore) { 8193 $(markup).insertBefore(_.$slides.eq(index)); 8194 } else { 8195 $(markup).insertAfter(_.$slides.eq(index)); 8196 } 8197 } else { 8198 if (addBefore === true) { 8199 $(markup).prependTo(_.$slideTrack); 8200 } else { 8201 $(markup).appendTo(_.$slideTrack); 8202 } 8203 } 8204 8205 _.$slides = _.$slideTrack.children(this.options.slide); 8206 8207 _.$slideTrack.children(this.options.slide).detach(); 8208 8209 _.$slideTrack.append(_.$slides); 8210 8211 _.$slides.each(function(index, element) { 8212 $(element).attr('data-slick-index', index); 8213 }); 8214 8215 _.$slidesCache = _.$slides; 8216 8217 _.reinit(); 8218 8219 }; 8220 8221 Slick.prototype.animateHeight = function() { 8222 var _ = this; 8223 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 8224 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 8225 _.$list.animate({ 8226 height: targetHeight 8227 }, _.options.speed); 8228 } 8229 }; 8230 8231 Slick.prototype.animateSlide = function(targetLeft, callback) { 8232 8233 var animProps = {}, 8234 _ = this; 8235 8236 _.animateHeight(); 8237 8238 if (_.options.rtl === true && _.options.vertical === false) { 8239 targetLeft = -targetLeft; 8240 } 8241 if (_.transformsEnabled === false) { 8242 if (_.options.vertical === false) { 8243 _.$slideTrack.animate({ 8244 left: targetLeft 8245 }, _.options.speed, _.options.easing, callback); 8246 } else { 8247 _.$slideTrack.animate({ 8248 top: targetLeft 8249 }, _.options.speed, _.options.easing, callback); 8250 } 8251 8252 } else { 8253 8254 if (_.cssTransitions === false) { 8255 if (_.options.rtl === true) { 8256 _.currentLeft = -(_.currentLeft); 8257 } 8258 $({ 8259 animStart: _.currentLeft 8260 }).animate({ 8261 animStart: targetLeft 8262 }, { 8263 duration: _.options.speed, 8264 easing: _.options.easing, 8265 step: function(now) { 8266 now = Math.ceil(now); 8267 if (_.options.vertical === false) { 8268 animProps[_.animType] = 'translate(' + 8269 now + 'px, 0px)'; 8270 _.$slideTrack.css(animProps); 8271 } else { 8272 animProps[_.animType] = 'translate(0px,' + 8273 now + 'px)'; 8274 _.$slideTrack.css(animProps); 8275 } 8276 }, 8277 complete: function() { 8278 if (callback) { 8279 callback.call(); 8280 } 8281 } 8282 }); 8283 8284 } else { 8285 8286 _.applyTransition(); 8287 targetLeft = Math.ceil(targetLeft); 8288 8289 if (_.options.vertical === false) { 8290 animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)'; 8291 } else { 8292 animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)'; 8293 } 8294 _.$slideTrack.css(animProps); 8295 8296 if (callback) { 8297 setTimeout(function() { 8298 8299 _.disableTransition(); 8300 8301 callback.call(); 8302 }, _.options.speed); 8303 } 8304 8305 } 8306 8307 } 8308 8309 }; 8310 8311 Slick.prototype.getNavTarget = function() { 8312 8313 var _ = this, 8314 asNavFor = _.options.asNavFor; 8315 8316 if ( asNavFor && asNavFor !== null ) { 8317 asNavFor = $(asNavFor).not(_.$slider); 8318 } 8319 8320 return asNavFor; 8321 8322 }; 8323 8324 Slick.prototype.asNavFor = function(index) { 8325 8326 var _ = this, 8327 asNavFor = _.getNavTarget(); 8328 8329 if ( asNavFor !== null && typeof asNavFor === 'object' ) { 8330 asNavFor.each(function() { 8331 var target = $(this).slick('getSlick'); 8332 if(!target.unslicked) { 8333 target.slideHandler(index, true); 8334 } 8335 }); 8336 } 8337 8338 }; 8339 8340 Slick.prototype.applyTransition = function(slide) { 8341 8342 var _ = this, 8343 transition = {}; 8344 8345 if (_.options.fade === false) { 8346 transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase; 8347 } else { 8348 transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase; 8349 } 8350 8351 if (_.options.fade === false) { 8352 _.$slideTrack.css(transition); 8353 } else { 8354 _.$slides.eq(slide).css(transition); 8355 } 8356 8357 }; 8358 8359 Slick.prototype.autoPlay = function() { 8360 8361 var _ = this; 8362 8363 _.autoPlayClear(); 8364 8365 if ( _.slideCount > _.options.slidesToShow ) { 8366 _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed ); 8367 } 8368 8369 }; 8370 8371 Slick.prototype.autoPlayClear = function() { 8372 8373 var _ = this; 8374 8375 if (_.autoPlayTimer) { 8376 clearInterval(_.autoPlayTimer); 8377 } 8378 8379 }; 8380 8381 Slick.prototype.autoPlayIterator = function() { 8382 8383 var _ = this, 8384 slideTo = _.currentSlide + _.options.slidesToScroll; 8385 8386 if ( !_.paused && !_.interrupted && !_.focussed ) { 8387 8388 if ( _.options.infinite === false ) { 8389 8390 if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) { 8391 _.direction = 0; 8392 } 8393 8394 else if ( _.direction === 0 ) { 8395 8396 slideTo = _.currentSlide - _.options.slidesToScroll; 8397 8398 if ( _.currentSlide - 1 === 0 ) { 8399 _.direction = 1; 8400 } 8401 8402 } 8403 8404 } 8405 8406 _.slideHandler( slideTo ); 8407 8408 } 8409 8410 }; 8411 8412 Slick.prototype.buildArrows = function() { 8413 8414 var _ = this; 8415 8416 if (_.options.arrows === true ) { 8417 8418 _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow'); 8419 _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow'); 8420 8421 if( _.slideCount > _.options.slidesToShow ) { 8422 8423 _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 8424 _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 8425 8426 if (_.htmlExpr.test(_.options.prevArrow)) { 8427 _.$prevArrow.prependTo(_.options.appendArrows); 8428 } 8429 8430 if (_.htmlExpr.test(_.options.nextArrow)) { 8431 _.$nextArrow.appendTo(_.options.appendArrows); 8432 } 8433 8434 if (_.options.infinite !== true) { 8435 _.$prevArrow 8436 .addClass('slick-disabled') 8437 .attr('aria-disabled', 'true'); 8438 } 8439 8440 } else { 8441 8442 _.$prevArrow.add( _.$nextArrow ) 8443 8444 .addClass('slick-hidden') 8445 .attr({ 8446 'aria-disabled': 'true', 8447 'tabindex': '-1' 8448 }); 8449 8450 } 8451 8452 } 8453 8454 }; 8455 8456 Slick.prototype.buildDots = function() { 8457 8458 var _ = this, 8459 i, dot; 8460 8461 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 8462 8463 _.$slider.addClass('slick-dotted'); 8464 8465 dot = $('<ul />').addClass(_.options.dotsClass); 8466 8467 for (i = 0; i <= _.getDotCount(); i += 1) { 8468 dot.append($('<li />').append(_.options.customPaging.call(this, _, i))); 8469 } 8470 8471 _.$dots = dot.appendTo(_.options.appendDots); 8472 8473 _.$dots.find('li').first().addClass('slick-active'); 8474 8475 } 8476 8477 }; 8478 8479 Slick.prototype.buildOut = function() { 8480 8481 var _ = this; 8482 8483 _.$slides = 8484 _.$slider 8485 .children( _.options.slide + ':not(.slick-cloned)') 8486 .addClass('slick-slide'); 8487 8488 _.slideCount = _.$slides.length; 8489 8490 _.$slides.each(function(index, element) { 8491 $(element) 8492 .attr('data-slick-index', index) 8493 .data('originalStyling', $(element).attr('style') || ''); 8494 }); 8495 8496 _.$slider.addClass('slick-slider'); 8497 8498 _.$slideTrack = (_.slideCount === 0) ? 8499 $('<div class="slick-track"/>').appendTo(_.$slider) : 8500 _.$slides.wrapAll('<div class="slick-track"/>').parent(); 8501 8502 _.$list = _.$slideTrack.wrap( 8503 '<div class="slick-list"/>').parent(); 8504 _.$slideTrack.css('opacity', 0); 8505 8506 if (_.options.centerMode === true || _.options.swipeToSlide === true) { 8507 _.options.slidesToScroll = 1; 8508 } 8509 8510 $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading'); 8511 8512 _.setupInfinite(); 8513 8514 _.buildArrows(); 8515 8516 _.buildDots(); 8517 8518 _.updateDots(); 8519 8520 8521 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 8522 8523 if (_.options.draggable === true) { 8524 _.$list.addClass('draggable'); 8525 } 8526 8527 }; 8528 8529 Slick.prototype.buildRows = function() { 8530 8531 var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection; 8532 8533 newSlides = document.createDocumentFragment(); 8534 originalSlides = _.$slider.children(); 8535 8536 if(_.options.rows > 0) { 8537 8538 slidesPerSection = _.options.slidesPerRow * _.options.rows; 8539 numOfSlides = Math.ceil( 8540 originalSlides.length / slidesPerSection 8541 ); 8542 8543 for(a = 0; a < numOfSlides; a++){ 8544 var slide = document.createElement('div'); 8545 for(b = 0; b < _.options.rows; b++) { 8546 var row = document.createElement('div'); 8547 for(c = 0; c < _.options.slidesPerRow; c++) { 8548 var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c)); 8549 if (originalSlides.get(target)) { 8550 row.appendChild(originalSlides.get(target)); 8551 } 8552 } 8553 slide.appendChild(row); 8554 } 8555 newSlides.appendChild(slide); 8556 } 8557 8558 _.$slider.empty().append(newSlides); 8559 _.$slider.children().children().children() 8560 .css({ 8561 'width':(100 / _.options.slidesPerRow) + '%', 8562 'display': 'inline-block' 8563 }); 8564 8565 } 8566 8567 }; 8568 8569 Slick.prototype.checkResponsive = function(initial, forceUpdate) { 8570 8571 var _ = this, 8572 breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false; 8573 var sliderWidth = _.$slider.width(); 8574 var windowWidth = window.innerWidth || $(window).width(); 8575 8576 if (_.respondTo === 'window') { 8577 respondToWidth = windowWidth; 8578 } else if (_.respondTo === 'slider') { 8579 respondToWidth = sliderWidth; 8580 } else if (_.respondTo === 'min') { 8581 respondToWidth = Math.min(windowWidth, sliderWidth); 8582 } 8583 8584 if ( _.options.responsive && 8585 _.options.responsive.length && 8586 _.options.responsive !== null) { 8587 8588 targetBreakpoint = null; 8589 8590 for (breakpoint in _.breakpoints) { 8591 if (_.breakpoints.hasOwnProperty(breakpoint)) { 8592 if (_.originalSettings.mobileFirst === false) { 8593 if (respondToWidth < _.breakpoints[breakpoint]) { 8594 targetBreakpoint = _.breakpoints[breakpoint]; 8595 } 8596 } else { 8597 if (respondToWidth > _.breakpoints[breakpoint]) { 8598 targetBreakpoint = _.breakpoints[breakpoint]; 8599 } 8600 } 8601 } 8602 } 8603 8604 if (targetBreakpoint !== null) { 8605 if (_.activeBreakpoint !== null) { 8606 if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) { 8607 _.activeBreakpoint = 8608 targetBreakpoint; 8609 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 8610 _.unslick(targetBreakpoint); 8611 } else { 8612 _.options = $.extend({}, _.originalSettings, 8613 _.breakpointSettings[ 8614 targetBreakpoint]); 8615 if (initial === true) { 8616 _.currentSlide = _.options.initialSlide; 8617 } 8618 _.refresh(initial); 8619 } 8620 triggerBreakpoint = targetBreakpoint; 8621 } 8622 } else { 8623 _.activeBreakpoint = targetBreakpoint; 8624 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 8625 _.unslick(targetBreakpoint); 8626 } else { 8627 _.options = $.extend({}, _.originalSettings, 8628 _.breakpointSettings[ 8629 targetBreakpoint]); 8630 if (initial === true) { 8631 _.currentSlide = _.options.initialSlide; 8632 } 8633 _.refresh(initial); 8634 } 8635 triggerBreakpoint = targetBreakpoint; 8636 } 8637 } else { 8638 if (_.activeBreakpoint !== null) { 8639 _.activeBreakpoint = null; 8640 _.options = _.originalSettings; 8641 if (initial === true) { 8642 _.currentSlide = _.options.initialSlide; 8643 } 8644 _.refresh(initial); 8645 triggerBreakpoint = targetBreakpoint; 8646 } 8647 } 8648 8649 // only trigger breakpoints during an actual break. not on initialize. 8650 if( !initial && triggerBreakpoint !== false ) { 8651 _.$slider.trigger('breakpoint', [_, triggerBreakpoint]); 8652 } 8653 } 8654 8655 }; 8656 8657 Slick.prototype.changeSlide = function(event, dontAnimate) { 8658 8659 var _ = this, 8660 $target = $(event.currentTarget), 8661 indexOffset, slideOffset, unevenOffset; 8662 8663 // If target is a link, prevent default action. 8664 if($target.is('a')) { 8665 event.preventDefault(); 8666 } 8667 8668 // If target is not the <li> element (ie: a child), find the <li>. 8669 if(!$target.is('li')) { 8670 $target = $target.closest('li'); 8671 } 8672 8673 unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0); 8674 indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll; 8675 8676 switch (event.data.message) { 8677 8678 case 'previous': 8679 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset; 8680 if (_.slideCount > _.options.slidesToShow) { 8681 _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate); 8682 } 8683 break; 8684 8685 case 'next': 8686 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset; 8687 if (_.slideCount > _.options.slidesToShow) { 8688 _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate); 8689 } 8690 break; 8691 8692 case 'index': 8693 var index = event.data.index === 0 ? 0 : 8694 event.data.index || $target.index() * _.options.slidesToScroll; 8695 8696 _.slideHandler(_.checkNavigable(index), false, dontAnimate); 8697 $target.children().trigger('focus'); 8698 break; 8699 8700 default: 8701 return; 8702 } 8703 8704 }; 8705 8706 Slick.prototype.checkNavigable = function(index) { 8707 8708 var _ = this, 8709 navigables, prevNavigable; 8710 8711 navigables = _.getNavigableIndexes(); 8712 prevNavigable = 0; 8713 if (index > navigables[navigables.length - 1]) { 8714 index = navigables[navigables.length - 1]; 8715 } else { 8716 for (var n in navigables) { 8717 if (index < navigables[n]) { 8718 index = prevNavigable; 8719 break; 8720 } 8721 prevNavigable = navigables[n]; 8722 } 8723 } 8724 8725 return index; 8726 }; 8727 8728 Slick.prototype.cleanUpEvents = function() { 8729 8730 var _ = this; 8731 8732 if (_.options.dots && _.$dots !== null) { 8733 8734 $('li', _.$dots) 8735 .off('click.slick', _.changeSlide) 8736 .off('mouseenter.slick', $.proxy(_.interrupt, _, true)) 8737 .off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 8738 8739 if (_.options.accessibility === true) { 8740 _.$dots.off('keydown.slick', _.keyHandler); 8741 } 8742 } 8743 8744 _.$slider.off('focus.slick blur.slick'); 8745 8746 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 8747 _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide); 8748 _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide); 8749 8750 if (_.options.accessibility === true) { 8751 _.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler); 8752 _.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler); 8753 } 8754 } 8755 8756 _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler); 8757 _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler); 8758 _.$list.off('touchend.slick mouseup.slick', _.swipeHandler); 8759 _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler); 8760 8761 _.$list.off('click.slick', _.clickHandler); 8762 8763 $(document).off(_.visibilityChange, _.visibility); 8764 8765 _.cleanUpSlideEvents(); 8766 8767 if (_.options.accessibility === true) { 8768 _.$list.off('keydown.slick', _.keyHandler); 8769 } 8770 8771 if (_.options.focusOnSelect === true) { 8772 $(_.$slideTrack).children().off('click.slick', _.selectHandler); 8773 } 8774 8775 $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange); 8776 8777 $(window).off('resize.slick.slick-' + _.instanceUid, _.resize); 8778 8779 $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault); 8780 8781 $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition); 8782 8783 }; 8784 8785 Slick.prototype.cleanUpSlideEvents = function() { 8786 8787 var _ = this; 8788 8789 _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true)); 8790 _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 8791 8792 }; 8793 8794 Slick.prototype.cleanUpRows = function() { 8795 8796 var _ = this, originalSlides; 8797 8798 if(_.options.rows > 0) { 8799 originalSlides = _.$slides.children().children(); 8800 originalSlides.removeAttr('style'); 8801 _.$slider.empty().append(originalSlides); 8802 } 8803 8804 }; 8805 8806 Slick.prototype.clickHandler = function(event) { 8807 8808 var _ = this; 8809 8810 if (_.shouldClick === false) { 8811 event.stopImmediatePropagation(); 8812 event.stopPropagation(); 8813 event.preventDefault(); 8814 } 8815 8816 }; 8817 8818 Slick.prototype.destroy = function(refresh) { 8819 8820 var _ = this; 8821 8822 _.autoPlayClear(); 8823 8824 _.touchObject = {}; 8825 8826 _.cleanUpEvents(); 8827 8828 $('.slick-cloned', _.$slider).detach(); 8829 8830 if (_.$dots) { 8831 _.$dots.remove(); 8832 } 8833 8834 if ( _.$prevArrow && _.$prevArrow.length ) { 8835 8836 _.$prevArrow 8837 .removeClass('slick-disabled slick-arrow slick-hidden') 8838 .removeAttr('aria-hidden aria-disabled tabindex') 8839 .css('display',''); 8840 8841 if ( _.htmlExpr.test( _.options.prevArrow )) { 8842 _.$prevArrow.remove(); 8843 } 8844 } 8845 8846 if ( _.$nextArrow && _.$nextArrow.length ) { 8847 8848 _.$nextArrow 8849 .removeClass('slick-disabled slick-arrow slick-hidden') 8850 .removeAttr('aria-hidden aria-disabled tabindex') 8851 .css('display',''); 8852 8853 if ( _.htmlExpr.test( _.options.nextArrow )) { 8854 _.$nextArrow.remove(); 8855 } 8856 } 8857 8858 8859 if (_.$slides) { 8860 8861 _.$slides 8862 .removeClass('slick-slide slick-active slick-center slick-visible slick-current') 8863 .removeAttr('aria-hidden') 8864 .removeAttr('data-slick-index') 8865 .each(function(){ 8866 $(this).attr('style', $(this).data('originalStyling')); 8867 }); 8868 8869 _.$slideTrack.children(this.options.slide).detach(); 8870 8871 _.$slideTrack.detach(); 8872 8873 _.$list.detach(); 8874 8875 _.$slider.append(_.$slides); 8876 } 8877 8878 _.cleanUpRows(); 8879 8880 _.$slider.removeClass('slick-slider'); 8881 _.$slider.removeClass('slick-initialized'); 8882 _.$slider.removeClass('slick-dotted'); 8883 8884 _.unslicked = true; 8885 8886 if(!refresh) { 8887 _.$slider.trigger('destroy', [_]); 8888 } 8889 8890 }; 8891 8892 Slick.prototype.disableTransition = function(slide) { 8893 8894 var _ = this, 8895 transition = {}; 8896 8897 transition[_.transitionType] = ''; 8898 8899 if (_.options.fade === false) { 8900 _.$slideTrack.css(transition); 8901 } else { 8902 _.$slides.eq(slide).css(transition); 8903 } 8904 8905 }; 8906 8907 Slick.prototype.fadeSlide = function(slideIndex, callback) { 8908 8909 var _ = this; 8910 8911 if (_.cssTransitions === false) { 8912 8913 _.$slides.eq(slideIndex).css({ 8914 zIndex: _.options.zIndex 8915 }); 8916 8917 _.$slides.eq(slideIndex).animate({ 8918 opacity: 1 8919 }, _.options.speed, _.options.easing, callback); 8920 8921 } else { 8922 8923 _.applyTransition(slideIndex); 8924 8925 _.$slides.eq(slideIndex).css({ 8926 opacity: 1, 8927 zIndex: _.options.zIndex 8928 }); 8929 8930 if (callback) { 8931 setTimeout(function() { 8932 8933 _.disableTransition(slideIndex); 8934 8935 callback.call(); 8936 }, _.options.speed); 8937 } 8938 8939 } 8940 8941 }; 8942 8943 Slick.prototype.fadeSlideOut = function(slideIndex) { 8944 8945 var _ = this; 8946 8947 if (_.cssTransitions === false) { 8948 8949 _.$slides.eq(slideIndex).animate({ 8950 opacity: 0, 8951 zIndex: _.options.zIndex - 2 8952 }, _.options.speed, _.options.easing); 8953 8954 } else { 8955 8956 _.applyTransition(slideIndex); 8957 8958 _.$slides.eq(slideIndex).css({ 8959 opacity: 0, 8960 zIndex: _.options.zIndex - 2 8961 }); 8962 8963 } 8964 8965 }; 8966 8967 Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) { 8968 8969 var _ = this; 8970 8971 if (filter !== null) { 8972 8973 _.$slidesCache = _.$slides; 8974 8975 _.unload(); 8976 8977 _.$slideTrack.children(this.options.slide).detach(); 8978 8979 _.$slidesCache.filter(filter).appendTo(_.$slideTrack); 8980 8981 _.reinit(); 8982 8983 } 8984 8985 }; 8986 8987 Slick.prototype.focusHandler = function() { 8988 8989 var _ = this; 8990 8991 _.$slider 8992 .off('focus.slick blur.slick') 8993 .on('focus.slick blur.slick', '*', function(event) { 8994 8995 event.stopImmediatePropagation(); 8996 var $sf = $(this); 8997 8998 setTimeout(function() { 8999 9000 if( _.options.pauseOnFocus ) { 9001 _.focussed = $sf.is(':focus'); 9002 _.autoPlay(); 9003 } 9004 9005 }, 0); 9006 9007 }); 9008 }; 9009 9010 Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() { 9011 9012 var _ = this; 9013 return _.currentSlide; 9014 9015 }; 9016 9017 Slick.prototype.getDotCount = function() { 9018 9019 var _ = this; 9020 9021 var breakPoint = 0; 9022 var counter = 0; 9023 var pagerQty = 0; 9024 9025 if (_.options.infinite === true) { 9026 if (_.slideCount <= _.options.slidesToShow) { 9027 ++pagerQty; 9028 } else { 9029 while (breakPoint < _.slideCount) { 9030 ++pagerQty; 9031 breakPoint = counter + _.options.slidesToScroll; 9032 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 9033 } 9034 } 9035 } else if (_.options.centerMode === true) { 9036 pagerQty = _.slideCount; 9037 } else if(!_.options.asNavFor) { 9038 pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll); 9039 }else { 9040 while (breakPoint < _.slideCount) { 9041 ++pagerQty; 9042 breakPoint = counter + _.options.slidesToScroll; 9043 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 9044 } 9045 } 9046 9047 return pagerQty - 1; 9048 9049 }; 9050 9051 Slick.prototype.getLeft = function(slideIndex) { 9052 9053 var _ = this, 9054 targetLeft, 9055 verticalHeight, 9056 verticalOffset = 0, 9057 targetSlide, 9058 coef; 9059 9060 _.slideOffset = 0; 9061 verticalHeight = _.$slides.first().outerHeight(true); 9062 9063 if (_.options.infinite === true) { 9064 if (_.slideCount > _.options.slidesToShow) { 9065 _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1; 9066 coef = -1 9067 9068 if (_.options.vertical === true && _.options.centerMode === true) { 9069 if (_.options.slidesToShow === 2) { 9070 coef = -1.5; 9071 } else if (_.options.slidesToShow === 1) { 9072 coef = -2 9073 } 9074 } 9075 verticalOffset = (verticalHeight * _.options.slidesToShow) * coef; 9076 } 9077 if (_.slideCount % _.options.slidesToScroll !== 0) { 9078 if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) { 9079 if (slideIndex > _.slideCount) { 9080 _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1; 9081 verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1; 9082 } else { 9083 _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1; 9084 verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1; 9085 } 9086 } 9087 } 9088 } else { 9089 if (slideIndex + _.options.slidesToShow > _.slideCount) { 9090 _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth; 9091 verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight; 9092 } 9093 } 9094 9095 if (_.slideCount <= _.options.slidesToShow) { 9096 _.slideOffset = 0; 9097 verticalOffset = 0; 9098 } 9099 9100 if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) { 9101 _.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2); 9102 } else if (_.options.centerMode === true && _.options.infinite === true) { 9103 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth; 9104 } else if (_.options.centerMode === true) { 9105 _.slideOffset = 0; 9106 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2); 9107 } 9108 9109 if (_.options.vertical === false) { 9110 targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset; 9111 } else { 9112 targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset; 9113 } 9114 9115 if (_.options.variableWidth === true) { 9116 9117 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 9118 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 9119 } else { 9120 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow); 9121 } 9122 9123 if (_.options.rtl === true) { 9124 if (targetSlide[0]) { 9125 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 9126 } else { 9127 targetLeft = 0; 9128 } 9129 } else { 9130 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 9131 } 9132 9133 if (_.options.centerMode === true) { 9134 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 9135 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 9136 } else { 9137 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1); 9138 } 9139 9140 if (_.options.rtl === true) { 9141 if (targetSlide[0]) { 9142 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 9143 } else { 9144 targetLeft = 0; 9145 } 9146 } else { 9147 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 9148 } 9149 9150 targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2; 9151 } 9152 } 9153 9154 return targetLeft; 9155 9156 }; 9157 9158 Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) { 9159 9160 var _ = this; 9161 9162 return _.options[option]; 9163 9164 }; 9165 9166 Slick.prototype.getNavigableIndexes = function() { 9167 9168 var _ = this, 9169 breakPoint = 0, 9170 counter = 0, 9171 indexes = [], 9172 max; 9173 9174 if (_.options.infinite === false) { 9175 max = _.slideCount; 9176 } else { 9177 breakPoint = _.options.slidesToScroll * -1; 9178 counter = _.options.slidesToScroll * -1; 9179 max = _.slideCount * 2; 9180 } 9181 9182 while (breakPoint < max) { 9183 indexes.push(breakPoint); 9184 breakPoint = counter + _.options.slidesToScroll; 9185 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 9186 } 9187 9188 return indexes; 9189 9190 }; 9191 9192 Slick.prototype.getSlick = function() { 9193 9194 return this; 9195 9196 }; 9197 9198 Slick.prototype.getSlideCount = function() { 9199 9200 var _ = this, 9201 slidesTraversed, swipedSlide, centerOffset; 9202 9203 centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0; 9204 9205 if (_.options.swipeToSlide === true) { 9206 _.$slideTrack.find('.slick-slide').each(function(index, slide) { 9207 if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) { 9208 swipedSlide = slide; 9209 return false; 9210 } 9211 }); 9212 9213 slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1; 9214 9215 return slidesTraversed; 9216 9217 } else { 9218 return _.options.slidesToScroll; 9219 } 9220 9221 }; 9222 9223 Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) { 9224 9225 var _ = this; 9226 9227 _.changeSlide({ 9228 data: { 9229 message: 'index', 9230 index: parseInt(slide) 9231 } 9232 }, dontAnimate); 9233 9234 }; 9235 9236 Slick.prototype.init = function(creation) { 9237 9238 var _ = this; 9239 9240 if (!$(_.$slider).hasClass('slick-initialized')) { 9241 9242 $(_.$slider).addClass('slick-initialized'); 9243 9244 _.buildRows(); 9245 _.buildOut(); 9246 _.setProps(); 9247 _.startLoad(); 9248 _.loadSlider(); 9249 _.initializeEvents(); 9250 _.updateArrows(); 9251 _.updateDots(); 9252 _.checkResponsive(true); 9253 _.focusHandler(); 9254 9255 } 9256 9257 if (creation) { 9258 _.$slider.trigger('init', [_]); 9259 } 9260 9261 if (_.options.accessibility === true) { 9262 _.initADA(); 9263 } 9264 9265 if ( _.options.autoplay ) { 9266 9267 _.paused = false; 9268 _.autoPlay(); 9269 9270 } 9271 9272 }; 9273 9274 Slick.prototype.initADA = function() { 9275 var _ = this, 9276 numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow), 9277 tabControlIndexes = _.getNavigableIndexes().filter(function(val) { 9278 return (val >= 0) && (val < _.slideCount); 9279 }); 9280 9281 _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({ 9282 'aria-hidden': 'true', 9283 'tabindex': '-1' 9284 }).find('a, input, button, select').attr({ 9285 'tabindex': '-1' 9286 }); 9287 9288 if (_.$dots !== null) { 9289 _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) { 9290 var slideControlIndex = tabControlIndexes.indexOf(i); 9291 9292 $(this).attr({ 9293 'role': 'tabpanel', 9294 'id': 'slick-slide' + _.instanceUid + i, 9295 'tabindex': -1 9296 }); 9297 9298 if (slideControlIndex !== -1) { 9299 var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex 9300 if ($('#' + ariaButtonControl).length) { 9301 $(this).attr({ 9302 'aria-describedby': ariaButtonControl 9303 }); 9304 } 9305 } 9306 }); 9307 9308 _.$dots.attr('role', 'tablist').find('li').each(function(i) { 9309 var mappedSlideIndex = tabControlIndexes[i]; 9310 9311 $(this).attr({ 9312 'role': 'presentation' 9313 }); 9314 9315 $(this).find('button').first().attr({ 9316 'role': 'tab', 9317 'id': 'slick-slide-control' + _.instanceUid + i, 9318 'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex, 9319 'aria-label': (i + 1) + ' of ' + numDotGroups, 9320 'aria-selected': null, 9321 'tabindex': '-1' 9322 }); 9323 9324 }).eq(_.currentSlide).find('button').attr({ 9325 'aria-selected': 'true', 9326 'tabindex': '0' 9327 }).end(); 9328 } 9329 9330 for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) { 9331 if (_.options.focusOnChange) { 9332 _.$slides.eq(i).attr({'tabindex': '0'}); 9333 } else { 9334 _.$slides.eq(i).removeAttr('tabindex'); 9335 } 9336 } 9337 9338 _.activateADA(); 9339 9340 }; 9341 9342 Slick.prototype.initArrowEvents = function() { 9343 9344 var _ = this; 9345 9346 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 9347 _.$prevArrow 9348 .off('click.slick') 9349 .on('click.slick', { 9350 message: 'previous' 9351 }, _.changeSlide); 9352 _.$nextArrow 9353 .off('click.slick') 9354 .on('click.slick', { 9355 message: 'next' 9356 }, _.changeSlide); 9357 9358 if (_.options.accessibility === true) { 9359 _.$prevArrow.on('keydown.slick', _.keyHandler); 9360 _.$nextArrow.on('keydown.slick', _.keyHandler); 9361 } 9362 } 9363 9364 }; 9365 9366 Slick.prototype.initDotEvents = function() { 9367 9368 var _ = this; 9369 9370 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 9371 $('li', _.$dots).on('click.slick', { 9372 message: 'index' 9373 }, _.changeSlide); 9374 9375 if (_.options.accessibility === true) { 9376 _.$dots.on('keydown.slick', _.keyHandler); 9377 } 9378 } 9379 9380 if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) { 9381 9382 $('li', _.$dots) 9383 .on('mouseenter.slick', $.proxy(_.interrupt, _, true)) 9384 .on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 9385 9386 } 9387 9388 }; 9389 9390 Slick.prototype.initSlideEvents = function() { 9391 9392 var _ = this; 9393 9394 if ( _.options.pauseOnHover ) { 9395 9396 _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true)); 9397 _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 9398 9399 } 9400 9401 }; 9402 9403 Slick.prototype.initializeEvents = function() { 9404 9405 var _ = this; 9406 9407 _.initArrowEvents(); 9408 9409 _.initDotEvents(); 9410 _.initSlideEvents(); 9411 9412 _.$list.on('touchstart.slick mousedown.slick', { 9413 action: 'start' 9414 }, _.swipeHandler); 9415 _.$list.on('touchmove.slick mousemove.slick', { 9416 action: 'move' 9417 }, _.swipeHandler); 9418 _.$list.on('touchend.slick mouseup.slick', { 9419 action: 'end' 9420 }, _.swipeHandler); 9421 _.$list.on('touchcancel.slick mouseleave.slick', { 9422 action: 'end' 9423 }, _.swipeHandler); 9424 9425 _.$list.on('click.slick', _.clickHandler); 9426 9427 $(document).on(_.visibilityChange, $.proxy(_.visibility, _)); 9428 9429 if (_.options.accessibility === true) { 9430 _.$list.on('keydown.slick', _.keyHandler); 9431 } 9432 9433 if (_.options.focusOnSelect === true) { 9434 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 9435 } 9436 9437 $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _)); 9438 9439 $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _)); 9440 9441 $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault); 9442 9443 $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition); 9444 $(_.setPosition); 9445 9446 }; 9447 9448 Slick.prototype.initUI = function() { 9449 9450 var _ = this; 9451 9452 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 9453 9454 _.$prevArrow.show(); 9455 _.$nextArrow.show(); 9456 9457 } 9458 9459 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 9460 9461 _.$dots.show(); 9462 9463 } 9464 9465 }; 9466 9467 Slick.prototype.keyHandler = function(event) { 9468 9469 var _ = this; 9470 //Dont slide if the cursor is inside the form fields and arrow keys are pressed 9471 if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) { 9472 if (event.keyCode === 37 && _.options.accessibility === true) { 9473 _.changeSlide({ 9474 data: { 9475 message: _.options.rtl === true ? 'next' : 'previous' 9476 } 9477 }); 9478 } else if (event.keyCode === 39 && _.options.accessibility === true) { 9479 _.changeSlide({ 9480 data: { 9481 message: _.options.rtl === true ? 'previous' : 'next' 9482 } 9483 }); 9484 } 9485 } 9486 9487 }; 9488 9489 Slick.prototype.lazyLoad = function() { 9490 9491 var _ = this, 9492 loadRange, cloneRange, rangeStart, rangeEnd; 9493 9494 function loadImages(imagesScope) { 9495 9496 $('img[data-lazy]', imagesScope).each(function() { 9497 9498 var image = $(this), 9499 imageSource = $(this).attr('data-lazy'), 9500 imageSrcSet = $(this).attr('data-srcset'), 9501 imageSizes = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'), 9502 imageToLoad = document.createElement('img'); 9503 9504 imageToLoad.onload = function() { 9505 9506 image 9507 .animate({ opacity: 0 }, 100, function() { 9508 9509 if (imageSrcSet) { 9510 image 9511 .attr('srcset', imageSrcSet ); 9512 9513 if (imageSizes) { 9514 image 9515 .attr('sizes', imageSizes ); 9516 } 9517 } 9518 9519 image 9520 .attr('src', imageSource) 9521 .animate({ opacity: 1 }, 200, function() { 9522 image 9523 .removeAttr('data-lazy data-srcset data-sizes') 9524 .removeClass('slick-loading'); 9525 }); 9526 _.$slider.trigger('lazyLoaded', [_, image, imageSource]); 9527 }); 9528 9529 }; 9530 9531 imageToLoad.onerror = function() { 9532 9533 image 9534 .removeAttr( 'data-lazy' ) 9535 .removeClass( 'slick-loading' ) 9536 .addClass( 'slick-lazyload-error' ); 9537 9538 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 9539 9540 }; 9541 9542 imageToLoad.src = imageSource; 9543 9544 }); 9545 9546 } 9547 9548 if (_.options.centerMode === true) { 9549 if (_.options.infinite === true) { 9550 rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1); 9551 rangeEnd = rangeStart + _.options.slidesToShow + 2; 9552 } else { 9553 rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1)); 9554 rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide; 9555 } 9556 } else { 9557 rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide; 9558 rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow); 9559 if (_.options.fade === true) { 9560 if (rangeStart > 0) rangeStart--; 9561 if (rangeEnd <= _.slideCount) rangeEnd++; 9562 } 9563 } 9564 9565 loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd); 9566 9567 if (_.options.lazyLoad === 'anticipated') { 9568 var prevSlide = rangeStart - 1, 9569 nextSlide = rangeEnd, 9570 $slides = _.$slider.find('.slick-slide'); 9571 9572 for (var i = 0; i < _.options.slidesToScroll; i++) { 9573 if (prevSlide < 0) prevSlide = _.slideCount - 1; 9574 loadRange = loadRange.add($slides.eq(prevSlide)); 9575 loadRange = loadRange.add($slides.eq(nextSlide)); 9576 prevSlide--; 9577 nextSlide++; 9578 } 9579 } 9580 9581 loadImages(loadRange); 9582 9583 if (_.slideCount <= _.options.slidesToShow) { 9584 cloneRange = _.$slider.find('.slick-slide'); 9585 loadImages(cloneRange); 9586 } else 9587 if (_.currentSlide >= _.slideCount - _.options.slidesToShow) { 9588 cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow); 9589 loadImages(cloneRange); 9590 } else if (_.currentSlide === 0) { 9591 cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1); 9592 loadImages(cloneRange); 9593 } 9594 9595 }; 9596 9597 Slick.prototype.loadSlider = function() { 9598 9599 var _ = this; 9600 9601 _.setPosition(); 9602 9603 _.$slideTrack.css({ 9604 opacity: 1 9605 }); 9606 9607 _.$slider.removeClass('slick-loading'); 9608 9609 _.initUI(); 9610 9611 if (_.options.lazyLoad === 'progressive') { 9612 _.progressiveLazyLoad(); 9613 } 9614 9615 }; 9616 9617 Slick.prototype.next = Slick.prototype.slickNext = function() { 9618 9619 var _ = this; 9620 9621 _.changeSlide({ 9622 data: { 9623 message: 'next' 9624 } 9625 }); 9626 9627 }; 9628 9629 Slick.prototype.orientationChange = function() { 9630 9631 var _ = this; 9632 9633 _.checkResponsive(); 9634 _.setPosition(); 9635 9636 }; 9637 9638 Slick.prototype.pause = Slick.prototype.slickPause = function() { 9639 9640 var _ = this; 9641 9642 _.autoPlayClear(); 9643 _.paused = true; 9644 9645 }; 9646 9647 Slick.prototype.play = Slick.prototype.slickPlay = function() { 9648 9649 var _ = this; 9650 9651 _.autoPlay(); 9652 _.options.autoplay = true; 9653 _.paused = false; 9654 _.focussed = false; 9655 _.interrupted = false; 9656 9657 }; 9658 9659 Slick.prototype.postSlide = function(index) { 9660 9661 var _ = this; 9662 9663 if( !_.unslicked ) { 9664 9665 _.$slider.trigger('afterChange', [_, index]); 9666 9667 _.animating = false; 9668 9669 if (_.slideCount > _.options.slidesToShow) { 9670 _.setPosition(); 9671 } 9672 9673 _.swipeLeft = null; 9674 9675 if ( _.options.autoplay ) { 9676 _.autoPlay(); 9677 } 9678 9679 if (_.options.accessibility === true) { 9680 _.initADA(); 9681 9682 if (_.options.focusOnChange) { 9683 var $currentSlide = $(_.$slides.get(_.currentSlide)); 9684 $currentSlide.attr('tabindex', 0).focus(); 9685 } 9686 } 9687 9688 } 9689 9690 }; 9691 9692 Slick.prototype.prev = Slick.prototype.slickPrev = function() { 9693 9694 var _ = this; 9695 9696 _.changeSlide({ 9697 data: { 9698 message: 'previous' 9699 } 9700 }); 9701 9702 }; 9703 9704 Slick.prototype.preventDefault = function(event) { 9705 9706 event.preventDefault(); 9707 9708 }; 9709 9710 Slick.prototype.progressiveLazyLoad = function( tryCount ) { 9711 9712 tryCount = tryCount || 1; 9713 9714 var _ = this, 9715 $imgsToLoad = $( 'img[data-lazy]', _.$slider ), 9716 image, 9717 imageSource, 9718 imageSrcSet, 9719 imageSizes, 9720 imageToLoad; 9721 9722 if ( $imgsToLoad.length ) { 9723 9724 image = $imgsToLoad.first(); 9725 imageSource = image.attr('data-lazy'); 9726 imageSrcSet = image.attr('data-srcset'); 9727 imageSizes = image.attr('data-sizes') || _.$slider.attr('data-sizes'); 9728 imageToLoad = document.createElement('img'); 9729 9730 imageToLoad.onload = function() { 9731 9732 if (imageSrcSet) { 9733 image 9734 .attr('srcset', imageSrcSet ); 9735 9736 if (imageSizes) { 9737 image 9738 .attr('sizes', imageSizes ); 9739 } 9740 } 9741 9742 image 9743 .attr( 'src', imageSource ) 9744 .removeAttr('data-lazy data-srcset data-sizes') 9745 .removeClass('slick-loading'); 9746 9747 if ( _.options.adaptiveHeight === true ) { 9748 _.setPosition(); 9749 } 9750 9751 _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]); 9752 _.progressiveLazyLoad(); 9753 9754 }; 9755 9756 imageToLoad.onerror = function() { 9757 9758 if ( tryCount < 3 ) { 9759 9760 /** 9761 * try to load the image 3 times, 9762 * leave a slight delay so we don't get 9763 * servers blocking the request. 9764 */ 9765 setTimeout( function() { 9766 _.progressiveLazyLoad( tryCount + 1 ); 9767 }, 500 ); 9768 9769 } else { 9770 9771 image 9772 .removeAttr( 'data-lazy' ) 9773 .removeClass( 'slick-loading' ) 9774 .addClass( 'slick-lazyload-error' ); 9775 9776 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 9777 9778 _.progressiveLazyLoad(); 9779 9780 } 9781 9782 }; 9783 9784 imageToLoad.src = imageSource; 9785 9786 } else { 9787 9788 _.$slider.trigger('allImagesLoaded', [ _ ]); 9789 9790 } 9791 9792 }; 9793 9794 Slick.prototype.refresh = function( initializing ) { 9795 9796 var _ = this, currentSlide, lastVisibleIndex; 9797 9798 lastVisibleIndex = _.slideCount - _.options.slidesToShow; 9799 9800 // in non-infinite sliders, we don't want to go past the 9801 // last visible index. 9802 if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) { 9803 _.currentSlide = lastVisibleIndex; 9804 } 9805 9806 // if less slides than to show, go to start. 9807 if ( _.slideCount <= _.options.slidesToShow ) { 9808 _.currentSlide = 0; 9809 9810 } 9811 9812 currentSlide = _.currentSlide; 9813 9814 _.destroy(true); 9815 9816 $.extend(_, _.initials, { currentSlide: currentSlide }); 9817 9818 _.init(); 9819 9820 if( !initializing ) { 9821 9822 _.changeSlide({ 9823 data: { 9824 message: 'index', 9825 index: currentSlide 9826 } 9827 }, false); 9828 9829 } 9830 9831 }; 9832 9833 Slick.prototype.registerBreakpoints = function() { 9834 9835 var _ = this, breakpoint, currentBreakpoint, l, 9836 responsiveSettings = _.options.responsive || null; 9837 9838 if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) { 9839 9840 _.respondTo = _.options.respondTo || 'window'; 9841 9842 for ( breakpoint in responsiveSettings ) { 9843 9844 l = _.breakpoints.length-1; 9845 9846 if (responsiveSettings.hasOwnProperty(breakpoint)) { 9847 currentBreakpoint = responsiveSettings[breakpoint].breakpoint; 9848 9849 // loop through the breakpoints and cut out any existing 9850 // ones with the same breakpoint number, we don't want dupes. 9851 while( l >= 0 ) { 9852 if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) { 9853 _.breakpoints.splice(l,1); 9854 } 9855 l--; 9856 } 9857 9858 _.breakpoints.push(currentBreakpoint); 9859 _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings; 9860 9861 } 9862 9863 } 9864 9865 _.breakpoints.sort(function(a, b) { 9866 return ( _.options.mobileFirst ) ? a-b : b-a; 9867 }); 9868 9869 } 9870 9871 }; 9872 9873 Slick.prototype.reinit = function() { 9874 9875 var _ = this; 9876 9877 _.$slides = 9878 _.$slideTrack 9879 .children(_.options.slide) 9880 .addClass('slick-slide'); 9881 9882 _.slideCount = _.$slides.length; 9883 9884 if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) { 9885 _.currentSlide = _.currentSlide - _.options.slidesToScroll; 9886 } 9887 9888 if (_.slideCount <= _.options.slidesToShow) { 9889 _.currentSlide = 0; 9890 } 9891 9892 _.registerBreakpoints(); 9893 9894 _.setProps(); 9895 _.setupInfinite(); 9896 _.buildArrows(); 9897 _.updateArrows(); 9898 _.initArrowEvents(); 9899 _.buildDots(); 9900 _.updateDots(); 9901 _.initDotEvents(); 9902 _.cleanUpSlideEvents(); 9903 _.initSlideEvents(); 9904 9905 _.checkResponsive(false, true); 9906 9907 if (_.options.focusOnSelect === true) { 9908 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 9909 } 9910 9911 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 9912 9913 _.setPosition(); 9914 _.focusHandler(); 9915 9916 _.paused = !_.options.autoplay; 9917 _.autoPlay(); 9918 9919 _.$slider.trigger('reInit', [_]); 9920 9921 }; 9922 9923 Slick.prototype.resize = function() { 9924 9925 var _ = this; 9926 9927 if ($(window).width() !== _.windowWidth) { 9928 clearTimeout(_.windowDelay); 9929 _.windowDelay = window.setTimeout(function() { 9930 _.windowWidth = $(window).width(); 9931 _.checkResponsive(); 9932 if( !_.unslicked ) { _.setPosition(); } 9933 }, 50); 9934 } 9935 }; 9936 9937 Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) { 9938 9939 var _ = this; 9940 9941 if (typeof(index) === 'boolean') { 9942 removeBefore = index; 9943 index = removeBefore === true ? 0 : _.slideCount - 1; 9944 } else { 9945 index = removeBefore === true ? --index : index; 9946 } 9947 9948 if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) { 9949 return false; 9950 } 9951 9952 _.unload(); 9953 9954 if (removeAll === true) { 9955 _.$slideTrack.children().remove(); 9956 } else { 9957 _.$slideTrack.children(this.options.slide).eq(index).remove(); 9958 } 9959 9960 _.$slides = _.$slideTrack.children(this.options.slide); 9961 9962 _.$slideTrack.children(this.options.slide).detach(); 9963 9964 _.$slideTrack.append(_.$slides); 9965 9966 _.$slidesCache = _.$slides; 9967 9968 _.reinit(); 9969 9970 }; 9971 9972 Slick.prototype.setCSS = function(position) { 9973 9974 var _ = this, 9975 positionProps = {}, 9976 x, y; 9977 9978 if (_.options.rtl === true) { 9979 position = -position; 9980 } 9981 x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px'; 9982 y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px'; 9983 9984 positionProps[_.positionProp] = position; 9985 9986 if (_.transformsEnabled === false) { 9987 _.$slideTrack.css(positionProps); 9988 } else { 9989 positionProps = {}; 9990 if (_.cssTransitions === false) { 9991 positionProps[_.animType] = 'translate(' + x + ', ' + y + ')'; 9992 _.$slideTrack.css(positionProps); 9993 } else { 9994 positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)'; 9995 _.$slideTrack.css(positionProps); 9996 } 9997 } 9998 9999 }; 10000 10001 Slick.prototype.setDimensions = function() { 10002 10003 var _ = this; 10004 10005 if (_.options.vertical === false) { 10006 if (_.options.centerMode === true) { 10007 _.$list.css({ 10008 padding: ('0px ' + _.options.centerPadding) 10009 }); 10010 } 10011 } else { 10012 _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow); 10013 if (_.options.centerMode === true) { 10014 _.$list.css({ 10015 padding: (_.options.centerPadding + ' 0px') 10016 }); 10017 } 10018 } 10019 10020 _.listWidth = _.$list.width(); 10021 _.listHeight = _.$list.height(); 10022 10023 10024 if (_.options.vertical === false && _.options.variableWidth === false) { 10025 _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow); 10026 _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length))); 10027 10028 } else if (_.options.variableWidth === true) { 10029 _.$slideTrack.width(5000 * _.slideCount); 10030 } else { 10031 _.slideWidth = Math.ceil(_.listWidth); 10032 _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length))); 10033 } 10034 10035 var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width(); 10036 if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset); 10037 10038 }; 10039 10040 Slick.prototype.setFade = function() { 10041 10042 var _ = this, 10043 targetLeft; 10044 10045 _.$slides.each(function(index, element) { 10046 targetLeft = (_.slideWidth * index) * -1; 10047 if (_.options.rtl === true) { 10048 $(element).css({ 10049 position: 'relative', 10050 right: targetLeft, 10051 top: 0, 10052 zIndex: _.options.zIndex - 2, 10053 opacity: 0 10054 }); 10055 } else { 10056 $(element).css({ 10057 position: 'relative', 10058 left: targetLeft, 10059 top: 0, 10060 zIndex: _.options.zIndex - 2, 10061 opacity: 0 10062 }); 10063 } 10064 }); 10065 10066 _.$slides.eq(_.currentSlide).css({ 10067 zIndex: _.options.zIndex - 1, 10068 opacity: 1 10069 }); 10070 10071 }; 10072 10073 Slick.prototype.setHeight = function() { 10074 10075 var _ = this; 10076 10077 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 10078 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 10079 _.$list.css('height', targetHeight); 10080 } 10081 10082 }; 10083 10084 Slick.prototype.setOption = 10085 Slick.prototype.slickSetOption = function() { 10086 10087 /** 10088 * accepts arguments in format of: 10089 * 10090 * - for changing a single option's value: 10091 * .slick("setOption", option, value, refresh ) 10092 * 10093 * - for changing a set of responsive options: 10094 * .slick("setOption", 'responsive', [{}, ...], refresh ) 10095 * 10096 * - for updating multiple values at once (not responsive) 10097 * .slick("setOption", { 'option': value, ... }, refresh ) 10098 */ 10099 10100 var _ = this, l, item, option, value, refresh = false, type; 10101 10102 if( $.type( arguments[0] ) === 'object' ) { 10103 10104 option = arguments[0]; 10105 refresh = arguments[1]; 10106 type = 'multiple'; 10107 10108 } else if ( $.type( arguments[0] ) === 'string' ) { 10109 10110 option = arguments[0]; 10111 value = arguments[1]; 10112 refresh = arguments[2]; 10113 10114 if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) { 10115 10116 type = 'responsive'; 10117 10118 } else if ( typeof arguments[1] !== 'undefined' ) { 10119 10120 type = 'single'; 10121 10122 } 10123 10124 } 10125 10126 if ( type === 'single' ) { 10127 10128 _.options[option] = value; 10129 10130 10131 } else if ( type === 'multiple' ) { 10132 10133 $.each( option , function( opt, val ) { 10134 10135 _.options[opt] = val; 10136 10137 }); 10138 10139 10140 } else if ( type === 'responsive' ) { 10141 10142 for ( item in value ) { 10143 10144 if( $.type( _.options.responsive ) !== 'array' ) { 10145 10146 _.options.responsive = [ value[item] ]; 10147 10148 } else { 10149 10150 l = _.options.responsive.length-1; 10151 10152 // loop through the responsive object and splice out duplicates. 10153 while( l >= 0 ) { 10154 10155 if( _.options.responsive[l].breakpoint === value[item].breakpoint ) { 10156 10157 _.options.responsive.splice(l,1); 10158 10159 } 10160 10161 l--; 10162 10163 } 10164 10165 _.options.responsive.push( value[item] ); 10166 10167 } 10168 10169 } 10170 10171 } 10172 10173 if ( refresh ) { 10174 10175 _.unload(); 10176 _.reinit(); 10177 10178 } 10179 10180 }; 10181 10182 Slick.prototype.setPosition = function() { 10183 10184 var _ = this; 10185 10186 _.setDimensions(); 10187 10188 _.setHeight(); 10189 10190 if (_.options.fade === false) { 10191 _.setCSS(_.getLeft(_.currentSlide)); 10192 } else { 10193 _.setFade(); 10194 } 10195 10196 _.$slider.trigger('setPosition', [_]); 10197 10198 }; 10199 10200 Slick.prototype.setProps = function() { 10201 10202 var _ = this, 10203 bodyStyle = document.body.style; 10204 10205 _.positionProp = _.options.vertical === true ? 'top' : 'left'; 10206 10207 if (_.positionProp === 'top') { 10208 _.$slider.addClass('slick-vertical'); 10209 } else { 10210 _.$slider.removeClass('slick-vertical'); 10211 } 10212 10213 if (bodyStyle.WebkitTransition !== undefined || 10214 bodyStyle.MozTransition !== undefined || 10215 bodyStyle.msTransition !== undefined) { 10216 if (_.options.useCSS === true) { 10217 _.cssTransitions = true; 10218 } 10219 } 10220 10221 if ( _.options.fade ) { 10222 if ( typeof _.options.zIndex === 'number' ) { 10223 if( _.options.zIndex < 3 ) { 10224 _.options.zIndex = 3; 10225 } 10226 } else { 10227 _.options.zIndex = _.defaults.zIndex; 10228 } 10229 } 10230 10231 if (bodyStyle.OTransform !== undefined) { 10232 _.animType = 'OTransform'; 10233 _.transformType = '-o-transform'; 10234 _.transitionType = 'OTransition'; 10235 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 10236 } 10237 if (bodyStyle.MozTransform !== undefined) { 10238 _.animType = 'MozTransform'; 10239 _.transformType = '-moz-transform'; 10240 _.transitionType = 'MozTransition'; 10241 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false; 10242 } 10243 if (bodyStyle.webkitTransform !== undefined) { 10244 _.animType = 'webkitTransform'; 10245 _.transformType = '-webkit-transform'; 10246 _.transitionType = 'webkitTransition'; 10247 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 10248 } 10249 if (bodyStyle.msTransform !== undefined) { 10250 _.animType = 'msTransform'; 10251 _.transformType = '-ms-transform'; 10252 _.transitionType = 'msTransition'; 10253 if (bodyStyle.msTransform === undefined) _.animType = false; 10254 } 10255 if (bodyStyle.transform !== undefined && _.animType !== false) { 10256 _.animType = 'transform'; 10257 _.transformType = 'transform'; 10258 _.transitionType = 'transition'; 10259 } 10260 _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false); 10261 }; 10262 10263 10264 Slick.prototype.setSlideClasses = function(index) { 10265 10266 var _ = this, 10267 centerOffset, allSlides, indexOffset, remainder; 10268 10269 allSlides = _.$slider 10270 .find('.slick-slide') 10271 .removeClass('slick-active slick-center slick-current') 10272 .attr('aria-hidden', 'true'); 10273 10274 _.$slides 10275 .eq(index) 10276 .addClass('slick-current'); 10277 10278 if (_.options.centerMode === true) { 10279 10280 var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0; 10281 10282 centerOffset = Math.floor(_.options.slidesToShow / 2); 10283 10284 if (_.options.infinite === true) { 10285 10286 if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) { 10287 _.$slides 10288 .slice(index - centerOffset + evenCoef, index + centerOffset + 1) 10289 .addClass('slick-active') 10290 .attr('aria-hidden', 'false'); 10291 10292 } else { 10293 10294 indexOffset = _.options.slidesToShow + index; 10295 allSlides 10296 .slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2) 10297 .addClass('slick-active') 10298 .attr('aria-hidden', 'false'); 10299 10300 } 10301 10302 if (index === 0) { 10303 10304 allSlides 10305 .eq(allSlides.length - 1 - _.options.slidesToShow) 10306 .addClass('slick-center'); 10307 10308 } else if (index === _.slideCount - 1) { 10309 10310 allSlides 10311 .eq(_.options.slidesToShow) 10312 .addClass('slick-center'); 10313 10314 } 10315 10316 } 10317 10318 _.$slides 10319 .eq(index) 10320 .addClass('slick-center'); 10321 10322 } else { 10323 10324 if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) { 10325 10326 _.$slides 10327 .slice(index, index + _.options.slidesToShow) 10328 .addClass('slick-active') 10329 .attr('aria-hidden', 'false'); 10330 10331 } else if (allSlides.length <= _.options.slidesToShow) { 10332 10333 allSlides 10334 .addClass('slick-active') 10335 .attr('aria-hidden', 'false'); 10336 10337 } else { 10338 10339 remainder = _.slideCount % _.options.slidesToShow; 10340 indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index; 10341 10342 if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) { 10343 10344 allSlides 10345 .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder) 10346 .addClass('slick-active') 10347 .attr('aria-hidden', 'false'); 10348 10349 } else { 10350 10351 allSlides 10352 .slice(indexOffset, indexOffset + _.options.slidesToShow) 10353 .addClass('slick-active') 10354 .attr('aria-hidden', 'false'); 10355 10356 } 10357 10358 } 10359 10360 } 10361 10362 if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') { 10363 _.lazyLoad(); 10364 } 10365 }; 10366 10367 Slick.prototype.setupInfinite = function() { 10368 10369 var _ = this, 10370 i, slideIndex, infiniteCount; 10371 10372 if (_.options.fade === true) { 10373 _.options.centerMode = false; 10374 } 10375 10376 if (_.options.infinite === true && _.options.fade === false) { 10377 10378 slideIndex = null; 10379 10380 if (_.slideCount > _.options.slidesToShow) { 10381 10382 if (_.options.centerMode === true) { 10383 infiniteCount = _.options.slidesToShow + 1; 10384 } else { 10385 infiniteCount = _.options.slidesToShow; 10386 } 10387 10388 for (i = _.slideCount; i > (_.slideCount - 10389 infiniteCount); i -= 1) { 10390 slideIndex = i - 1; 10391 $(_.$slides[slideIndex]).clone(true).attr('id', '') 10392 .attr('data-slick-index', slideIndex - _.slideCount) 10393 .prependTo(_.$slideTrack).addClass('slick-cloned'); 10394 } 10395 for (i = 0; i < infiniteCount + _.slideCount; i += 1) { 10396 slideIndex = i; 10397 $(_.$slides[slideIndex]).clone(true).attr('id', '') 10398 .attr('data-slick-index', slideIndex + _.slideCount) 10399 .appendTo(_.$slideTrack).addClass('slick-cloned'); 10400 } 10401 _.$slideTrack.find('.slick-cloned').find('[id]').each(function() { 10402 $(this).attr('id', ''); 10403 }); 10404 10405 } 10406 10407 } 10408 10409 }; 10410 10411 Slick.prototype.interrupt = function( toggle ) { 10412 10413 var _ = this; 10414 10415 if( !toggle ) { 10416 _.autoPlay(); 10417 } 10418 _.interrupted = toggle; 10419 10420 }; 10421 10422 Slick.prototype.selectHandler = function(event) { 10423 10424 var _ = this; 10425 10426 var targetElement = 10427 $(event.target).is('.slick-slide') ? 10428 $(event.target) : 10429 $(event.target).parents('.slick-slide'); 10430 10431 var index = parseInt(targetElement.attr('data-slick-index')); 10432 10433 if (!index) index = 0; 10434 10435 if (_.slideCount <= _.options.slidesToShow) { 10436 10437 _.slideHandler(index, false, true); 10438 return; 10439 10440 } 10441 10442 _.slideHandler(index); 10443 10444 }; 10445 10446 Slick.prototype.slideHandler = function(index, sync, dontAnimate) { 10447 10448 var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null, 10449 _ = this, navTarget; 10450 10451 sync = sync || false; 10452 10453 if (_.animating === true && _.options.waitForAnimate === true) { 10454 return; 10455 } 10456 10457 if (_.options.fade === true && _.currentSlide === index) { 10458 return; 10459 } 10460 10461 if (sync === false) { 10462 _.asNavFor(index); 10463 } 10464 10465 targetSlide = index; 10466 targetLeft = _.getLeft(targetSlide); 10467 slideLeft = _.getLeft(_.currentSlide); 10468 10469 _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft; 10470 10471 if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) { 10472 if (_.options.fade === false) { 10473 targetSlide = _.currentSlide; 10474 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 10475 _.animateSlide(slideLeft, function() { 10476 _.postSlide(targetSlide); 10477 }); 10478 } else { 10479 _.postSlide(targetSlide); 10480 } 10481 } 10482 return; 10483 } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) { 10484 if (_.options.fade === false) { 10485 targetSlide = _.currentSlide; 10486 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 10487 _.animateSlide(slideLeft, function() { 10488 _.postSlide(targetSlide); 10489 }); 10490 } else { 10491 _.postSlide(targetSlide); 10492 } 10493 } 10494 return; 10495 } 10496 10497 if ( _.options.autoplay ) { 10498 clearInterval(_.autoPlayTimer); 10499 } 10500 10501 if (targetSlide < 0) { 10502 if (_.slideCount % _.options.slidesToScroll !== 0) { 10503 animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll); 10504 } else { 10505 animSlide = _.slideCount + targetSlide; 10506 } 10507 } else if (targetSlide >= _.slideCount) { 10508 if (_.slideCount % _.options.slidesToScroll !== 0) { 10509 animSlide = 0; 10510 } else { 10511 animSlide = targetSlide - _.slideCount; 10512 } 10513 } else { 10514 animSlide = targetSlide; 10515 } 10516 10517 _.animating = true; 10518 10519 _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]); 10520 10521 oldSlide = _.currentSlide; 10522 _.currentSlide = animSlide; 10523 10524 _.setSlideClasses(_.currentSlide); 10525 10526 if ( _.options.asNavFor ) { 10527 10528 navTarget = _.getNavTarget(); 10529 navTarget = navTarget.slick('getSlick'); 10530 10531 if ( navTarget.slideCount <= navTarget.options.slidesToShow ) { 10532 navTarget.setSlideClasses(_.currentSlide); 10533 } 10534 10535 } 10536 10537 _.updateDots(); 10538 _.updateArrows(); 10539 10540 if (_.options.fade === true) { 10541 if (dontAnimate !== true) { 10542 10543 _.fadeSlideOut(oldSlide); 10544 10545 _.fadeSlide(animSlide, function() { 10546 _.postSlide(animSlide); 10547 }); 10548 10549 } else { 10550 _.postSlide(animSlide); 10551 } 10552 _.animateHeight(); 10553 return; 10554 } 10555 10556 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 10557 _.animateSlide(targetLeft, function() { 10558 _.postSlide(animSlide); 10559 }); 10560 } else { 10561 _.postSlide(animSlide); 10562 } 10563 10564 }; 10565 10566 Slick.prototype.startLoad = function() { 10567 10568 var _ = this; 10569 10570 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 10571 10572 _.$prevArrow.hide(); 10573 _.$nextArrow.hide(); 10574 10575 } 10576 10577 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 10578 10579 _.$dots.hide(); 10580 10581 } 10582 10583 _.$slider.addClass('slick-loading'); 10584 10585 }; 10586 10587 Slick.prototype.swipeDirection = function() { 10588 10589 var xDist, yDist, r, swipeAngle, _ = this; 10590 10591 xDist = _.touchObject.startX - _.touchObject.curX; 10592 yDist = _.touchObject.startY - _.touchObject.curY; 10593 r = Math.atan2(yDist, xDist); 10594 10595 swipeAngle = Math.round(r * 180 / Math.PI); 10596 if (swipeAngle < 0) { 10597 swipeAngle = 360 - Math.abs(swipeAngle); 10598 } 10599 10600 if ((swipeAngle <= 45) && (swipeAngle >= 0)) { 10601 return (_.options.rtl === false ? 'left' : 'right'); 10602 } 10603 if ((swipeAngle <= 360) && (swipeAngle >= 315)) { 10604 return (_.options.rtl === false ? 'left' : 'right'); 10605 } 10606 if ((swipeAngle >= 135) && (swipeAngle <= 225)) { 10607 return (_.options.rtl === false ? 'right' : 'left'); 10608 } 10609 if (_.options.verticalSwiping === true) { 10610 if ((swipeAngle >= 35) && (swipeAngle <= 135)) { 10611 return 'down'; 10612 } else { 10613 return 'up'; 10614 } 10615 } 10616 10617 return 'vertical'; 10618 10619 }; 10620 10621 Slick.prototype.swipeEnd = function(event) { 10622 10623 var _ = this, 10624 slideCount, 10625 direction; 10626 10627 _.dragging = false; 10628 _.swiping = false; 10629 10630 if (_.scrolling) { 10631 _.scrolling = false; 10632 return false; 10633 } 10634 10635 _.interrupted = false; 10636 _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true; 10637 10638 if ( _.touchObject.curX === undefined ) { 10639 return false; 10640 } 10641 10642 if ( _.touchObject.edgeHit === true ) { 10643 _.$slider.trigger('edge', [_, _.swipeDirection() ]); 10644 } 10645 10646 if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) { 10647 10648 direction = _.swipeDirection(); 10649 10650 switch ( direction ) { 10651 10652 case 'left': 10653 case 'down': 10654 10655 slideCount = 10656 _.options.swipeToSlide ? 10657 _.checkNavigable( _.currentSlide + _.getSlideCount() ) : 10658 _.currentSlide + _.getSlideCount(); 10659 10660 _.currentDirection = 0; 10661 10662 break; 10663 10664 case 'right': 10665 case 'up': 10666 10667 slideCount = 10668 _.options.swipeToSlide ? 10669 _.checkNavigable( _.currentSlide - _.getSlideCount() ) : 10670 _.currentSlide - _.getSlideCount(); 10671 10672 _.currentDirection = 1; 10673 10674 break; 10675 10676 default: 10677 10678 10679 } 10680 10681 if( direction != 'vertical' ) { 10682 10683 _.slideHandler( slideCount ); 10684 _.touchObject = {}; 10685 _.$slider.trigger('swipe', [_, direction ]); 10686 10687 } 10688 10689 } else { 10690 10691 if ( _.touchObject.startX !== _.touchObject.curX ) { 10692 10693 _.slideHandler( _.currentSlide ); 10694 _.touchObject = {}; 10695 10696 } 10697 10698 } 10699 10700 }; 10701 10702 Slick.prototype.swipeHandler = function(event) { 10703 10704 var _ = this; 10705 10706 if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) { 10707 return; 10708 } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) { 10709 return; 10710 } 10711 10712 _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ? 10713 event.originalEvent.touches.length : 1; 10714 10715 _.touchObject.minSwipe = _.listWidth / _.options 10716 .touchThreshold; 10717 10718 if (_.options.verticalSwiping === true) { 10719 _.touchObject.minSwipe = _.listHeight / _.options 10720 .touchThreshold; 10721 } 10722 10723 switch (event.data.action) { 10724 10725 case 'start': 10726 _.swipeStart(event); 10727 break; 10728 10729 case 'move': 10730 _.swipeMove(event); 10731 break; 10732 10733 case 'end': 10734 _.swipeEnd(event); 10735 break; 10736 10737 } 10738 10739 }; 10740 10741 Slick.prototype.swipeMove = function(event) { 10742 10743 var _ = this, 10744 edgeWasHit = false, 10745 curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength; 10746 10747 touches = event.originalEvent !== undefined ? event.originalEvent.touches : null; 10748 10749 if (!_.dragging || _.scrolling || touches && touches.length !== 1) { 10750 return false; 10751 } 10752 10753 curLeft = _.getLeft(_.currentSlide); 10754 10755 _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX; 10756 _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY; 10757 10758 _.touchObject.swipeLength = Math.round(Math.sqrt( 10759 Math.pow(_.touchObject.curX - _.touchObject.startX, 2))); 10760 10761 verticalSwipeLength = Math.round(Math.sqrt( 10762 Math.pow(_.touchObject.curY - _.touchObject.startY, 2))); 10763 10764 if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) { 10765 _.scrolling = true; 10766 return false; 10767 } 10768 10769 if (_.options.verticalSwiping === true) { 10770 _.touchObject.swipeLength = verticalSwipeLength; 10771 } 10772 10773 swipeDirection = _.swipeDirection(); 10774 10775 if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) { 10776 _.swiping = true; 10777 event.preventDefault(); 10778 } 10779 10780 positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1); 10781 if (_.options.verticalSwiping === true) { 10782 positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1; 10783 } 10784 10785 10786 swipeLength = _.touchObject.swipeLength; 10787 10788 _.touchObject.edgeHit = false; 10789 10790 if (_.options.infinite === false) { 10791 if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) { 10792 swipeLength = _.touchObject.swipeLength * _.options.edgeFriction; 10793 _.touchObject.edgeHit = true; 10794 } 10795 } 10796 10797 if (_.options.vertical === false) { 10798 _.swipeLeft = curLeft + swipeLength * positionOffset; 10799 } else { 10800 _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset; 10801 } 10802 if (_.options.verticalSwiping === true) { 10803 _.swipeLeft = curLeft + swipeLength * positionOffset; 10804 } 10805 10806 if (_.options.fade === true || _.options.touchMove === false) { 10807 return false; 10808 } 10809 10810 if (_.animating === true) { 10811 _.swipeLeft = null; 10812 return false; 10813 } 10814 10815 _.setCSS(_.swipeLeft); 10816 10817 }; 10818 10819 Slick.prototype.swipeStart = function(event) { 10820 10821 var _ = this, 10822 touches; 10823 10824 _.interrupted = true; 10825 10826 if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) { 10827 _.touchObject = {}; 10828 return false; 10829 } 10830 10831 if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) { 10832 touches = event.originalEvent.touches[0]; 10833 } 10834 10835 _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX; 10836 _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY; 10837 10838 _.dragging = true; 10839 10840 }; 10841 10842 Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() { 10843 10844 var _ = this; 10845 10846 if (_.$slidesCache !== null) { 10847 10848 _.unload(); 10849 10850 _.$slideTrack.children(this.options.slide).detach(); 10851 10852 _.$slidesCache.appendTo(_.$slideTrack); 10853 10854 _.reinit(); 10855 10856 } 10857 10858 }; 10859 10860 Slick.prototype.unload = function() { 10861 10862 var _ = this; 10863 10864 $('.slick-cloned', _.$slider).remove(); 10865 10866 if (_.$dots) { 10867 _.$dots.remove(); 10868 } 10869 10870 if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) { 10871 _.$prevArrow.remove(); 10872 } 10873 10874 if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) { 10875 _.$nextArrow.remove(); 10876 } 10877 10878 _.$slides 10879 .removeClass('slick-slide slick-active slick-visible slick-current') 10880 .attr('aria-hidden', 'true') 10881 .css('width', ''); 10882 10883 }; 10884 10885 Slick.prototype.unslick = function(fromBreakpoint) { 10886 10887 var _ = this; 10888 _.$slider.trigger('unslick', [_, fromBreakpoint]); 10889 _.destroy(); 10890 10891 }; 10892 10893 Slick.prototype.updateArrows = function() { 10894 10895 var _ = this, 10896 centerOffset; 10897 10898 centerOffset = Math.floor(_.options.slidesToShow / 2); 10899 10900 if ( _.options.arrows === true && 10901 _.slideCount > _.options.slidesToShow && 10902 !_.options.infinite ) { 10903 10904 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 10905 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 10906 10907 if (_.currentSlide === 0) { 10908 10909 _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 10910 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 10911 10912 } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) { 10913 10914 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 10915 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 10916 10917 } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) { 10918 10919 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 10920 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 10921 10922 } 10923 10924 } 10925 10926 }; 10927 10928 Slick.prototype.updateDots = function() { 10929 10930 var _ = this; 10931 10932 if (_.$dots !== null) { 10933 10934 _.$dots 10935 .find('li') 10936 .removeClass('slick-active') 10937 .end(); 10938 10939 _.$dots 10940 .find('li') 10941 .eq(Math.floor(_.currentSlide / _.options.slidesToScroll)) 10942 .addClass('slick-active'); 10943 10944 } 10945 10946 }; 10947 10948 Slick.prototype.visibility = function() { 10949 10950 var _ = this; 10951 10952 if ( _.options.autoplay ) { 10953 10954 if ( document[_.hidden] ) { 10955 10956 _.interrupted = true; 10957 10958 } else { 10959 10960 _.interrupted = false; 10961 10962 } 10963 10964 } 10965 10966 }; 10967 10968 $.fn.slick = function() { 10969 var _ = this, 10970 opt = arguments[0], 10971 args = Array.prototype.slice.call(arguments, 1), 10972 l = _.length, 10973 i, 10974 ret; 10975 for (i = 0; i < l; i++) { 10976 if (typeof opt == 'object' || typeof opt == 'undefined') 10977 _[i].slick = new Slick(_[i], opt); 10978 else 10979 ret = _[i].slick[opt].apply(_[i].slick, args); 10980 if (typeof ret != 'undefined') return ret; 10981 } 10982 return _; 10983 }; 10984 10985})); 10986 10987 10988/***/ }), 10989
vendor: 151,338 bytes, lines 10990-15284
10990/***/ "./node_modules/tippy.js/dist/tippy.all.js": 10991/*!*************************************************!*\ 10992 !*** ./node_modules/tippy.js/dist/tippy.all.js ***! 10993 \*************************************************/ 10994/*! no static exports found */ 10995/***/ (function(module, exports, __webpack_require__) { 10996 10997/* WEBPACK VAR INJECTION */(function(global) {/*! 10998* Tippy.js v2.5.4 10999* (c) 2017-2018 atomiks 11000* MIT 11001*/ 11002(function (global, factory) { 11003 true ? module.exports = factory() : 11004 undefined; 11005}(this, (function () { 'use strict'; 11006 11007var styles = ".tippy-touch{cursor:pointer!important}.tippy-notransition{transition:none!important}.tippy-popper{max-width:350px;-webkit-perspective:700px;perspective:700px;z-index:9999;outline:0;transition-timing-function:cubic-bezier(.165,.84,.44,1);pointer-events:none;line-height:1.4}.tippy-popper[data-html]{max-width:96%;max-width:calc(100% - 20px)}.tippy-popper[x-placement^=top] .tippy-backdrop{border-radius:40% 40% 0 0}.tippy-popper[x-placement^=top] .tippy-roundarrow{bottom:-8px;-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=top] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.tippy-popper[x-placement^=top] .tippy-arrow{border-top:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;bottom:-7px;margin:0 6px;-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=top] .tippy-backdrop{-webkit-transform-origin:0 90%;transform-origin:0 90%}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(6) translate(-50%,25%);transform:scale(6) translate(-50%,25%);opacity:1}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(1) translate(-50%,25%);transform:scale(1) translate(-50%,25%);opacity:0}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=visible]{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}.tippy-popper[x-placement^=top] [data-animation=perspective]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=visible]{opacity:1;-webkit-transform:translateY(-10px) rotateX(0);transform:translateY(-10px) rotateX(0)}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:translateY(0) rotateX(90deg);transform:translateY(0) rotateX(90deg)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=visible]{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=visible]{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=visible]{opacity:1;-webkit-transform:translateY(-10px) scale(1);transform:translateY(-10px) scale(1)}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=bottom] .tippy-backdrop{border-radius:0 0 30% 30%}.tippy-popper[x-placement^=bottom] .tippy-roundarrow{top:-8px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%}.tippy-popper[x-placement^=bottom] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(0);transform:rotate(0)}.tippy-popper[x-placement^=bottom] .tippy-arrow{border-bottom:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;top:-7px;margin:0 6px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%}.tippy-popper[x-placement^=bottom] .tippy-backdrop{-webkit-transform-origin:0 -90%;transform-origin:0 -90%}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(6) translate(-50%,-125%);transform:scale(6) translate(-50%,-125%);opacity:1}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(1) translate(-50%,-125%);transform:scale(1) translate(-50%,-125%);opacity:0}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=visible]{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}.tippy-popper[x-placement^=bottom] [data-animation=perspective]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=visible]{opacity:1;-webkit-transform:translateY(10px) rotateX(0);transform:translateY(10px) rotateX(0)}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:translateY(0) rotateX(-90deg);transform:translateY(0) rotateX(-90deg)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=visible]{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=visible]{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=visible]{opacity:1;-webkit-transform:translateY(10px) scale(1);transform:translateY(10px) scale(1)}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=left] .tippy-backdrop{border-radius:50% 0 0 50%}.tippy-popper[x-placement^=left] .tippy-roundarrow{right:-16px;-webkit-transform-origin:33.33333333% 50%;transform-origin:33.33333333% 50%}.tippy-popper[x-placement^=left] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(90deg);transform:rotate(90deg)}.tippy-popper[x-placement^=left] .tippy-arrow{border-left:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;right:-7px;margin:3px 0;-webkit-transform-origin:0 50%;transform-origin:0 50%}.tippy-popper[x-placement^=left] .tippy-backdrop{-webkit-transform-origin:100% 0;transform-origin:100% 0}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(6) translate(40%,-50%);transform:scale(6) translate(40%,-50%);opacity:1}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(1.5) translate(40%,-50%);transform:scale(1.5) translate(40%,-50%);opacity:0}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=visible]{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}.tippy-popper[x-placement^=left] [data-animation=perspective]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=visible]{opacity:1;-webkit-transform:translateX(-10px) rotateY(0);transform:translateX(-10px) rotateY(0)}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:translateX(0) rotateY(-90deg);transform:translateX(0) rotateY(-90deg)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=visible]{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=visible]{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=visible]{opacity:1;-webkit-transform:translateX(-10px) scale(1);transform:translateX(-10px) scale(1)}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-popper[x-placement^=right] .tippy-backdrop{border-radius:0 50% 50% 0}.tippy-popper[x-placement^=right] .tippy-roundarrow{left:-16px;-webkit-transform-origin:66.66666666% 50%;transform-origin:66.66666666% 50%}.tippy-popper[x-placement^=right] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.tippy-popper[x-placement^=right] .tippy-arrow{border-right:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;left:-7px;margin:3px 0;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.tippy-popper[x-placement^=right] .tippy-backdrop{-webkit-transform-origin:-100% 0;transform-origin:-100% 0}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(6) translate(-140%,-50%);transform:scale(6) translate(-140%,-50%);opacity:1}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(1.5) translate(-140%,-50%);transform:scale(1.5) translate(-140%,-50%);opacity:0}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=visible]{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}.tippy-popper[x-placement^=right] [data-animation=perspective]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=visible]{opacity:1;-webkit-transform:translateX(10px) rotateY(0);transform:translateX(10px) rotateY(0)}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:translateX(0) rotateY(90deg);transform:translateX(0) rotateY(90deg)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=visible]{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=visible]{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=visible]{opacity:1;-webkit-transform:translateX(10px) scale(1);transform:translateX(10px) scale(1)}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:.9rem;padding:.3rem .6rem;text-align:center;will-change:transform;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#333}.tippy-tooltip[data-size=small]{padding:.2rem .4rem;font-size:.75rem}.tippy-tooltip[data-size=large]{padding:.4rem .8rem;font-size:1rem}.tippy-tooltip[data-animatefill]{overflow:hidden;background-color:transparent}.tippy-tooltip[data-animatefill] .tippy-content{transition:-webkit-clip-path cubic-bezier(.46,.1,.52,.98);transition:clip-path cubic-bezier(.46,.1,.52,.98);transition:clip-path cubic-bezier(.46,.1,.52,.98),-webkit-clip-path cubic-bezier(.46,.1,.52,.98)}.tippy-tooltip[data-interactive],.tippy-tooltip[data-interactive] path{pointer-events:auto}.tippy-tooltip[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.53,2,.36,.85)}.tippy-tooltip[data-inertia][data-state=hidden]{transition-timing-function:ease}.tippy-arrow,.tippy-roundarrow{position:absolute;width:0;height:0}.tippy-roundarrow{width:24px;height:8px;fill:#333;pointer-events:none}.tippy-backdrop{position:absolute;will-change:transform;background-color:#333;border-radius:50%;width:26%;left:50%;top:50%;z-index:-1;transition:all cubic-bezier(.46,.1,.52,.98);-webkit-backface-visibility:hidden;backface-visibility:hidden}.tippy-backdrop:after{content:\"\";float:left;padding-top:100%}body:not(.tippy-touch) .tippy-tooltip[data-animatefill][data-state=visible] .tippy-content{-webkit-clip-path:ellipse(100% 100% at 50% 50%);clip-path:ellipse(100% 100% at 50% 50%)}body:not(.tippy-touch) .tippy-tooltip[data-animatefill][data-state=hidden] .tippy-content{-webkit-clip-path:ellipse(5% 50% at 50% 50%);clip-path:ellipse(5% 50% at 50% 50%)}body:not(.tippy-touch) .tippy-popper[x-placement=right] .tippy-tooltip[data-animatefill][data-state=visible] .tippy-content{-webkit-clip-path:ellipse(135% 100% at 0 50%);clip-path:ellipse(135% 100% at 0 50%)}body:not(.tippy-touch) .tippy-popper[x-placement=right] .tippy-tooltip[data-animatefill][data-state=hidden] .tippy-content{-webkit-clip-path:ellipse(40% 100% at 0 50%);clip-path:ellipse(40% 100% at 0 50%)}body:not(.tippy-touch) .tippy-popper[x-placement=left] .tippy-tooltip[data-animatefill][data-state=visible] .tippy-content{-webkit-clip-path:ellipse(135% 100% at 100% 50%);clip-path:ellipse(135% 100% at 100% 50%)}body:not(.tippy-touch) .tippy-popper[x-placement=left] .tippy-tooltip[data-animatefill][data-state=hidden] .tippy-content{-webkit-clip-path:ellipse(40% 100% at 100% 50%);clip-path:ellipse(40% 100% at 100% 50%)}@media (max-width:360px){.tippy-popper{max-width:96%;max-width:calc(100% - 20px)}}"; 11008 11009var version = "2.5.4"; 11010 11011var isBrowser = typeof window !== 'undefined'; 11012 11013var isIE = isBrowser && /MSIE |Trident\//.test(navigator.userAgent); 11014 11015var browser = {}; 11016 11017if (isBrowser) { 11018 browser.supported = 'requestAnimationFrame' in window; 11019 browser.supportsTouch = 'ontouchstart' in window; 11020 browser.usingTouch = false; 11021 browser.dynamicInputDetection = true; 11022 browser.iOS = /iPhone|iPad|iPod/.test(navigator.platform) && !window.MSStream; 11023 browser.onUserInputChange = function () {}; 11024} 11025 11026/** 11027 * Selector constants used for grabbing elements 11028 */ 11029var selectors = { 11030 POPPER: '.tippy-popper', 11031 TOOLTIP: '.tippy-tooltip', 11032 CONTENT: '.tippy-content', 11033 BACKDROP: '.tippy-backdrop', 11034 ARROW: '.tippy-arrow', 11035 ROUND_ARROW: '.tippy-roundarrow', 11036 REFERENCE: '[data-tippy]' 11037}; 11038 11039var defaults = { 11040 placement: 'top', 11041 livePlacement: true, 11042 trigger: 'mouseenter focus', 11043 animation: 'shift-away', 11044 html: false, 11045 animateFill: true, 11046 arrow: false, 11047 delay: 0, 11048 duration: [350, 300], 11049 interactive: false, 11050 interactiveBorder: 2, 11051 theme: 'dark', 11052 size: 'regular', 11053 distance: 10, 11054 offset: 0, 11055 hideOnClick: true, 11056 multiple: false, 11057 followCursor: false, 11058 inertia: false, 11059 updateDuration: 350, 11060 sticky: false, 11061 appendTo: function appendTo() { 11062 return document.body; 11063 }, 11064 zIndex: 9999, 11065 touchHold: false, 11066 performance: false, 11067 dynamicTitle: false, 11068 flip: true, 11069 flipBehavior: 'flip', 11070 arrowType: 'sharp', 11071 arrowTransform: '', 11072 maxWidth: '', 11073 target: null, 11074 allowTitleHTML: true, 11075 popperOptions: {}, 11076 createPopperInstanceOnInit: false, 11077 onShow: function onShow() {}, 11078 onShown: function onShown() {}, 11079 onHide: function onHide() {}, 11080 onHidden: function onHidden() {} 11081}; 11082 11083/** 11084 * The keys of the defaults object for reducing down into a new object 11085 * Used in `getIndividualOptions()` 11086 */ 11087var defaultsKeys = browser.supported && Object.keys(defaults); 11088 11089/** 11090 * Determines if a value is an object literal 11091 * @param {*} value 11092 * @return {Boolean} 11093 */ 11094function isObjectLiteral(value) { 11095 return {}.toString.call(value) === '[object Object]'; 11096} 11097 11098/** 11099 * Ponyfill for Array.from 11100 * @param {*} value 11101 * @return {Array} 11102 */ 11103function toArray(value) { 11104 return [].slice.call(value); 11105} 11106 11107/** 11108 * Returns an array of elements based on the selector input 11109 * @param {String|Element|Element[]|NodeList|Object} selector 11110 * @return {Element[]} 11111 */ 11112function getArrayOfElements(selector) { 11113 if (selector instanceof Element || isObjectLiteral(selector)) { 11114 return [selector]; 11115 } 11116 11117 if (selector instanceof NodeList) { 11118 return toArray(selector); 11119 } 11120 11121 if (Array.isArray(selector)) { 11122 return selector; 11123 } 11124 11125 try { 11126 return toArray(document.querySelectorAll(selector)); 11127 } catch (_) { 11128 return []; 11129 } 11130} 11131 11132/** 11133 * Polyfills needed props/methods for a virtual reference object 11134 * NOTE: in v3.0 this will be pure 11135 * @param {Object} reference 11136 */ 11137function polyfillVirtualReferenceProps(reference) { 11138 reference.refObj = true; 11139 reference.attributes = reference.attributes || {}; 11140 reference.setAttribute = function (key, val) { 11141 reference.attributes[key] = val; 11142 }; 11143 reference.getAttribute = function (key) { 11144 return reference.attributes[key]; 11145 }; 11146 reference.removeAttribute = function (key) { 11147 delete reference.attributes[key]; 11148 }; 11149 reference.hasAttribute = function (key) { 11150 return key in reference.attributes; 11151 }; 11152 reference.addEventListener = function () {}; 11153 reference.removeEventListener = function () {}; 11154 reference.classList = { 11155 classNames: {}, 11156 add: function add(key) { 11157 return reference.classList.classNames[key] = true; 11158 }, 11159 remove: function remove(key) { 11160 delete reference.classList.classNames[key]; 11161 return true; 11162 }, 11163 contains: function contains(key) { 11164 return key in reference.classList.classNames; 11165 } 11166 }; 11167} 11168 11169/** 11170 * Returns the supported prefixed property - only `webkit` is needed, `moz`, `ms` and `o` are obsolete 11171 * @param {String} property 11172 * @return {String} - browser supported prefixed property 11173 */ 11174function prefix(property) { 11175 var prefixes = ['', 'webkit']; 11176 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 11177 11178 for (var i = 0; i < prefixes.length; i++) { 11179 var _prefix = prefixes[i]; 11180 var prefixedProp = _prefix ? _prefix + upperProp : property; 11181 if (typeof document.body.style[prefixedProp] !== 'undefined') { 11182 return prefixedProp; 11183 } 11184 } 11185 11186 return null; 11187} 11188 11189/** 11190 * Creates a div element 11191 * @return {Element} 11192 */ 11193function div() { 11194 return document.createElement('div'); 11195} 11196 11197/** 11198 * Creates a popper element then returns it 11199 * @param {Number} id - the popper id 11200 * @param {String} title - the tooltip's `title` attribute 11201 * @param {Object} options - individual options 11202 * @return {Element} - the popper element 11203 */ 11204function createPopperElement(id, title, options) { 11205 var popper = div(); 11206 popper.setAttribute('class', 'tippy-popper'); 11207 popper.setAttribute('role', 'tooltip'); 11208 popper.setAttribute('id', 'tippy-' + id); 11209 popper.style.zIndex = options.zIndex; 11210 popper.style.maxWidth = options.maxWidth; 11211 11212 var tooltip = div(); 11213 tooltip.setAttribute('class', 'tippy-tooltip'); 11214 tooltip.setAttribute('data-size', options.size); 11215 tooltip.setAttribute('data-animation', options.animation); 11216 tooltip.setAttribute('data-state', 'hidden'); 11217 options.theme.split(' ').forEach(function (t) { 11218 tooltip.classList.add(t + '-theme'); 11219 }); 11220 11221 var content = div(); 11222 content.setAttribute('class', 'tippy-content'); 11223 11224 if (options.arrow) { 11225 var arrow = div(); 11226 arrow.style[prefix('transform')] = options.arrowTransform; 11227 11228 if (options.arrowType === 'round') { 11229 arrow.classList.add('tippy-roundarrow'); 11230 arrow.innerHTML = '<svg viewBox="0 0 24 8" xmlns="http://www.w3.org/2000/svg"><path d="M3 8s2.021-.015 5.253-4.218C9.584 2.051 10.797 1.007 12 1c1.203-.007 2.416 1.035 3.761 2.782C19.012 8.005 21 8 21 8H3z"/></svg>'; 11231 } else { 11232 arrow.classList.add('tippy-arrow'); 11233 } 11234 11235 tooltip.appendChild(arrow); 11236 } 11237 11238 if (options.animateFill) { 11239 // Create animateFill circle element for animation 11240 tooltip.setAttribute('data-animatefill', ''); 11241 var backdrop = div(); 11242 backdrop.classList.add('tippy-backdrop'); 11243 backdrop.setAttribute('data-state', 'hidden'); 11244 tooltip.appendChild(backdrop); 11245 } 11246 11247 if (options.inertia) { 11248 // Change transition timing function cubic bezier 11249 tooltip.setAttribute('data-inertia', ''); 11250 } 11251 11252 if (options.interactive) { 11253 tooltip.setAttribute('data-interactive', ''); 11254 } 11255 11256 var html = options.html; 11257 if (html) { 11258 var templateId = void 0; 11259 11260 if (html instanceof Element) { 11261 content.appendChild(html); 11262 templateId = '#' + (html.id || 'tippy-html-template'); 11263 } else { 11264 // trick linters: https://github.com/atomiks/tippyjs/issues/197 11265 content[true && 'innerHTML'] = document.querySelector(html)[true && 'innerHTML']; 11266 templateId = html; 11267 } 11268 11269 popper.setAttribute('data-html', ''); 11270 tooltip.setAttribute('data-template-id', templateId); 11271 11272 if (options.interactive) { 11273 popper.setAttribute('tabindex', '-1'); 11274 } 11275 } else { 11276 content[options.allowTitleHTML ? 'innerHTML' : 'textContent'] = title; 11277 } 11278 11279 tooltip.appendChild(content); 11280 popper.appendChild(tooltip); 11281 11282 return popper; 11283} 11284 11285/** 11286 * Creates a trigger by adding the necessary event listeners to the reference element 11287 * @param {String} eventType - the custom event specified in the `trigger` setting 11288 * @param {Element} reference 11289 * @param {Object} handlers - the handlers for each event 11290 * @param {Object} options 11291 * @return {Array} - array of listener objects 11292 */ 11293function createTrigger(eventType, reference, handlers, options) { 11294 var onTrigger = handlers.onTrigger, 11295 onMouseLeave = handlers.onMouseLeave, 11296 onBlur = handlers.onBlur, 11297 onDelegateShow = handlers.onDelegateShow, 11298 onDelegateHide = handlers.onDelegateHide; 11299 11300 var listeners = []; 11301 11302 if (eventType === 'manual') return listeners; 11303 11304 var on = function on(eventType, handler) { 11305 reference.addEventListener(eventType, handler); 11306 listeners.push({ event: eventType, handler: handler }); 11307 }; 11308 11309 if (!options.target) { 11310 on(eventType, onTrigger); 11311 11312 if (browser.supportsTouch && options.touchHold) { 11313 on('touchstart', onTrigger); 11314 on('touchend', onMouseLeave); 11315 } 11316 if (eventType === 'mouseenter') { 11317 on('mouseleave', onMouseLeave); 11318 } 11319 if (eventType === 'focus') { 11320 on(isIE ? 'focusout' : 'blur', onBlur); 11321 } 11322 } else { 11323 if (browser.supportsTouch && options.touchHold) { 11324 on('touchstart', onDelegateShow); 11325 on('touchend', onDelegateHide); 11326 } 11327 if (eventType === 'mouseenter') { 11328 on('mouseover', onDelegateShow); 11329 on('mouseout', onDelegateHide); 11330 } 11331 if (eventType === 'focus') { 11332 on('focusin', onDelegateShow); 11333 on('focusout', onDelegateHide); 11334 } 11335 if (eventType === 'click') { 11336 on('click', onDelegateShow); 11337 } 11338 } 11339 11340 return listeners; 11341} 11342 11343var classCallCheck = function (instance, Constructor) { 11344 if (!(instance instanceof Constructor)) { 11345 throw new TypeError("Cannot call a class as a function"); 11346 } 11347}; 11348 11349var createClass = function () { 11350 function defineProperties(target, props) { 11351 for (var i = 0; i < props.length; i++) { 11352 var descriptor = props[i]; 11353 descriptor.enumerable = descriptor.enumerable || false; 11354 descriptor.configurable = true; 11355 if ("value" in descriptor) descriptor.writable = true; 11356 Object.defineProperty(target, descriptor.key, descriptor); 11357 } 11358 } 11359 11360 return function (Constructor, protoProps, staticProps) { 11361 if (protoProps) defineProperties(Constructor.prototype, protoProps); 11362 if (staticProps) defineProperties(Constructor, staticProps); 11363 return Constructor; 11364 }; 11365}(); 11366 11367 11368 11369 11370 11371 11372 11373var _extends = Object.assign || function (target) { 11374 for (var i = 1; i < arguments.length; i++) { 11375 var source = arguments[i]; 11376 11377 for (var key in source) { 11378 if (Object.prototype.hasOwnProperty.call(source, key)) { 11379 target[key] = source[key]; 11380 } 11381 } 11382 } 11383 11384 return target; 11385}; 11386 11387/** 11388 * Returns an object of settings to override global settings 11389 * @param {Element} reference 11390 * @param {Object} instanceOptions 11391 * @return {Object} - individual options 11392 */ 11393function getIndividualOptions(reference, instanceOptions) { 11394 var options = defaultsKeys.reduce(function (acc, key) { 11395 var val = reference.getAttribute('data-tippy-' + key.toLowerCase()) || instanceOptions[key]; 11396 11397 // Convert strings to booleans 11398 if (val === 'false') val = false; 11399 if (val === 'true') val = true; 11400 11401 // Convert number strings to true numbers 11402 if (isFinite(val) && !isNaN(parseFloat(val))) { 11403 val = parseFloat(val); 11404 } 11405 11406 // Convert array strings to actual arrays 11407 if (key !== 'target' && typeof val === 'string' && val.trim().charAt(0) === '[') { 11408 val = JSON.parse(val); 11409 } 11410 11411 acc[key] = val; 11412 11413 return acc; 11414 }, {}); 11415 11416 return _extends({}, instanceOptions, options); 11417} 11418 11419/** 11420 * Evaluates/modifies the options object for appropriate behavior 11421 * @param {Element|Object} reference 11422 * @param {Object} options 11423 * @return {Object} modified/evaluated options 11424 */ 11425function evaluateOptions(reference, options) { 11426 // animateFill is disabled if an arrow is true 11427 if (options.arrow) { 11428 options.animateFill = false; 11429 } 11430 11431 if (options.appendTo && typeof options.appendTo === 'function') { 11432 options.appendTo = options.appendTo(); 11433 } 11434 11435 if (typeof options.html === 'function') { 11436 options.html = options.html(reference); 11437 } 11438 11439 return options; 11440} 11441 11442/** 11443 * Returns inner elements of the popper element 11444 * @param {Element} popper 11445 * @return {Object} 11446 */ 11447function getInnerElements(popper) { 11448 var select = function select(s) { 11449 return popper.querySelector(s); 11450 }; 11451 return { 11452 tooltip: select(selectors.TOOLTIP), 11453 backdrop: select(selectors.BACKDROP), 11454 content: select(selectors.CONTENT), 11455 arrow: select(selectors.ARROW) || select(selectors.ROUND_ARROW) 11456 }; 11457} 11458 11459/** 11460 * Removes the title from an element, setting `data-original-title` 11461 * appropriately 11462 * @param {Element} el 11463 */ 11464function removeTitle(el) { 11465 var title = el.getAttribute('title'); 11466 // Only set `data-original-title` attr if there is a title 11467 if (title) { 11468 el.setAttribute('data-original-title', title); 11469 } 11470 el.removeAttribute('title'); 11471} 11472 11473/**! 11474 * @fileOverview Kickass library to create and place poppers near their reference elements. 11475 * @version 1.14.3 11476 * @license 11477 * Copyright (c) 2016 Federico Zivolo and contributors 11478 * 11479 * Permission is hereby granted, free of charge, to any person obtaining a copy 11480 * of this software and associated documentation files (the "Software"), to deal 11481 * in the Software without restriction, including without limitation the rights 11482 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11483 * copies of the Software, and to permit persons to whom the Software is 11484 * furnished to do so, subject to the following conditions: 11485 * 11486 * The above copyright notice and this permission notice shall be included in all 11487 * copies or substantial portions of the Software. 11488 * 11489 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11490 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11491 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 11492 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11493 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 11494 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 11495 * SOFTWARE. 11496 */ 11497var isBrowser$1 = typeof window !== 'undefined' && typeof document !== 'undefined'; 11498 11499var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 11500var timeoutDuration = 0; 11501for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { 11502 if (isBrowser$1 && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 11503 timeoutDuration = 1; 11504 break; 11505 } 11506} 11507 11508function microtaskDebounce(fn) { 11509 var called = false; 11510 return function () { 11511 if (called) { 11512 return; 11513 } 11514 called = true; 11515 window.Promise.resolve().then(function () { 11516 called = false; 11517 fn(); 11518 }); 11519 }; 11520} 11521 11522function taskDebounce(fn) { 11523 var scheduled = false; 11524 return function () { 11525 if (!scheduled) { 11526 scheduled = true; 11527 setTimeout(function () { 11528 scheduled = false; 11529 fn(); 11530 }, timeoutDuration); 11531 } 11532 }; 11533} 11534 11535var supportsMicroTasks = isBrowser$1 && window.Promise; 11536 11537/** 11538* Create a debounced version of a method, that's asynchronously deferred 11539* but called in the minimum time possible. 11540* 11541* @method 11542* @memberof Popper.Utils 11543* @argument {Function} fn 11544* @returns {Function} 11545*/ 11546var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; 11547 11548/** 11549 * Check if the given variable is a function 11550 * @method 11551 * @memberof Popper.Utils 11552 * @argument {Any} functionToCheck - variable to check 11553 * @returns {Boolean} answer to: is a function? 11554 */ 11555function isFunction(functionToCheck) { 11556 var getType = {}; 11557 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 11558} 11559 11560/** 11561 * Get CSS computed property of the given element 11562 * @method 11563 * @memberof Popper.Utils 11564 * @argument {Eement} element 11565 * @argument {String} property 11566 */ 11567function getStyleComputedProperty(element, property) { 11568 if (element.nodeType !== 1) { 11569 return []; 11570 } 11571 // NOTE: 1 DOM access here 11572 var css = getComputedStyle(element, null); 11573 return property ? css[property] : css; 11574} 11575 11576/** 11577 * Returns the parentNode or the host of the element 11578 * @method 11579 * @memberof Popper.Utils 11580 * @argument {Element} element 11581 * @returns {Element} parent 11582 */ 11583function getParentNode(element) { 11584 if (element.nodeName === 'HTML') { 11585 return element; 11586 } 11587 return element.parentNode || element.host; 11588} 11589 11590/** 11591 * Returns the scrolling parent of the given element 11592 * @method 11593 * @memberof Popper.Utils 11594 * @argument {Element} element 11595 * @returns {Element} scroll parent 11596 */ 11597function getScrollParent(element) { 11598 // Return body, `getScroll` will take care to get the correct `scrollTop` from it 11599 if (!element) { 11600 return document.body; 11601 } 11602 11603 switch (element.nodeName) { 11604 case 'HTML': 11605 case 'BODY': 11606 return element.ownerDocument.body; 11607 case '#document': 11608 return element.body; 11609 } 11610 11611 // Firefox want us to check `-x` and `-y` variations as well 11612 11613 var _getStyleComputedProp = getStyleComputedProperty(element), 11614 overflow = _getStyleComputedProp.overflow, 11615 overflowX = _getStyleComputedProp.overflowX, 11616 overflowY = _getStyleComputedProp.overflowY; 11617 11618 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 11619 return element; 11620 } 11621 11622 return getScrollParent(getParentNode(element)); 11623} 11624 11625var isIE11 = isBrowser$1 && !!(window.MSInputMethodContext && document.documentMode); 11626var isIE10 = isBrowser$1 && /MSIE 10/.test(navigator.userAgent); 11627 11628/** 11629 * Determines if the browser is Internet Explorer 11630 * @method 11631 * @memberof Popper.Utils 11632 * @param {Number} version to check 11633 * @returns {Boolean} isIE 11634 */ 11635function isIE$1(version) { 11636 if (version === 11) { 11637 return isIE11; 11638 } 11639 if (version === 10) { 11640 return isIE10; 11641 } 11642 return isIE11 || isIE10; 11643} 11644 11645/** 11646 * Returns the offset parent of the given element 11647 * @method 11648 * @memberof Popper.Utils 11649 * @argument {Element} element 11650 * @returns {Element} offset parent 11651 */ 11652function getOffsetParent(element) { 11653 if (!element) { 11654 return document.documentElement; 11655 } 11656 11657 var noOffsetParent = isIE$1(10) ? document.body : null; 11658 11659 // NOTE: 1 DOM access here 11660 var offsetParent = element.offsetParent; 11661 // Skip hidden elements which don't have an offsetParent 11662 while (offsetParent === noOffsetParent && element.nextElementSibling) { 11663 offsetParent = (element = element.nextElementSibling).offsetParent; 11664 } 11665 11666 var nodeName = offsetParent && offsetParent.nodeName; 11667 11668 if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 11669 return element ? element.ownerDocument.documentElement : document.documentElement; 11670 } 11671 11672 // .offsetParent will return the closest TD or TABLE in case 11673 // no offsetParent is present, I hate this job... 11674 if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { 11675 return getOffsetParent(offsetParent); 11676 } 11677 11678 return offsetParent; 11679} 11680 11681function isOffsetContainer(element) { 11682 var nodeName = element.nodeName; 11683 11684 if (nodeName === 'BODY') { 11685 return false; 11686 } 11687 return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; 11688} 11689 11690/** 11691 * Finds the root node (document, shadowDOM root) of the given element 11692 * @method 11693 * @memberof Popper.Utils 11694 * @argument {Element} node 11695 * @returns {Element} root node 11696 */ 11697function getRoot(node) { 11698 if (node.parentNode !== null) { 11699 return getRoot(node.parentNode); 11700 } 11701 11702 return node; 11703} 11704 11705/** 11706 * Finds the offset parent common to the two provided nodes 11707 * @method 11708 * @memberof Popper.Utils 11709 * @argument {Element} element1 11710 * @argument {Element} element2 11711 * @returns {Element} common offset parent 11712 */ 11713function findCommonOffsetParent(element1, element2) { 11714 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 11715 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 11716 return document.documentElement; 11717 } 11718 11719 // Here we make sure to give as "start" the element that comes first in the DOM 11720 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 11721 var start = order ? element1 : element2; 11722 var end = order ? element2 : element1; 11723 11724 // Get common ancestor container 11725 var range = document.createRange(); 11726 range.setStart(start, 0); 11727 range.setEnd(end, 0); 11728 var commonAncestorContainer = range.commonAncestorContainer; 11729 11730 // Both nodes are inside #document 11731 11732 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 11733 if (isOffsetContainer(commonAncestorContainer)) { 11734 return commonAncestorContainer; 11735 } 11736 11737 return getOffsetParent(commonAncestorContainer); 11738 } 11739 11740 // one of the nodes is inside shadowDOM, find which one 11741 var element1root = getRoot(element1); 11742 if (element1root.host) { 11743 return findCommonOffsetParent(element1root.host, element2); 11744 } else { 11745 return findCommonOffsetParent(element1, getRoot(element2).host); 11746 } 11747} 11748 11749/** 11750 * Gets the scroll value of the given element in the given side (top and left) 11751 * @method 11752 * @memberof Popper.Utils 11753 * @argument {Element} element 11754 * @argument {String} side `top` or `left` 11755 * @returns {number} amount of scrolled pixels 11756 */ 11757function getScroll(element) { 11758 var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; 11759 11760 var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 11761 var nodeName = element.nodeName; 11762 11763 if (nodeName === 'BODY' || nodeName === 'HTML') { 11764 var html = element.ownerDocument.documentElement; 11765 var scrollingElement = element.ownerDocument.scrollingElement || html; 11766 return scrollingElement[upperSide]; 11767 } 11768 11769 return element[upperSide]; 11770} 11771 11772/* 11773 * Sum or subtract the element scroll values (left and top) from a given rect object 11774 * @method 11775 * @memberof Popper.Utils 11776 * @param {Object} rect - Rect object you want to change 11777 * @param {HTMLElement} element - The element from the function reads the scroll values 11778 * @param {Boolean} subtract - set to true if you want to subtract the scroll values 11779 * @return {Object} rect - The modifier rect object 11780 */ 11781function includeScroll(rect, element) { 11782 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 11783 11784 var scrollTop = getScroll(element, 'top'); 11785 var scrollLeft = getScroll(element, 'left'); 11786 var modifier = subtract ? -1 : 1; 11787 rect.top += scrollTop * modifier; 11788 rect.bottom += scrollTop * modifier; 11789 rect.left += scrollLeft * modifier; 11790 rect.right += scrollLeft * modifier; 11791 return rect; 11792} 11793 11794/* 11795 * Helper to detect borders of a given element 11796 * @method 11797 * @memberof Popper.Utils 11798 * @param {CSSStyleDeclaration} styles 11799 * Result of `getStyleComputedProperty` on the given element 11800 * @param {String} axis - `x` or `y` 11801 * @return {number} borders - The borders size of the given axis 11802 */ 11803 11804function getBordersSize(styles, axis) { 11805 var sideA = axis === 'x' ? 'Left' : 'Top'; 11806 var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 11807 11808 return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); 11809} 11810 11811function getSize(axis, body, html, computedStyle) { 11812 return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE$1(10) ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0); 11813} 11814 11815function getWindowSizes() { 11816 var body = document.body; 11817 var html = document.documentElement; 11818 var computedStyle = isIE$1(10) && getComputedStyle(html); 11819 11820 return { 11821 height: getSize('Height', body, html, computedStyle), 11822 width: getSize('Width', body, html, computedStyle) 11823 }; 11824} 11825 11826var classCallCheck$1 = function classCallCheck(instance, Constructor) { 11827 if (!(instance instanceof Constructor)) { 11828 throw new TypeError("Cannot call a class as a function"); 11829 } 11830}; 11831 11832var createClass$1 = function () { 11833 function defineProperties(target, props) { 11834 for (var i = 0; i < props.length; i++) { 11835 var descriptor = props[i]; 11836 descriptor.enumerable = descriptor.enumerable || false; 11837 descriptor.configurable = true; 11838 if ("value" in descriptor) descriptor.writable = true; 11839 Object.defineProperty(target, descriptor.key, descriptor); 11840 } 11841 } 11842 11843 return function (Constructor, protoProps, staticProps) { 11844 if (protoProps) defineProperties(Constructor.prototype, protoProps); 11845 if (staticProps) defineProperties(Constructor, staticProps); 11846 return Constructor; 11847 }; 11848}(); 11849 11850var defineProperty$1 = function defineProperty(obj, key, value) { 11851 if (key in obj) { 11852 Object.defineProperty(obj, key, { 11853 value: value, 11854 enumerable: true, 11855 configurable: true, 11856 writable: true 11857 }); 11858 } else { 11859 obj[key] = value; 11860 } 11861 11862 return obj; 11863}; 11864 11865var _extends$1 = Object.assign || function (target) { 11866 for (var i = 1; i < arguments.length; i++) { 11867 var source = arguments[i]; 11868 11869 for (var key in source) { 11870 if (Object.prototype.hasOwnProperty.call(source, key)) { 11871 target[key] = source[key]; 11872 } 11873 } 11874 } 11875 11876 return target; 11877}; 11878 11879/** 11880 * Given element offsets, generate an output similar to getBoundingClientRect 11881 * @method 11882 * @memberof Popper.Utils 11883 * @argument {Object} offsets 11884 * @returns {Object} ClientRect like output 11885 */ 11886function getClientRect(offsets) { 11887 return _extends$1({}, offsets, { 11888 right: offsets.left + offsets.width, 11889 bottom: offsets.top + offsets.height 11890 }); 11891} 11892 11893/** 11894 * Get bounding client rect of given element 11895 * @method 11896 * @memberof Popper.Utils 11897 * @param {HTMLElement} element 11898 * @return {Object} client rect 11899 */ 11900function getBoundingClientRect(element) { 11901 var rect = {}; 11902 11903 // IE10 10 FIX: Please, don't ask, the element isn't 11904 // considered in DOM in some circumstances... 11905 // This isn't reproducible in IE10 compatibility mode of IE11 11906 try { 11907 if (isIE$1(10)) { 11908 rect = element.getBoundingClientRect(); 11909 var scrollTop = getScroll(element, 'top'); 11910 var scrollLeft = getScroll(element, 'left'); 11911 rect.top += scrollTop; 11912 rect.left += scrollLeft; 11913 rect.bottom += scrollTop; 11914 rect.right += scrollLeft; 11915 } else { 11916 rect = element.getBoundingClientRect(); 11917 } 11918 } catch (e) {} 11919 11920 var result = { 11921 left: rect.left, 11922 top: rect.top, 11923 width: rect.right - rect.left, 11924 height: rect.bottom - rect.top 11925 }; 11926 11927 // subtract scrollbar size from sizes 11928 var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {}; 11929 var width = sizes.width || element.clientWidth || result.right - result.left; 11930 var height = sizes.height || element.clientHeight || result.bottom - result.top; 11931 11932 var horizScrollbar = element.offsetWidth - width; 11933 var vertScrollbar = element.offsetHeight - height; 11934 11935 // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 11936 // we make this check conditional for performance reasons 11937 if (horizScrollbar || vertScrollbar) { 11938 var styles = getStyleComputedProperty(element); 11939 horizScrollbar -= getBordersSize(styles, 'x'); 11940 vertScrollbar -= getBordersSize(styles, 'y'); 11941 11942 result.width -= horizScrollbar; 11943 result.height -= vertScrollbar; 11944 } 11945 11946 return getClientRect(result); 11947} 11948 11949function getOffsetRectRelativeToArbitraryNode(children, parent) { 11950 var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 11951 11952 var isIE10 = isIE$1(10); 11953 var isHTML = parent.nodeName === 'HTML'; 11954 var childrenRect = getBoundingClientRect(children); 11955 var parentRect = getBoundingClientRect(parent); 11956 var scrollParent = getScrollParent(children); 11957 11958 var styles = getStyleComputedProperty(parent); 11959 var borderTopWidth = parseFloat(styles.borderTopWidth, 10); 11960 var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); 11961 11962 // In cases where the parent is fixed, we must ignore negative scroll in offset calc 11963 if (fixedPosition && parent.nodeName === 'HTML') { 11964 parentRect.top = Math.max(parentRect.top, 0); 11965 parentRect.left = Math.max(parentRect.left, 0); 11966 } 11967 var offsets = getClientRect({ 11968 top: childrenRect.top - parentRect.top - borderTopWidth, 11969 left: childrenRect.left - parentRect.left - borderLeftWidth, 11970 width: childrenRect.width, 11971 height: childrenRect.height 11972 }); 11973 offsets.marginTop = 0; 11974 offsets.marginLeft = 0; 11975 11976 // Subtract margins of documentElement in case it's being used as parent 11977 // we do this only on HTML because it's the only element that behaves 11978 // differently when margins are applied to it. The margins are included in 11979 // the box of the documentElement, in the other cases not. 11980 if (!isIE10 && isHTML) { 11981 var marginTop = parseFloat(styles.marginTop, 10); 11982 var marginLeft = parseFloat(styles.marginLeft, 10); 11983 11984 offsets.top -= borderTopWidth - marginTop; 11985 offsets.bottom -= borderTopWidth - marginTop; 11986 offsets.left -= borderLeftWidth - marginLeft; 11987 offsets.right -= borderLeftWidth - marginLeft; 11988 11989 // Attach marginTop and marginLeft because in some circumstances we may need them 11990 offsets.marginTop = marginTop; 11991 offsets.marginLeft = marginLeft; 11992 } 11993 11994 if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { 11995 offsets = includeScroll(offsets, parent); 11996 } 11997 11998 return offsets; 11999} 12000 12001function getViewportOffsetRectRelativeToArtbitraryNode(element) { 12002 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 12003 12004 var html = element.ownerDocument.documentElement; 12005 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 12006 var width = Math.max(html.clientWidth, window.innerWidth || 0); 12007 var height = Math.max(html.clientHeight, window.innerHeight || 0); 12008 12009 var scrollTop = !excludeScroll ? getScroll(html) : 0; 12010 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 12011 12012 var offset = { 12013 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 12014 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 12015 width: width, 12016 height: height 12017 }; 12018 12019 return getClientRect(offset); 12020} 12021 12022/** 12023 * Check if the given element is fixed or is inside a fixed parent 12024 * @method 12025 * @memberof Popper.Utils 12026 * @argument {Element} element 12027 * @argument {Element} customContainer 12028 * @returns {Boolean} answer to "isFixed?" 12029 */ 12030function isFixed(element) { 12031 var nodeName = element.nodeName; 12032 if (nodeName === 'BODY' || nodeName === 'HTML') { 12033 return false; 12034 } 12035 if (getStyleComputedProperty(element, 'position') === 'fixed') { 12036 return true; 12037 } 12038 return isFixed(getParentNode(element)); 12039} 12040 12041/** 12042 * Finds the first parent of an element that has a transformed property defined 12043 * @method 12044 * @memberof Popper.Utils 12045 * @argument {Element} element 12046 * @returns {Element} first transformed parent or documentElement 12047 */ 12048 12049function getFixedPositionOffsetParent(element) { 12050 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 12051 if (!element || !element.parentElement || isIE$1()) { 12052 return document.documentElement; 12053 } 12054 var el = element.parentElement; 12055 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 12056 el = el.parentElement; 12057 } 12058 return el || document.documentElement; 12059} 12060 12061/** 12062 * Computed the boundaries limits and return them 12063 * @method 12064 * @memberof Popper.Utils 12065 * @param {HTMLElement} popper 12066 * @param {HTMLElement} reference 12067 * @param {number} padding 12068 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 12069 * @param {Boolean} fixedPosition - Is in fixed position mode 12070 * @returns {Object} Coordinates of the boundaries 12071 */ 12072function getBoundaries(popper, reference, padding, boundariesElement) { 12073 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; 12074 12075 // NOTE: 1 DOM access here 12076 12077 var boundaries = { top: 0, left: 0 }; 12078 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 12079 12080 // Handle viewport case 12081 if (boundariesElement === 'viewport') { 12082 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 12083 } else { 12084 // Handle other cases based on DOM element used as boundaries 12085 var boundariesNode = void 0; 12086 if (boundariesElement === 'scrollParent') { 12087 boundariesNode = getScrollParent(getParentNode(reference)); 12088 if (boundariesNode.nodeName === 'BODY') { 12089 boundariesNode = popper.ownerDocument.documentElement; 12090 } 12091 } else if (boundariesElement === 'window') { 12092 boundariesNode = popper.ownerDocument.documentElement; 12093 } else { 12094 boundariesNode = boundariesElement; 12095 } 12096 12097 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); 12098 12099 // In case of HTML, we need a different computation 12100 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 12101 var _getWindowSizes = getWindowSizes(), 12102 height = _getWindowSizes.height, 12103 width = _getWindowSizes.width; 12104 12105 boundaries.top += offsets.top - offsets.marginTop; 12106 boundaries.bottom = height + offsets.top; 12107 boundaries.left += offsets.left - offsets.marginLeft; 12108 boundaries.right = width + offsets.left; 12109 } else { 12110 // for all the other DOM elements, this one is good 12111 boundaries = offsets; 12112 } 12113 } 12114 12115 // Add paddings 12116 boundaries.left += padding; 12117 boundaries.top += padding; 12118 boundaries.right -= padding; 12119 boundaries.bottom -= padding; 12120 12121 return boundaries; 12122} 12123 12124function getArea(_ref) { 12125 var width = _ref.width, 12126 height = _ref.height; 12127 12128 return width * height; 12129} 12130 12131/** 12132 * Utility used to transform the `auto` placement to the placement with more 12133 * available space. 12134 * @method 12135 * @memberof Popper.Utils 12136 * @argument {Object} data - The data object generated by update method 12137 * @argument {Object} options - Modifiers configuration and options 12138 * @returns {Object} The data object, properly modified 12139 */ 12140function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 12141 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 12142 12143 if (placement.indexOf('auto') === -1) { 12144 return placement; 12145 } 12146 12147 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 12148 12149 var rects = { 12150 top: { 12151 width: boundaries.width, 12152 height: refRect.top - boundaries.top 12153 }, 12154 right: { 12155 width: boundaries.right - refRect.right, 12156 height: boundaries.height 12157 }, 12158 bottom: { 12159 width: boundaries.width, 12160 height: boundaries.bottom - refRect.bottom 12161 }, 12162 left: { 12163 width: refRect.left - boundaries.left, 12164 height: boundaries.height 12165 } 12166 }; 12167 12168 var sortedAreas = Object.keys(rects).map(function (key) { 12169 return _extends$1({ 12170 key: key 12171 }, rects[key], { 12172 area: getArea(rects[key]) 12173 }); 12174 }).sort(function (a, b) { 12175 return b.area - a.area; 12176 }); 12177 12178 var filteredAreas = sortedAreas.filter(function (_ref2) { 12179 var width = _ref2.width, 12180 height = _ref2.height; 12181 return width >= popper.clientWidth && height >= popper.clientHeight; 12182 }); 12183 12184 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 12185 12186 var variation = placement.split('-')[1]; 12187 12188 return computedPlacement + (variation ? '-' + variation : ''); 12189} 12190 12191/** 12192 * Get offsets to the reference element 12193 * @method 12194 * @memberof Popper.Utils 12195 * @param {Object} state 12196 * @param {Element} popper - the popper element 12197 * @param {Element} reference - the reference element (the popper will be relative to this) 12198 * @param {Element} fixedPosition - is in fixed position mode 12199 * @returns {Object} An object containing the offsets which will be applied to the popper 12200 */ 12201function getReferenceOffsets(state, popper, reference) { 12202 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 12203 12204 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 12205 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 12206} 12207 12208/** 12209 * Get the outer sizes of the given element (offset size + margins) 12210 * @method 12211 * @memberof Popper.Utils 12212 * @argument {Element} element 12213 * @returns {Object} object containing width and height properties 12214 */ 12215function getOuterSizes(element) { 12216 var styles = getComputedStyle(element); 12217 var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); 12218 var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); 12219 var result = { 12220 width: element.offsetWidth + y, 12221 height: element.offsetHeight + x 12222 }; 12223 return result; 12224} 12225 12226/** 12227 * Get the opposite placement of the given one 12228 * @method 12229 * @memberof Popper.Utils 12230 * @argument {String} placement 12231 * @returns {String} flipped placement 12232 */ 12233function getOppositePlacement(placement) { 12234 var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 12235 return placement.replace(/left|right|bottom|top/g, function (matched) { 12236 return hash[matched]; 12237 }); 12238} 12239 12240/** 12241 * Get offsets to the popper 12242 * @method 12243 * @memberof Popper.Utils 12244 * @param {Object} position - CSS position the Popper will get applied 12245 * @param {HTMLElement} popper - the popper element 12246 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 12247 * @param {String} placement - one of the valid placement options 12248 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 12249 */ 12250function getPopperOffsets(popper, referenceOffsets, placement) { 12251 placement = placement.split('-')[0]; 12252 12253 // Get popper node sizes 12254 var popperRect = getOuterSizes(popper); 12255 12256 // Add position, width and height to our offsets object 12257 var popperOffsets = { 12258 width: popperRect.width, 12259 height: popperRect.height 12260 }; 12261 12262 // depending by the popper placement we have to compute its offsets slightly differently 12263 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 12264 var mainSide = isHoriz ? 'top' : 'left'; 12265 var secondarySide = isHoriz ? 'left' : 'top'; 12266 var measurement = isHoriz ? 'height' : 'width'; 12267 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 12268 12269 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 12270 if (placement === secondarySide) { 12271 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 12272 } else { 12273 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 12274 } 12275 12276 return popperOffsets; 12277} 12278 12279/** 12280 * Mimics the `find` method of Array 12281 * @method 12282 * @memberof Popper.Utils 12283 * @argument {Array} arr 12284 * @argument prop 12285 * @argument value 12286 * @returns index or -1 12287 */ 12288function find(arr, check) { 12289 // use native find if supported 12290 if (Array.prototype.find) { 12291 return arr.find(check); 12292 } 12293 12294 // use `filter` to obtain the same behavior of `find` 12295 return arr.filter(check)[0]; 12296} 12297 12298/** 12299 * Return the index of the matching object 12300 * @method 12301 * @memberof Popper.Utils 12302 * @argument {Array} arr 12303 * @argument prop 12304 * @argument value 12305 * @returns index or -1 12306 */ 12307function findIndex(arr, prop, value) { 12308 // use native findIndex if supported 12309 if (Array.prototype.findIndex) { 12310 return arr.findIndex(function (cur) { 12311 return cur[prop] === value; 12312 }); 12313 } 12314 12315 // use `find` + `indexOf` if `findIndex` isn't supported 12316 var match = find(arr, function (obj) { 12317 return obj[prop] === value; 12318 }); 12319 return arr.indexOf(match); 12320} 12321 12322/** 12323 * Loop trough the list of modifiers and run them in order, 12324 * each of them will then edit the data object. 12325 * @method 12326 * @memberof Popper.Utils 12327 * @param {dataObject} data 12328 * @param {Array} modifiers 12329 * @param {String} ends - Optional modifier name used as stopper 12330 * @returns {dataObject} 12331 */ 12332function runModifiers(modifiers, data, ends) { 12333 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 12334 12335 modifiersToRun.forEach(function (modifier) { 12336 if (modifier['function']) { 12337 // eslint-disable-line dot-notation 12338 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 12339 } 12340 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 12341 if (modifier.enabled && isFunction(fn)) { 12342 // Add properties to offsets to make them a complete clientRect object 12343 // we do this before each modifier to make sure the previous one doesn't 12344 // mess with these values 12345 data.offsets.popper = getClientRect(data.offsets.popper); 12346 data.offsets.reference = getClientRect(data.offsets.reference); 12347 12348 data = fn(data, modifier); 12349 } 12350 }); 12351 12352 return data; 12353} 12354 12355/** 12356 * Updates the position of the popper, computing the new offsets and applying 12357 * the new style.<br /> 12358 * Prefer `scheduleUpdate` over `update` because of performance reasons. 12359 * @method 12360 * @memberof Popper 12361 */ 12362function update() { 12363 // if popper is destroyed, don't perform any further update 12364 if (this.state.isDestroyed) { 12365 return; 12366 } 12367 12368 var data = { 12369 instance: this, 12370 styles: {}, 12371 arrowStyles: {}, 12372 attributes: {}, 12373 flipped: false, 12374 offsets: {} 12375 }; 12376 12377 // compute reference element offsets 12378 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); 12379 12380 // compute auto placement, store placement inside the data object, 12381 // modifiers will be able to edit `placement` if needed 12382 // and refer to originalPlacement to know the original value 12383 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); 12384 12385 // store the computed placement inside `originalPlacement` 12386 data.originalPlacement = data.placement; 12387 12388 data.positionFixed = this.options.positionFixed; 12389 12390 // compute the popper offsets 12391 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 12392 12393 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; 12394 12395 // run the modifiers 12396 data = runModifiers(this.modifiers, data); 12397 12398 // the first `update` will call `onCreate` callback 12399 // the other ones will call `onUpdate` callback 12400 if (!this.state.isCreated) { 12401 this.state.isCreated = true; 12402 this.options.onCreate(data); 12403 } else { 12404 this.options.onUpdate(data); 12405 } 12406} 12407 12408/** 12409 * Helper used to know if the given modifier is enabled. 12410 * @method 12411 * @memberof Popper.Utils 12412 * @returns {Boolean} 12413 */ 12414function isModifierEnabled(modifiers, modifierName) { 12415 return modifiers.some(function (_ref) { 12416 var name = _ref.name, 12417 enabled = _ref.enabled; 12418 return enabled && name === modifierName; 12419 }); 12420} 12421 12422/** 12423 * Get the prefixed supported property name 12424 * @method 12425 * @memberof Popper.Utils 12426 * @argument {String} property (camelCase) 12427 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 12428 */ 12429function getSupportedPropertyName(property) { 12430 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 12431 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 12432 12433 for (var i = 0; i < prefixes.length; i++) { 12434 var prefix = prefixes[i]; 12435 var toCheck = prefix ? '' + prefix + upperProp : property; 12436 if (typeof document.body.style[toCheck] !== 'undefined') { 12437 return toCheck; 12438 } 12439 } 12440 return null; 12441} 12442 12443/** 12444 * Destroy the popper 12445 * @method 12446 * @memberof Popper 12447 */ 12448function destroy() { 12449 this.state.isDestroyed = true; 12450 12451 // touch DOM only if `applyStyle` modifier is enabled 12452 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 12453 this.popper.removeAttribute('x-placement'); 12454 this.popper.style.position = ''; 12455 this.popper.style.top = ''; 12456 this.popper.style.left = ''; 12457 this.popper.style.right = ''; 12458 this.popper.style.bottom = ''; 12459 this.popper.style.willChange = ''; 12460 this.popper.style[getSupportedPropertyName('transform')] = ''; 12461 } 12462 12463 this.disableEventListeners(); 12464 12465 // remove the popper if user explicity asked for the deletion on destroy 12466 // do not use `remove` because IE11 doesn't support it 12467 if (this.options.removeOnDestroy) { 12468 this.popper.parentNode.removeChild(this.popper); 12469 } 12470 return this; 12471} 12472 12473/** 12474 * Get the window associated with the element 12475 * @argument {Element} element 12476 * @returns {Window} 12477 */ 12478function getWindow(element) { 12479 var ownerDocument = element.ownerDocument; 12480 return ownerDocument ? ownerDocument.defaultView : window; 12481} 12482 12483function attachToScrollParents(scrollParent, event, callback, scrollParents) { 12484 var isBody = scrollParent.nodeName === 'BODY'; 12485 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 12486 target.addEventListener(event, callback, { passive: true }); 12487 12488 if (!isBody) { 12489 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 12490 } 12491 scrollParents.push(target); 12492} 12493 12494/** 12495 * Setup needed event listeners used to update the popper position 12496 * @method 12497 * @memberof Popper.Utils 12498 * @private 12499 */ 12500function setupEventListeners(reference, options, state, updateBound) { 12501 // Resize event listener on window 12502 state.updateBound = updateBound; 12503 getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 12504 12505 // Scroll event listener on scroll parents 12506 var scrollElement = getScrollParent(reference); 12507 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 12508 state.scrollElement = scrollElement; 12509 state.eventsEnabled = true; 12510 12511 return state; 12512} 12513 12514/** 12515 * It will add resize/scroll events and start recalculating 12516 * position of the popper element when they are triggered. 12517 * @method 12518 * @memberof Popper 12519 */ 12520function enableEventListeners() { 12521 if (!this.state.eventsEnabled) { 12522 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 12523 } 12524} 12525 12526/** 12527 * Remove event listeners used to update the popper position 12528 * @method 12529 * @memberof Popper.Utils 12530 * @private 12531 */ 12532function removeEventListeners(reference, state) { 12533 // Remove resize event listener on window 12534 getWindow(reference).removeEventListener('resize', state.updateBound); 12535 12536 // Remove scroll event listener on scroll parents 12537 state.scrollParents.forEach(function (target) { 12538 target.removeEventListener('scroll', state.updateBound); 12539 }); 12540 12541 // Reset state 12542 state.updateBound = null; 12543 state.scrollParents = []; 12544 state.scrollElement = null; 12545 state.eventsEnabled = false; 12546 return state; 12547} 12548 12549/** 12550 * It will remove resize/scroll events and won't recalculate popper position 12551 * when they are triggered. It also won't trigger onUpdate callback anymore, 12552 * unless you call `update` method manually. 12553 * @method 12554 * @memberof Popper 12555 */ 12556function disableEventListeners() { 12557 if (this.state.eventsEnabled) { 12558 cancelAnimationFrame(this.scheduleUpdate); 12559 this.state = removeEventListeners(this.reference, this.state); 12560 } 12561} 12562 12563/** 12564 * Tells if a given input is a number 12565 * @method 12566 * @memberof Popper.Utils 12567 * @param {*} input to check 12568 * @return {Boolean} 12569 */ 12570function isNumeric(n) { 12571 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 12572} 12573 12574/** 12575 * Set the style to the given popper 12576 * @method 12577 * @memberof Popper.Utils 12578 * @argument {Element} element - Element to apply the style to 12579 * @argument {Object} styles 12580 * Object with a list of properties and values which will be applied to the element 12581 */ 12582function setStyles(element, styles) { 12583 Object.keys(styles).forEach(function (prop) { 12584 var unit = ''; 12585 // add unit if the value is numeric and is one of the following 12586 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 12587 unit = 'px'; 12588 } 12589 element.style[prop] = styles[prop] + unit; 12590 }); 12591} 12592 12593/** 12594 * Set the attributes to the given popper 12595 * @method 12596 * @memberof Popper.Utils 12597 * @argument {Element} element - Element to apply the attributes to 12598 * @argument {Object} styles 12599 * Object with a list of properties and values which will be applied to the element 12600 */ 12601function setAttributes(element, attributes) { 12602 Object.keys(attributes).forEach(function (prop) { 12603 var value = attributes[prop]; 12604 if (value !== false) { 12605 element.setAttribute(prop, attributes[prop]); 12606 } else { 12607 element.removeAttribute(prop); 12608 } 12609 }); 12610} 12611 12612/** 12613 * @function 12614 * @memberof Modifiers 12615 * @argument {Object} data - The data object generated by `update` method 12616 * @argument {Object} data.styles - List of style properties - values to apply to popper element 12617 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 12618 * @argument {Object} options - Modifiers configuration and options 12619 * @returns {Object} The same data object 12620 */ 12621function applyStyle(data) { 12622 // any property present in `data.styles` will be applied to the popper, 12623 // in this way we can make the 3rd party modifiers add custom styles to it 12624 // Be aware, modifiers could override the properties defined in the previous 12625 // lines of this modifier! 12626 setStyles(data.instance.popper, data.styles); 12627 12628 // any property present in `data.attributes` will be applied to the popper, 12629 // they will be set as HTML attributes of the element 12630 setAttributes(data.instance.popper, data.attributes); 12631 12632 // if arrowElement is defined and arrowStyles has some properties 12633 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 12634 setStyles(data.arrowElement, data.arrowStyles); 12635 } 12636 12637 return data; 12638} 12639 12640/** 12641 * Set the x-placement attribute before everything else because it could be used 12642 * to add margins to the popper margins needs to be calculated to get the 12643 * correct popper offsets. 12644 * @method 12645 * @memberof Popper.modifiers 12646 * @param {HTMLElement} reference - The reference element used to position the popper 12647 * @param {HTMLElement} popper - The HTML element used as popper 12648 * @param {Object} options - Popper.js options 12649 */ 12650function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 12651 // compute reference element offsets 12652 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 12653 12654 // compute auto placement, store placement inside the data object, 12655 // modifiers will be able to edit `placement` if needed 12656 // and refer to originalPlacement to know the original value 12657 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 12658 12659 popper.setAttribute('x-placement', placement); 12660 12661 // Apply `position` to popper before anything else because 12662 // without the position applied we can't guarantee correct computations 12663 setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 12664 12665 return options; 12666} 12667 12668/** 12669 * @function 12670 * @memberof Modifiers 12671 * @argument {Object} data - The data object generated by `update` method 12672 * @argument {Object} options - Modifiers configuration and options 12673 * @returns {Object} The data object, properly modified 12674 */ 12675function computeStyle(data, options) { 12676 var x = options.x, 12677 y = options.y; 12678 var popper = data.offsets.popper; 12679 12680 // Remove this legacy support in Popper.js v2 12681 12682 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 12683 return modifier.name === 'applyStyle'; 12684 }).gpuAcceleration; 12685 if (legacyGpuAccelerationOption !== undefined) { 12686 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 12687 } 12688 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 12689 12690 var offsetParent = getOffsetParent(data.instance.popper); 12691 var offsetParentRect = getBoundingClientRect(offsetParent); 12692 12693 // Styles 12694 var styles = { 12695 position: popper.position 12696 }; 12697 12698 // Avoid blurry text by using full pixel integers. 12699 // For pixel-perfect positioning, top/bottom prefers rounded 12700 // values, while left/right prefers floored values. 12701 var offsets = { 12702 left: Math.floor(popper.left), 12703 top: Math.round(popper.top), 12704 bottom: Math.round(popper.bottom), 12705 right: Math.floor(popper.right) 12706 }; 12707 12708 var sideA = x === 'bottom' ? 'top' : 'bottom'; 12709 var sideB = y === 'right' ? 'left' : 'right'; 12710 12711 // if gpuAcceleration is set to `true` and transform is supported, 12712 // we use `translate3d` to apply the position to the popper we 12713 // automatically use the supported prefixed version if needed 12714 var prefixedProperty = getSupportedPropertyName('transform'); 12715 12716 // now, let's make a step back and look at this code closely (wtf?) 12717 // If the content of the popper grows once it's been positioned, it 12718 // may happen that the popper gets misplaced because of the new content 12719 // overflowing its reference element 12720 // To avoid this problem, we provide two options (x and y), which allow 12721 // the consumer to define the offset origin. 12722 // If we position a popper on top of a reference element, we can set 12723 // `x` to `top` to make the popper grow towards its top instead of 12724 // its bottom. 12725 var left = void 0, 12726 top = void 0; 12727 if (sideA === 'bottom') { 12728 top = -offsetParentRect.height + offsets.bottom; 12729 } else { 12730 top = offsets.top; 12731 } 12732 if (sideB === 'right') { 12733 left = -offsetParentRect.width + offsets.right; 12734 } else { 12735 left = offsets.left; 12736 } 12737 if (gpuAcceleration && prefixedProperty) { 12738 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 12739 styles[sideA] = 0; 12740 styles[sideB] = 0; 12741 styles.willChange = 'transform'; 12742 } else { 12743 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 12744 var invertTop = sideA === 'bottom' ? -1 : 1; 12745 var invertLeft = sideB === 'right' ? -1 : 1; 12746 styles[sideA] = top * invertTop; 12747 styles[sideB] = left * invertLeft; 12748 styles.willChange = sideA + ', ' + sideB; 12749 } 12750 12751 // Attributes 12752 var attributes = { 12753 'x-placement': data.placement 12754 }; 12755 12756 // Update `data` attributes, styles and arrowStyles 12757 data.attributes = _extends$1({}, attributes, data.attributes); 12758 data.styles = _extends$1({}, styles, data.styles); 12759 data.arrowStyles = _extends$1({}, data.offsets.arrow, data.arrowStyles); 12760 12761 return data; 12762} 12763 12764/** 12765 * Helper used to know if the given modifier depends from another one.<br /> 12766 * It checks if the needed modifier is listed and enabled. 12767 * @method 12768 * @memberof Popper.Utils 12769 * @param {Array} modifiers - list of modifiers 12770 * @param {String} requestingName - name of requesting modifier 12771 * @param {String} requestedName - name of requested modifier 12772 * @returns {Boolean} 12773 */ 12774function isModifierRequired(modifiers, requestingName, requestedName) { 12775 var requesting = find(modifiers, function (_ref) { 12776 var name = _ref.name; 12777 return name === requestingName; 12778 }); 12779 12780 var isRequired = !!requesting && modifiers.some(function (modifier) { 12781 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 12782 }); 12783 12784 if (!isRequired) { 12785 var _requesting = '`' + requestingName + '`'; 12786 var requested = '`' + requestedName + '`'; 12787 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 12788 } 12789 return isRequired; 12790} 12791 12792/** 12793 * @function 12794 * @memberof Modifiers 12795 * @argument {Object} data - The data object generated by update method 12796 * @argument {Object} options - Modifiers configuration and options 12797 * @returns {Object} The data object, properly modified 12798 */ 12799function arrow(data, options) { 12800 var _data$offsets$arrow; 12801 12802 // arrow depends on keepTogether in order to work 12803 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 12804 return data; 12805 } 12806 12807 var arrowElement = options.element; 12808 12809 // if arrowElement is a string, suppose it's a CSS selector 12810 if (typeof arrowElement === 'string') { 12811 arrowElement = data.instance.popper.querySelector(arrowElement); 12812 12813 // if arrowElement is not found, don't run the modifier 12814 if (!arrowElement) { 12815 return data; 12816 } 12817 } else { 12818 // if the arrowElement isn't a query selector we must check that the 12819 // provided DOM node is child of its popper node 12820 if (!data.instance.popper.contains(arrowElement)) { 12821 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 12822 return data; 12823 } 12824 } 12825 12826 var placement = data.placement.split('-')[0]; 12827 var _data$offsets = data.offsets, 12828 popper = _data$offsets.popper, 12829 reference = _data$offsets.reference; 12830 12831 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 12832 12833 var len = isVertical ? 'height' : 'width'; 12834 var sideCapitalized = isVertical ? 'Top' : 'Left'; 12835 var side = sideCapitalized.toLowerCase(); 12836 var altSide = isVertical ? 'left' : 'top'; 12837 var opSide = isVertical ? 'bottom' : 'right'; 12838 var arrowElementSize = getOuterSizes(arrowElement)[len]; 12839 12840 // 12841 // extends keepTogether behavior making sure the popper and its 12842 // reference have enough pixels in conjuction 12843 // 12844 12845 // top/left side 12846 if (reference[opSide] - arrowElementSize < popper[side]) { 12847 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 12848 } 12849 // bottom/right side 12850 if (reference[side] + arrowElementSize > popper[opSide]) { 12851 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 12852 } 12853 data.offsets.popper = getClientRect(data.offsets.popper); 12854 12855 // compute center of the popper 12856 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 12857 12858 // Compute the sideValue using the updated popper offsets 12859 // take popper margin in account because we don't have this info available 12860 var css = getStyleComputedProperty(data.instance.popper); 12861 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 12862 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 12863 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 12864 12865 // prevent arrowElement from being placed not contiguously to its popper 12866 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 12867 12868 data.arrowElement = arrowElement; 12869 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty$1(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty$1(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 12870 12871 return data; 12872} 12873 12874/** 12875 * Get the opposite placement variation of the given one 12876 * @method 12877 * @memberof Popper.Utils 12878 * @argument {String} placement variation 12879 * @returns {String} flipped placement variation 12880 */ 12881function getOppositeVariation(variation) { 12882 if (variation === 'end') { 12883 return 'start'; 12884 } else if (variation === 'start') { 12885 return 'end'; 12886 } 12887 return variation; 12888} 12889 12890/** 12891 * List of accepted placements to use as values of the `placement` option.<br /> 12892 * Valid placements are: 12893 * - `auto` 12894 * - `top` 12895 * - `right` 12896 * - `bottom` 12897 * - `left` 12898 * 12899 * Each placement can have a variation from this list: 12900 * - `-start` 12901 * - `-end` 12902 * 12903 * Variations are interpreted easily if you think of them as the left to right 12904 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 12905 * is right.<br /> 12906 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 12907 * 12908 * Some valid examples are: 12909 * - `top-end` (on top of reference, right aligned) 12910 * - `right-start` (on right of reference, top aligned) 12911 * - `bottom` (on bottom, centered) 12912 * - `auto-right` (on the side with more space available, alignment depends by placement) 12913 * 12914 * @static 12915 * @type {Array} 12916 * @enum {String} 12917 * @readonly 12918 * @method placements 12919 * @memberof Popper 12920 */ 12921var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; 12922 12923// Get rid of `auto` `auto-start` and `auto-end` 12924var validPlacements = placements.slice(3); 12925 12926/** 12927 * Given an initial placement, returns all the subsequent placements 12928 * clockwise (or counter-clockwise). 12929 * 12930 * @method 12931 * @memberof Popper.Utils 12932 * @argument {String} placement - A valid placement (it accepts variations) 12933 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 12934 * @returns {Array} placements including their variations 12935 */ 12936function clockwise(placement) { 12937 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 12938 12939 var index = validPlacements.indexOf(placement); 12940 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 12941 return counter ? arr.reverse() : arr; 12942} 12943 12944var BEHAVIORS = { 12945 FLIP: 'flip', 12946 CLOCKWISE: 'clockwise', 12947 COUNTERCLOCKWISE: 'counterclockwise' 12948}; 12949 12950/** 12951 * @function 12952 * @memberof Modifiers 12953 * @argument {Object} data - The data object generated by update method 12954 * @argument {Object} options - Modifiers configuration and options 12955 * @returns {Object} The data object, properly modified 12956 */ 12957function flip(data, options) { 12958 // if `inner` modifier is enabled, we can't use the `flip` modifier 12959 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 12960 return data; 12961 } 12962 12963 if (data.flipped && data.placement === data.originalPlacement) { 12964 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 12965 return data; 12966 } 12967 12968 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 12969 12970 var placement = data.placement.split('-')[0]; 12971 var placementOpposite = getOppositePlacement(placement); 12972 var variation = data.placement.split('-')[1] || ''; 12973 12974 var flipOrder = []; 12975 12976 switch (options.behavior) { 12977 case BEHAVIORS.FLIP: 12978 flipOrder = [placement, placementOpposite]; 12979 break; 12980 case BEHAVIORS.CLOCKWISE: 12981 flipOrder = clockwise(placement); 12982 break; 12983 case BEHAVIORS.COUNTERCLOCKWISE: 12984 flipOrder = clockwise(placement, true); 12985 break; 12986 default: 12987 flipOrder = options.behavior; 12988 } 12989 12990 flipOrder.forEach(function (step, index) { 12991 if (placement !== step || flipOrder.length === index + 1) { 12992 return data; 12993 } 12994 12995 placement = data.placement.split('-')[0]; 12996 placementOpposite = getOppositePlacement(placement); 12997 12998 var popperOffsets = data.offsets.popper; 12999 var refOffsets = data.offsets.reference; 13000 13001 // using floor because the reference offsets may contain decimals we are not going to consider here 13002 var floor = Math.floor; 13003 var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); 13004 13005 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 13006 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 13007 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 13008 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 13009 13010 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 13011 13012 // flip the variation if required 13013 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 13014 var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 13015 13016 if (overlapsRef || overflowsBoundaries || flippedVariation) { 13017 // this boolean to detect any flip loop 13018 data.flipped = true; 13019 13020 if (overlapsRef || overflowsBoundaries) { 13021 placement = flipOrder[index + 1]; 13022 } 13023 13024 if (flippedVariation) { 13025 variation = getOppositeVariation(variation); 13026 } 13027 13028 data.placement = placement + (variation ? '-' + variation : ''); 13029 13030 // this object contains `position`, we want to preserve it along with 13031 // any additional property we may add in the future 13032 data.offsets.popper = _extends$1({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 13033 13034 data = runModifiers(data.instance.modifiers, data, 'flip'); 13035 } 13036 }); 13037 return data; 13038} 13039 13040/** 13041 * @function 13042 * @memberof Modifiers 13043 * @argument {Object} data - The data object generated by update method 13044 * @argument {Object} options - Modifiers configuration and options 13045 * @returns {Object} The data object, properly modified 13046 */ 13047function keepTogether(data) { 13048 var _data$offsets = data.offsets, 13049 popper = _data$offsets.popper, 13050 reference = _data$offsets.reference; 13051 13052 var placement = data.placement.split('-')[0]; 13053 var floor = Math.floor; 13054 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 13055 var side = isVertical ? 'right' : 'bottom'; 13056 var opSide = isVertical ? 'left' : 'top'; 13057 var measurement = isVertical ? 'width' : 'height'; 13058 13059 if (popper[side] < floor(reference[opSide])) { 13060 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 13061 } 13062 if (popper[opSide] > floor(reference[side])) { 13063 data.offsets.popper[opSide] = floor(reference[side]); 13064 } 13065 13066 return data; 13067} 13068 13069/** 13070 * Converts a string containing value + unit into a px value number 13071 * @function 13072 * @memberof {modifiers~offset} 13073 * @private 13074 * @argument {String} str - Value + unit string 13075 * @argument {String} measurement - `height` or `width` 13076 * @argument {Object} popperOffsets 13077 * @argument {Object} referenceOffsets 13078 * @returns {Number|String} 13079 * Value in pixels, or original string if no values were extracted 13080 */ 13081function toValue(str, measurement, popperOffsets, referenceOffsets) { 13082 // separate value from unit 13083 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 13084 var value = +split[1]; 13085 var unit = split[2]; 13086 13087 // If it's not a number it's an operator, I guess 13088 if (!value) { 13089 return str; 13090 } 13091 13092 if (unit.indexOf('%') === 0) { 13093 var element = void 0; 13094 switch (unit) { 13095 case '%p': 13096 element = popperOffsets; 13097 break; 13098 case '%': 13099 case '%r': 13100 default: 13101 element = referenceOffsets; 13102 } 13103 13104 var rect = getClientRect(element); 13105 return rect[measurement] / 100 * value; 13106 } else if (unit === 'vh' || unit === 'vw') { 13107 // if is a vh or vw, we calculate the size based on the viewport 13108 var size = void 0; 13109 if (unit === 'vh') { 13110 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 13111 } else { 13112 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 13113 } 13114 return size / 100 * value; 13115 } else { 13116 // if is an explicit pixel unit, we get rid of the unit and keep the value 13117 // if is an implicit unit, it's px, and we return just the value 13118 return value; 13119 } 13120} 13121 13122/** 13123 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 13124 * @function 13125 * @memberof {modifiers~offset} 13126 * @private 13127 * @argument {String} offset 13128 * @argument {Object} popperOffsets 13129 * @argument {Object} referenceOffsets 13130 * @argument {String} basePlacement 13131 * @returns {Array} a two cells array with x and y offsets in numbers 13132 */ 13133function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 13134 var offsets = [0, 0]; 13135 13136 // Use height if placement is left or right and index is 0 otherwise use width 13137 // in this way the first offset will use an axis and the second one 13138 // will use the other one 13139 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 13140 13141 // Split the offset string to obtain a list of values and operands 13142 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 13143 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 13144 return frag.trim(); 13145 }); 13146 13147 // Detect if the offset string contains a pair of values or a single one 13148 // they could be separated by comma or space 13149 var divider = fragments.indexOf(find(fragments, function (frag) { 13150 return frag.search(/,|\s/) !== -1; 13151 })); 13152 13153 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 13154 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 13155 } 13156 13157 // If divider is found, we divide the list of values and operands to divide 13158 // them by ofset X and Y. 13159 var splitRegex = /\s*,\s*|\s+/; 13160 var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; 13161 13162 // Convert the values with units to absolute pixels to allow our computations 13163 ops = ops.map(function (op, index) { 13164 // Most of the units rely on the orientation of the popper 13165 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 13166 var mergeWithPrevious = false; 13167 return op 13168 // This aggregates any `+` or `-` sign that aren't considered operators 13169 // e.g.: 10 + +5 => [10, +, +5] 13170 .reduce(function (a, b) { 13171 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 13172 a[a.length - 1] = b; 13173 mergeWithPrevious = true; 13174 return a; 13175 } else if (mergeWithPrevious) { 13176 a[a.length - 1] += b; 13177 mergeWithPrevious = false; 13178 return a; 13179 } else { 13180 return a.concat(b); 13181 } 13182 }, []) 13183 // Here we convert the string values into number values (in px) 13184 .map(function (str) { 13185 return toValue(str, measurement, popperOffsets, referenceOffsets); 13186 }); 13187 }); 13188 13189 // Loop trough the offsets arrays and execute the operations 13190 ops.forEach(function (op, index) { 13191 op.forEach(function (frag, index2) { 13192 if (isNumeric(frag)) { 13193 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 13194 } 13195 }); 13196 }); 13197 return offsets; 13198} 13199 13200/** 13201 * @function 13202 * @memberof Modifiers 13203 * @argument {Object} data - The data object generated by update method 13204 * @argument {Object} options - Modifiers configuration and options 13205 * @argument {Number|String} options.offset=0 13206 * The offset value as described in the modifier description 13207 * @returns {Object} The data object, properly modified 13208 */ 13209function offset(data, _ref) { 13210 var offset = _ref.offset; 13211 var placement = data.placement, 13212 _data$offsets = data.offsets, 13213 popper = _data$offsets.popper, 13214 reference = _data$offsets.reference; 13215 13216 var basePlacement = placement.split('-')[0]; 13217 13218 var offsets = void 0; 13219 if (isNumeric(+offset)) { 13220 offsets = [+offset, 0]; 13221 } else { 13222 offsets = parseOffset(offset, popper, reference, basePlacement); 13223 } 13224 13225 if (basePlacement === 'left') { 13226 popper.top += offsets[0]; 13227 popper.left -= offsets[1]; 13228 } else if (basePlacement === 'right') { 13229 popper.top += offsets[0]; 13230 popper.left += offsets[1]; 13231 } else if (basePlacement === 'top') { 13232 popper.left += offsets[0]; 13233 popper.top -= offsets[1]; 13234 } else if (basePlacement === 'bottom') { 13235 popper.left += offsets[0]; 13236 popper.top += offsets[1]; 13237 } 13238 13239 data.popper = popper; 13240 return data; 13241} 13242 13243/** 13244 * @function 13245 * @memberof Modifiers 13246 * @argument {Object} data - The data object generated by `update` method 13247 * @argument {Object} options - Modifiers configuration and options 13248 * @returns {Object} The data object, properly modified 13249 */ 13250function preventOverflow(data, options) { 13251 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 13252 13253 // If offsetParent is the reference element, we really want to 13254 // go one step up and use the next offsetParent as reference to 13255 // avoid to make this modifier completely useless and look like broken 13256 if (data.instance.reference === boundariesElement) { 13257 boundariesElement = getOffsetParent(boundariesElement); 13258 } 13259 13260 // NOTE: DOM access here 13261 // resets the popper's position so that the document size can be calculated excluding 13262 // the size of the popper element itself 13263 var transformProp = getSupportedPropertyName('transform'); 13264 var popperStyles = data.instance.popper.style; // assignment to help minification 13265 var top = popperStyles.top, 13266 left = popperStyles.left, 13267 transform = popperStyles[transformProp]; 13268 13269 popperStyles.top = ''; 13270 popperStyles.left = ''; 13271 popperStyles[transformProp] = ''; 13272 13273 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 13274 13275 // NOTE: DOM access here 13276 // restores the original style properties after the offsets have been computed 13277 popperStyles.top = top; 13278 popperStyles.left = left; 13279 popperStyles[transformProp] = transform; 13280 13281 options.boundaries = boundaries; 13282 13283 var order = options.priority; 13284 var popper = data.offsets.popper; 13285 13286 var check = { 13287 primary: function primary(placement) { 13288 var value = popper[placement]; 13289 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 13290 value = Math.max(popper[placement], boundaries[placement]); 13291 } 13292 return defineProperty$1({}, placement, value); 13293 }, 13294 secondary: function secondary(placement) { 13295 var mainSide = placement === 'right' ? 'left' : 'top'; 13296 var value = popper[mainSide]; 13297 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 13298 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 13299 } 13300 return defineProperty$1({}, mainSide, value); 13301 } 13302 }; 13303 13304 order.forEach(function (placement) { 13305 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 13306 popper = _extends$1({}, popper, check[side](placement)); 13307 }); 13308 13309 data.offsets.popper = popper; 13310 13311 return data; 13312} 13313 13314/** 13315 * @function 13316 * @memberof Modifiers 13317 * @argument {Object} data - The data object generated by `update` method 13318 * @argument {Object} options - Modifiers configuration and options 13319 * @returns {Object} The data object, properly modified 13320 */ 13321function shift(data) { 13322 var placement = data.placement; 13323 var basePlacement = placement.split('-')[0]; 13324 var shiftvariation = placement.split('-')[1]; 13325 13326 // if shift shiftvariation is specified, run the modifier 13327 if (shiftvariation) { 13328 var _data$offsets = data.offsets, 13329 reference = _data$offsets.reference, 13330 popper = _data$offsets.popper; 13331 13332 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 13333 var side = isVertical ? 'left' : 'top'; 13334 var measurement = isVertical ? 'width' : 'height'; 13335 13336 var shiftOffsets = { 13337 start: defineProperty$1({}, side, reference[side]), 13338 end: defineProperty$1({}, side, reference[side] + reference[measurement] - popper[measurement]) 13339 }; 13340 13341 data.offsets.popper = _extends$1({}, popper, shiftOffsets[shiftvariation]); 13342 } 13343 13344 return data; 13345} 13346 13347/** 13348 * @function 13349 * @memberof Modifiers 13350 * @argument {Object} data - The data object generated by update method 13351 * @argument {Object} options - Modifiers configuration and options 13352 * @returns {Object} The data object, properly modified 13353 */ 13354function hide(data) { 13355 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 13356 return data; 13357 } 13358 13359 var refRect = data.offsets.reference; 13360 var bound = find(data.instance.modifiers, function (modifier) { 13361 return modifier.name === 'preventOverflow'; 13362 }).boundaries; 13363 13364 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 13365 // Avoid unnecessary DOM access if visibility hasn't changed 13366 if (data.hide === true) { 13367 return data; 13368 } 13369 13370 data.hide = true; 13371 data.attributes['x-out-of-boundaries'] = ''; 13372 } else { 13373 // Avoid unnecessary DOM access if visibility hasn't changed 13374 if (data.hide === false) { 13375 return data; 13376 } 13377 13378 data.hide = false; 13379 data.attributes['x-out-of-boundaries'] = false; 13380 } 13381 13382 return data; 13383} 13384 13385/** 13386 * @function 13387 * @memberof Modifiers 13388 * @argument {Object} data - The data object generated by `update` method 13389 * @argument {Object} options - Modifiers configuration and options 13390 * @returns {Object} The data object, properly modified 13391 */ 13392function inner(data) { 13393 var placement = data.placement; 13394 var basePlacement = placement.split('-')[0]; 13395 var _data$offsets = data.offsets, 13396 popper = _data$offsets.popper, 13397 reference = _data$offsets.reference; 13398 13399 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 13400 13401 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 13402 13403 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 13404 13405 data.placement = getOppositePlacement(placement); 13406 data.offsets.popper = getClientRect(popper); 13407 13408 return data; 13409} 13410 13411/** 13412 * Modifier function, each modifier can have a function of this type assigned 13413 * to its `fn` property.<br /> 13414 * These functions will be called on each update, this means that you must 13415 * make sure they are performant enough to avoid performance bottlenecks. 13416 * 13417 * @function ModifierFn 13418 * @argument {dataObject} data - The data object generated by `update` method 13419 * @argument {Object} options - Modifiers configuration and options 13420 * @returns {dataObject} The data object, properly modified 13421 */ 13422 13423/** 13424 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 13425 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 13426 * needed by the library. 13427 * 13428 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 13429 * All the other properties are configurations that could be tweaked. 13430 * @namespace modifiers 13431 */ 13432var modifiers = { 13433 /** 13434 * Modifier used to shift the popper on the start or end of its reference 13435 * element.<br /> 13436 * It will read the variation of the `placement` property.<br /> 13437 * It can be one either `-end` or `-start`. 13438 * @memberof modifiers 13439 * @inner 13440 */ 13441 shift: { 13442 /** @prop {number} order=100 - Index used to define the order of execution */ 13443 order: 100, 13444 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13445 enabled: true, 13446 /** @prop {ModifierFn} */ 13447 fn: shift 13448 }, 13449 13450 /** 13451 * The `offset` modifier can shift your popper on both its axis. 13452 * 13453 * It accepts the following units: 13454 * - `px` or unitless, interpreted as pixels 13455 * - `%` or `%r`, percentage relative to the length of the reference element 13456 * - `%p`, percentage relative to the length of the popper element 13457 * - `vw`, CSS viewport width unit 13458 * - `vh`, CSS viewport height unit 13459 * 13460 * For length is intended the main axis relative to the placement of the popper.<br /> 13461 * This means that if the placement is `top` or `bottom`, the length will be the 13462 * `width`. In case of `left` or `right`, it will be the height. 13463 * 13464 * You can provide a single value (as `Number` or `String`), or a pair of values 13465 * as `String` divided by a comma or one (or more) white spaces.<br /> 13466 * The latter is a deprecated method because it leads to confusion and will be 13467 * removed in v2.<br /> 13468 * Additionally, it accepts additions and subtractions between different units. 13469 * Note that multiplications and divisions aren't supported. 13470 * 13471 * Valid examples are: 13472 * ``` 13473 * 10 13474 * '10%' 13475 * '10, 10' 13476 * '10%, 10' 13477 * '10 + 10%' 13478 * '10 - 5vh + 3%' 13479 * '-10px + 5vh, 5px - 6%' 13480 * ``` 13481 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 13482 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 13483 * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373) 13484 * 13485 * @memberof modifiers 13486 * @inner 13487 */ 13488 offset: { 13489 /** @prop {number} order=200 - Index used to define the order of execution */ 13490 order: 200, 13491 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13492 enabled: true, 13493 /** @prop {ModifierFn} */ 13494 fn: offset, 13495 /** @prop {Number|String} offset=0 13496 * The offset value as described in the modifier description 13497 */ 13498 offset: 0 13499 }, 13500 13501 /** 13502 * Modifier used to prevent the popper from being positioned outside the boundary. 13503 * 13504 * An scenario exists where the reference itself is not within the boundaries.<br /> 13505 * We can say it has "escaped the boundaries" â or just "escaped".<br /> 13506 * In this case we need to decide whether the popper should either: 13507 * 13508 * - detach from the reference and remain "trapped" in the boundaries, or 13509 * - if it should ignore the boundary and "escape with its reference" 13510 * 13511 * When `escapeWithReference` is set to`true` and reference is completely 13512 * outside its boundaries, the popper will overflow (or completely leave) 13513 * the boundaries in order to remain attached to the edge of the reference. 13514 * 13515 * @memberof modifiers 13516 * @inner 13517 */ 13518 preventOverflow: { 13519 /** @prop {number} order=300 - Index used to define the order of execution */ 13520 order: 300, 13521 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13522 enabled: true, 13523 /** @prop {ModifierFn} */ 13524 fn: preventOverflow, 13525 /** 13526 * @prop {Array} [priority=['left','right','top','bottom']] 13527 * Popper will try to prevent overflow following these priorities by default, 13528 * then, it could overflow on the left and on top of the `boundariesElement` 13529 */ 13530 priority: ['left', 'right', 'top', 'bottom'], 13531 /** 13532 * @prop {number} padding=5 13533 * Amount of pixel used to define a minimum distance between the boundaries 13534 * and the popper this makes sure the popper has always a little padding 13535 * between the edges of its container 13536 */ 13537 padding: 5, 13538 /** 13539 * @prop {String|HTMLElement} boundariesElement='scrollParent' 13540 * Boundaries used by the modifier, can be `scrollParent`, `window`, 13541 * `viewport` or any DOM element. 13542 */ 13543 boundariesElement: 'scrollParent' 13544 }, 13545 13546 /** 13547 * Modifier used to make sure the reference and its popper stay near eachothers 13548 * without leaving any gap between the two. Expecially useful when the arrow is 13549 * enabled and you want to assure it to point to its reference element. 13550 * It cares only about the first axis, you can still have poppers with margin 13551 * between the popper and its reference element. 13552 * @memberof modifiers 13553 * @inner 13554 */ 13555 keepTogether: { 13556 /** @prop {number} order=400 - Index used to define the order of execution */ 13557 order: 400, 13558 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13559 enabled: true, 13560 /** @prop {ModifierFn} */ 13561 fn: keepTogether 13562 }, 13563 13564 /** 13565 * This modifier is used to move the `arrowElement` of the popper to make 13566 * sure it is positioned between the reference element and its popper element. 13567 * It will read the outer size of the `arrowElement` node to detect how many 13568 * pixels of conjuction are needed. 13569 * 13570 * It has no effect if no `arrowElement` is provided. 13571 * @memberof modifiers 13572 * @inner 13573 */ 13574 arrow: { 13575 /** @prop {number} order=500 - Index used to define the order of execution */ 13576 order: 500, 13577 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13578 enabled: true, 13579 /** @prop {ModifierFn} */ 13580 fn: arrow, 13581 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 13582 element: '[x-arrow]' 13583 }, 13584 13585 /** 13586 * Modifier used to flip the popper's placement when it starts to overlap its 13587 * reference element. 13588 * 13589 * Requires the `preventOverflow` modifier before it in order to work. 13590 * 13591 * **NOTE:** this modifier will interrupt the current update cycle and will 13592 * restart it if it detects the need to flip the placement. 13593 * @memberof modifiers 13594 * @inner 13595 */ 13596 flip: { 13597 /** @prop {number} order=600 - Index used to define the order of execution */ 13598 order: 600, 13599 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13600 enabled: true, 13601 /** @prop {ModifierFn} */ 13602 fn: flip, 13603 /** 13604 * @prop {String|Array} behavior='flip' 13605 * The behavior used to change the popper's placement. It can be one of 13606 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 13607 * placements (with optional variations). 13608 */ 13609 behavior: 'flip', 13610 /** 13611 * @prop {number} padding=5 13612 * The popper will flip if it hits the edges of the `boundariesElement` 13613 */ 13614 padding: 5, 13615 /** 13616 * @prop {String|HTMLElement} boundariesElement='viewport' 13617 * The element which will define the boundaries of the popper position, 13618 * the popper will never be placed outside of the defined boundaries 13619 * (except if keepTogether is enabled) 13620 */ 13621 boundariesElement: 'viewport' 13622 }, 13623 13624 /** 13625 * Modifier used to make the popper flow toward the inner of the reference element. 13626 * By default, when this modifier is disabled, the popper will be placed outside 13627 * the reference element. 13628 * @memberof modifiers 13629 * @inner 13630 */ 13631 inner: { 13632 /** @prop {number} order=700 - Index used to define the order of execution */ 13633 order: 700, 13634 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 13635 enabled: false, 13636 /** @prop {ModifierFn} */ 13637 fn: inner 13638 }, 13639 13640 /** 13641 * Modifier used to hide the popper when its reference element is outside of the 13642 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 13643 * be used to hide with a CSS selector the popper when its reference is 13644 * out of boundaries. 13645 * 13646 * Requires the `preventOverflow` modifier before it in order to work. 13647 * @memberof modifiers 13648 * @inner 13649 */ 13650 hide: { 13651 /** @prop {number} order=800 - Index used to define the order of execution */ 13652 order: 800, 13653 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13654 enabled: true, 13655 /** @prop {ModifierFn} */ 13656 fn: hide 13657 }, 13658 13659 /** 13660 * Computes the style that will be applied to the popper element to gets 13661 * properly positioned. 13662 * 13663 * Note that this modifier will not touch the DOM, it just prepares the styles 13664 * so that `applyStyle` modifier can apply it. This separation is useful 13665 * in case you need to replace `applyStyle` with a custom implementation. 13666 * 13667 * This modifier has `850` as `order` value to maintain backward compatibility 13668 * with previous versions of Popper.js. Expect the modifiers ordering method 13669 * to change in future major versions of the library. 13670 * 13671 * @memberof modifiers 13672 * @inner 13673 */ 13674 computeStyle: { 13675 /** @prop {number} order=850 - Index used to define the order of execution */ 13676 order: 850, 13677 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13678 enabled: true, 13679 /** @prop {ModifierFn} */ 13680 fn: computeStyle, 13681 /** 13682 * @prop {Boolean} gpuAcceleration=true 13683 * If true, it uses the CSS 3d transformation to position the popper. 13684 * Otherwise, it will use the `top` and `left` properties. 13685 */ 13686 gpuAcceleration: true, 13687 /** 13688 * @prop {string} [x='bottom'] 13689 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 13690 * Change this if your popper should grow in a direction different from `bottom` 13691 */ 13692 x: 'bottom', 13693 /** 13694 * @prop {string} [x='left'] 13695 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 13696 * Change this if your popper should grow in a direction different from `right` 13697 */ 13698 y: 'right' 13699 }, 13700 13701 /** 13702 * Applies the computed styles to the popper element. 13703 * 13704 * All the DOM manipulations are limited to this modifier. This is useful in case 13705 * you want to integrate Popper.js inside a framework or view library and you 13706 * want to delegate all the DOM manipulations to it. 13707 * 13708 * Note that if you disable this modifier, you must make sure the popper element 13709 * has its position set to `absolute` before Popper.js can do its work! 13710 * 13711 * Just disable this modifier and define you own to achieve the desired effect. 13712 * 13713 * @memberof modifiers 13714 * @inner 13715 */ 13716 applyStyle: { 13717 /** @prop {number} order=900 - Index used to define the order of execution */ 13718 order: 900, 13719 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 13720 enabled: true, 13721 /** @prop {ModifierFn} */ 13722 fn: applyStyle, 13723 /** @prop {Function} */ 13724 onLoad: applyStyleOnLoad, 13725 /** 13726 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 13727 * @prop {Boolean} gpuAcceleration=true 13728 * If true, it uses the CSS 3d transformation to position the popper. 13729 * Otherwise, it will use the `top` and `left` properties. 13730 */ 13731 gpuAcceleration: undefined 13732 } 13733}; 13734 13735/** 13736 * The `dataObject` is an object containing all the informations used by Popper.js 13737 * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 13738 * @name dataObject 13739 * @property {Object} data.instance The Popper.js instance 13740 * @property {String} data.placement Placement applied to popper 13741 * @property {String} data.originalPlacement Placement originally defined on init 13742 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 13743 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper. 13744 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 13745 * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`) 13746 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`) 13747 * @property {Object} data.boundaries Offsets of the popper boundaries 13748 * @property {Object} data.offsets The measurements of popper, reference and arrow elements. 13749 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 13750 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 13751 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 13752 */ 13753 13754/** 13755 * Default options provided to Popper.js constructor.<br /> 13756 * These can be overriden using the `options` argument of Popper.js.<br /> 13757 * To override an option, simply pass as 3rd argument an object with the same 13758 * structure of this object, example: 13759 * ``` 13760 * new Popper(ref, pop, { 13761 * modifiers: { 13762 * preventOverflow: { enabled: false } 13763 * } 13764 * }) 13765 * ``` 13766 * @type {Object} 13767 * @static 13768 * @memberof Popper 13769 */ 13770var Defaults = { 13771 /** 13772 * Popper's placement 13773 * @prop {Popper.placements} placement='bottom' 13774 */ 13775 placement: 'bottom', 13776 13777 /** 13778 * Set this to true if you want popper to position it self in 'fixed' mode 13779 * @prop {Boolean} positionFixed=false 13780 */ 13781 positionFixed: false, 13782 13783 /** 13784 * Whether events (resize, scroll) are initially enabled 13785 * @prop {Boolean} eventsEnabled=true 13786 */ 13787 eventsEnabled: true, 13788 13789 /** 13790 * Set to true if you want to automatically remove the popper when 13791 * you call the `destroy` method. 13792 * @prop {Boolean} removeOnDestroy=false 13793 */ 13794 removeOnDestroy: false, 13795 13796 /** 13797 * Callback called when the popper is created.<br /> 13798 * By default, is set to no-op.<br /> 13799 * Access Popper.js instance with `data.instance`. 13800 * @prop {onCreate} 13801 */ 13802 onCreate: function onCreate() {}, 13803 13804 /** 13805 * Callback called when the popper is updated, this callback is not called 13806 * on the initialization/creation of the popper, but only on subsequent 13807 * updates.<br /> 13808 * By default, is set to no-op.<br /> 13809 * Access Popper.js instance with `data.instance`. 13810 * @prop {onUpdate} 13811 */ 13812 onUpdate: function onUpdate() {}, 13813 13814 /** 13815 * List of modifiers used to modify the offsets before they are applied to the popper. 13816 * They provide most of the functionalities of Popper.js 13817 * @prop {modifiers} 13818 */ 13819 modifiers: modifiers 13820}; 13821 13822/** 13823 * @callback onCreate 13824 * @param {dataObject} data 13825 */ 13826 13827/** 13828 * @callback onUpdate 13829 * @param {dataObject} data 13830 */ 13831 13832// Utils 13833// Methods 13834var Popper = function () { 13835 /** 13836 * Create a new Popper.js instance 13837 * @class Popper 13838 * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper 13839 * @param {HTMLElement} popper - The HTML element used as popper. 13840 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 13841 * @return {Object} instance - The generated Popper.js instance 13842 */ 13843 function Popper(reference, popper) { 13844 var _this = this; 13845 13846 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 13847 classCallCheck$1(this, Popper); 13848 13849 this.scheduleUpdate = function () { 13850 return requestAnimationFrame(_this.update); 13851 }; 13852 13853 // make update() debounced, so that it only runs at most once-per-tick 13854 this.update = debounce(this.update.bind(this)); 13855 13856 // with {} we create a new object with the options inside it 13857 this.options = _extends$1({}, Popper.Defaults, options); 13858 13859 // init state 13860 this.state = { 13861 isDestroyed: false, 13862 isCreated: false, 13863 scrollParents: [] 13864 }; 13865 13866 // get reference and popper elements (allow jQuery wrappers) 13867 this.reference = reference && reference.jquery ? reference[0] : reference; 13868 this.popper = popper && popper.jquery ? popper[0] : popper; 13869 13870 // Deep merge modifiers options 13871 this.options.modifiers = {}; 13872 Object.keys(_extends$1({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 13873 _this.options.modifiers[name] = _extends$1({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 13874 }); 13875 13876 // Refactoring modifiers' list (Object => Array) 13877 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 13878 return _extends$1({ 13879 name: name 13880 }, _this.options.modifiers[name]); 13881 }) 13882 // sort the modifiers by order 13883 .sort(function (a, b) { 13884 return a.order - b.order; 13885 }); 13886 13887 // modifiers have the ability to execute arbitrary code when Popper.js get inited 13888 // such code is executed in the same order of its modifier 13889 // they could add new properties to their options configuration 13890 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 13891 this.modifiers.forEach(function (modifierOptions) { 13892 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 13893 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 13894 } 13895 }); 13896 13897 // fire the first update to position the popper in the right place 13898 this.update(); 13899 13900 var eventsEnabled = this.options.eventsEnabled; 13901 if (eventsEnabled) { 13902 // setup event listeners, they will take care of update the position in specific situations 13903 this.enableEventListeners(); 13904 } 13905 13906 this.state.eventsEnabled = eventsEnabled; 13907 } 13908 13909 // We can't use class properties because they don't get listed in the 13910 // class prototype and break stuff like Sinon stubs 13911 13912 13913 createClass$1(Popper, [{ 13914 key: 'update', 13915 value: function update$$1() { 13916 return update.call(this); 13917 } 13918 }, { 13919 key: 'destroy', 13920 value: function destroy$$1() { 13921 return destroy.call(this); 13922 } 13923 }, { 13924 key: 'enableEventListeners', 13925 value: function enableEventListeners$$1() { 13926 return enableEventListeners.call(this); 13927 } 13928 }, { 13929 key: 'disableEventListeners', 13930 value: function disableEventListeners$$1() { 13931 return disableEventListeners.call(this); 13932 } 13933 13934 /** 13935 * Schedule an update, it will run on the next UI update available 13936 * @method scheduleUpdate 13937 * @memberof Popper 13938 */ 13939 13940 /** 13941 * Collection of utilities useful when writing custom modifiers. 13942 * Starting from version 1.7, this method is available only if you 13943 * include `popper-utils.js` before `popper.js`. 13944 * 13945 * **DEPRECATION**: This way to access PopperUtils is deprecated 13946 * and will be removed in v2! Use the PopperUtils module directly instead. 13947 * Due to the high instability of the methods contained in Utils, we can't 13948 * guarantee them to follow semver. Use them at your own risk! 13949 * @static 13950 * @private 13951 * @type {Object} 13952 * @deprecated since version 1.8 13953 * @member Utils 13954 * @memberof Popper 13955 */ 13956 13957 }]); 13958 return Popper; 13959}(); 13960 13961/** 13962 * The `referenceObject` is an object that provides an interface compatible with Popper.js 13963 * and lets you use it as replacement of a real DOM node.<br /> 13964 * You can use this method to position a popper relatively to a set of coordinates 13965 * in case you don't have a DOM node to use as reference. 13966 * 13967 * ``` 13968 * new Popper(referenceObject, popperNode); 13969 * ``` 13970 * 13971 * NB: This feature isn't supported in Internet Explorer 10 13972 * @name referenceObject 13973 * @property {Function} data.getBoundingClientRect 13974 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 13975 * @property {number} data.clientWidth 13976 * An ES6 getter that will return the width of the virtual reference element. 13977 * @property {number} data.clientHeight 13978 * An ES6 getter that will return the height of the virtual reference element. 13979 */ 13980 13981Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 13982Popper.placements = placements; 13983Popper.Defaults = Defaults; 13984 13985/** 13986 * Triggers document reflow. 13987 * Use void because some minifiers or engines think simply accessing the property 13988 * is unnecessary. 13989 * @param {Element} popper 13990 */ 13991function reflow(popper) { 13992 void popper.offsetHeight; 13993} 13994 13995/** 13996 * Wrapper util for popper position updating. 13997 * Updates the popper's position and invokes the callback on update. 13998 * Hackish workaround until Popper 2.0's update() becomes sync. 13999 * @param {Popper} popperInstance 14000 * @param {Function} callback: to run once popper's position was updated 14001 * @param {Boolean} updateAlreadyCalled: was scheduleUpdate() already called? 14002 */ 14003function updatePopperPosition(popperInstance, callback, updateAlreadyCalled) { 14004 var popper = popperInstance.popper, 14005 options = popperInstance.options; 14006 14007 var onCreate = options.onCreate; 14008 var onUpdate = options.onUpdate; 14009 14010 options.onCreate = options.onUpdate = function () { 14011 reflow(popper), callback && callback(), onUpdate(); 14012 options.onCreate = onCreate; 14013 options.onUpdate = onUpdate; 14014 }; 14015 14016 if (!updateAlreadyCalled) { 14017 popperInstance.scheduleUpdate(); 14018 } 14019} 14020 14021/** 14022 * Returns the core placement ('top', 'bottom', 'left', 'right') of a popper 14023 * @param {Element} popper 14024 * @return {String} 14025 */ 14026function getPopperPlacement(popper) { 14027 return popper.getAttribute('x-placement').replace(/-.+/, ''); 14028} 14029 14030/** 14031 * Determines if the mouse's cursor is outside the interactive border 14032 * @param {MouseEvent} event 14033 * @param {Element} popper 14034 * @param {Object} options 14035 * @return {Boolean} 14036 */ 14037function cursorIsOutsideInteractiveBorder(event, popper, options) { 14038 if (!popper.getAttribute('x-placement')) return true; 14039 14040 var x = event.clientX, 14041 y = event.clientY; 14042 var interactiveBorder = options.interactiveBorder, 14043 distance = options.distance; 14044 14045 14046 var rect = popper.getBoundingClientRect(); 14047 var placement = getPopperPlacement(popper); 14048 var borderWithDistance = interactiveBorder + distance; 14049 14050 var exceeds = { 14051 top: rect.top - y > interactiveBorder, 14052 bottom: y - rect.bottom > interactiveBorder, 14053 left: rect.left - x > interactiveBorder, 14054 right: x - rect.right > interactiveBorder 14055 }; 14056 14057 switch (placement) { 14058 case 'top': 14059 exceeds.top = rect.top - y > borderWithDistance; 14060 break; 14061 case 'bottom': 14062 exceeds.bottom = y - rect.bottom > borderWithDistance; 14063 break; 14064 case 'left': 14065 exceeds.left = rect.left - x > borderWithDistance; 14066 break; 14067 case 'right': 14068 exceeds.right = x - rect.right > borderWithDistance; 14069 break; 14070 } 14071 14072 return exceeds.top || exceeds.bottom || exceeds.left || exceeds.right; 14073} 14074 14075/** 14076 * Transforms the `arrowTransform` numbers based on the placement axis 14077 * @param {String} type 'scale' or 'translate' 14078 * @param {Number[]} numbers 14079 * @param {Boolean} isVertical 14080 * @param {Boolean} isReverse 14081 * @return {String} 14082 */ 14083function transformNumbersBasedOnPlacementAxis(type, numbers, isVertical, isReverse) { 14084 if (!numbers.length) return ''; 14085 14086 var transforms = { 14087 scale: function () { 14088 if (numbers.length === 1) { 14089 return '' + numbers[0]; 14090 } else { 14091 return isVertical ? numbers[0] + ', ' + numbers[1] : numbers[1] + ', ' + numbers[0]; 14092 } 14093 }(), 14094 translate: function () { 14095 if (numbers.length === 1) { 14096 return isReverse ? -numbers[0] + 'px' : numbers[0] + 'px'; 14097 } else { 14098 if (isVertical) { 14099 return isReverse ? numbers[0] + 'px, ' + -numbers[1] + 'px' : numbers[0] + 'px, ' + numbers[1] + 'px'; 14100 } else { 14101 return isReverse ? -numbers[1] + 'px, ' + numbers[0] + 'px' : numbers[1] + 'px, ' + numbers[0] + 'px'; 14102 } 14103 } 14104 }() 14105 }; 14106 14107 return transforms[type]; 14108} 14109 14110/** 14111 * Transforms the `arrowTransform` x or y axis based on the placement axis 14112 * @param {String} axis 'X', 'Y', '' 14113 * @param {Boolean} isVertical 14114 * @return {String} 14115 */ 14116function transformAxis(axis, isVertical) { 14117 if (!axis) return ''; 14118 var map = { 14119 X: 'Y', 14120 Y: 'X' 14121 }; 14122 return isVertical ? axis : map[axis]; 14123} 14124 14125/** 14126 * Computes and applies the necessary arrow transform 14127 * @param {Element} popper 14128 * @param {Element} arrow 14129 * @param {String} arrowTransform 14130 */ 14131function computeArrowTransform(popper, arrow, arrowTransform) { 14132 var placement = getPopperPlacement(popper); 14133 var isVertical = placement === 'top' || placement === 'bottom'; 14134 var isReverse = placement === 'right' || placement === 'bottom'; 14135 14136 var getAxis = function getAxis(re) { 14137 var match = arrowTransform.match(re); 14138 return match ? match[1] : ''; 14139 }; 14140 14141 var getNumbers = function getNumbers(re) { 14142 var match = arrowTransform.match(re); 14143 return match ? match[1].split(',').map(parseFloat) : []; 14144 }; 14145 14146 var re = { 14147 translate: /translateX?Y?\(([^)]+)\)/, 14148 scale: /scaleX?Y?\(([^)]+)\)/ 14149 }; 14150 14151 var matches = { 14152 translate: { 14153 axis: getAxis(/translate([XY])/), 14154 numbers: getNumbers(re.translate) 14155 }, 14156 scale: { 14157 axis: getAxis(/scale([XY])/), 14158 numbers: getNumbers(re.scale) 14159 } 14160 }; 14161 14162 var computedTransform = arrowTransform.replace(re.translate, 'translate' + transformAxis(matches.translate.axis, isVertical) + '(' + transformNumbersBasedOnPlacementAxis('translate', matches.translate.numbers, isVertical, isReverse) + ')').replace(re.scale, 'scale' + transformAxis(matches.scale.axis, isVertical) + '(' + transformNumbersBasedOnPlacementAxis('scale', matches.scale.numbers, isVertical, isReverse) + ')'); 14163 14164 arrow.style[prefix('transform')] = computedTransform; 14165} 14166 14167/** 14168 * Returns the distance taking into account the default distance due to 14169 * the transform: translate setting in CSS 14170 * @param {Number} distance 14171 * @return {String} 14172 */ 14173function getOffsetDistanceInPx(distance) { 14174 return -(distance - defaults.distance) + 'px'; 14175} 14176 14177/** 14178 * Waits until next repaint to execute a fn 14179 * @param {Function} fn 14180 */ 14181function defer(fn) { 14182 requestAnimationFrame(function () { 14183 setTimeout(fn, 1); 14184 }); 14185} 14186 14187var matches = {}; 14188 14189if (isBrowser) { 14190 var e = Element.prototype; 14191 matches = e.matches || e.matchesSelector || e.webkitMatchesSelector || e.mozMatchesSelector || e.msMatchesSelector || function (s) { 14192 var matches = (this.document || this.ownerDocument).querySelectorAll(s); 14193 var i = matches.length; 14194 while (--i >= 0 && matches.item(i) !== this) {} // eslint-disable-line no-empty 14195 return i > -1; 14196 }; 14197} 14198 14199var matches$1 = matches; 14200 14201/** 14202 * Ponyfill to get the closest parent element 14203 * @param {Element} element - child of parent to be returned 14204 * @param {String} parentSelector - selector to match the parent if found 14205 * @return {Element} 14206 */ 14207function closest(element, parentSelector) { 14208 var fn = Element.prototype.closest || function (selector) { 14209 var el = this; 14210 while (el) { 14211 if (matches$1.call(el, selector)) { 14212 return el; 14213 } 14214 el = el.parentElement; 14215 } 14216 }; 14217 14218 return fn.call(element, parentSelector); 14219} 14220 14221/** 14222 * Returns the value taking into account the value being either a number or array 14223 * @param {Number|Array} value 14224 * @param {Number} index 14225 * @return {Number} 14226 */ 14227function getValue(value, index) { 14228 return Array.isArray(value) ? value[index] : value; 14229} 14230 14231/** 14232 * Sets the visibility state of an element for transition to begin 14233 * @param {Element[]} els - array of elements 14234 * @param {String} type - 'visible' or 'hidden' 14235 */ 14236function setVisibilityState(els, type) { 14237 els.forEach(function (el) { 14238 if (!el) return; 14239 el.setAttribute('data-state', type); 14240 }); 14241} 14242 14243/** 14244 * Sets the transition property to each element 14245 * @param {Element[]} els - Array of elements 14246 * @param {String} value 14247 */ 14248function applyTransitionDuration(els, value) { 14249 els.filter(Boolean).forEach(function (el) { 14250 el.style[prefix('transitionDuration')] = value + 'ms'; 14251 }); 14252} 14253 14254/** 14255 * Focuses an element while preventing a scroll jump if it's not entirely within the viewport 14256 * @param {Element} el 14257 */ 14258function focus(el) { 14259 var x = window.scrollX || window.pageXOffset; 14260 var y = window.scrollY || window.pageYOffset; 14261 el.focus(); 14262 scroll(x, y); 14263} 14264 14265var key = {}; 14266var store = function store(data) { 14267 return function (k) { 14268 return k === key && data; 14269 }; 14270}; 14271 14272var Tippy = function () { 14273 function Tippy(config) { 14274 classCallCheck(this, Tippy); 14275 14276 for (var _key in config) { 14277 this[_key] = config[_key]; 14278 } 14279 14280 this.state = { 14281 destroyed: false, 14282 visible: false, 14283 enabled: true 14284 }; 14285 14286 this._ = store({ 14287 mutationObservers: [] 14288 }); 14289 } 14290 14291 /** 14292 * Enables the tooltip to allow it to show or hide 14293 * @memberof Tippy 14294 * @public 14295 */ 14296 14297 14298 createClass(Tippy, [{ 14299 key: 'enable', 14300 value: function enable() { 14301 this.state.enabled = true; 14302 } 14303 14304 /** 14305 * Disables the tooltip from showing or hiding, but does not destroy it 14306 * @memberof Tippy 14307 * @public 14308 */ 14309 14310 }, { 14311 key: 'disable', 14312 value: function disable() { 14313 this.state.enabled = false; 14314 } 14315 14316 /** 14317 * Shows the tooltip 14318 * @param {Number} duration in milliseconds 14319 * @memberof Tippy 14320 * @public 14321 */ 14322 14323 }, { 14324 key: 'show', 14325 value: function show(duration) { 14326 var _this = this; 14327 14328 if (this.state.destroyed || !this.state.enabled) return; 14329 14330 var popper = this.popper, 14331 reference = this.reference, 14332 options = this.options; 14333 14334 var _getInnerElements = getInnerElements(popper), 14335 tooltip = _getInnerElements.tooltip, 14336 backdrop = _getInnerElements.backdrop, 14337 content = _getInnerElements.content; 14338 14339 // If the `dynamicTitle` option is true, the instance is allowed 14340 // to be created with an empty title. Make sure that the tooltip 14341 // content is not empty before showing it 14342 14343 14344 if (options.dynamicTitle && !reference.getAttribute('data-original-title')) { 14345 return; 14346 } 14347 14348 // Do not show tooltip if reference contains 'disabled' attribute. FF fix for #221 14349 if (reference.hasAttribute('disabled')) return; 14350 14351 // Destroy tooltip if the reference element is no longer on the DOM 14352 if (!reference.refObj && !document.documentElement.contains(reference)) { 14353 this.destroy(); 14354 return; 14355 } 14356 14357 options.onShow.call(popper, this); 14358 14359 duration = getValue(duration !== undefined ? duration : options.duration, 0); 14360 14361 // Prevent a transition when popper changes position 14362 applyTransitionDuration([popper, tooltip, backdrop], 0); 14363 14364 popper.style.visibility = 'visible'; 14365 this.state.visible = true; 14366 14367 _mount.call(this, function () { 14368 if (!_this.state.visible) return; 14369 14370 if (!_hasFollowCursorBehavior.call(_this)) { 14371 // FIX: Arrow will sometimes not be positioned correctly. Force another update. 14372 _this.popperInstance.scheduleUpdate(); 14373 } 14374 14375 // Set initial position near the cursor 14376 if (_hasFollowCursorBehavior.call(_this)) { 14377 _this.popperInstance.disableEventListeners(); 14378 var delay = getValue(options.delay, 0); 14379 var lastTriggerEvent = _this._(key).lastTriggerEvent; 14380 if (lastTriggerEvent) { 14381 _this._(key).followCursorListener(delay && _this._(key).lastMouseMoveEvent ? _this._(key).lastMouseMoveEvent : lastTriggerEvent); 14382 } 14383 } 14384 14385 // Re-apply transition durations 14386 applyTransitionDuration([tooltip, backdrop, backdrop ? content : null], duration); 14387 14388 if (backdrop) { 14389 getComputedStyle(backdrop)[prefix('transform')]; 14390 } 14391 14392 if (options.interactive) { 14393 reference.classList.add('tippy-active'); 14394 } 14395 14396 if (options.sticky) { 14397 _makeSticky.call(_this); 14398 } 14399 14400 setVisibilityState([tooltip, backdrop], 'visible'); 14401 14402 _onTransitionEnd.call(_this, duration, function () { 14403 if (!options.updateDuration) { 14404 tooltip.classList.add('tippy-notransition'); 14405 } 14406 14407 if (options.interactive) { 14408 focus(popper); 14409 } 14410 14411 reference.setAttribute('aria-describedby', 'tippy-' + _this.id); 14412 14413 options.onShown.call(popper, _this); 14414 }); 14415 }); 14416 } 14417 14418 /** 14419 * Hides the tooltip 14420 * @param {Number} duration in milliseconds 14421 * @memberof Tippy 14422 * @public 14423 */ 14424 14425 }, { 14426 key: 'hide', 14427 value: function hide(duration) { 14428 var _this2 = this; 14429 14430 if (this.state.destroyed || !this.state.enabled) return; 14431 14432 var popper = this.popper, 14433 reference = this.reference, 14434 options = this.options; 14435 14436 var _getInnerElements2 = getInnerElements(popper), 14437 tooltip = _getInnerElements2.tooltip, 14438 backdrop = _getInnerElements2.backdrop, 14439 content = _getInnerElements2.content; 14440 14441 options.onHide.call(popper, this); 14442 14443 duration = getValue(duration !== undefined ? duration : options.duration, 1); 14444 14445 if (!options.updateDuration) { 14446 tooltip.classList.remove('tippy-notransition'); 14447 } 14448 14449 if (options.interactive) { 14450 reference.classList.remove('tippy-active'); 14451 } 14452 14453 popper.style.visibility = 'hidden'; 14454 this.state.visible = false; 14455 14456 applyTransitionDuration([tooltip, backdrop, backdrop ? content : null], duration); 14457 14458 setVisibilityState([tooltip, backdrop], 'hidden'); 14459 14460 if (options.interactive && options.trigger.indexOf('click') > -1) { 14461 focus(reference); 14462 } 14463 14464 /* 14465 * This call is deferred because sometimes when the tooltip is still transitioning in but hide() 14466 * is called before it finishes, the CSS transition won't reverse quickly enough, meaning 14467 * the CSS transition will finish 1-2 frames later, and onHidden() will run since the JS set it 14468 * more quickly. It should actually be onShown(). Seems to be something Chrome does, not Safari 14469 */ 14470 defer(function () { 14471 _onTransitionEnd.call(_this2, duration, function () { 14472 if (_this2.state.visible || !options.appendTo.contains(popper)) return; 14473 14474 if (!_this2._(key).isPreparingToShow) { 14475 document.removeEventListener('mousemove', _this2._(key).followCursorListener); 14476 _this2._(key).lastMouseMoveEvent = null; 14477 } 14478 14479 if (_this2.popperInstance) { 14480 _this2.popperInstance.disableEventListeners(); 14481 } 14482 14483 reference.removeAttribute('aria-describedby'); 14484 14485 options.appendTo.removeChild(popper); 14486 14487 options.onHidden.call(popper, _this2); 14488 }); 14489 }); 14490 } 14491 14492 /** 14493 * Destroys the tooltip instance 14494 * @param {Boolean} destroyTargetInstances - relevant only when destroying delegates 14495 * @memberof Tippy 14496 * @public 14497 */ 14498 14499 }, { 14500 key: 'destroy', 14501 value: function destroy() { 14502 var _this3 = this; 14503 14504 var destroyTargetInstances = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; 14505 14506 if (this.state.destroyed) return; 14507 14508 // Ensure the popper is hidden 14509 if (this.state.visible) { 14510 this.hide(0); 14511 } 14512 14513 this.listeners.forEach(function (listener) { 14514 _this3.reference.removeEventListener(listener.event, listener.handler); 14515 }); 14516 14517 // Restore title 14518 if (this.title) { 14519 this.reference.setAttribute('title', this.title); 14520 } 14521 14522 delete this.reference._tippy; 14523 14524 var attributes = ['data-original-title', 'data-tippy', 'data-tippy-delegate']; 14525 attributes.forEach(function (attr) { 14526 _this3.reference.removeAttribute(attr); 14527 }); 14528 14529 if (this.options.target && destroyTargetInstances) { 14530 toArray(this.reference.querySelectorAll(this.options.target)).forEach(function (child) { 14531 return child._tippy && child._tippy.destroy(); 14532 }); 14533 } 14534 14535 if (this.popperInstance) { 14536 this.popperInstance.destroy(); 14537 } 14538 14539 this._(key).mutationObservers.forEach(function (observer) { 14540 observer.disconnect(); 14541 }); 14542 14543 this.state.destroyed = true; 14544 } 14545 }]); 14546 return Tippy; 14547}(); 14548 14549/** 14550 * ------------------------------------------------------------------------ 14551 * Private methods 14552 * ------------------------------------------------------------------------ 14553 * Standalone functions to be called with the instance's `this` context to make 14554 * them truly private and not accessible on the prototype 14555 */ 14556 14557/** 14558 * Determines if the tooltip instance has followCursor behavior 14559 * @return {Boolean} 14560 * @memberof Tippy 14561 * @private 14562 */ 14563function _hasFollowCursorBehavior() { 14564 var lastTriggerEvent = this._(key).lastTriggerEvent; 14565 return this.options.followCursor && !browser.usingTouch && lastTriggerEvent && lastTriggerEvent.type !== 'focus'; 14566} 14567 14568/** 14569 * Creates the Tippy instance for the child target of the delegate container 14570 * @param {Event} event 14571 * @memberof Tippy 14572 * @private 14573 */ 14574function _createDelegateChildTippy(event) { 14575 var targetEl = closest(event.target, this.options.target); 14576 if (targetEl && !targetEl._tippy) { 14577 var title = targetEl.getAttribute('title') || this.title; 14578 if (title) { 14579 targetEl.setAttribute('title', title); 14580 tippy(targetEl, _extends({}, this.options, { target: null })); 14581 _enter.call(targetEl._tippy, event); 14582 } 14583 } 14584} 14585 14586/** 14587 * Method used by event listeners to invoke the show method, taking into account delays and 14588 * the `wait` option 14589 * @param {Event} event 14590 * @memberof Tippy 14591 * @private 14592 */ 14593function _enter(event) { 14594 var _this4 = this; 14595 14596 var options = this.options; 14597 14598 14599 _clearDelayTimeouts.call(this); 14600 14601 if (this.state.visible) return; 14602 14603 // Is a delegate, create Tippy instance for the child target 14604 if (options.target) { 14605 _createDelegateChildTippy.call(this, event); 14606 return; 14607 } 14608 14609 this._(key).isPreparingToShow = true; 14610 14611 if (options.wait) { 14612 options.wait.call(this.popper, this.show.bind(this), event); 14613 return; 14614 } 14615 14616 // If the tooltip has a delay, we need to be listening to the mousemove as soon as the trigger 14617 // event is fired so that it's in the correct position upon mount. 14618 if (_hasFollowCursorBehavior.call(this)) { 14619 if (!this._(key).followCursorListener) { 14620 _setFollowCursorListener.call(this); 14621 } 14622 14623 var _getInnerElements3 = getInnerElements(this.popper), 14624 arrow = _getInnerElements3.arrow; 14625 14626 if (arrow) arrow.style.margin = '0'; 14627 document.addEventListener('mousemove', this._(key).followCursorListener); 14628 } 14629 14630 var delay = getValue(options.delay, 0); 14631 14632 if (delay) { 14633 this._(key).showTimeout = setTimeout(function () { 14634 _this4.show(); 14635 }, delay); 14636 } else { 14637 this.show(); 14638 } 14639} 14640 14641/** 14642 * Method used by event listeners to invoke the hide method, taking into account delays 14643 * @memberof Tippy 14644 * @private 14645 */ 14646function _leave() { 14647 var _this5 = this; 14648 14649 _clearDelayTimeouts.call(this); 14650 14651 if (!this.state.visible) return; 14652 14653 this._(key).isPreparingToShow = false; 14654 14655 var delay = getValue(this.options.delay, 1); 14656 14657 if (delay) { 14658 this._(key).hideTimeout = setTimeout(function () { 14659 if (_this5.state.visible) { 14660 _this5.hide(); 14661 } 14662 }, delay); 14663 } else { 14664 this.hide(); 14665 } 14666} 14667 14668/** 14669 * Returns relevant listeners for the instance 14670 * @return {Object} of listeners 14671 * @memberof Tippy 14672 * @private 14673 */ 14674function _getEventListeners() { 14675 var _this6 = this; 14676 14677 var onTrigger = function onTrigger(event) { 14678 if (!_this6.state.enabled) return; 14679 14680 var shouldStopEvent = browser.supportsTouch && browser.usingTouch && ['mouseenter', 'mouseover', 'focus'].indexOf(event.type) > -1; 14681 14682 if (shouldStopEvent && _this6.options.touchHold) return; 14683 14684 _this6._(key).lastTriggerEvent = event; 14685 14686 // Toggle show/hide when clicking click-triggered tooltips 14687 if (event.type === 'click' && _this6.options.hideOnClick !== 'persistent' && _this6.state.visible) { 14688 _leave.call(_this6); 14689 } else { 14690 _enter.call(_this6, event); 14691 } 14692 }; 14693 14694 var onMouseLeave = function onMouseLeave(event) { 14695 if (['mouseleave', 'mouseout'].indexOf(event.type) > -1 && browser.supportsTouch && browser.usingTouch && _this6.options.touchHold) return; 14696 14697 if (_this6.options.interactive) { 14698 var hide = _leave.bind(_this6); 14699 14700 var onMouseMove = function onMouseMove(event) { 14701 var referenceCursorIsOver = closest(event.target, selectors.REFERENCE); 14702 var cursorIsOverPopper = closest(event.target, selectors.POPPER) === _this6.popper; 14703 var cursorIsOverReference = referenceCursorIsOver === _this6.reference; 14704 14705 if (cursorIsOverPopper || cursorIsOverReference) return; 14706 14707 if (cursorIsOutsideInteractiveBorder(event, _this6.popper, _this6.options)) { 14708 document.body.removeEventListener('mouseleave', hide); 14709 document.removeEventListener('mousemove', onMouseMove); 14710 14711 _leave.call(_this6, onMouseMove); 14712 } 14713 }; 14714 14715 document.body.addEventListener('mouseleave', hide); 14716 document.addEventListener('mousemove', onMouseMove); 14717 return; 14718 } 14719 14720 _leave.call(_this6); 14721 }; 14722 14723 var onBlur = function onBlur(event) { 14724 if (event.target !== _this6.reference || browser.usingTouch) return; 14725 14726 if (_this6.options.interactive) { 14727 if (!event.relatedTarget) return; 14728 if (closest(event.relatedTarget, selectors.POPPER)) return; 14729 } 14730 14731 _leave.call(_this6); 14732 }; 14733 14734 var onDelegateShow = function onDelegateShow(event) { 14735 if (closest(event.target, _this6.options.target)) { 14736 _enter.call(_this6, event); 14737 } 14738 }; 14739 14740 var onDelegateHide = function onDelegateHide(event) { 14741 if (closest(event.target, _this6.options.target)) { 14742 _leave.call(_this6); 14743 } 14744 }; 14745 14746 return { 14747 onTrigger: onTrigger, 14748 onMouseLeave: onMouseLeave, 14749 onBlur: onBlur, 14750 onDelegateShow: onDelegateShow, 14751 onDelegateHide: onDelegateHide 14752 }; 14753} 14754 14755/** 14756 * Creates and returns a new popper instance 14757 * @return {Popper} 14758 * @memberof Tippy 14759 * @private 14760 */ 14761function _createPopperInstance() { 14762 var _this7 = this; 14763 14764 var popper = this.popper, 14765 reference = this.reference, 14766 options = this.options; 14767 14768 var _getInnerElements4 = getInnerElements(popper), 14769 tooltip = _getInnerElements4.tooltip; 14770 14771 var popperOptions = options.popperOptions; 14772 14773 var arrowSelector = options.arrowType === 'round' ? selectors.ROUND_ARROW : selectors.ARROW; 14774 var arrow = tooltip.querySelector(arrowSelector); 14775 14776 var config = _extends({ 14777 placement: options.placement 14778 }, popperOptions || {}, { 14779 modifiers: _extends({}, popperOptions ? popperOptions.modifiers : {}, { 14780 arrow: _extends({ 14781 element: arrowSelector 14782 }, popperOptions && popperOptions.modifiers ? popperOptions.modifiers.arrow : {}), 14783 flip: _extends({ 14784 enabled: options.flip, 14785 padding: options.distance + 5 /* 5px from viewport boundary */ 14786 , behavior: options.flipBehavior 14787 }, popperOptions && popperOptions.modifiers ? popperOptions.modifiers.flip : {}), 14788 offset: _extends({ 14789 offset: options.offset 14790 }, popperOptions && popperOptions.modifiers ? popperOptions.modifiers.offset : {}) 14791 }), 14792 onCreate: function onCreate() { 14793 tooltip.style[getPopperPlacement(popper)] = getOffsetDistanceInPx(options.distance); 14794 14795 if (arrow && options.arrowTransform) { 14796 computeArrowTransform(popper, arrow, options.arrowTransform); 14797 } 14798 }, 14799 onUpdate: function onUpdate() { 14800 var styles = tooltip.style; 14801 styles.top = ''; 14802 styles.bottom = ''; 14803 styles.left = ''; 14804 styles.right = ''; 14805 styles[getPopperPlacement(popper)] = getOffsetDistanceInPx(options.distance); 14806 14807 if (arrow && options.arrowTransform) { 14808 computeArrowTransform(popper, arrow, options.arrowTransform); 14809 } 14810 } 14811 }); 14812 14813 _addMutationObserver.call(this, { 14814 target: popper, 14815 callback: function callback() { 14816 _this7.popperInstance.update(); 14817 }, 14818 options: { 14819 childList: true, 14820 subtree: true, 14821 characterData: true 14822 } 14823 }); 14824 14825 return new Popper(reference, popper, config); 14826} 14827 14828/** 14829 * Appends the popper element to the DOM, updating or creating the popper instance 14830 * @param {Function} callback 14831 * @memberof Tippy 14832 * @private 14833 */ 14834function _mount(callback) { 14835 var options = this.options; 14836 14837 14838 if (!this.popperInstance) { 14839 this.popperInstance = _createPopperInstance.call(this); 14840 if (!options.livePlacement) { 14841 this.popperInstance.disableEventListeners(); 14842 } 14843 } else { 14844 this.popperInstance.scheduleUpdate(); 14845 if (options.livePlacement && !_hasFollowCursorBehavior.call(this)) { 14846 this.popperInstance.enableEventListeners(); 14847 } 14848 } 14849 14850 // If the instance previously had followCursor behavior, it will be positioned incorrectly 14851 // if triggered by `focus` afterwards - update the reference back to the real DOM element 14852 if (!_hasFollowCursorBehavior.call(this)) { 14853 var _getInnerElements5 = getInnerElements(this.popper), 14854 arrow = _getInnerElements5.arrow; 14855 14856 if (arrow) arrow.style.margin = ''; 14857 this.popperInstance.reference = this.reference; 14858 } 14859 14860 updatePopperPosition(this.popperInstance, callback, true); 14861 14862 if (!options.appendTo.contains(this.popper)) { 14863 options.appendTo.appendChild(this.popper); 14864 } 14865} 14866 14867/** 14868 * Clears the show and hide delay timeouts 14869 * @memberof Tippy 14870 * @private 14871 */ 14872function _clearDelayTimeouts() { 14873 var _ref = this._(key), 14874 showTimeout = _ref.showTimeout, 14875 hideTimeout = _ref.hideTimeout; 14876 14877 clearTimeout(showTimeout); 14878 clearTimeout(hideTimeout); 14879} 14880 14881/** 14882 * Sets the mousemove event listener function for `followCursor` option 14883 * @memberof Tippy 14884 * @private 14885 */ 14886function _setFollowCursorListener() { 14887 var _this8 = this; 14888 14889 this._(key).followCursorListener = function (event) { 14890 var _$lastMouseMoveEvent = _this8._(key).lastMouseMoveEvent = event, 14891 clientX = _$lastMouseMoveEvent.clientX, 14892 clientY = _$lastMouseMoveEvent.clientY; 14893 14894 if (!_this8.popperInstance) return; 14895 14896 _this8.popperInstance.reference = { 14897 getBoundingClientRect: function getBoundingClientRect() { 14898 return { 14899 width: 0, 14900 height: 0, 14901 top: clientY, 14902 left: clientX, 14903 right: clientX, 14904 bottom: clientY 14905 }; 14906 }, 14907 clientWidth: 0, 14908 clientHeight: 0 14909 }; 14910 14911 _this8.popperInstance.scheduleUpdate(); 14912 }; 14913} 14914 14915/** 14916 * Updates the popper's position on each animation frame 14917 * @memberof Tippy 14918 * @private 14919 */ 14920function _makeSticky() { 14921 var _this9 = this; 14922 14923 var applyTransitionDuration$$1 = function applyTransitionDuration$$1() { 14924 _this9.popper.style[prefix('transitionDuration')] = _this9.options.updateDuration + 'ms'; 14925 }; 14926 14927 var removeTransitionDuration = function removeTransitionDuration() { 14928 _this9.popper.style[prefix('transitionDuration')] = ''; 14929 }; 14930 14931 var updatePosition = function updatePosition() { 14932 if (_this9.popperInstance) { 14933 _this9.popperInstance.update(); 14934 } 14935 14936 applyTransitionDuration$$1(); 14937 14938 if (_this9.state.visible) { 14939 requestAnimationFrame(updatePosition); 14940 } else { 14941 removeTransitionDuration(); 14942 } 14943 }; 14944 14945 updatePosition(); 14946} 14947 14948/** 14949 * Adds a mutation observer to an element and stores it in the instance 14950 * @param {Object} 14951 * @memberof Tippy 14952 * @private 14953 */ 14954function _addMutationObserver(_ref2) { 14955 var target = _ref2.target, 14956 callback = _ref2.callback, 14957 options = _ref2.options; 14958 14959 if (!window.MutationObserver) return; 14960 14961 var observer = new MutationObserver(callback); 14962 observer.observe(target, options); 14963 14964 this._(key).mutationObservers.push(observer); 14965} 14966 14967/** 14968 * Fires the callback functions once the CSS transition ends for `show` and `hide` methods 14969 * @param {Number} duration 14970 * @param {Function} callback - callback function to fire once transition completes 14971 * @memberof Tippy 14972 * @private 14973 */ 14974function _onTransitionEnd(duration, callback) { 14975 // Make callback synchronous if duration is 0 14976 if (!duration) { 14977 return callback(); 14978 } 14979 14980 var _getInnerElements6 = getInnerElements(this.popper), 14981 tooltip = _getInnerElements6.tooltip; 14982 14983 var toggleListeners = function toggleListeners(action, listener) { 14984 if (!listener) return; 14985 tooltip[action + 'EventListener']('transition' in document.body.style ? 'transitionend' : 'webkitTransitionEnd', listener); 14986 }; 14987 14988 var listener = function listener(e) { 14989 if (e.target === tooltip) { 14990 toggleListeners('remove', listener); 14991 callback(); 14992 } 14993 }; 14994 14995 toggleListeners('remove', this._(key).transitionendListener); 14996 toggleListeners('add', listener); 14997 14998 this._(key).transitionendListener = listener; 14999} 15000 15001var idCounter = 1; 15002 15003/** 15004 * Creates tooltips for each reference element 15005 * @param {Element[]} els 15006 * @param {Object} config 15007 * @return {Tippy[]} Array of Tippy instances 15008 */ 15009function createTooltips(els, config) { 15010 return els.reduce(function (acc, reference) { 15011 var id = idCounter; 15012 15013 var options = evaluateOptions(reference, config.performance ? config : getIndividualOptions(reference, config)); 15014 15015 var title = reference.getAttribute('title'); 15016 15017 // Don't create an instance when: 15018 // * the `title` attribute is falsy (null or empty string), and 15019 // * it's not a delegate for tooltips, and 15020 // * there is no html template specified, and 15021 // * `dynamicTitle` option is false 15022 if (!title && !options.target && !options.html && !options.dynamicTitle) { 15023 return acc; 15024 } 15025 15026 // Delegates should be highlighted as different 15027 reference.setAttribute(options.target ? 'data-tippy-delegate' : 'data-tippy', ''); 15028 15029 removeTitle(reference); 15030 15031 var popper = createPopperElement(id, title, options); 15032 15033 var tippy = new Tippy({ 15034 id: id, 15035 reference: reference, 15036 popper: popper, 15037 options: options, 15038 title: title, 15039 popperInstance: null 15040 }); 15041 15042 if (options.createPopperInstanceOnInit) { 15043 tippy.popperInstance = _createPopperInstance.call(tippy); 15044 tippy.popperInstance.disableEventListeners(); 15045 } 15046 15047 var listeners = _getEventListeners.call(tippy); 15048 tippy.listeners = options.trigger.trim().split(' ').reduce(function (acc, eventType) { 15049 return acc.concat(createTrigger(eventType, reference, listeners, options)); 15050 }, []); 15051 15052 // Update tooltip content whenever the title attribute on the reference changes 15053 if (options.dynamicTitle) { 15054 _addMutationObserver.call(tippy, { 15055 target: reference, 15056 callback: function callback() { 15057 var _getInnerElements = getInnerElements(popper), 15058 content = _getInnerElements.content; 15059 15060 var title = reference.getAttribute('title'); 15061 if (title) { 15062 content[options.allowTitleHTML ? 'innerHTML' : 'textContent'] = tippy.title = title; 15063 removeTitle(reference); 15064 } 15065 }, 15066 15067 options: { 15068 attributes: true 15069 } 15070 }); 15071 } 15072 15073 // Shortcuts 15074 reference._tippy = tippy; 15075 popper._tippy = tippy; 15076 popper._reference = reference; 15077 15078 acc.push(tippy); 15079 15080 idCounter++; 15081 15082 return acc; 15083 }, []); 15084} 15085 15086/** 15087 * Hides all poppers 15088 * @param {Tippy} excludeTippy - tippy to exclude if needed 15089 */ 15090function hideAllPoppers(excludeTippy) { 15091 var poppers = toArray(document.querySelectorAll(selectors.POPPER)); 15092 15093 poppers.forEach(function (popper) { 15094 var tippy = popper._tippy; 15095 if (!tippy) return; 15096 15097 var options = tippy.options; 15098 15099 15100 if ((options.hideOnClick === true || options.trigger.indexOf('focus') > -1) && (!excludeTippy || popper !== excludeTippy.popper)) { 15101 tippy.hide(); 15102 } 15103 }); 15104} 15105 15106/** 15107 * Adds the needed event listeners 15108 */ 15109function bindEventListeners() { 15110 var onDocumentTouch = function onDocumentTouch() { 15111 if (browser.usingTouch) return; 15112 15113 browser.usingTouch = true; 15114 15115 if (browser.iOS) { 15116 document.body.classList.add('tippy-touch'); 15117 } 15118 15119 if (browser.dynamicInputDetection && window.performance) { 15120 document.addEventListener('mousemove', onDocumentMouseMove); 15121 } 15122 15123 browser.onUserInputChange('touch'); 15124 }; 15125 15126 var onDocumentMouseMove = function () { 15127 var time = void 0; 15128 15129 return function () { 15130 var now = performance.now(); 15131 15132 // Chrome 60+ is 1 mousemove per animation frame, use 20ms time difference 15133 if (now - time < 20) { 15134 browser.usingTouch = false; 15135 document.removeEventListener('mousemove', onDocumentMouseMove); 15136 if (!browser.iOS) { 15137 document.body.classList.remove('tippy-touch'); 15138 } 15139 browser.onUserInputChange('mouse'); 15140 } 15141 15142 time = now; 15143 }; 15144 }(); 15145 15146 var onDocumentClick = function onDocumentClick(event) { 15147 // Simulated events dispatched on the document 15148 if (!(event.target instanceof Element)) { 15149 return hideAllPoppers(); 15150 } 15151 15152 var reference = closest(event.target, selectors.REFERENCE); 15153 var popper = closest(event.target, selectors.POPPER); 15154 15155 if (popper && popper._tippy && popper._tippy.options.interactive) { 15156 return; 15157 } 15158 15159 if (reference && reference._tippy) { 15160 var options = reference._tippy.options; 15161 15162 var isClickTrigger = options.trigger.indexOf('click') > -1; 15163 var isMultiple = options.multiple; 15164 15165 // Hide all poppers except the one belonging to the element that was clicked 15166 if (!isMultiple && browser.usingTouch || !isMultiple && isClickTrigger) { 15167 return hideAllPoppers(reference._tippy); 15168 } 15169 15170 if (options.hideOnClick !== true || isClickTrigger) { 15171 return; 15172 } 15173 } 15174 15175 hideAllPoppers(); 15176 }; 15177 15178 var onWindowBlur = function onWindowBlur() { 15179 var _document = document, 15180 el = _document.activeElement; 15181 15182 if (el && el.blur && matches$1.call(el, selectors.REFERENCE)) { 15183 el.blur(); 15184 } 15185 }; 15186 15187 var onWindowResize = function onWindowResize() { 15188 toArray(document.querySelectorAll(selectors.POPPER)).forEach(function (popper) { 15189 var tippyInstance = popper._tippy; 15190 if (tippyInstance && !tippyInstance.options.livePlacement) { 15191 tippyInstance.popperInstance.scheduleUpdate(); 15192 } 15193 }); 15194 }; 15195 15196 document.addEventListener('click', onDocumentClick); 15197 document.addEventListener('touchstart', onDocumentTouch); 15198 window.addEventListener('blur', onWindowBlur); 15199 window.addEventListener('resize', onWindowResize); 15200 15201 if (!browser.supportsTouch && (navigator.maxTouchPoints || navigator.msMaxTouchPoints)) { 15202 document.addEventListener('pointerdown', onDocumentTouch); 15203 } 15204} 15205 15206var eventListenersBound = false; 15207 15208/** 15209 * Exported module 15210 * @param {String|Element|Element[]|NodeList|Object} selector 15211 * @param {Object} options 15212 * @param {Boolean} one - create one tooltip 15213 * @return {Object} 15214 */ 15215function tippy(selector, options, one) { 15216 if (browser.supported && !eventListenersBound) { 15217 bindEventListeners(); 15218 eventListenersBound = true; 15219 } 15220 15221 if (isObjectLiteral(selector)) { 15222 polyfillVirtualReferenceProps(selector); 15223 } 15224 15225 options = _extends({}, defaults, options); 15226 15227 var references = getArrayOfElements(selector); 15228 var firstReference = references[0]; 15229 15230 return { 15231 selector: selector, 15232 options: options, 15233 tooltips: browser.supported ? createTooltips(one && firstReference ? [firstReference] : references, options) : [], 15234 destroyAll: function destroyAll() { 15235 this.tooltips.forEach(function (tooltip) { 15236 return tooltip.destroy(); 15237 }); 15238 this.tooltips = []; 15239 } 15240 }; 15241} 15242 15243tippy.version = version; 15244tippy.browser = browser; 15245tippy.defaults = defaults; 15246tippy.one = function (selector, options) { 15247 return tippy(selector, options, true).tooltips[0]; 15248}; 15249tippy.disableAnimations = function () { 15250 defaults.updateDuration = defaults.duration = 0; 15251 defaults.animateFill = false; 15252}; 15253 15254/** 15255 * Injects CSS styles to document head 15256 * @param {String} css 15257 */ 15258function injectCSS() { 15259 var css = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 15260 15261 if (isBrowser && browser.supported) { 15262 var head = document.head || document.querySelector('head'); 15263 var style = document.createElement('style'); 15264 style.type = 'text/css'; 15265 head.insertBefore(style, head.firstChild); 15266 15267 if (style.styleSheet) { 15268 style.styleSheet.cssText = css; 15269 } else { 15270 style.appendChild(document.createTextNode(css)); 15271 } 15272 } 15273} 15274 15275injectCSS(styles); 15276 15277return tippy; 15278 15279}))); 15280 15281/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"))) 15282 15283/***/ }), 15284
vendor: 772 bytes, lines 15285-15315
15285/***/ "./node_modules/webpack/buildin/global.js": 15286/*!***********************************!*\ 15287 !*** (webpack)/buildin/global.js ***! 15288 \***********************************/ 15289/*! no static exports found */ 15290/***/ (function(module, exports) { 15291 15292var g; 15293 15294// This works in non-strict mode 15295g = (function() { 15296 return this; 15297})(); 15298 15299try { 15300 // This works if eval is allowed (see CSP) 15301 g = g || Function("return this")() || (1, eval)("this"); 15302} catch (e) { 15303 // This works if the window reference is available 15304 if (typeof window === "object") g = window; 15305} 15306 15307// g can still be undefined, but nothing to do about it... 15308// We return undefined, instead of nothing here, so it's 15309// easier to handle this case. if(!global) { ...} 15310 15311module.exports = g; 15312 15313 15314/***/ }), 15315
vendor: 9,666 bytes, lines 15316-15677
15316/***/ "./node_modules/wnumb/wNumb.js": 15317/*!*************************************!*\ 15318 !*** ./node_modules/wnumb/wNumb.js ***! 15319 \*************************************/ 15320/*! no static exports found */ 15321/***/ (function(module, exports, __webpack_require__) { 15322 15323var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (factory) { 15324 15325 if ( true ) { 15326 15327 // AMD. Register as an anonymous module. 15328 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 15329 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 15330 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 15331 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 15332 15333 } else {} 15334 15335}(function(){ 15336 15337 'use strict'; 15338 15339var FormatOptions = [ 15340 'decimals', 15341 'thousand', 15342 'mark', 15343 'prefix', 15344 'suffix', 15345 'encoder', 15346 'decoder', 15347 'negativeBefore', 15348 'negative', 15349 'edit', 15350 'undo' 15351]; 15352 15353// General 15354 15355 // Reverse a string 15356 function strReverse ( a ) { 15357 return a.split('').reverse().join(''); 15358 } 15359 15360 // Check if a string starts with a specified prefix. 15361 function strStartsWith ( input, match ) { 15362 return input.substring(0, match.length) === match; 15363 } 15364 15365 // Check is a string ends in a specified suffix. 15366 function strEndsWith ( input, match ) { 15367 return input.slice(-1 * match.length) === match; 15368 } 15369 15370 // Throw an error if formatting options are incompatible. 15371 function throwEqualError( F, a, b ) { 15372 if ( (F[a] || F[b]) && (F[a] === F[b]) ) { 15373 throw new Error(a); 15374 } 15375 } 15376 15377 // Check if a number is finite and not NaN 15378 function isValidNumber ( input ) { 15379 return typeof input === 'number' && isFinite( input ); 15380 } 15381 15382 // Provide rounding-accurate toFixed method. 15383 // Borrowed: http://stackoverflow.com/a/21323330/775265 15384 function toFixed ( value, exp ) { 15385 value = value.toString().split('e'); 15386 value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp))); 15387 value = value.toString().split('e'); 15388 return (+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))).toFixed(exp); 15389 } 15390 15391 15392// Formatting 15393 15394 // Accept a number as input, output formatted string. 15395 function formatTo ( decimals, thousand, mark, prefix, suffix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { 15396 15397 var originalInput = input, inputIsNegative, inputPieces, inputBase, inputDecimals = '', output = ''; 15398 15399 // Apply user encoder to the input. 15400 // Expected outcome: number. 15401 if ( encoder ) { 15402 input = encoder(input); 15403 } 15404 15405 // Stop if no valid number was provided, the number is infinite or NaN. 15406 if ( !isValidNumber(input) ) { 15407 return false; 15408 } 15409 15410 // Rounding away decimals might cause a value of -0 15411 // when using very small ranges. Remove those cases. 15412 if ( decimals !== false && parseFloat(input.toFixed(decimals)) === 0 ) { 15413 input = 0; 15414 } 15415 15416 // Formatting is done on absolute numbers, 15417 // decorated by an optional negative symbol. 15418 if ( input < 0 ) { 15419 inputIsNegative = true; 15420 input = Math.abs(input); 15421 } 15422 15423 // Reduce the number of decimals to the specified option. 15424 if ( decimals !== false ) { 15425 input = toFixed( input, decimals ); 15426 } 15427 15428 // Transform the number into a string, so it can be split. 15429 input = input.toString(); 15430 15431 // Break the number on the decimal separator. 15432 if ( input.indexOf('.') !== -1 ) { 15433 inputPieces = input.split('.'); 15434 15435 inputBase = inputPieces[0]; 15436 15437 if ( mark ) { 15438 inputDecimals = mark + inputPieces[1]; 15439 } 15440 15441 } else { 15442 15443 // If it isn't split, the entire number will do. 15444 inputBase = input; 15445 } 15446 15447 // Group numbers in sets of three. 15448 if ( thousand ) { 15449 inputBase = strReverse(inputBase).match(/.{1,3}/g); 15450 inputBase = strReverse(inputBase.join( strReverse( thousand ) )); 15451 } 15452 15453 // If the number is negative, prefix with negation symbol. 15454 if ( inputIsNegative && negativeBefore ) { 15455 output += negativeBefore; 15456 } 15457 15458 // Prefix the number 15459 if ( prefix ) { 15460 output += prefix; 15461 } 15462 15463 // Normal negative option comes after the prefix. Defaults to '-'. 15464 if ( inputIsNegative && negative ) { 15465 output += negative; 15466 } 15467 15468 // Append the actual number. 15469 output += inputBase; 15470 output += inputDecimals; 15471 15472 // Apply the suffix. 15473 if ( suffix ) { 15474 output += suffix; 15475 } 15476 15477 // Run the output through a user-specified post-formatter. 15478 if ( edit ) { 15479 output = edit ( output, originalInput ); 15480 } 15481 15482 // All done. 15483 return output; 15484 } 15485 15486 // Accept a sting as input, output decoded number. 15487 function formatFrom ( decimals, thousand, mark, prefix, suffix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { 15488 15489 var originalInput = input, inputIsNegative, output = ''; 15490 15491 // User defined pre-decoder. Result must be a non empty string. 15492 if ( undo ) { 15493 input = undo(input); 15494 } 15495 15496 // Test the input. Can't be empty. 15497 if ( !input || typeof input !== 'string' ) { 15498 return false; 15499 } 15500 15501 // If the string starts with the negativeBefore value: remove it. 15502 // Remember is was there, the number is negative. 15503 if ( negativeBefore && strStartsWith(input, negativeBefore) ) { 15504 input = input.replace(negativeBefore, ''); 15505 inputIsNegative = true; 15506 } 15507 15508 // Repeat the same procedure for the prefix. 15509 if ( prefix && strStartsWith(input, prefix) ) { 15510 input = input.replace(prefix, ''); 15511 } 15512 15513 // And again for negative. 15514 if ( negative && strStartsWith(input, negative) ) { 15515 input = input.replace(negative, ''); 15516 inputIsNegative = true; 15517 } 15518 15519 // Remove the suffix. 15520 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice 15521 if ( suffix && strEndsWith(input, suffix) ) { 15522 input = input.slice(0, -1 * suffix.length); 15523 } 15524 15525 // Remove the thousand grouping. 15526 if ( thousand ) { 15527 input = input.split(thousand).join(''); 15528 } 15529 15530 // Set the decimal separator back to period. 15531 if ( mark ) { 15532 input = input.replace(mark, '.'); 15533 } 15534 15535 // Prepend the negative symbol. 15536 if ( inputIsNegative ) { 15537 output += '-'; 15538 } 15539 15540 // Add the number 15541 output += input; 15542 15543 // Trim all non-numeric characters (allow '.' and '-'); 15544 output = output.replace(/[^0-9\.\-.]/g, ''); 15545 15546 // The value contains no parse-able number. 15547 if ( output === '' ) { 15548 return false; 15549 } 15550 15551 // Covert to number. 15552 output = Number(output); 15553 15554 // Run the user-specified post-decoder. 15555 if ( decoder ) { 15556 output = decoder(output); 15557 } 15558 15559 // Check is the output is valid, otherwise: return false. 15560 if ( !isValidNumber(output) ) { 15561 return false; 15562 } 15563 15564 return output; 15565 } 15566 15567 15568// Framework 15569 15570 // Validate formatting options 15571 function validate ( inputOptions ) { 15572 15573 var i, optionName, optionValue, 15574 filteredOptions = {}; 15575 15576 if ( inputOptions['suffix'] === undefined ) { 15577 inputOptions['suffix'] = inputOptions['postfix']; 15578 } 15579 15580 for ( i = 0; i < FormatOptions.length; i+=1 ) { 15581 15582 optionName = FormatOptions[i]; 15583 optionValue = inputOptions[optionName]; 15584 15585 if ( optionValue === undefined ) { 15586 15587 // Only default if negativeBefore isn't set. 15588 if ( optionName === 'negative' && !filteredOptions.negativeBefore ) { 15589 filteredOptions[optionName] = '-'; 15590 // Don't set a default for mark when 'thousand' is set. 15591 } else if ( optionName === 'mark' && filteredOptions.thousand !== '.' ) { 15592 filteredOptions[optionName] = '.'; 15593 } else { 15594 filteredOptions[optionName] = false; 15595 } 15596 15597 // Floating points in JS are stable up to 7 decimals. 15598 } else if ( optionName === 'decimals' ) { 15599 if ( optionValue >= 0 && optionValue < 8 ) { 15600 filteredOptions[optionName] = optionValue; 15601 } else { 15602 throw new Error(optionName); 15603 } 15604 15605 // These options, when provided, must be functions. 15606 } else if ( optionName === 'encoder' || optionName === 'decoder' || optionName === 'edit' || optionName === 'undo' ) { 15607 if ( typeof optionValue === 'function' ) { 15608 filteredOptions[optionName] = optionValue; 15609 } else { 15610 throw new Error(optionName); 15611 } 15612 15613 // Other options are strings. 15614 } else { 15615 15616 if ( typeof optionValue === 'string' ) { 15617 filteredOptions[optionName] = optionValue; 15618 } else { 15619 throw new Error(optionName); 15620 } 15621 } 15622 } 15623 15624 // Some values can't be extracted from a 15625 // string if certain combinations are present. 15626 throwEqualError(filteredOptions, 'mark', 'thousand'); 15627 throwEqualError(filteredOptions, 'prefix', 'negative'); 15628 throwEqualError(filteredOptions, 'prefix', 'negativeBefore'); 15629 15630 return filteredOptions; 15631 } 15632 15633 // Pass all options as function arguments 15634 function passAll ( options, method, input ) { 15635 var i, args = []; 15636 15637 // Add all options in order of FormatOptions 15638 for ( i = 0; i < FormatOptions.length; i+=1 ) { 15639 args.push(options[FormatOptions[i]]); 15640 } 15641 15642 // Append the input, then call the method, presenting all 15643 // options as arguments. 15644 args.push(input); 15645 return method.apply('', args); 15646 } 15647 15648 function wNumb ( options ) { 15649 15650 if ( !(this instanceof wNumb) ) { 15651 return new wNumb ( options ); 15652 } 15653 15654 if ( typeof options !== "object" ) { 15655 return; 15656 } 15657 15658 options = validate(options); 15659 15660 // Call 'formatTo' with proper arguments. 15661 this.to = function ( input ) { 15662 return passAll(options, formatTo, input); 15663 }; 15664 15665 // Call 'formatFrom' with proper arguments. 15666 this.from = function ( input ) { 15667 return passAll(options, formatFrom, input); 15668 }; 15669 } 15670 15671 return wNumb; 15672 15673})); 15674 15675 15676/***/ }), 15677
15678/***/ "./src/css/media-queries.json": 15679/*!************************************!*\ 15680 !*** ./src/css/media-queries.json ***! 15681 \************************************/ 15682/*! exports provided: breakpoints, rules, default */ 15683/***/ (function(module) { 15684 15685module.exports = {"breakpoints":{"sm":"480","md":"750","lg":"1000","xl":"1232"},"rules":{"webkit":"(-webkit-min-device-pixel-ratio: 0)","retina":"(-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)"}}; 15686 15687/***/ }), 15688
15689/***/ "./src/js/app.js": 15690/*!***********************!*\ 15691 !*** ./src/js/app.js ***! 15692 \***********************/ 15693/*! no exports provided */ 15694/***/ (function(module, __webpack_exports__, __webpack_require__) { 15695 15696"use strict"; 15697__webpack_require__.r(__webpack_exports__); 15698/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 15699/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 15700/* harmony import */ var _tools_svg4everybody__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tools/svg4everybody */ "./src/js/tools/svg4everybody.js"); 15701/* harmony import */ var _tools_svg4everybody__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_tools_svg4everybody__WEBPACK_IMPORTED_MODULE_1__); 15702/* harmony import */ var _components_slick__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/slick */ "./src/js/components/slick.js"); 15703/* harmony import */ var _components_linkSlide__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/linkSlide */ "./src/js/components/linkSlide.js"); 15704/* harmony import */ var _components_popupOpen__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/popupOpen */ "./src/js/components/popupOpen.js"); 15705/* harmony import */ var _components_formOpen__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/formOpen */ "./src/js/components/formOpen.js"); 15706/* harmony import */ var _components_suggest__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/suggest */ "./src/js/components/suggest.js"); 15707/* harmony import */ var _components_inpCount__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/inpCount */ "./src/js/components/inpCount.js"); 15708/* harmony import */ var _components_menuMain__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/menuMain */ "./src/js/components/menuMain.js"); 15709/* harmony import */ var _components_fixed__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/fixed */ "./src/js/components/fixed.js"); 15710/* harmony import */ var _components_fancybox__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/fancybox */ "./src/js/components/fancybox.js"); 15711/* harmony import */ var _components_ajaxFormFancybox__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/ajaxFormFancybox */ "./src/js/components/ajaxFormFancybox.js"); 15712/* harmony import */ var _components_toggleClass__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/toggleClass */ "./src/js/components/toggleClass.js"); 15713/* harmony import */ var _components_transportPayment__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/transportPayment */ "./src/js/components/transportPayment.js"); 15714/* harmony import */ var _components_slider__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/slider */ "./src/js/components/slider.js"); 15715/* harmony import */ var _components_customSelect__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/customSelect */ "./src/js/components/customSelect.js"); 15716/* harmony import */ var _components_top__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/top */ "./src/js/components/top.js"); 15717/* harmony import */ var _components_tippy__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./components/tippy */ "./src/js/components/tippy.js"); 15718/* harmony import */ var _components_menuToggle__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./components/menuToggle */ "./src/js/components/menuToggle.js"); 15719/* harmony import */ var _components_tabs__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./components/tabs */ "./src/js/components/tabs.js"); 15720/* harmony import */ var _components_tabs_filter__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./components/tabs-filter */ "./src/js/components/tabs-filter.js"); 15721/* harmony import */ var _components_menuSection__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./components/menuSection */ "./src/js/components/menuSection.js"); 15722/* harmony import */ var _components_search__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./components/search */ "./src/js/components/search.js"); 15723/* harmony import */ var _components_footer__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./components/footer */ "./src/js/components/footer.js"); 15724/* harmony import */ var _components_toggleAnimate__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./components/toggleAnimate */ "./src/js/components/toggleAnimate.js"); 15725/* harmony import */ var _components_detectIt__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./components/detectIt */ "./src/js/components/detectIt.js"); 15726/* harmony import */ var _components_inputDebouncedSubmit__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./components/inputDebouncedSubmit */ "./src/js/components/inputDebouncedSubmit.js"); 15727/* harmony import */ var _components_headerBasket__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./components/headerBasket */ "./src/js/components/headerBasket.js"); 15728/* harmony import */ var _components_autoSubmitCheckbox__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./components/
15728autoSubmitCheckbox */ "./src/js/components/autoSubmitCheckbox.js"); 15729 15730 15731// import { MQ } from './tools/MQ'; 15732 15733// Components 15734// import * as fontFaceObserver from './components/fontFaceObserver'; 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763// content load components 15764var componentsload = [_components_suggest__WEBPACK_IMPORTED_MODULE_6__, _components_slick__WEBPACK_IMPORTED_MODULE_2__, _components_slider__WEBPACK_IMPORTED_MODULE_14__, _components_fancybox__WEBPACK_IMPORTED_MODULE_10__]; 15765 15766// once delegated components 15767var components = [ 15768// fontFaceObserver, 15769_components_transportPayment__WEBPACK_IMPORTED_MODULE_13__, _components_ajaxFormFancybox__WEBPACK_IMPORTED_MODULE_11__, _components_fixed__WEBPACK_IMPORTED_MODULE_9__, _components_linkSlide__WEBPACK_IMPORTED_MODULE_3__, _components_popupOpen__WEBPACK_IMPORTED_MODULE_4__, _components_formOpen__WEBPACK_IMPORTED_MODULE_5__, _components_inpCount__WEBPACK_IMPORTED_MODULE_7__, _components_menuMain__WEBPACK_IMPORTED_MODULE_8__, _components_toggleClass__WEBPACK_IMPORTED_MODULE_12__, _components_customSelect__WEBPACK_IMPORTED_MODULE_15__, _components_top__WEBPACK_IMPORTED_MODULE_16__, _components_tippy__WEBPACK_IMPORTED_MODULE_17__, _components_menuToggle__WEBPACK_IMPORTED_MODULE_18__, _components_tabs__WEBPACK_IMPORTED_MODULE_19__, _components_tabs_filter__WEBPACK_IMPORTED_MODULE_20__, _components_menuSection__WEBPACK_IMPORTED_MODULE_21__, _components_search__WEBPACK_IMPORTED_MODULE_22__, _components_footer__WEBPACK_IMPORTED_MODULE_23__, _components_toggleAnimate__WEBPACK_IMPORTED_MODULE_24__, _components_detectIt__WEBPACK_IMPORTED_MODULE_25__, _components_inputDebouncedSubmit__WEBPACK_IMPORTED_MODULE_26__, _components_headerBasket__WEBPACK_IMPORTED_MODULE_27__, _components_autoSubmitCheckbox__WEBPACK_IMPORTED_MODULE_28__].concat(componentsload); 15770 15771window.App = { 15772 run: function run() { 15773 // MQ('lgUp'); 15774 15775 15776 15777 var $target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document); 15778 components.forEach(function (component) { 15779 console.log(component.toString()); 15780 return component.init($target); 15781 }); 15782 15783 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('contentload', function (event) { 15784 var $target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(event.target); 15785 componentsload.forEach(function (component) { 15786 return component.init($target); 15787 }); 15788 }); 15789 }, 15790 initComponent: function initComponent(component) { 15791 return component.init(); 15792 } 15793}; 15794 15795/***/ }), 15796
15797/***/ "./src/js/class/sk.js": 15798/*!****************************!*\ 15799 !*** ./src/js/class/sk.js ***! 15800 \****************************/ 15801/*! no static exports found */ 15802/***/ (function(module, exports) { 15803 15804(function ($) { 15805 var sk = window.sk = { 15806 mediator: $({}), 15807 base: {}, 15808 utils: {}, 15809 widgets: {}, 15810 events: {} 15811 }; 15812 15813 sk.extend = function (child, parent) { 15814 var F = function F() {}; 15815 F.prototype = parent.prototype; 15816 child.prototype = new F(); 15817 child._super = parent.prototype; 15818 child.prototype.constructor = child; 15819 }; 15820})(jQuery); 15821 15822/***/ }), 15823
15824/***/ "./src/js/class/sk.widgets.Suggest.js": 15825/*!********************************************!*\ 15826 !*** ./src/js/class/sk.widgets.Suggest.js ***! 15827 \********************************************/ 15828/*! no static exports found */ 15829/***/ (function(module, exports) { 15830 15831(function (sk, $) { 15832 15833 sk.widgets.Suggest = function (element, options) { 15834 this.$input = element.jquery ? element : $(element); 15835 15836 this.options = $.extend({ 15837 minLength: 2, 15838 typeInterval: 500, //ms 15839 url: '/', 15840 loadingClass: 'is-loading', 15841 typingClass: 'is-typing' 15842 }, options); 15843 15844 this.isResult = false; 15845 this.splashScreenVisible = false; 15846 this.typeTimer = null; 15847 this.searchTerm = ''; 15848 this.ajax = []; 15849 }; 15850 15851 // prototype 15852 var _fn = sk.widgets.Suggest.prototype; 15853 15854 // prototype methods 15855 _fn.init = function () { 15856 this.$input.attr('autocomplete', 'off').on('keydown', $.proxy(this.keydown, this)).on('keypress', $.proxy(this.keypress, this)).on('focus', $.proxy(this.focus, this)).on('blur', $.proxy(this.blur, this)); 15857 15858 return this; 15859 }; 15860 15861 _fn.destroy = function () { 15862 this.$input.off('keydown', this.keydown).off('keypress', this.keypress).off('focus', this.focus).off('blur', this.blur); 15863 15864 return this; 15865 }; 15866 15867 _fn.focus = function () { 15868 $(this).trigger('suggeststart'); 15869 var o = this.options; 15870 if (o.useSplashScreen) { 15871 value = this.$input.val(); 15872 if (value.length <= 2) { 15873 //otevru splash screen 15874 this.showSplashScreen(); 15875 } 15876 } 15877 15878 15879 this.type(); 15880 }; 15881 _fn.blur = function () { 15882 $(this).trigger('suggestend'); 15883 15884 this.$input.removeClass(this.options.typingClass); 15885 }; 15886 15887 _fn.keydown = function (e) { 15888 var that = this; 15889 var o = this.options; 15890 15891 this.typeTimer = clearTimeout(this.typeTimer); 15892 this.typeTimer = setTimeout(function () { 15893 that.type(); 15894 }, o.typeInterval); 15895 15896 var typeEvent = jQuery.Event('typestart', { 15897 which: e.which 15898 }); 15899 $(this).trigger(typeEvent); 15900 15901 if (typeEvent.isDefaultPrevented()) { 15902 e.preventDefault(); 15903 } else { 15904 this.$input.addClass(this.options.typingClass); 15905 } 15906 }; 15907 _fn.keypress = function (e) { 15908 $(this).trigger('typing'); 15909 15910 if (this.$input.val() !== this.searchTerm) { 15911 this.ajaxAbort(); 15912 } 15913 }; 15914 15915 _fn.ajaxRemove = function (instance) { 15916 var arr = this.ajax; 15917 15918 for (var i = 0, l = arr.length; i < l; i++) { 15919 if (arr[i] === instance) { 15920 break; 15921 } 15922 } 15923 15924 arr.splice(i, 1); 15925 }; 15926 15927 _fn.ajaxAbort = function () { 15928 var arr = this.ajax; 15929 15930 for (var i = 0, l = arr.length; i < l; i++) { 15931 arr[i].abort(); 15932 } 15933 }; 15934 15935 _fn.showSplashScreen = function(){ 15936 15937 var value = this.$input.val(); 15938 var o = this.options; 15939 if(o.useSplashScreen) { 15940 if(this.$input.parent().find('.b-suggest.preloaded').length){ 15941 this.$input.parent().find('.b-suggest.preloaded').removeClass('preloaded'); 15942 this.$input.parent().find('.b-suggest').show(); 15943 return; 15944 } 15945 this.ajaxAbort(); 15946 15947 // Sestavenà dat k poslánà na server 15948 var data = {}; 15949 data[this.$input.attr('name')] = value; 15950 15951 this.ajax.push($.ajax({ 15952 type: 'GET', 15953 url: o.url, 15954 data: data, 15955 beforeSend: $.proxy(function (jqXHR, settings) { 15956 var beforeSendEvent = jQuery.Event('beforeSend'); 15957 $(this).trigger(beforeSendEvent, [jqXHR, settings]); 15958 15959 if (beforeSendEvent.isDefaultPrevented()) { 15960 return false; 15961 } 15962 15963 this.$input.addClass(o.loadingClass); 15964 }, this), 15965 success: $.proxy(function (respond, textStatus, jqXHR) { 15966 this.ajaxRemove(jqXHR); 15967 15968 var successEvent = jQuery.Event('success'); 15969 $(this).trigger(successEvent, [respond, textStatus, jqXHR]); 15970 15971 this.$input.removeClass(o.loadingClass); 15972 this.isResult = true; 15973 this.splashScreenVisible = true; 15974 }, this), 15975 error: $.proxy(function (jqXHR, textStatus, errorThrown) { 15976 this.ajaxRemove(jqXHR); 15977 this.$input.removeClass(o.loadingClass); 15978 }, this) 15979 })); 15980 } 15981 } 15982 15983 _fn.type = function () { 15984 var value = this.$input.val(); 15985 var o = this.options; 15986 15987 if (value !== this.searchTerm) { 15988 this.searchTerm = value; 15989 15990 if (value.length >= o.minLength) { 15991 this.ajaxAbort(); 15992 15993 // Sestavenà dat k poslánà na server 15994 var data = {}; 15995 data[this.$input.attr('name')] = value; 15996 this.splashScreenVisible=false 15997 this.ajax.push($.ajax({
15998 type: 'GET', 15999 url: o.url, 16000 data: data, 16001 beforeSend: $.proxy(function (jqXHR, settings) { 16002 var beforeSendEvent = jQuery.Event('beforeSend'); 16003 $(this).trigger(beforeSendEvent, [jqXHR, settings]); 16004 16005 if (beforeSendEvent.isDefaultPrevented()) { 16006 return false; 16007 } 16008 16009 this.$input.addClass(o.loadingClass); 16010 }, this), 16011 success: $.proxy(function (respond, textStatus, jqXHR) { 16012 this.ajaxRemove(jqXHR); 16013 16014 var successEvent = jQuery.Event('success'); 16015 $(this).trigger(successEvent, [respond, textStatus, jqXHR]); 16016 16017 this.$input.removeClass(o.loadingClass); 16018 this.isResult = true; 16019 }, this), 16020 error: $.proxy(function (jqXHR, textStatus, errorThrown) { 16021 this.ajaxRemove(jqXHR); 16022 this.$input.removeClass(o.loadingClass); 16023 }, this) 16024 })); 16025 } else if (this.isResult) { 16026 if(o.useSplashScreen==false) { 16027 this.isResult = false; 16028 this.ajaxAbort(); 16029 $(this).trigger('typeclear'); 16030 } 16031 16032 if(o.useSplashScreen && this.splashScreenVisible==false){ 16033 this.showSplashScreen(); 16034 } 16035 } else { 16036 $(this).trigger('typeend'); 16037 if(o.useSplashScreen && this.splashScreenVisible==false){ 16038 this.showSplashScreen(); 16039 } 16040 } 16041 } else { 16042 $(this).trigger('typeend'); 16043 } 16044 16045 this.$input.removeClass(o.typingClass); 16046 }; 16047 16048 _fn.clear = function () { 16049 this.$input.val(''); 16050 this.typeTimer = clearTimeout(this.typeTimer); 16051 this.type(); 16052 }; 16053})(sk, jQuery); 16054 16055/***/ }), 16056
16057/***/ "./src/js/class/sk.widgets.SuggestMenu.js": 16058/*!************************************************!*\ 16059 !*** ./src/js/class/sk.widgets.SuggestMenu.js ***! 16060 \************************************************/ 16061/*! no static exports found */ 16062/***/ (function(module, exports) { 16063 16064(function (sk, $, undefined) { 16065 16066 sk.widgets.SuggestMenu = function (element, Suggest, options) { 16067 this.$element = element.jquery ? element : $(element); 16068 this.Suggest = Suggest; 16069 16070 this.options = $.extend({ 16071 item: 'li', 16072 selectedClass: 'is-selected' 16073 }, options); 16074 16075 this.$items = $([]); 16076 this.selectedIndex = 0; 16077 this.size = 0; 16078 this.isOpen = false; 16079 }; 16080 16081 // prototype 16082 var _fn = sk.widgets.SuggestMenu.prototype; 16083 16084 _fn.init = function () { 16085 if (!this.$element.length || this.Suggest === undefined) { 16086 return this; 16087 } 16088 16089 this.$element.hide().on('mouseenter', this.options.item, $.proxy(this.handleMouseEnter, this)); 16090 // .on('click', this.options.item, $.proxy(this.handleClick, this)); 16091 16092 $(this.Suggest).on('suggeststart', $.proxy(this.handleSuggestStart, this)).on('suggestend', $.proxy(this.handleSuggestEnd, this)).on('beforeSend', $.proxy(this.handleBeforeSend, this)).on('success', $.proxy(this.handleSuccess, this)).on('typestart', $.proxy(this.handleTypeStart, this)) 16093 //.on('typeend', $.proxy(this.handleTypeEnd, this)) 16094 .on('typeclear', $.proxy(this.handleTypeClear, this)); 16095 16096 this.Suggest.init(); 16097 16098 return this; 16099 }; 16100 16101 _fn.destroy = function () { 16102 if (!this.$element.length || this.Suggest === undefined) { 16103 return this; 16104 } 16105 16106 this.$element.hide().empty().off('mouseenter', this.options.item, this.handleMouseEnter).off('click', this.options.item, this.handleMouseEnter); 16107 16108 $(this.Suggest).off('suggeststart', this.handleSuggestStart).off('suggestend', this.handleSuggestEnd).off('success', this.handleSuccess).off('typestart', this.handleTypeStart).off('typeclear', this.handleTypeClear); 16109 16110 this.Suggest.destroy(); 16111 }; 16112 16113 _fn.open = function () { 16114 if (!this.isOpen && !this.$element.is(':empty')) { 16115 $(this).trigger('beforeopen'); 16116 16117 this.$element.fadeIn(250, $.proxy(function () { 16118 $(this).trigger('afteropen'); 16119 }, this)); 16120 16121 this.isOpen = true; 16122 } 16123 }; 16124 16125 _fn.hide = function (fastHide) { 16126 if (this.isOpen) { 16127 $(this).trigger('beforehide'); 16128 16129 if (fastHide) { 16130 this.$element.hide(); 16131 $(this).trigger('afterhide'); 16132 } else { 16133 this.$element.fadeOut(250, $.proxy(function () { 16134 $(this).trigger('afterhide'); 16135 }, this)); 16136 } 16137 16138 this.isOpen = false; 16139 } 16140 }; 16141 16142 _fn.handleSuggestStart = function (e) { 16143 if (this.Suggest.isResult) { 16144 this.clearIndex(); 16145 this.open(); 16146 } 16147 }; 16148 16149 _fn.handleSuggestEnd = function (e) { 16150 // oddÄleno zkrz vyhledávánà bez focosu, u menu nemá smysl 16151 this.Suggest.typeTimer = clearTimeout(this.Suggest.typeTimer); 16152 this.Suggest.ajaxAbort(); 16153 this.Suggest.$input.removeClass(this.Suggest.options.loadingClass); 16154 16155 this.hide(); 16156 }; 16157 16158 _fn.handleSuccess = function (e, respond) { 16159 var contentEvent = jQuery.Event('content'); 16160 $(this).trigger(contentEvent, [respond]); 16161 16162 if (!contentEvent.isDefaultPrevented()) { 16163 this.$element.html(respond); 16164 } 16165 16166 this.$items = this.$element.find(this.options.item); 16167 this.size = this.$items.length + 1; 16168 16169 this.clearIndex(); 16170 16171 if (this.$element.is(':empty')) { 16172 this.hide(true); 16173 } else { 16174 this.open(); 16175 } 16176 16177 this.$element.trigger('contentload'); 16178 }; 16179 16180 _fn.handleTypeStart = function (e) { 16181 if (e.which === 38) { 16182 this.handleArrUp(e); 16183 } else if (e.which === 40) { 16184 this.handleArrDown(e); 16185 } else if (e.which === 13 && this.selectedIndex) { 16186 this.handleEnter(e); 16187 } 16188 }; 16189 16190 _fn.handleTypeClear = function (e) { 16191 this.hide(); 16192 this.clearIndex(); 16193 }; 16194 16195 _fn.handleMouseEnter = function (e) { 16196 // if(this.isOpen) 16197 // { 16198 // // console.log(e.currentTarget) 16199 // // console.log( $(e.currentTarget) ) 16200 // // console.log( $(e.currentTarget).index() ) 16201 // // console.log( $(e.currentTarget).index( $('.f-search__item') ) ) 16202 // this.setIndex( $(e.currentTarget).index()+1, 'enter' ); 16203 // } 16204 }; 16205 16206 _fn.setIndex = function (index, type) { 16207 var o = this.options; 16208 16209 if (index !== this.selectedIndex) { 16210 this.$items.removeClass(o.selectedClass); 16211 16212 if (index) { 16213 this.$items.eq(index - 1).addClass(o.selectedClass); 16214 } 16215 16216 // Scroll to invisible item if keys 16217 if (index && type !== 'enter') { 16218 var scroll = this.$element.scrollTop(); 16219 var top = scroll + this.$items.eq(index - 1).position().top; 16220 var height = this.$element.height(); 16221 16222 if (top < scroll || top > scroll + height) { 16223 this.$element.scrollTop(top); 16224 } 16225 } 16226 16227 this.selectedIndex = index; 16228 16229 $(this).trigger('menuchange'); 16230 } 16231 }; 16232 _fn.clearIndex = function () { 16233 this.$items.removeClass(this.options.selectedClass); 16234 this.selectedIndex = 0; 16235 }; 16236 16237 _fn.handleArrUp = function (e) { 16238 this.setIndex((this.selectedIndex - 1 + this.size) % this.size, 'up'); 16239 e.preventDefault(); 16240 }; 16241 16242 _fn.handleArrDown = function (e) { 16243 this.setIndex((this.selectedIndex + 1) % this.size, 'down'); 16244 e.preventDefault(); 16245 }; 16246 16247 _fn.handleEnter = function (e) { 16248 e.preventDefault(); 16249 16250 $(this).trigger('menuselect'); 16251 }; 16252 _fn.handleClick = function (e) { 16253 e.preventDefault(); 16254 16255 this.setIndex($(e.currentTarget).index() + 1, 'click'); 16256 16257 $(this).trigger('menuselect'); 16258 }; 16259})(sk, jQuery); 16260 16261/***/ }), 16262
16263/***/ "./src/js/components/ajaxCartInit.js": 16264/*!*******************************************!*\ 16265 !*** ./src/js/components/ajaxCartInit.js ***! 16266 \*******************************************/ 16267/*! exports provided: default */ 16268/***/ (function(module, __webpack_exports__, __webpack_require__) { 16269 16270"use strict"; 16271__webpack_require__.r(__webpack_exports__); 16272/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return initAjaxCart; }); 16273/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16274/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16275/* harmony import */ var _headerCartRefresh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./headerCartRefresh */ "./src/js/components/headerCartRefresh.js"); 16276 16277 16278 16279function initAjaxCart() { 16280 16281 setTimeout(function () { 16282 jquery__WEBPACK_IMPORTED_MODULE_0___default()('#crossselling-products').find('form').on('submit', function () { 16283 var href = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('action'); 16284 href += '&ajaxeshop=1'; 16285 var isFancyboxSurelyClosed = false; 16286 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.fancybox.close(); 16287 16288 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.ajax({ url: href }).done(function (response) { 16289 var openFancybox = function openFancybox() { 16290 var $fancybox = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.fancybox.open(response, { 16291 btnTpl: { 16292 smallBtn: '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"><svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 15 15" style="enable-background:new 0 0 15 15;" xml:space="preserve"><path class="st0" fill="#576371" d="M9.6,7.5l4.9-4.9c0.4-0.4,0.4-1,0-1.4l-0.6-0.6c-0.4-0.4-1-0.4-1.4,0L7.5,5.4L2.6,0.5c-0.4-0.4-1-0.4-1.4,0 L0.5,1.1c-0.4,0.4-0.4,1,0,1.4l4.9,4.9l-4.9,4.9c-0.4,0.4-0.4,1,0,1.4l0.6,0.6c0.4,0.4,1,0.4,1.4,0l4.9-4.9l4.9,4.9 c0.4,0.4,1,0.4,1.4,0l0.6-0.6c0.4-0.4,0.4-1,0-1.4L9.6,7.5z"/></svg></button>' 16293 }, 16294 touch: false 16295 }); 16296 $fancybox.current.$content.trigger('contentload'); 16297 Object(_headerCartRefresh__WEBPACK_IMPORTED_MODULE_1__["default"])(); 16298 initAjaxCart(); 16299 }; 16300 if (isFancyboxSurelyClosed) { 16301 openFancybox(); 16302 } else { 16303 setTimeout(function () { 16304 openFancybox(); 16305 }, 500); 16306 } 16307 }); 16308 16309 setTimeout(function () { 16310 isFancyboxSurelyClosed = true; 16311 }, 500); 16312 16313 return false; 16314 }); 16315 }, 100); 16316} 16317 16318/***/ }), 16319
16320/***/ "./src/js/components/ajaxFormFancybox.js": 16321/*!***********************************************!*\ 16322 !*** ./src/js/components/ajaxFormFancybox.js ***! 16323 \***********************************************/ 16324/*! exports provided: init */ 16325/***/ (function(module, __webpack_exports__, __webpack_require__) { 16326 16327"use strict"; 16328__webpack_require__.r(__webpack_exports__); 16329/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16330/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16331/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16332/* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fancyapps/fancybox */ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js"); 16333/* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1__); 16334/* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! slick-carousel */ "./node_modules/slick-carousel/slick/slick.js"); 16335/* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(slick_carousel__WEBPACK_IMPORTED_MODULE_2__); 16336/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tippy.js */ "./node_modules/tippy.js/dist/tippy.all.js"); 16337/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(tippy_js__WEBPACK_IMPORTED_MODULE_3__); 16338/* harmony import */ var _headerCartRefresh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./headerCartRefresh */ "./src/js/components/headerCartRefresh.js"); 16339/* harmony import */ var _ajaxCartInit__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ajaxCartInit */ "./src/js/components/ajaxCartInit.js"); 16340 16341 16342 16343 16344 16345 16346 16347var init = function init() { 16348 16349 var request = null; 16350 16351 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('submit', '.f-add-to-cart', function (e) { 16352 16353 e.preventDefault(); 16354 16355 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 16356 var tip = null; 16357 var btn = null; 16358 16359 if (request != null) { 16360 request.abort(); 16361 } 16362 16363 request = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.ajax({ 16364 url: $this.attr('action'), 16365 data: $this.serialize(), 16366 16367 beforeSend: function beforeSend() { 16368 $this.addClass('is-loading'); 16369 } 16370 }).done(function (response) { 16371 $this.removeClass('is-loading'); 16372 16373 request = null; 16374 16375 if ($this.is(':not(.f-add-to-cart--tooltip)')) { 16376 var $fancybox = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.fancybox.open(response, { 16377 btnTpl: { 16378 smallBtn: '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"><svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 15 15" style="enable-background:new 0 0 15 15;" xml:space="preserve"><path class="st0" fill="#576371" d="M9.6,7.5l4.9-4.9c0.4-0.4,0.4-1,0-1.4l-0.6-0.6c-0.4-0.4-1-0.4-1.4,0L7.5,5.4L2.6,0.5c-0.4-0.4-1-0.4-1.4,0 L0.5,1.1c-0.4,0.4-0.4,1,0,1.4l4.9,4.9l-4.9,4.9c-0.4,0.4-0.4,1,0,1.4l0.6,0.6c0.4,0.4,1,0.4,1.4,0l4.9-4.9l4.9,4.9 c0.4,0.4,1,0.4,1.4,0l0.6-0.6c0.4-0.4,0.4-1,0-1.4L9.6,7.5z"/></svg></button>' 16379 }, 16380 touch: false 16381 }); 16382 16383 $fancybox.current.$content.trigger('contentload'); 16384 Object(_ajaxCartInit__WEBPACK_IMPORTED_MODULE_5__["default"])(); 16385 Object(_headerCartRefresh__WEBPACK_IMPORTED_MODULE_4__["default"])(); 16386 } else { 16387 btn = $this.find('.f-add-to-cart__btn').get(0); 16388 var data = $this.data('tippy'); 16389 16390 if (data == null) { 16391 tip = tippy_js__WEBPACK_IMPORTED_MODULE_3___default.a.one(btn, { 16392 animation: 'shift-toward', 16393 arrow: true, 16394 arrowType: 'sharp', 16395 arrowTransform: 'scaleX(1.3)', 16396 duration: 500, 16397 size: 'large', 16398 placement: 'bottom', 16399 position: 'bottom-start', 16400 theme: 'light', 16401 hideOnClick: false, 16402 trigger: 'manual', 16403 dynamicTitle: true 16404 });
16405 tip.show(); 16406 16407 $this.data('tippy', { 16408 tip: tip, 16409 btn: btn, 16410 timer: setTimeout(function () { 16411 tip.hide(); 16412 }, 2000) 16413 }); 16414 } else { 16415 16416 clearTimeout(data.timer); 16417 data.btn.title = 'Nový údaj o poÄtu kusů v koÅ¡Ãku'; 16418 data.tip.show(); 16419 16420 data.timer = setTimeout(function () { 16421 data.tip.hide(); 16422 }, 2000); 16423 } 16424 } 16425 }); 16426 }); 16427}; 16428 16429/***/ }), 16430
16431/***/ "./src/js/components/autoSubmitCheckbox.js": 16432/*!*************************************************!*\ 16433 !*** ./src/js/components/autoSubmitCheckbox.js ***! 16434 \*************************************************/ 16435/*! exports provided: init */ 16436/***/ (function(module, __webpack_exports__, __webpack_require__) { 16437 16438"use strict"; 16439__webpack_require__.r(__webpack_exports__); 16440/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16441/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16442/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16443 16444 16445var init = function init() { 16446 16447 var autosubmitTimeout = null; 16448 var autosubmitNow = function autosubmitNow(sender) { 16449 jquery__WEBPACK_IMPORTED_MODULE_0___default()(sender).closest('form').submit(); 16450 }; 16451 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-auto-submit-checkbox', function (e) { 16452 if (autosubmitTimeout) { 16453 clearTimeout(autosubmitTimeout); 16454 autosubmitTimeout = null; 16455 } 16456 autosubmitTimeout = setTimeout(function () { 16457 autosubmitNow(e.target); 16458 }, 800); 16459 }); 16460}; 16461 16462/***/ }), 16463
16464/***/ "./src/js/components/customSelect.js": 16465/*!*******************************************!*\ 16466 !*** ./src/js/components/customSelect.js ***! 16467 \*******************************************/ 16468/*! exports provided: init */ 16469/***/ (function(module, __webpack_exports__, __webpack_require__) { 16470 16471"use strict"; 16472__webpack_require__.r(__webpack_exports__); 16473/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16474/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16475/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16476 16477 16478var init = function init($target) { 16479 16480 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.inp-custom-select__select', function (e) { 16481 e.preventDefault(); 16482 16483 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16484 $closest = $this.closest('.inp-custom-select'); 16485 16486 $closest.toggleClass('is-open'); 16487 }).on('click', function (e) { 16488 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.inp-custom-select').length) { 16489 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.inp-custom-select').removeClass('is-open'); 16490 } 16491 }).on('change', '.inp-custom-select .inp-item__inp', function (e) { 16492 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16493 $closest = $this.closest('.inp-custom-select'), 16494 $select = $closest.find('.inp-custom-select__select'), 16495 $selectWrap = $closest.find('.inp-custom-select__select-wrap'), 16496 $parent = $this.parent(), 16497 $active = $parent.find('.inp-item__text').clone(); 16498 16499 // if called by b-tabs, check manualy 16500 $this.prop('checked', true); 16501 16502 $selectWrap.html('<span class="inp-custom-select__item inp-item">' + $active.html() + '</span>'); 16503 $closest.removeClass('is-open'); 16504 }); 16505}; 16506 16507/***/ }), 16508
16509/***/ "./src/js/components/detectIt.js": 16510/*!***************************************!*\ 16511 !*** ./src/js/components/detectIt.js ***! 16512 \***************************************/ 16513/*! exports provided: init */ 16514/***/ (function(module, __webpack_exports__, __webpack_require__) { 16515 16516"use strict"; 16517__webpack_require__.r(__webpack_exports__); 16518/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16519/* harmony import */ var detect_it__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! detect-it */ "./node_modules/detect-it/lib/index.js"); 16520/* harmony import */ var detect_it__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(detect_it__WEBPACK_IMPORTED_MODULE_0__); 16521 16522 16523var init = function init() { 16524 16525 if (detect_it__WEBPACK_IMPORTED_MODULE_0___default.a.primaryInput === 'mouse') { 16526 $('html').addClass('no-touchevents'); 16527 } else { 16528 $('html').addClass('touchevents'); 16529 } 16530}; 16531 16532/***/ }), 16533
16534/***/ "./src/js/components/fancybox.js": 16535/*!***************************************!*\ 16536 !*** ./src/js/components/fancybox.js ***! 16537 \***************************************/ 16538/*! exports provided: init */ 16539/***/ (function(module, __webpack_exports__, __webpack_require__) { 16540 16541"use strict"; 16542__webpack_require__.r(__webpack_exports__); 16543/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16544/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16545/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16546/* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fancyapps/fancybox */ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js"); 16547/* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_1__); 16548 16549 16550 16551/*! 16552 * Examples at http://fancyapps.com/fancybox/ 16553 * License: www.fancyapps.com/fancybox/#license 16554 * License Name: Tomáš KrejÄà 16555 * License key: 669ff49044a69167735d4c8de99d3a8a 16556 */ 16557 16558var init = function init($target) { 16559 16560 $target.find('[data-fancybox][data-type="ajax"]').fancybox({ 16561 afterShow: function afterShow(obj) { 16562 obj.current.$content.trigger('contentload'); 16563 }, 16564 btnTpl: { 16565 smallBtn: '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"><svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 15 15" style="enable-background:new 0 0 15 15;" xml:space="preserve"><path class="st0" fill="#576371" d="M9.6,7.5l4.9-4.9c0.4-0.4,0.4-1,0-1.4l-0.6-0.6c-0.4-0.4-1-0.4-1.4,0L7.5,5.4L2.6,0.5c-0.4-0.4-1-0.4-1.4,0 L0.5,1.1c-0.4,0.4-0.4,1,0,1.4l4.9,4.9l-4.9,4.9c-0.4,0.4-0.4,1,0,1.4l0.6,0.6c0.4,0.4,1,0.4,1.4,0l4.9-4.9l4.9,4.9 c0.4,0.4,1,0.4,1.4,0l0.6-0.6c0.4-0.4,0.4-1,0-1.4L9.6,7.5z"/></svg></button>' 16566 }, 16567 touch: false 16568 }); 16569}; 16570 16571/***/ }), 16572
16573/***/ "./src/js/components/fixed.js": 16574/*!************************************!*\ 16575 !*** ./src/js/components/fixed.js ***! 16576 \************************************/ 16577/*! exports provided: init */ 16578/***/ (function(module, __webpack_exports__, __webpack_require__) { 16579 16580"use strict"; 16581__webpack_require__.r(__webpack_exports__); 16582/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16583/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16584/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16585 16586 16587var init = function init($target) { 16588 // fixed bar 16589 16590 $target.find('.js-fixed').each(function () { 16591 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16592 $wrap = $this.find('.js-fixed__wrap'), 16593 $wrappedTarget = $this.find('.js-fixed__target--wrapped'), 16594 $target = $this.find('.js-fixed__target'); 16595 16596 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('scroll resize', function () { 16597 16598 $wrap.height($wrappedTarget.outerHeight()); 16599 $wrappedTarget.width($wrappedTarget.parent().innerWidth()); 16600 16601 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).width() >= 750) { 16602 16603 if ($this.outerHeight() > $target.outerHeight()) { 16604 16605 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).scrollTop() + 200 > $this.offset().top) { 16606 16607 $target.addClass('is-fixed'); 16608 16609 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).scrollTop() + $target.height() > $this.offset().top + $this.outerHeight()) { 16610 //$target.addClass('is-fixed-bottom'); 16611 //$target.removeClass('is-fixed'); 16612 } else { 16613 //$target.removeClass('is-fixed-bottom'); 16614 $target.addClass('is-fixed'); 16615 } 16616 } else { 16617 $target.removeClass('is-fixed'); 16618 } 16619 } 16620 } else { 16621 $target.removeClass('is-fixed'); 16622 } 16623 }); 16624 }); 16625 16626 $target.find('.js-fixed-side').each(function () { 16627 16628 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16629 $target = $this.find('.js-fixed-side__target'); 16630 16631 $target.width($target.parent().innerWidth()); 16632 16633 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('scroll', function () { 16634 16635 if ($this.outerHeight() > $target.outerHeight()) { 16636 16637 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).scrollTop() > $this.offset().top - 32) { 16638 // top fixed space (match CSS: $gridGutter*2) 16639 16640 $target.addClass('is-fixed'); 16641 16642 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).scrollTop() + $target.height() > $this.offset().top + $this.outerHeight() - 80) { 16643 // bottom fixed space 16644 $target.addClass('is-fixed-bottom'); 16645 } else { 16646 $target.removeClass('is-fixed-bottom'); 16647 } 16648 } else { 16649 $target.removeClass('is-fixed'); 16650 } 16651 } 16652 }); 16653 16654 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize', function () { 16655 $target.width($target.parent().innerWidth()); 16656 }); 16657 }); 16658}; 16659 16660/***/ }), 16661
16662/***/ "./src/js/components/footer.js": 16663/*!*************************************!*\ 16664 !*** ./src/js/components/footer.js ***! 16665 \*************************************/ 16666/*! exports provided: init */ 16667/***/ (function(module, __webpack_exports__, __webpack_require__) { 16668 16669"use strict"; 16670__webpack_require__.r(__webpack_exports__); 16671/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16672/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16673/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16674 16675 16676var init = function init() { 16677 16678 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize', function (e) { 16679 var $content = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.footer__inner'); 16680 16681 $content.removeAttr('style'); 16682 }); 16683}; 16684 16685/***/ }), 16686
16687/***/ "./src/js/components/formOpen.js": 16688/*!***************************************!*\ 16689 !*** ./src/js/components/formOpen.js ***! 16690 \***************************************/ 16691/*! exports provided: init */ 16692/***/ (function(module, __webpack_exports__, __webpack_require__) { 16693 16694"use strict"; 16695__webpack_require__.r(__webpack_exports__); 16696/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16697/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16698/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16699 16700 16701var init = function init() { 16702 16703 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('change', '.f-open__inp[type="checkbox"]', function (e) { 16704 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16705 $closest = $this.closest('.f-open'), 16706 $box = $closest.find('.f-open__box'); 16707 16708 if ($this.is(':checked')) { 16709 if (e.isTrigger) { 16710 $box.show(); 16711 } else { 16712 $box.slideDown(); 16713 } 16714 } else { 16715 if (e.isTrigger) { 16716 $box.hide(); 16717 } else { 16718 $box.slideUp(); 16719 } 16720 } 16721 }).on('click', '.f-open__link', function (e) { 16722 e.preventDefault(); 16723 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16724 $closest = $this.closest('.f-open'), 16725 $box = $closest.find('.f-open__box'); 16726 16727 if ($box.is(':visible')) { 16728 $box.slideUp(); 16729 } else { 16730 $box.slideDown(); 16731 } 16732 }).on('change', '.f-open__inp[type="radio"]', function (e) { 16733 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16734 $closest = $this.closest('.f-open'), 16735 $box = $closest.find('.f-open__box'); 16736 16737 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.f-open__box').slideUp(); 16738 16739 if ($this.is(':checked')) { 16740 if (e.isTrigger) { 16741 $box.show(); 16742 } else { 16743 $box.slideDown(); 16744 } 16745 } 16746 }); 16747 16748 // trigger 16749 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.f-open__inp').trigger('change'); 16750}; 16751 16752/***/ }), 16753
16754/***/ "./src/js/components/headerBasket.js": 16755/*!*******************************************!*\ 16756 !*** ./src/js/components/headerBasket.js ***! 16757 \*******************************************/ 16758/*! exports provided: ajaxifyBasket, init */ 16759/***/ (function(module, __webpack_exports__, __webpack_require__) { 16760 16761"use strict"; 16762__webpack_require__.r(__webpack_exports__); 16763/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ajaxifyBasket", function() { return ajaxifyBasket; }); 16764/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16765/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16766/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16767 16768 16769function ajaxifyBasket() { 16770 var $headerRoot = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#headerBasket'); 16771 jquery__WEBPACK_IMPORTED_MODULE_0___default()('#headerBasket form, #headerBasket a.js-ajaxifiable').ajaxify({ 16772 refresh: ['#headerBasket'], 16773 history: false, 16774 onStart: function onStart() { 16775 $headerRoot.addClass('b-basket--loading-in-progress'); 16776 }, 16777 onFinish: function onFinish() { 16778 $headerRoot.removeClass('b-basket--loading-in-progress'); 16779 ajaxifyBasket(); 16780 } 16781 }); 16782}; 16783 16784function init() { 16785 jquery__WEBPACK_IMPORTED_MODULE_0___default()(function () { 16786 ajaxifyBasket(); 16787 }); 16788} 16789 16790/***/ }), 16791
16792/***/ "./src/js/components/headerCartRefresh.js": 16793/*!************************************************!*\ 16794 !*** ./src/js/components/headerCartRefresh.js ***! 16795 \************************************************/ 16796/*! exports provided: default */ 16797/***/ (function(module, __webpack_exports__, __webpack_require__) { 16798 16799"use strict"; 16800__webpack_require__.r(__webpack_exports__); 16801/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return headerCartRefresh; }); 16802/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16803/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16804/* harmony import */ var _headerBasket__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./headerBasket */ "./src/js/components/headerBasket.js"); 16805 16806 16807 16808function headerCartRefresh() { 16809 16810 var targetUrl = 'eshop-kosik.html'; 16811 var refreshes = ['.header__basket']; 16812 16813 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.get(targetUrl).done(function (response) { 16814 16815 var $parsedResponse = jquery__WEBPACK_IMPORTED_MODULE_0___default()(response); 16816 16817 var _iteratorNormalCompletion = true; 16818 var _didIteratorError = false; 16819 var _iteratorError = undefined; 16820 16821 try { 16822 for (var _iterator = refreshes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 16823 var refreshSelector = _step.value; 16824 16825 var newSource = $parsedResponse.find(refreshSelector); 16826 var targetPlace = jquery__WEBPACK_IMPORTED_MODULE_0___default()(refreshSelector); 16827 if (newSource.length === 1 && targetPlace.length === 1) { 16828 targetPlace.html(newSource.html()); 16829 setTimeout(function () { 16830 Object(_headerBasket__WEBPACK_IMPORTED_MODULE_1__["ajaxifyBasket"])(); 16831 }, 0); 16832 } else { 16833 console.error('Can\'t ajax-refresh this:', refreshSelector, 'newSource.length', newSource.length, 'targetPlace.length', targetPlace.length); 16834 } 16835 } 16836 } catch (err) { 16837 _didIteratorError = true; 16838 _iteratorError = err; 16839 } finally { 16840 try { 16841 if (!_iteratorNormalCompletion && _iterator.return) { 16842 _iterator.return(); 16843 } 16844 } finally { 16845 if (_didIteratorError) { 16846 throw _iteratorError; 16847 } 16848 } 16849 } 16850 }); 16851}; 16852 16853window['headerCartRefresh'] = headerCartRefresh; 16854 16855/***/ }), 16856
16857/***/ "./src/js/components/inpCount.js": 16858/*!***************************************!*\ 16859 !*** ./src/js/components/inpCount.js ***! 16860 \***************************************/ 16861/*! exports provided: init */ 16862/***/ (function(module, __webpack_exports__, __webpack_require__) { 16863 16864"use strict"; 16865__webpack_require__.r(__webpack_exports__); 16866/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16867/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16868/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16869 16870 16871var init = function init() { 16872 16873 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.inp-count__item', function (e) { 16874 e.preventDefault(); 16875 16876 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16877 $closest = $this.closest('.inp-count'), 16878 $inp = $closest.find('.inp-text'), 16879 val = Number($inp.val()) + $this.data('step'); 16880 16881 if (val > 0) { 16882 $inp.val(val); 16883 $inp.trigger('input'); 16884 } 16885 }).on('change', '.inp-text', function () { 16886 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16887 val = Number($this.val()); 16888 16889 if (val < 0) { 16890 $this.val(1); 16891 $this.trigger('input'); 16892 } 16893 }); 16894}; 16895 16896/***/ }), 16897
16898/***/ "./src/js/components/inputDebouncedSubmit.js": 16899/*!***************************************************!*\ 16900 !*** ./src/js/components/inputDebouncedSubmit.js ***! 16901 \***************************************************/ 16902/*! exports provided: init */ 16903/***/ (function(module, __webpack_exports__, __webpack_require__) { 16904 16905"use strict"; 16906__webpack_require__.r(__webpack_exports__); 16907/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16908/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16909/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16910/* harmony import */ var _tools_debounce_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../tools/debounce.js */ "./src/js/tools/debounce.js"); 16911/* harmony import */ var _tools_debounce_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_tools_debounce_js__WEBPACK_IMPORTED_MODULE_1__); 16912 16913 16914 16915var init = function init() { 16916 16917 var submitSomeForm = function submitSomeForm(formElement) { 16918 formElement.submit(); 16919 }; 16920 16921 var debouncedSubmit = _tools_debounce_js__WEBPACK_IMPORTED_MODULE_1__(submitSomeForm, 750); 16922 16923 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('input', '.js-input-debounced-submit', function () { 16924 var $field = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 16925 var $form = $field.closest('form'); 16926 debouncedSubmit($form); 16927 }); 16928}; 16929 16930/***/ }), 16931
16932/***/ "./src/js/components/linkSlide.js": 16933/*!****************************************!*\ 16934 !*** ./src/js/components/linkSlide.js ***! 16935 \****************************************/ 16936/*! exports provided: init */ 16937/***/ (function(module, __webpack_exports__, __webpack_require__) { 16938 16939"use strict"; 16940__webpack_require__.r(__webpack_exports__); 16941/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16942/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16943/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16944/* harmony import */ var _tools_MQ__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../tools/MQ */ "./src/js/tools/MQ.js"); 16945 16946 16947 16948var init = function init($slider) { 16949 16950 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-link-slide', function (e) { 16951 e.preventDefault(); 16952 16953 if (Object(_tools_MQ__WEBPACK_IMPORTED_MODULE_1__["MQ"])('mdUp')) { 16954 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body, html').animate({ 16955 scrollTop: jquery__WEBPACK_IMPORTED_MODULE_0___default()(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('href')).offset().top - jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-fixed').outerHeight() - 16 16956 }, 500, 'linear'); 16957 } else { 16958 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body, html').animate({ 16959 scrollTop: jquery__WEBPACK_IMPORTED_MODULE_0___default()(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('href')).offset().top - 16 16960 }, 500, 'linear'); 16961 } 16962 }); 16963}; 16964 16965/***/ }), 16966
16967/***/ "./src/js/components/menuMain.js": 16968/*!***************************************!*\ 16969 !*** ./src/js/components/menuMain.js ***! 16970 \***************************************/ 16971/*! exports provided: init */ 16972/***/ (function(module, __webpack_exports__, __webpack_require__) { 16973 16974"use strict"; 16975__webpack_require__.r(__webpack_exports__); 16976/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 16977/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 16978/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 16979 16980 16981var init = function init() { 16982 16983 // hide items into responsive menu 16984 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-responsive').each(function () { 16985 var $menuResponsive = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 16986 $menuResponsiveItems = $menuResponsive.find('.m-responsive__item'), 16987 $closest = $menuResponsive.closest('.header__menu'), 16988 $wrap = $closest.find('.header__menu-wrap'), 16989 $menuMain = $closest.find('.m-main'), 16990 $menuMainItems = $menuMain.find('.m-main__item'); 16991 16992 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize.menuMain', function () { 16993 //console.log('resize'); 16994 $wrap.removeClass('is-visible'); 16995 $menuMainItems.removeClass('is-invisible'); 16996 $menuResponsiveItems.removeClass('is-visible'); 16997 $menuResponsive.removeClass('is-visible'); 16998 16999 if ($wrap.width() < $menuMain.width()) { 17000 $menuResponsive.addClass('is-visible'); 17001 } 17002 17003 $menuMainItems.each(function () { 17004 var $that = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 17005 /*console.log($that); 17006 console.log($that.position().left); 17007 console.log(($that.position().left + $that.width())); 17008 console.log(($wrap.width() - $menuResponsive.filter(':visible').width())); 17009 console.log(($that.position().left + $that.width()) > ($wrap.width() - $menuResponsive.filter(':visible').width()) );*/ 17010 if ($that.position().left + $that.width() > $wrap.width() - $menuResponsive.filter(':visible').width()) { 17011 $that.addClass('is-invisible'); 17012 $menuResponsiveItems.eq($that.index()).addClass('is-visible'); 17013 } 17014 }); 17015 17016 $wrap.addClass('is-visible'); 17017 }); 17018 }); 17019 17020 // hide items in .m-all menu 17021 // $('.m-all').each(function () { 17022 // var $this = $(this), 17023 // $closest = $this.closest('.header__menu'), 17024 // $wrap = $closest.find('.header__menu-wrap'), 17025 // $menuMain = $closest.find('.m-main'), 17026 // $menuMainItems = $menuMain.find('.m-main__item'); 17027 17028 // $(window).on('resize.menuAll', function () { 17029 // $wrap.removeClass('is-visible'); 17030 // $menuMainItems.removeClass('is-invisible'); 17031 17032 // $menuMainItems.each(function () { 17033 // var $that = $(this); 17034 // if (($that.position().left + $that.width()) > $wrap.width()) { 17035 // $that.addClass('is-invisible'); 17036 // } 17037 // }); 17038 17039 // $wrap.addClass('is-visible'); 17040 // }); 17041 // }); 17042 17043 // submenu width fix 17044 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-submenu--full:not(.m-submenu--side)').each(function () { 17045 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17046 $closest = $this.closest('.row-main'); 17047 17048 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize.menuSide', function () { 17049 $this.css('margin-left', 0); 17050 $this.css('margin-left', $closest.offset().left - $this.offset().left + Number($closest.css('paddingLeft').split('px')[0])); 17051 }); 17052 }); 17053 17054 // delegate 17055 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document) 17056 // all categories 17057 .on('click', '.m-main__item--all .m-main__link', function (e) { 17058 e.preventDefault(); 17059 17060 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17061 $closest = $this.closest('.m-main__item--all'); 17062 17063 $closest.toggleClass('is-open'); 17064 }) 17065 // responsive menu 17066 .on('click', '.m-responsive__title', function (e) { 17067 e.preventDefault(); 17068 17069 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17070 $closest = $this.closest('.m-responsive'); 17071 17072 $closest.toggleClass('is-open'); 17073 }) 17074 // touch click 17075 .on('click', '.m-main__item:not(.m-main__item--all) .m-main__link:not(.is-cl
17075ickable), .m-all__link:not(.is-clickable)', function (e) { 17076 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').hasClass('touchevents')) { 17077 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17078 $closest = $this.parent(), 17079 $submenu = $closest.find('.m-submenu'); 17080 17081 if ($submenu.length) { 17082 e.preventDefault(); 17083 $this.addClass('is-clickable'); 17084 $closest.addClass('is-hover'); 17085 } 17086 } 17087 }) 17088 // out click 17089 .on('click', function (e) { 17090 17091 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.m-main__item--all').length) { 17092 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-main__item--all').removeClass('is-open'); 17093 } 17094 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.m-responsive').length) { 17095 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-responsive').removeClass('is-open'); 17096 } 17097 17098 // touch reset 17099 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-main__item').not(jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.m-main__item.is-hover')).removeClass('is-hover').find('.m-main__link').removeClass('is-clickable'); 17100 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-all__item').not(jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.m-all__item.is-hover')).removeClass('is-hover').find('.m-all__link').removeClass('is-clickable'); 17101 }); 17102 17103 // triggers 17104 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).trigger('resize.menuMain'); 17105 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).trigger('resize.menuSide'); 17106 // $(window).trigger('resize.menuAll'); 17107}; 17108 17109/***/ }), 17110
17111/***/ "./src/js/components/menuSection.js": 17112/*!******************************************!*\ 17113 !*** ./src/js/components/menuSection.js ***! 17114 \******************************************/ 17115/*! exports provided: init */ 17116/***/ (function(module, __webpack_exports__, __webpack_require__) { 17117 17118"use strict"; 17119__webpack_require__.r(__webpack_exports__); 17120/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17121/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17122/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17123 17124 17125var init = function init() { 17126 17127 var $links = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-main--fixed .m-main__link, .m-detail--fixed .m-detail__link'); 17128 17129 // Click 17130 $links.on('click', function (e) { 17131 e.preventDefault(); 17132 17133 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body, html').animate({ 17134 scrollTop: jquery__WEBPACK_IMPORTED_MODULE_0___default()(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('href')).offset().top - jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-fixed').outerHeight() - 16 17135 }, 500); 17136 }); 17137 17138 // Anchors corresponding to menu items 17139 var $items = $links.map(function () { 17140 var item = jquery__WEBPACK_IMPORTED_MODULE_0___default()(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('href')); 17141 if (item.length) { 17142 return item; 17143 } 17144 }); 17145 17146 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('scroll', function () { 17147 17148 // Get container scroll position 17149 var fromTop = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).scrollTop(); 17150 17151 // Get id of current scroll item 17152 var cur = $items.map(function () { 17153 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).offset().top + jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).outerHeight() - jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-fixed').outerHeight() >= fromTop) { 17154 return this; 17155 } 17156 }); 17157 17158 // Get the id of the current element 17159 // cur = cur[cur.length-1]; 17160 var id = cur && cur.length ? cur[0].attr('id') : ''; 17161 17162 // Set/remove active class 17163 $links.addClass('is-active'); 17164 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-detail__item').has('.m-detail__link[href="#' + id + '"]').find('.m-detail__link').removeClass('is-active'); 17165 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-detail__item').has('.m-detail__link[href="#' + id + '"]').find('~ .m-detail__item').find('.m-detail__link').removeClass('is-active'); 17166 }); 17167 17168 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).trigger('scroll'); 17169}; 17170 17171/***/ }), 17172
17173/***/ "./src/js/components/menuToggle.js": 17174/*!*****************************************!*\ 17175 !*** ./src/js/components/menuToggle.js ***! 17176 \*****************************************/ 17177/*! exports provided: init */ 17178/***/ (function(module, __webpack_exports__, __webpack_require__) { 17179 17180"use strict"; 17181__webpack_require__.r(__webpack_exports__); 17182/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17183/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17184/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17185 17186 17187var init = function init() { 17188 17189 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-menu__link', function (e) { 17190 e.preventDefault(); 17191 17192 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17193 $menu = $this.closest('.js-menu'), 17194 $parent = $this.closest('.js-menu__item'), 17195 $content = $parent.children('.js-menu__content'); 17196 17197 if ($parent.hasClass('is-opened')) { 17198 $content.slideUp(function () { 17199 $parent.removeClass('is-opened'); 17200 }); 17201 } else { 17202 $content.slideDown(function () { 17203 $parent.addClass('is-opened'); 17204 }); 17205 } 17206 17207 // close other menus of dropdown menu 17208 $menu.find('.m-dropdown__item').not($parent).find('.m-dropdown__content').slideUp(function () { 17209 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).closest('.m-dropdown__item').not($parent).removeClass('is-opened'); 17210 }); 17211 }); 17212}; 17213 17214/***/ }), 17215
17216/***/ "./src/js/components/popupOpen.js": 17217/*!****************************************!*\ 17218 !*** ./src/js/components/popupOpen.js ***! 17219 \****************************************/ 17220/*! exports provided: init */ 17221/***/ (function(module, __webpack_exports__, __webpack_require__) { 17222 17223"use strict"; 17224__webpack_require__.r(__webpack_exports__); 17225/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17226/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17227/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17228/* harmony import */ var _tools_MQ__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../tools/MQ */ "./src/js/tools/MQ.js"); 17229 17230 17231 17232var init = function init() { 17233 17234 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document) 17235 // secondary 17236 .on('click', '.m-secondary__item--submenu .m-secondary__link', function (e) { 17237 e.preventDefault(); 17238 17239 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17240 $other = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-secondary__item--submenu'), 17241 $closest = $this.closest('.m-secondary__item--submenu'), 17242 $popup = $closest.find('.m-popup'); 17243
17244 // fixed width 17245 $popup.removeAttr('style'); 17246 if ($popup.offset().left < 0) { 17247 $popup.width(Math.floor($popup.width() + $popup.offset().left - 20)); 17248 } 17249 17250 // classes 17251 $other.not($closest).removeClass('is-open'); 17252 $closest.toggleClass('is-open'); 17253 }) 17254 // basket 17255 .on('click', '.b-basket__link', function (e) { 17256 if (Object(_tools_MQ__WEBPACK_IMPORTED_MODULE_1__["MQ"])('mdUp')) { 17257 e.preventDefault(); 17258 17259 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17260 $closest = $this.closest('.b-basket'); 17261 17262 $closest.toggleClass('is-open'); 17263 } 17264 }) 17265 // out click 17266 .on('click', function (e) { 17267 17268 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.m-secondary__item--submenu').length) { 17269 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.m-secondary__item--submenu').removeClass('is-open'); 17270 } 17271 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest('.b-basket').length) { 17272 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-basket').removeClass('is-open'); 17273 } 17274 }); 17275}; 17276 17277/***/ }), 17278
17279/***/ "./src/js/components/search.js": 17280/*!*************************************!*\ 17281 !*** ./src/js/components/search.js ***! 17282 \*************************************/ 17283/*! exports provided: init */ 17284/***/ (function(module, __webpack_exports__, __webpack_require__) { 17285 17286"use strict"; 17287__webpack_require__.r(__webpack_exports__); 17288/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17289/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17290/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17291/* harmony import */ var _tools_MQ__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../tools/MQ */ "./src/js/tools/MQ.js"); 17292 17293 17294 17295var init = function init($target) { 17296 17297 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize.search', function () { 17298 var $inp = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.f-search .inp-text'); 17299 17300 if (Object(_tools_MQ__WEBPACK_IMPORTED_MODULE_1__["MQ"])('xlUp') || Object(_tools_MQ__WEBPACK_IMPORTED_MODULE_1__["MQ"])('smUp') && Object(_tools_MQ__WEBPACK_IMPORTED_MODULE_1__["MQ"])('mdDown')) { 17301 $inp.attr('placeholder', $inp.data('placeholder')); 17302 } else { 17303 $inp.attr('placeholder', $inp.data('placeholder-sm')); 17304 } 17305 }); 17306 17307 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).trigger('resize.search'); 17308}; 17309 17310/***/ }), 17311
17312/***/ "./src/js/components/slick.js": 17313/*!************************************!*\ 17314 !*** ./src/js/components/slick.js ***! 17315 \************************************/ 17316/*! exports provided: init */ 17317/***/ (function(module, __webpack_exports__, __webpack_require__) { 17318 17319"use strict"; 17320__webpack_require__.r(__webpack_exports__); 17321/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17322/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17323/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17324/* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! slick-carousel */ "./node_modules/slick-carousel/slick/slick.js"); 17325/* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(slick_carousel__WEBPACK_IMPORTED_MODULE_1__); 17326 17327 17328 17329var init = function init($target) { 17330 17331 $target.find('.c-products--carousel').each(function () { 17332 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17333 $scroll = $this.find('.c-products__scroll'), 17334 $next = $this.find('.c-products__next'), 17335 $prev = $this.find('.c-products__prev'); 17336 17337 $scroll.slick({ 17338 arrow: true, 17339 dots: true, 17340 speed: 500, 17341 slidesToShow: 4, 17342 slidesToScroll: 2, 17343 infinite: true, 17344 prevArrow: $target.find($prev), 17345 nextArrow: $target.find($next), 17346 responsive: [{ 17347 breakpoint: 1000, 17348 settings: { 17349 slidesToShow: 3, 17350 slidesToScroll: 3, 17351 infinite: true, 17352 dots: true 17353 } 17354 }, { 17355 breakpoint: 750, 17356 settings: { 17357 slidesToShow: 2, 17358 slidesToScroll: 2, 17359 infinitie: true, 17360 dots: true 17361 } 17362 }, { 17363 breakpoint: 480, 17364 settings: { 17365 slidesToShow: 1, 17366 slidesToScroll: 1, 17367 infinite: true, 17368 dots: true 17369 } 17370 }] 17371 }); 17372 }).on('breakpoint', function () { 17373 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).find('.icon-svg').each(function () { 17374 var _this = this; 17375 17376 var svg = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).find('> svg').detach(); 17377 setTimeout(function () { 17378 svg.appendTo(_this); 17379 }, 0); 17380 }); 17381 }); 17382 17383 $target.find('.c-promo--carousel').each(function () { 17384 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17385 $scroll = $this.find('.c-promo__list'), 17386 $menuItems = $this.find('.c-promo__menu .m-side__item'), 17387 $progressBar = $this.find('.c-promo__progress-inner'), 17388 $menuArrow = $this.find('.m-side__arrow'), 17389 $menuList = $this.find('.m-side__list'), 17390 time = 5000; 17391 17392 $scroll.slick({ 17393 arrow: false, 17394 dots: false,
17395 prevArrow: false, 17396 nextArrow: false, 17397 speed: 600, 17398 slidesToShow: 1, 17399 slidesToScroll: 1, 17400 responsive: [{ 17401 breakpoint: 1000, 17402 settings: { 17403 dots: true 17404 } 17405 }] 17406 }).on('beforeChange', function (event, slick, currentSlide, nextSlide) { 17407 $menuItems.removeClass('is-active').eq(nextSlide).addClass('is-active'); 17408 17409 var activeItemOffset = $menuItems.eq(nextSlide).offset().top - $menuList.offset().top; 17410 setArrowPosition(activeItemOffset); 17411 resetProgressbar(); 17412 }).on('afterChange', function (event, slick, currentSlide) { 17413 startProgressbar(); 17414 }); 17415 17416 $menuItems.on('click', function (e) { 17417 e.preventDefault(); 17418 $scroll.slick('slickGoTo', jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).index(), function () { 17419 startProgressbar(); 17420 }); 17421 }); 17422 17423 startProgressbar(); 17424 17425 function setArrowPosition(offset) { 17426 $menuArrow.css('transform', 'translateY(' + offset + 'px)'); 17427 } 17428 function startProgressbar() { 17429 resetProgressbar(); 17430 $progressBar.animate({ width: '100%' }, time, 'linear', function () { 17431 $scroll.slick('slickNext'); 17432 }); 17433 } 17434 17435 function resetProgressbar() { 17436 $progressBar.stop().css('width', 0 + '%'); 17437 } 17438 }); 17439}; 17440 17441/***/ }), 17442
17443/***/ "./src/js/components/slider.js": 17444/*!*************************************!*\ 17445 !*** ./src/js/components/slider.js ***! 17446 \*************************************/ 17447/*! exports provided: init */ 17448/***/ (function(module, __webpack_exports__, __webpack_require__) { 17449 17450"use strict"; 17451__webpack_require__.r(__webpack_exports__); 17452/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17453/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17454/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17455/* harmony import */ var wnumb___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! wnumb/ */ "./node_modules/wnumb/wNumb.js"); 17456/* harmony import */ var wnumb___WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(wnumb___WEBPACK_IMPORTED_MODULE_1__); 17457/* harmony import */ var nouislider___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! nouislider/ */ "./node_modules/nouislider/distribute/nouislider.js"); 17458/* harmony import */ var nouislider___WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(nouislider___WEBPACK_IMPORTED_MODULE_2__); 17459 17460 17461 17462 17463var init = function init($target) { 17464 17465 $target.find('.js-slider').each(function () { 17466 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17467 $textFrom = $this.find('.js-slider__text--from'), 17468 $textTo = $this.find('.js-slider__text--to'), 17469 $inpFrom = $this.find('.js-slider__inp--from'), 17470 $inpTo = $this.find('.js-slider__inp--to'), 17471 $slider = $this.find('.js-slider__range').get(0), 17472 start = Number($this.data('start')), 17473 end = Number($this.data('end')), 17474 min = Number($this.data('min')), 17475 max = Number($this.data('max')), 17476 step = Number($this.data('step')), 17477 tooltips = $this.data('tooltips'), 17478 slider = null; 17479 17480 slider = nouislider___WEBPACK_IMPORTED_MODULE_2___default.a.create($slider, { 17481 start: [start, end], 17482 connect: true, 17483 step: step, 17484 tooltips: tooltips, 17485 range: { 17486 'min': min, 17487 'max': max 17488 }, 17489 format: wnumb___WEBPACK_IMPORTED_MODULE_1___default()({ 17490 decimals: 0 17491 }) 17492 }); 17493 17494 $slider.noUiSlider.on('slide', function (values) { 17495 $textFrom.text(values[0]); 17496 $textTo.text(values[1]); 17497 }); 17498 17499 $slider.noUiSlider.on('slide', function (values) { 17500 $inpFrom.val(values[0]).trigger('change'); 17501 $inpTo.val(values[1]).trigger('change'); 17502 }); 17503 17504 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.f-filter__multislider input[type=number]').on('change', function () { 17505 $slider.noUiSlider.updateOptions({ 17506 start: [$inpFrom.val(), $inpTo.val()] 17507 }); 17508 }); 17509 17510 // Ondra - autosubmit 17511 var timeout = null; 17512 var autosubmitNow = function autosubmitNow() { 17513 var $form = $this.closest('form'); 17514 if ($form.is('.js-slider-autosubmit')) { 17515 $form.submit(); 17516 } 17517 }; 17518 $slider.noUiSlider.on('change', function () { 17519 if (timeout) { 17520 clearTimeout(timeout); 17521 timeout = null; 17522 } 17523 timeout = setTimeout(function () { 17524 autosubmitNow(); 17525 }, 750); 17526 }); 17527 $slider.noUiSlider.on('update', function () { 17528 if (timeout) { 17529 clearTimeout(timeout); 17530 timeout = null; 17531 } 17532 }); 17533 }); 17534}; 17535 17536/***/ }), 17537
17538/***/ "./src/js/components/suggest.js": 17539/*!**************************************!*\ 17540 !*** ./src/js/components/suggest.js ***! 17541 \**************************************/ 17542/*! exports provided: init */ 17543/***/ (function(module, __webpack_exports__, __webpack_require__) { 17544 17545"use strict"; 17546__webpack_require__.r(__webpack_exports__); 17547/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17548/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17549/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17550/* harmony import */ var _class_sk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../class/sk */ "./src/js/class/sk.js"); 17551/* harmony import */ var _class_sk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_class_sk__WEBPACK_IMPORTED_MODULE_1__); 17552/* harmony import */ var _class_sk_widgets_Suggest__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../class/sk.widgets.Suggest */ "./src/js/class/sk.widgets.Suggest.js"); 17553/* harmony import */ var _class_sk_widgets_Suggest__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_class_sk_widgets_Suggest__WEBPACK_IMPORTED_MODULE_2__); 17554/* harmony import */ var _class_sk_widgets_SuggestMenu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../class/sk.widgets.SuggestMenu */ "./src/js/class/sk.widgets.SuggestMenu.js"); 17555/* harmony import */ var _class_sk_widgets_SuggestMenu__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_class_sk_widgets_SuggestMenu__WEBPACK_IMPORTED_MODULE_3__); 17556 17557 17558 17559 17560 17561 17562var init = function init($target) { 17563 17564 $target.find('.js-suggest').each(function () { 17565 17566 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17567 $input = $this.find('.js-suggest__inp'); 17568 var minLettersCount = 2; 17569 17570 if($this.hasClass('with-splash-screen')){ 17571 minLettersCount = 2; 17572 } 17573 //var $menu = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div class="b-suggest"></div>').appendTo($this); 17574 var $menu = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div class="b-suggest"></div>').appendTo($this.find('.autocomplete-wrapper')); 17575 17576 var Suggest = new sk.widgets.Suggest($input, { 17577 minLength: minLettersCount, 17578 typeInterval: 250, 17579 url: $this.data('suggest'), 17580 useSplashScreen :$this.hasClass('with-splash-screen') 17581 }); 17582 17583 var SuggestMenu = new sk.widgets.SuggestMenu($menu, Suggest, { 17584 'item': '.js-suggest__item' 17585 }).init(); 17586 17587 jquery__WEBPACK_IMPORTED_MODULE_0___default()(SuggestMenu).on('menuselect', function (e) { 17588 var $item = this.$items.eq(this.selectedIndex - 1); 17589 17590 if ($item.hasClass('js-suggest__item--btn')) { 17591 e.preventDefault(); 17592 17593 $this.submit(); 17594 } else { 17595 window.location = $item.find('a').attr('href'); 17596 } 17597 }); 17598 17599 $this.on('click', '.js-suggest__item--btn a', function (e) { 17600 e.preventDefault(); 17601 17602 $this.submit(); 17603 }); 17604 }); 17605}; 17606 17607/***/ }), 17608
17609/***/ "./src/js/components/tabs-filter.js": 17610/*!******************************************!*\ 17611 !*** ./src/js/components/tabs-filter.js ***! 17612 \******************************************/ 17613/*! exports provided: init */ 17614/***/ (function(module, __webpack_exports__, __webpack_require__) { 17615 17616"use strict"; 17617__webpack_require__.r(__webpack_exports__); 17618/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17619/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17620/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17621 17622 17623var init = function init() { 17624 17625 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-tabs-filter__link', function (e) { 17626 17627 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17628 $item = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.js-transport__inp'), 17629 $closest = $this.closest('.js-tabs-filter'), 17630 $link = $closest.find('.js-tabs-filter__link'), 17631 selector = $this.data('selector'), 17632 $selectorElements = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-tabs *[data-selector="' + selector + '"]'); 17633 17634 if ($this.is('.b-tabs__link')) { 17635 e.preventDefault(); 17636 } 17637 17638 $link.removeClass('is-active'); 17639 $this.addClass('is-active'); 17640 17641 // connects tabs and dropdown menu on responsive 17642 $selectorElements.addClass('is-active'); 17643 $selectorElements.find('.inp-item__inp').change(); 17644 17645 $item.prop('disabled', true).closest('li').hide().addClass('is-hidden'); 17646 17647 $item.filter(selector).prop('disabled', false).closest('li').show().removeClass('is-hidden'); 17648 17649 $item.filter(':disabled:checked').prop('checked', false).closest('li').removeClass('is-checked').find('.f-open__box').slideUp(); 17650 17651 hideFixedBar(); 17652 }).on('click', '.b-ajax .js-fixed-show', function () { 17653 showFixedBar(); 17654 }).on('click', '.b-ajax .js-fixed-hide', function () { 17655 hideFixedBar(); 17656 }); 17657 17658 function showFixedBar() { 17659 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-ajax__fixed').fadeIn().css('display', 'flex').addClass('is-visible'); 17660 } 17661 17662 function hideFixedBar() { 17663 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-ajax__fixed').fadeOut().removeClass('is-visible'); 17664 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.b-ajax .f-open__inp[type="radio"]').prop('checked', false).closest('.f-open').removeClass('is-checked').find('.f-open__box').slideUp(); 17665 } 17666}; 17667 17668/***/ }), 17669
17670/***/ "./src/js/components/tabs.js": 17671/*!***********************************!*\ 17672 !*** ./src/js/components/tabs.js ***! 17673 \***********************************/ 17674/*! exports provided: init */ 17675/***/ (function(module, __webpack_exports__, __webpack_require__) { 17676 17677"use strict"; 17678__webpack_require__.r(__webpack_exports__); 17679/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17680/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17681/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17682 17683 17684var init = function init() { 17685 17686 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-tabs__link', function (e) { 17687 e.preventDefault(); 17688 17689 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17690 $closest = $this.closest('.js-tabs'), 17691 $links = $closest.find('.js-tabs__link'), 17692 $tabs = $closest.find('.js-tabs__fragment'); 17693 17694 $links.removeClass('is-active'); 17695 $this.addClass('is-active'); 17696 17697 $tabs.removeClass('is-active'); 17698 $tabs.filter($this.attr('href')).addClass('is-active'); 17699 }); 17700}; 17701 17702/***/ }), 17703
17704/***/ "./src/js/components/tippy.js": 17705/*!************************************!*\ 17706 !*** ./src/js/components/tippy.js ***! 17707 \************************************/ 17708/*! exports provided: init */ 17709/***/ (function(module, __webpack_exports__, __webpack_require__) { 17710 17711"use strict"; 17712__webpack_require__.r(__webpack_exports__); 17713/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17714/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17715/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17716/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tippy.js */ "./node_modules/tippy.js/dist/tippy.all.js"); 17717/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(tippy_js__WEBPACK_IMPORTED_MODULE_1__); 17718 17719 17720 17721var init = function init() { 17722 17723 tippy_js__WEBPACK_IMPORTED_MODULE_1___default()('.tippy', { 17724 animation: 'shift-toward', 17725 arrow: true, 17726 arrowType: 'sharp', 17727 arrowTransform: 'scaleX(1.3)', 17728 duration: 500, 17729 size: 'large', 17730 placement: 'bottom', 17731 position: 'bottom-start', 17732 theme: 'light', 17733 hideOnClick: false 17734 }); 17735 17736 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.tippy', function (e) { 17737 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is(':not(button)')) { 17738 e.preventDefault(); 17739 } 17740 }); 17741}; 17742 17743/***/ }), 17744
17745/***/ "./src/js/components/toggleAnimate.js": 17746/*!********************************************!*\ 17747 !*** ./src/js/components/toggleAnimate.js ***! 17748 \********************************************/ 17749/*! exports provided: init */ 17750/***/ (function(module, __webpack_exports__, __webpack_require__) { 17751 17752"use strict"; 17753__webpack_require__.r(__webpack_exports__); 17754/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17755/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17756/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17757 17758 17759var init = function init() { 17760 17761 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-toggle-animate__link', function () { 17762 17763 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17764 $generalParent = jquery__WEBPACK_IMPORTED_MODULE_0___default()('js-toggle-animate'), 17765 $parent = $this.closest('.js-toggle-animate'), 17766 $content = $parent.find('.js-toggle-animate__box'); 17767 17768 if ($parent.hasClass('is-open')) { 17769 $content.slideUp(function () { 17770 $parent.removeClass('is-open'); 17771 $content.removeAttr('style'); 17772 }); 17773 } else { 17774 $content.slideDown(function () { 17775 $parent.addClass('is-open'); 17776 }); 17777 } 17778 }); 17779}; 17780 17781/***/ }), 17782
17783/***/ "./src/js/components/toggleClass.js": 17784/*!******************************************!*\ 17785 !*** ./src/js/components/toggleClass.js ***! 17786 \******************************************/ 17787/*! exports provided: init */ 17788/***/ (function(module, __webpack_exports__, __webpack_require__) { 17789 17790"use strict"; 17791__webpack_require__.r(__webpack_exports__); 17792/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17793/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17794/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17795 17796 17797var init = function init() { 17798 17799 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('click', '.js-toggle-class', function (e) { 17800 e.preventDefault(); 17801 17802 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 17803 17804 $this.toggleClass('is-open'); 17805 jquery__WEBPACK_IMPORTED_MODULE_0___default()($this.data('target')).toggleClass($this.data('class')); 17806 }).on('click', '.js-footer__link', function (e) { 17807 e.preventDefault(); 17808 17809 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17810 $footer = $this.closest('.js-footer'), 17811 $parent = $this.closest('.js-footer__item'), 17812 $content = $parent.children('.js-footer__content'); 17813 17814 if ($parent.hasClass('is-open')) { 17815 $content.slideUp(function () { 17816 $parent.removeClass('is-open'); 17817 }); 17818 } else { 17819 $content.slideDown(function () { 17820 $parent.addClass('is-open'); 17821 }); 17822 } 17823 17824 // close other opened items 17825 $footer.find('.js-footer__item').not($parent).find('.js-footer__content').slideUp(function () { 17826 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).closest('.js-footer__item').not($parent).removeClass('is-open'); 17827 }); 17828 }).on('change', '.js-toggle-checked', function (e) { 17829 e.preventDefault(); 17830 17831 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 17832 17833 var $name = $this.attr('name'); 17834 17835 jquery__WEBPACK_IMPORTED_MODULE_0___default()('input[name="' + $name + '"]').closest('li').filter('.is-checked').removeClass('is-checked'); 17836 $this.closest('li').toggleClass('is-checked'); 17837 jquery__WEBPACK_IMPORTED_MODULE_0___default()($this.data('target')).closest('li').toggleClass($this.data('class')); 17838 }); 17839 17840 //$('.js-toggle-checked').trigger('change'); 17841}; 17842 17843/***/ }), 17844
17845/***/ "./src/js/components/top.js": 17846/*!**********************************!*\ 17847 !*** ./src/js/components/top.js ***! 17848 \**********************************/ 17849/*! exports provided: init */ 17850/***/ (function(module, __webpack_exports__, __webpack_require__) { 17851 17852"use strict"; 17853__webpack_require__.r(__webpack_exports__); 17854/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17855/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17856/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17857 17858 17859var init = function init() { 17860 17861 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('scroll', function (e) { 17862 e.preventDefault(); 17863 17864 var $scroll = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).scrollTop(); 17865 17866 if ($scroll > 300) { 17867 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.top').fadeIn(); 17868 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.top').css('display', 'flex'); 17869 } else { 17870 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.top').fadeOut(); 17871 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.top').css('display', 'none'); 17872 } 17873 }); 17874}; 17875 17876/***/ }), 17877
17878/***/ "./src/js/components/transportPayment.js": 17879/*!***********************************************!*\ 17880 !*** ./src/js/components/transportPayment.js ***! 17881 \***********************************************/ 17882/*! exports provided: init */ 17883/***/ (function(module, __webpack_exports__, __webpack_require__) { 17884 17885"use strict"; 17886__webpack_require__.r(__webpack_exports__); 17887/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "init", function() { return init; }); 17888/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 17889/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 17890 17891 17892var init = function init() { 17893 17894 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).on('change changeInit', '.js-transport__inp', function (e) { 17895 var $this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 17896 $item = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.js-payment__inp'), 17897 selector = jquery__WEBPACK_IMPORTED_MODULE_0___default()($this.data('selector')); 17898 17899 if (e.type != 'changeInit' || e.type == 'changeInit' && $this.is(':checked')) { 17900 $item.prop('disabled', true).closest('li').addClass('is-disabled').find('.f-open__box').slideUp(); 17901 17902 $item.filter(selector).prop('disabled', false).closest('li').removeClass('is-disabled'); 17903 17904 $item.filter(':disabled:checked').prop('checked', false).closest('li').removeClass('is-checked'); 17905 } 17906 }); 17907 17908 // trigger 17909 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.js-transport__inp').trigger('changeInit'); 17910}; 17911 17912/***/ }), 17913
17914/***/ "./src/js/tools/MQ.js": 17915/*!****************************!*\ 17916 !*** ./src/js/tools/MQ.js ***! 17917 \****************************/ 17918/*! exports provided: MQ, getDevices, showDevices, getBreakpoint, notify */ 17919/***/ (function(module, __webpack_exports__, __webpack_require__) { 17920 17921"use strict"; 17922__webpack_require__.r(__webpack_exports__); 17923/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MQ", function() { return MQ; }); 17924/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDevices", function() { return getDevices; }); 17925/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showDevices", function() { return showDevices; }); 17926/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBreakpoint", function() { return getBreakpoint; }); 17927/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "notify", function() { return notify; }); 17928/* harmony import */ var _css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../css/media-queries.json */ "./src/css/media-queries.json"); 17929var _css_media_queries_json__WEBPACK_IMPORTED_MODULE_0___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../../css/media-queries.json */ "./src/css/media-queries.json", 1); 17930 17931 17932var MQ = function MQ(device) { 17933 var devices = getDevices(); 17934 var query = devices.find(function (item) { 17935 return item.device === device; 17936 }); 17937 17938 var showWarning = function showWarning() { 17939 notify('Device "' + device + '" doesn\'t exist! Use one of the devices below.', 'warning'); 17940 showDevices(); 17941 }; 17942 17943 if (query) { 17944 var breakpoint = query.breakpoint; 17945 var media = breakpoint; 17946 17947 query = device.split(/(?=Down|Up)/); 17948 17949 if (query[1]) { 17950 switch (query[1]) { 17951 case 'Up': 17952 media = '(min-width: ' + breakpoint + 'px)'; 17953 break; 17954 case 'Down': 17955 media = '(max-width: ' + (breakpoint - 1) + 'px)'; 17956 break; 17957 default: 17958 showWarning(); 17959 17960 return false; 17961 } 17962 } 17963 17964 return window.matchMedia(media).matches; 17965 } else { 17966 showWarning(); 17967 17968 return false; 17969 } 17970}; 17971 17972var getDevices = function getDevices() { 17973 return Object.keys(_css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__).reduce(function (acc, group) { 17974 if (group === 'breakpoints') { 17975 Object.keys(_css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__[group]).map(function (device) { 17976 acc.push({ 17977 device: device + 'Down', 17978 breakpoint: parseInt(_css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__[group][device] - 1) 17979 }); 17980 acc.push({ 17981 device: device + 'Up', 17982 breakpoint: parseInt(_css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__[group][device]) 17983 }); 17984 }); 17985 } else { 17986 Object.keys(_css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__[group]).map(function (device) { 17987 acc.push({ 17988 device: device, 17989 breakpoint: _css_media_queries_json__WEBPACK_IMPORTED_MODULE_0__[group][device] 17990 }); 17991 }); 17992 } 17993 17994 return acc; 17995 }, []); 17996}; 17997 17998var showDevices = function showDevices() { 17999 var devices = getDevices(); 18000 18001 if (console.table) { 18002 console.table(devices); 18003 } else { 18004 console.log(devices.map(function (item) { 18005 return item.device + ': ' + item.breakpoint; 18006 })); 18007 } 18008}; 18009 18010var getBreakpoint = function getBreakpoint(device) { 18011 var devices = getDevices(); 18012 var query = devices.find(function (item) { 18013 return item.device === device; 18014 }); 18015 18016 return query && query.breakpoint || 0; 18017}; 18018 18019var notify = function notify(message, type) { 18020 if (type === 'warning') { 18021 console.log('%c' + message, 'font-weight: bold; font-size: 16px; color: red'); 18022 } 18023}; 18024 18025/***/ }), 18026
18027/***/ "./src/js/tools/debounce.js": 18028/*!**********************************!*\ 18029 !*** ./src/js/tools/debounce.js ***! 18030 \**********************************/ 18031/*! no static exports found */ 18032/***/ (function(module, exports) { 18033 18034/** 18035 * Returns a function, that, as long as it continues to be invoked, will not 18036 * be triggered. The function will be called after it stops being called for 18037 * N milliseconds. If `immediate` is passed, trigger the function on the 18038 * leading edge, instead of the trailing. The function also has a property 'clear' 18039 * that is a function which will clear the timer to prevent previously scheduled executions. 18040 * 18041 * @source underscore.js 18042 * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ 18043 * @param {Function} function to wrap 18044 * @param {Number} timeout in ms (`100`) 18045 * @param {Boolean} whether to execute at the beginning (`false`) 18046 * @api public 18047 */ 18048function debounce(func, wait, immediate) { 18049 var timeout, args, context, timestamp, result; 18050 if (null == wait) wait = 100; 18051 18052 function later() { 18053 var last = Date.now() - timestamp; 18054 18055 if (last < wait && last >= 0) { 18056 timeout = setTimeout(later, wait - last); 18057 } else { 18058 timeout = null; 18059 if (!immediate) { 18060 result = func.apply(context, args); 18061 context = args = null; 18062 } 18063 } 18064 }; 18065 18066 var debounced = function debounced() { 18067 context = this; 18068 args = arguments; 18069 timestamp = Date.now(); 18070 var callNow = immediate && !timeout; 18071 if (!timeout) timeout = setTimeout(later, wait); 18072 if (callNow) { 18073 result = func.apply(context, args); 18074 context = args = null; 18075 } 18076 18077 return result; 18078 }; 18079 18080 debounced.clear = function () { 18081 if (timeout) { 18082 clearTimeout(timeout); 18083 timeout = null; 18084 } 18085 }; 18086 18087 debounced.flush = function () { 18088 if (timeout) { 18089 result = func.apply(context, args); 18090 context = args = null; 18091 18092 clearTimeout(timeout); 18093 timeout = null; 18094 } 18095 }; 18096 18097 return debounced; 18098}; 18099 18100// Adds compatibility for ES modules 18101debounce.debounce = debounce; 18102 18103module.exports = debounce; 18104 18105/***/ }), 18106
18107/***/ "./src/js/tools/svg4everybody.js": 18108/*!***************************************!*\ 18109 !*** ./src/js/tools/svg4everybody.js ***! 18110 \***************************************/ 18111/*! no static exports found */ 18112/***/ (function(module, exports, __webpack_require__) { 18113 18114var newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/; 18115var webkitUA = /\bAppleWebKit\/(\d+)\b/; 18116var olderEdgeUA = /\bEdge\/12\.(\d+)\b/; 18117var edgeUA = /\bEdge\/.(\d+)\b/; 18118//Checks whether iframed 18119var inIframe = window.top !== window.self; 18120 18121if (newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe) { 18122 __webpack_require__.e(/*! import() | svg4everybody */ "svg4everybody").then(__webpack_require__.t.bind(null, /*! svg4everybody */ "./node_modules/svg4everybody/dist/svg4everybody.js", 7)).then(function (svg) { 18123 svg.default(); 18124 }); 18125} 18126 18127/***/ })
18127, 18128 18129/***/ "jquery": 18130/*!*************************!*\ 18131 !*** external "jQuery" ***! 18132 \*************************/ 18133/*! no static exports found */ 18134/***/ (function(module, exports) { 18135 18136module.exports = jQuery; 18137 18138/***/ }) 18139 18140/******/ }); 18141//# sourceMappingURL=app.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.