vendor: 3,594 bytes, lines 1-88
1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40/******/ } 41/******/ }; 42/******/ 43/******/ // define __esModule on exports 44/******/ __webpack_require__.r = function(exports) { 45/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47/******/ } 48/******/ Object.defineProperty(exports, '__esModule', { value: true }); 49/******/ }; 50/******/ 51/******/ // create a fake namespace object 52/******/ // mode & 1: value is a module id, require it 53/******/ // mode & 2: merge all properties of value into the ns 54/******/ // mode & 4: return value when already ns object 55/******/ // mode & 8|1: behave like require 56/******/ __webpack_require__.t = function(value, mode) { 57/******/ if(mode & 1) value = __webpack_require__(value); 58/******/ if(mode & 8) return value; 59/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60/******/ var ns = Object.create(null); 61/******/ __webpack_require__.r(ns); 62/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64/******/ return ns; 65/******/ }; 66/******/ 67/******/ // getDefaultExport function for compatibility with non-harmony modules 68/******/ __webpack_require__.n = function(module) { 69/******/ var getter = module && module.__esModule ? 70/******/ function getDefault() { return module['default']; } : 71/******/ function getModuleExports() { return module; }; 72/******/ __webpack_require__.d(getter, 'a', getter); 73/******/ return getter; 74/******/ }; 75/******/ 76/******/ // Object.prototype.hasOwnProperty.call 77/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78/******/ 79/******/ // __webpack_public_path__ 80/******/ __webpack_require__.p = ""; 81/******/ 82/******/ 83/******/ // Load entry module and return exports 84/******/ return __webpack_require__(__webpack_require__.s = 0); 85/******/ }) 86/************************************************************************/ 87/******/ ({ 88
vendor: 369,330 bytes, lines 89-11871
89/***/ "./node_modules/foundation-sites/dist/js/foundation.esm.js": 90/*!*****************************************************************!*\ 91 !*** ./node_modules/foundation-sites/dist/js/foundation.esm.js ***! 92 \*****************************************************************/ 93/*! exports provided: default, CoreUtils, Core, Box, onImagesLoaded, Keyboard, MediaQuery, Motion, Move, Nest, Timer, Touch, Triggers, Abide, Accordion, AccordionMenu, Drilldown, Dropdown, DropdownMenu, Equalizer, Interchange, Magellan, OffCanvas, Orbit, ResponsiveMenu, ResponsiveToggle, Reveal, Slider, SmoothScroll, Sticky, Tabs, Toggler, Tooltip, ResponsiveAccordionTabs, Foundation */ 94/***/ (function(module, __webpack_exports__, __webpack_require__) { 95 96"use strict"; 97__webpack_require__.r(__webpack_exports__); 98/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CoreUtils", function() { return foundation_core_utils; }); 99/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Core", function() { return Foundation; }); 100/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Box", function() { return Box; }); 101/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onImagesLoaded", function() { return onImagesLoaded; }); 102/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Keyboard", function() { return Keyboard; }); 103/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MediaQuery", function() { return MediaQuery; }); 104/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Motion", function() { return Motion; }); 105/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Move", function() { return Move; }); 106/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Nest", function() { return Nest; }); 107/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timer", function() { return Timer; }); 108/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Touch", function() { return Touch; }); 109/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Triggers", function() { return Triggers; }); 110/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Abide", function() { return Abide; }); 111/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Accordion", function() { return Accordion; }); 112/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AccordionMenu", function() { return AccordionMenu; }); 113/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Drilldown", function() { return Drilldown; }); 114/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Dropdown", function() { return Dropdown; }); 115/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DropdownMenu", function() { return DropdownMenu; }); 116/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Equalizer", function() { return Equalizer; }); 117/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Interchange", function() { return Interchange; }); 118/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Magellan", function() { return Magellan; }); 119/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OffCanvas", function() { return OffCanvas; }); 120/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Orbit", function() { return Orbit; }); 121/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ResponsiveMenu", function() { return ResponsiveMenu; }); 122/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ResponsiveToggle", function() { return ResponsiveToggle; }); 123/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Reveal", function() { return Reveal; }); 124/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Slider", function() { return Slider; }); 125/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SmoothScroll", function() { return SmoothScroll; }); 126/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sticky", function() { return Sticky; }); 127/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tabs", function() { return Tabs; }); 128/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Toggler", function() { return Toggler; }); 129/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tooltip", function() { return Tooltip; }); 130/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ResponsiveAccordionTabs", function() { return ResponsiveAccordionTabs; }); 131/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Foundation", function() { return Foundation; }); 132/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 133/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 134function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); } 135 136 137 138function _typeof(obj) { 139 if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") { 140 _typeof = function _typeof(obj) { 141 return _typeof2(obj); 142 }; 143 } else { 144 _typeof = function _typeof(obj) { 145 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj); 146 }; 147 } 148 149 return _typeof(obj); 150} 151 152function _classCallCheck(instance, Constructor) { 153 if (!(instance instanceof Constructor)) { 154 throw new TypeError("Cannot call a class as a function"); 155 } 156} 157 158function _defineProperties(target, props) { 159 for (var i = 0; i < props.length; i++) { 160 var descriptor = props[i]; 161 descriptor.enumerable = descriptor.enumerable || false; 162 descriptor.configurable = true; 163 if ("value" in descriptor) descriptor.writable = true; 164 Object.defineProperty(target, descriptor.key, descriptor); 165 } 166} 167 168function _createClass(Constructor, protoProps, staticProps) { 169 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 170 if (staticProps) _defineProperties(Constructor, staticProps); 171 return Constructor; 172} 173 174function _inherits(subClass, superClass) { 175 if (typeof superClass !== "function" && superClass !== null) { 176 throw new TypeError("Super expression must either be null or a function"); 177 } 178 179 subClass.prototype = Object.create(superClass && superClass.prototype, { 180 constructor: { 181 value: subClass, 182 writable: true, 183 configurable: true 184 } 185 }); 186 if (superClass) _setPrototypeOf(subClass, superClass); 187} 188 189function _getPrototypeOf(o) { 190 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 191 return o.__proto__ || Object.getPrototypeOf(o); 192 }; 193 return _getPrototypeOf(o); 194} 195 196function _setPrototypeOf(o, p) { 197 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 198 o.__proto__ = p; 199 return o; 200 }; 201 202 return _setPrototypeOf(o, p); 203} 204 205function _assertThisInitialized(self) { 206 if (self === void 0) { 207 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 208 } 209 210 return self; 211} 212 213function _possibleConstructorReturn(self, call) { 214 if (call && (_typeof2(call) === "object" || typeof call === "function")) { 215 return call; 216 } 217 218 return _assertThisInitialized(self); 219} 220 221function _superPropBase(object, property) { 222 while (!Object.prototype.hasOwnProperty.call(object, property)) { 223 object = _getPrototypeOf(object); 224 if (object === null) break; 225 } 226 227 return object; 228} 229 230function _get(target, property, receiver) { 231 if (typeof Reflect !== "undefined" && Reflect.get) { 232 _get = Reflect.get; 233 } else { 234 _get = function _get(target, property, receiver) { 235 var base = _superPropBase(target, property); 236 237 if (!base) return; 238 var desc = Object.getOwnPropertyDescriptor(base, property); 239 240 if (desc.get) { 241 return desc.get.call(receiver); 242 } 243 244 return desc.value; 245 }; 246 } 247 248 return _get(target, property, receiver || target); 249} 250/** 251 * Returns a boolean for RTL support 252 */ 253 254 255function rtl() { 256 return jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').attr('dir') === 'rtl'; 257} 258/** 259 * returns a random base-36 uid with namespacing 260 * @function 261 * @param {Number} length - number of random base-36 digits desired. Increase for more random strings. 262 * @param {String} namespace - name of plugin to be incorporated in uid, optional. 263 * @default {String} '' - if no plugin name is provided, nothing is appended to the uid. 264 * @returns {String} - unique id 265 */ 266 267 268function GetYoDigits(length, namespace) { 269 length = length || 6; 270 return Math.round(Math.pow(36, length + 1) - Math.random() * Math.pow(36, length)).toString(36).slice(1) + (namespace ? "-".concat(namespace) : ''); 271} 272/** 273 * Escape a string so it can be used as a regexp pattern 274 * @function 275 * @see https://stackoverflow.com/a/9310752/4317384 276 * 277 * @param {String} str - string to escape. 278 * @returns {String} - escaped string 279 */ 280 281 282function RegExpEscape(str) { 283 return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); 284} 285 286function transitionend($elem) { 287 var transitions = { 288 'transition': 'transitionend', 289 'WebkitTransition': 'webkitTransitionEnd', 290 'MozTransition': 'transitionend', 291 'OTransition': 'otransitionend' 292 }; 293 var elem = document.createElement('div'), 294 end; 295 296 for (var t in transitions) { 297 if (typeof elem.style[t] !== 'undefined') { 298 end = transitions[t]; 299 } 300 } 301 302 if (end) { 303 return end; 304 } else { 305 end = setTimeout(function () { 306 $elem.triggerHandler('transitionend', [$elem]); 307 }, 1); 308 return 'transitionend'; 309 } 310} 311/** 312 * Return an event type to listen for window load. 313 * 314 * If `$elem` is passed, an event will be triggered on `$elem`. If window is already loaded, the event will still be triggered. 315 * If `handler` is passed, attach it to the event on `$elem`. 316 * Calling `onLoad` without handler allows you to get the event type that will be triggered before attaching the handler by yourself. 317 * @function 318 * 319 * @param {Object} [] $elem - jQuery element on which the event will be triggered if passed. 320 * @param {Function} [] handler - function to attach to the event. 321 * @returns {String} - event type that should or will be triggered. 322 */ 323 324 325function onLoad($elem, handler) { 326 var didLoad = document.readyState === 'complete'; 327 var eventType = (didLoad ? '_didLoad' : 'load') + '.zf.util.onLoad'; 328 329 var cb = function cb() { 330 return $elem.triggerHandler(eventType); 331 }; 332 333 if ($elem) { 334 if (handler) $elem.one(eventType, handler); 335 if (didLoad) setTimeout(cb);else jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).one('load', cb); 336 } 337 338 return eventType; 339} 340/** 341 * Retuns an handler for the `mouseleave` that ignore disappeared mouses. 342 * 343 * If the mouse "disappeared" from the document (like when going on a browser UI element, See https://git.io/zf-11410), 344 * the event is ignored. 345 * - If the `ignoreLeaveWindow` is `true`, the event is ignored when the user actually left the window 346 * (like by switching to an other window with [Alt]+[Tab]). 347 * - If the `ignoreReappear` is `true`, the event will be ignored when the mouse will reappear later on the document 348 * outside of the element it left. 349 * 350 * @function 351 * 352 * @param {Function} [] handler - handler for the filtered `mouseleave` event to watch. 353 * @param {Object} [] options - object of options: 354 * - {Boolean} [false] ignoreLeaveWindow - also ignore when the user switched windows. 355 * - {Boolean} [false] ignoreReappear - also ignore when the mouse reappeared outside of the element it left. 356 * @returns {Function} - filtered handler to use to listen on the `mouseleave` event. 357 */ 358 359 360function ignoreMousedisappear(handler) { 361 var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 362 _ref$ignoreLeaveWindo = _ref.ignoreLeaveWindow, 363 ignoreLeaveWindow = _ref$ignoreLeaveWindo === void 0 ? false : _ref$ignoreLeaveWindo, 364 _ref$ignoreReappear = _ref.ignoreReappear, 365 ignoreReappear = _ref$ignoreReappear === void 0 ? false : _ref$ignoreReappear; 366 367 return function leaveEventHandler(eLeave) { 368 for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 369 rest[_key - 1] = arguments[_key]; 370 } 371 372 var callback = handler.bind.apply(handler, [this, eLeave].concat(rest)); // The mouse left: call the given callback if the mouse entered elsewhere 373 374 if (eLeave.relatedTarget !== null) { 375 return callback(); 376 } // Otherwise, check if the mouse actually left the window. 377 // In firefox if the user switched between windows, the window sill have the focus by the time 378 // the event is triggered. We have to debounce the event to test this case. 379 380 381 setTimeout(function leaveEventDebouncer() { 382 if (!ignoreLeaveWindow && document.hasFocus && !document.hasFocus()) { 383 return callback(); 384 } // Otherwise, wait for the mouse to reeapear outside of the element, 385 386 387 if (!ignoreReappear) { 388 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).one('mouseenter', function reenterEventHandler(eReenter) { 389 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(eLeave.currentTarget).has(eReenter.target).length) { 390 // Fill where the mouse finally entered. 391 eLeave.relatedTarget = eReenter.target; 392 callback(); 393 } 394 }); 395 } 396 }, 0); 397 }; 398} 399 400var foundation_core_utils = 401/*#__PURE__*/ 402Object.freeze({ 403 rtl: rtl, 404 GetYoDigits: GetYoDigits, 405 RegExpEscape: RegExpEscape, 406 transitionend: transitionend, 407 onLoad: onLoad, 408 ignoreMousedisappear: ignoreMousedisappear 409}); // Authors & copyright(c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. MIT license 410 411/* eslint-disable */ 412 413window.matchMedia || (window.matchMedia = function () { 414 var styleMedia = window.styleMedia || window.media; // For those that don't support matchMedium 415 416 if (!styleMedia) { 417 var style = document.createElement('style'), 418 script = document.getElementsByTagName('script')[0], 419 info = null; 420 style.type = 'text/css'; 421 style.id = 'matchmediajs-test'; 422 423 if (!script) { 424 document.head.appendChild(style); 425 } else { 426 script.parentNode.insertBefore(style, script); 427 } // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers 428 429 430 info = 'getComputedStyle' in window && window.getComputedStyle(style, null) || style.currentStyle; 431 styleMedia = { 432 matchMedium: function matchMedium(media) { 433 var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers 434 435 if (style.styleSheet) { 436 style.styleSheet.cssText = text; 437 } else { 438 style.textContent = text; 439 } // Test if media query is true or false 440 441 442 return info.width === '1px'; 443 } 444 }; 445 } 446 447 return function (media) { 448 return { 449 matches: styleMedia.matchMedium(media || 'all'), 450 media: media || 'all' 451 }; 452 }; 453}()); 454/* eslint-enable */ 455 456var MediaQuery = { 457 queries: [], 458 current: '', 459 460 /** 461 * Initializes the media query helper, by extracting the breakpoint list from the CSS and activating the breakpoint watcher. 462 * @function 463 * @private 464 */ 465 _init: function _init() { 466 var self = this; 467 var $meta = jquery__WEBPACK_IMPORTED_MODULE_0___default()('meta.foundation-mq'); 468 469 if (!$meta.length) { 470 jquery__WEBPACK_IMPORTED_MODULE_0___default()('<meta class="foundation-mq">').appendTo(document.head); 471 } 472 473 var extractedStyles = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.foundation-mq').css('font-family'); 474 var namedQueries; 475 namedQueries = parseStyleToObject(extractedStyles); 476 477 for (var key in namedQueries) { 478 if (namedQueries.hasOwnProperty(key)) { 479 self.queries.push({ 480 name: key, 481 value: "only screen and (min-width: ".concat(namedQueries[key], ")") 482 }); 483 } 484 } 485 486 this.current = this._getCurrentSize(); 487 488 this._watcher(); 489 }, 490 491 /** 492 * Checks if the screen is at least as wide as a breakpoint. 493 * @function 494 * @param {String} size - Name of the breakpoint to check. 495 * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller. 496 */ 497 atLeast: function atLeast(size) { 498 var query = this.get(size); 499 500 if (query) { 501 return window.matchMedia(query).matches; 502 } 503 504 return false; 505 }, 506 507 /** 508 * Checks if the screen matches to a breakpoint. 509 * @function 510 * @param {String} size - Name of the breakpoint to check, either 'small only' or 'small'. Omitting 'only' falls back to using atLeast() method. 511 * @returns {Boolean} `true` if the breakpoint matches, `false` if it does not. 512 */ 513 is: function is(size) { 514 size = size.trim().split(' '); 515 516 if (size.length > 1 && size[1] === 'only') { 517 if (size[0] === this._getCurrentSize()) return true; 518 } else { 519 return this.atLeast(size[0]); 520 } 521 522 return false; 523 }, 524 525 /** 526 * Gets the media query of a breakpoint. 527 * @function 528 * @param {String} size - Name of the breakpoint to get. 529 * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist. 530 */ 531 get: function get(size) { 532 for (var i in this.queries) { 533 if (this.queries.hasOwnProperty(i)) { 534 var query = this.queries[i]; 535 if (size === query.name) return query.value; 536 } 537 } 538 539 return null; 540 }, 541 542 /** 543 * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one). 544 * @function 545 * @private 546 * @returns {String} Name of the current breakpoint. 547 */ 548 _getCurrentSize: function _getCurrentSize() { 549 var matched; 550 551 for (var i = 0; i < this.queries.length; i++) { 552 var query = this.queries[i]; 553 554 if (window.matchMedia(query.value).matches) { 555 matched = query; 556 } 557 } 558 559 if (_typeof(matched) === 'object') { 560 return matched.name; 561 } else { 562 return matched; 563 } 564 }, 565 566 /** 567 * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes. 568 * @function 569 * @private 570 */ 571 _watcher: function _watcher() { 572 var _this = this; 573 574 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('resize.zf.mediaquery').on('resize.zf.mediaquery', function () { 575 var newSize = _this._getCurrentSize(), 576 currentSize = _this.current; 577 578 if (newSize !== currentSize) { 579 // Change the current media query 580 _this.current = newSize; // Broadcast the media query change on the window 581 582 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).trigger('changed.zf.mediaquery', [newSize, currentSize]); 583 } 584 }); 585 } 586}; // Thank you: https://github.com/sindresorhus/query-string 587 588function parseStyleToObject(str) { 589 var styleObject = {}; 590 591 if (typeof str !== 'string') { 592 return styleObject; 593 } 594 595 str = str.trim().slice(1, -1); // browsers re-quote string style values 596 597 if (!str) { 598 return styleObject; 599 } 600 601 styleObject = str.split('&').reduce(function (ret, param) { 602 var parts = param.replace(/\+/g, ' ').split('='); 603 var key = parts[0]; 604 var val = parts[1]; 605 key = decodeURIComponent(key); // missing `=` should be `null`: 606 // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters 607 608 val = typeof val === 'undefined' ? null : decodeURIComponent(val); 609 610 if (!ret.hasOwnProperty(key)) { 611 ret[key] = val; 612 } else if (Array.isArray(ret[key])) { 613 ret[key].push(val); 614 } else { 615 ret[key] = [ret[key], val]; 616 } 617 618 return ret; 619 }, {}); 620 return styleObject; 621} 622 623var FOUNDATION_VERSION = '6.5.1'; // Global Foundation object 624// This is attached to the window, or used as a module for AMD/Browserify 625 626var Foundation = { 627 version: FOUNDATION_VERSION, 628 629 /** 630 * Stores initialized plugins. 631 */ 632 _plugins: {}, 633 634 /** 635 * Stores generated unique ids for plugin instances 636 */ 637 _uuids: [], 638 639 /** 640 * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing. 641 * @param {Object} plugin - The constructor of the plugin. 642 */ 643 plugin: function plugin(_plugin, name) { 644 // Object key to use when adding to global Foundation object 645 // Examples: Foundation.Reveal, Foundation.OffCanvas 646 var className = name || functionName(_plugin); // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin 647 // Examples: data-reveal, data-off-canvas 648 649 var attrName = hyphenate(className); // Add to the Foundation object and the plugins list (for reflowing) 650 651 this._plugins[attrName] = this[className] = _plugin; 652 }, 653 654 /** 655 * @function 656 * Populates the _uuids array with pointers to each individual plugin instance. 657 * Adds the `zfPlugin` data-attribute to programmatically created plugins to allow use of $(selector).foundation(method) calls. 658 * Also fires the initialization event for each plugin, consolidating repetitive code. 659 * @param {Object} plugin - an instance of a plugin, usually `this` in context. 660 * @param {String} name - the name of the plugin, passed as a camelCased string. 661 * @fires Plugin#init 662 */ 663 registerPlugin: function registerPlugin(plugin, name) { 664 var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase(); 665 plugin.uuid = GetYoDigits(6, pluginName); 666 667 if (!plugin.$element.attr("data-".concat(pluginName))) { 668 plugin.$element.attr("data-".concat(pluginName), plugin.uuid); 669 } 670 671 if (!plugin.$element.data('zfPlugin')) { 672 plugin.$element.data('zfPlugin', plugin); 673 } 674 /** 675 * Fires when the plugin has initialized. 676 * @event Plugin#init 677 */ 678 679 680 plugin.$element.trigger("init.zf.".concat(pluginName)); 681 682 this._uuids.push(plugin.uuid); 683 684 return; 685 }, 686 687 /** 688 * @function 689 * Removes the plugins uuid from the _uuids array. 690 * Removes the zfPlugin data attribute, as well as the data-plugin-name attribute. 691 * Also fires the destroyed event for the plugin, consolidating repetitive code. 692 * @param {Object} plugin - an instance of a plugin, usually `this` in context. 693 * @fires Plugin#destroyed 694 */ 695 unregisterPlugin: function unregisterPlugin(plugin) { 696 var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor)); 697 698 this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1); 699 700 plugin.$element.removeAttr("data-".concat(pluginName)).removeData('zfPlugin') 701 /** 702 * Fires when the plugin has been destroyed. 703 * @event Plugin#destroyed 704 */ 705 .trigger("destroyed.zf.".concat(pluginName)); 706 707 for (var prop in plugin) { 708 plugin[prop] = null; //clean up script to prep for garbage collection. 709 } 710 711 return; 712 }, 713 714 /** 715 * @function 716 * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc. 717 * @param {String} plugins - optional string of an individual plugin key, attained by calling `$(element).data('pluginName')`, or string of a plugin class i.e. `'dropdown'` 718 * @default If no argument is passed, reflow all currently active plugins. 719 */ 720 reInit: function reInit(plugins) { 721 var isJQ = plugins instanceof jquery__WEBPACK_IMPORTED_MODULE_0___default.a; 722 723 try { 724 if (isJQ) { 725 plugins.each(function () { 726 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('zfPlugin')._init(); 727 }); 728 } else { 729 var type = _typeof(plugins), 730 _this = this, 731 fns = { 732 'object': function object(plgs) { 733 plgs.forEach(function (p) { 734 p = hyphenate(p); 735 jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-' + p + ']').foundation('_init'); 736 }); 737 }, 738 'string': function string() { 739 plugins = hyphenate(plugins); 740 jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-' + plugins + ']').foundation('_init'); 741 }, 742 'undefined': function undefined() { 743 this['object'](Object.keys(_this._plugins)); 744 } 745 }; 746 747 fns[type](plugins); 748 } 749 } catch (err) { 750 console.error(err); 751 } finally { 752 return plugins; 753 } 754 }, 755 756 /** 757 * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized. 758 * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object. 759 * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything. 760 */ 761 reflow: function reflow(elem, plugins) { 762 // If plugins is undefined, just grab everything 763 if (typeof plugins === 'undefined') { 764 plugins = Object.keys(this._plugins); 765 } // If plugins is a string, convert it to an array with one item 766 else if (typeof plugins === 'string') { 767 plugins = [plugins]; 768 } 769 770 var _this = this; // Iterate through each plugin 771 772 773 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.each(plugins, function (i, name) { 774 // Get the current plugin 775 var plugin = _this._plugins[name]; // Localize the search to all elements inside elem, as well as elem itself, unless elem === document 776 777 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(elem).find('[data-' + name + ']').addBack('[data-' + name + ']'); // For each plugin found, initialize it 778 779 $elem.each(function () { 780 var $el = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 781 opts = {}; // Don't double-dip on plugins 782 783 if ($el.data('zfPlugin')) { 784 console.warn("Tried to initialize " + name + " on an element that already has a Foundation plugin."); 785 return; 786 } 787 788 if ($el.attr('data-options')) { 789 var thing = $el.attr('data-options').split(';').forEach(function (e, i) { 790 var opt = e.split(':').map(function (el) { 791 return el.trim(); 792 }); 793 if (opt[0]) opts[opt[0]] = parseValue(opt[1]); 794 }); 795 } 796 797 try { 798 $el.data('zfPlugin', new plugin(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), opts)); 799 } catch (er) { 800 console.error(er); 801 } finally { 802 return; 803 } 804 }); 805 }); 806 }, 807 getFnName: functionName, 808 addToJquery: function addToJquery($$$1) { 809 // TODO: consider not making this a jQuery function 810 // TODO: need way to reflow vs. re-initialize 811 812 /** 813 * The Foundation jQuery method. 814 * @param {String|Array} method - An action to perform on the current jQuery object. 815 */ 816 var foundation = function foundation(method) { 817 var type = _typeof(method), 818 $noJS = $$$1('.no-js'); 819 820 if ($noJS.length) { 821 $noJS.removeClass('no-js'); 822 } 823 824 if (type === 'undefined') { 825 //needs to initialize the Foundation object, or an individual plugin. 826 MediaQuery._init(); 827 828 Foundation.reflow(this); 829 } else if (type === 'string') { 830 //an individual method to invoke on a plugin or group of plugins 831 var args = Array.prototype.slice.call(arguments, 1); //collect all the arguments, if necessary 832 833 var plugClass = this.data('zfPlugin'); //determine the class of plugin 834 835 if (typeof plugClass !== 'undefined' && typeof plugClass[method] !== 'undefined') { 836 //make sure both the class and method exist 837 if (this.length === 1) { 838 //if there's only one, call it directly. 839 plugClass[method].apply(plugClass, args); 840 } else { 841 this.each(function (i, el) { 842 //otherwise loop through the jQuery collection and invoke the method on each 843 plugClass[method].apply($$$1(el).data('zfPlugin'), args); 844 }); 845 } 846 } else { 847 //error for no class or no method 848 throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.'); 849 } 850 } else { 851 //error for invalid argument type 852 throw new TypeError("We're sorry, ".concat(type, " is not a valid parameter. You must use a string representing the method you wish to invoke.")); 853 } 854 855 return this; 856 }; 857 858 $$$1.fn.foundation = foundation; 859 return $$$1; 860 } 861}; 862Foundation.util = { 863 /** 864 * Function for applying a debounce effect to a function call. 865 * @function 866 * @param {Function} func - Function to be called at end of timeout. 867 * @param {Number} delay - Time in ms to delay the call of `func`. 868 * @returns function 869 */ 870 throttle: function throttle(func, delay) { 871 var timer = null; 872 return function () { 873 var context = this, 874 args = arguments; 875 876 if (timer === null) { 877 timer = setTimeout(function () { 878 func.apply(context, args); 879 timer = null; 880 }, delay); 881 } 882 }; 883 } 884}; 885window.Foundation = Foundation; // Polyfill for requestAnimationFrame 886 887(function () { 888 if (!Date.now || !window.Date.now) window.Date.now = Date.now = function () { 889 return new Date().getTime(); 890 }; 891 var vendors = ['webkit', 'moz']; 892 893 for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { 894 var vp = vendors[i]; 895 window.requestAnimationFrame = window[vp + 'RequestAnimationFrame']; 896 window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame']; 897 } 898 899 if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { 900 var lastTime = 0; 901 902 window.requestAnimationFrame = function (callback) { 903 var now = Date.now(); 904 var nextTime = Math.max(lastTime + 16, now); 905 return setTimeout(function () { 906 callback(lastTime = nextTime); 907 }, nextTime - now); 908 }; 909 910 window.cancelAnimationFrame = clearTimeout; 911 } 912 /** 913 * Polyfill for performance.now, required by rAF 914 */ 915 916 917 if (!window.performance || !window.performance.now) { 918 window.performance = { 919 start: Date.now(), 920 now: function now() { 921 return Date.now() - this.start; 922 } 923 }; 924 } 925})(); 926 927if (!Function.prototype.bind) { 928 Function.prototype.bind = function (oThis) { 929 if (typeof this !== 'function') { 930 // closest thing possible to the ECMAScript 5 931 // internal IsCallable function 932 throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 933 } 934 935 var aArgs = Array.prototype.slice.call(arguments, 1), 936 fToBind = this, 937 fNOP = function fNOP() {}, 938 fBound = function fBound() { 939 return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); 940 }; 941 942 if (this.prototype) { 943 // native functions don't have a prototype 944 fNOP.prototype = this.prototype; 945 } 946 947 fBound.prototype = new fNOP(); 948 return fBound; 949 }; 950} // Polyfill to get the name of a function in IE9 951 952 953function functionName(fn) { 954 if (typeof Function.prototype.name === 'undefined') { 955 var funcNameRegex = /function\s([^(]{1,})\(/; 956 var results = funcNameRegex.exec(fn.toString()); 957 return results && results.length > 1 ? results[1].trim() : ""; 958 } else if (typeof fn.prototype === 'undefined') { 959 return fn.constructor.name; 960 } else { 961 return fn.prototype.constructor.name; 962 } 963} 964 965function parseValue(str) { 966 if ('true' === str) return true;else if ('false' === str) return false;else if (!isNaN(str * 1)) return parseFloat(str); 967 return str; 968} // Convert PascalCase to kebab-case 969// Thank you: http://stackoverflow.com/a/8955580 970 971 972function hyphenate(str) { 973 return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 974} 975 976var Box = { 977 ImNotTouchingYou: ImNotTouchingYou, 978 OverlapArea: OverlapArea, 979 GetDimensions: GetDimensions, 980 GetOffsets: GetOffsets, 981 GetExplicitOffsets: GetExplicitOffsets 982 /** 983 * Compares the dimensions of an element to a container and determines collision events with container. 984 * @function 985 * @param {jQuery} element - jQuery object to test for collisions. 986 * @param {jQuery} parent - jQuery object to use as bounding container. 987 * @param {Boolean} lrOnly - set to true to check left and right values only. 988 * @param {Boolean} tbOnly - set to true to check top and bottom values only. 989 * @default if no parent object passed, detects collisions with `window`. 990 * @returns {Boolean} - true if collision free, false if a collision in any direction. 991 */ 992 993}; 994 995function ImNotTouchingYou(element, parent, lrOnly, tbOnly, ignoreBottom) { 996 return OverlapArea(element, parent, lrOnly, tbOnly, ignoreBottom) === 0; 997} 998 999function OverlapArea(element, parent, lrOnly, tbOnly, ignoreBottom) { 1000 var eleDims = GetDimensions(element), 1001 topOver, 1002 bottomOver, 1003 leftOver, 1004 rightOver; 1005 1006 if (parent) { 1007 var parDims = GetDimensions(parent); 1008 bottomOver = parDims.height + parDims.offset.top - (eleDims.offset.top + eleDims.height); 1009 topOver = eleDims.offset.top - parDims.offset.top; 1010 leftOver = eleDims.offset.left - parDims.offset.left; 1011 rightOver = parDims.width + parDims.offset.left - (eleDims.offset.left + eleDims.width); 1012 } else { 1013 bottomOver = eleDims.windowDims.height + eleDims.windowDims.offset.top - (eleDims.offset.top + eleDims.height); 1014 topOver = eleDims.offset.top - eleDims.windowDims.offset.top; 1015 leftOver = eleDims.offset.left - eleDims.windowDims.offset.left; 1016 rightOver = eleDims.windowDims.width - (eleDims.offset.left + eleDims.width); 1017 } 1018 1019 bottomOver = ignoreBottom ? 0 : Math.min(bottomOver, 0); 1020 topOver = Math.min(topOver, 0); 1021 leftOver = Math.min(leftOver, 0); 1022 rightOver = Math.min(rightOver, 0); 1023 1024 if (lrOnly) { 1025 return leftOver + rightOver; 1026 } 1027 1028 if (tbOnly) { 1029 return topOver + bottomOver; 1030 } // use sum of squares b/c we care about overlap area. 1031 1032 1033 return Math.sqrt(topOver * topOver + bottomOver * bottomOver + leftOver * leftOver + rightOver * rightOver); 1034} 1035/** 1036 * Uses native methods to return an object of dimension values. 1037 * @function 1038 * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window. 1039 * @returns {Object} - nested object of integer pixel values 1040 * TODO - if element is window, return only those values. 1041 */ 1042 1043 1044function GetDimensions(elem) { 1045 elem = elem.length ? elem[0] : elem; 1046 1047 if (elem === window || elem === document) { 1048 throw new Error("I'm sorry, Dave. I'm afraid I can't do that."); 1049 } 1050 1051 var rect = elem.getBoundingClientRect(), 1052 parRect = elem.parentNode.getBoundingClientRect(), 1053 winRect = document.body.getBoundingClientRect(), 1054 winY = window.pageYOffset, 1055 winX = window.pageXOffset; 1056 return { 1057 width: rect.width, 1058 height: rect.height, 1059 offset: { 1060 top: rect.top + winY, 1061 left: rect.left + winX 1062 }, 1063 parentDims: { 1064 width: parRect.width, 1065 height: parRect.height, 1066 offset: { 1067 top: parRect.top + winY, 1068 left: parRect.left + winX 1069 } 1070 }, 1071 windowDims: { 1072 width: winRect.width, 1073 height: winRect.height, 1074 offset: { 1075 top: winY, 1076 left: winX 1077 } 1078 } 1079 }; 1080} 1081/** 1082 * Returns an object of top and left integer pixel values for dynamically rendered elements, 1083 * such as: Tooltip, Reveal, and Dropdown. Maintained for backwards compatibility, and where 1084 * you don't know alignment, but generally from 1085 * 6.4 forward you should use GetExplicitOffsets, as GetOffsets conflates position and alignment. 1086 * @function 1087 * @param {jQuery} element - jQuery object for the element being positioned. 1088 * @param {jQuery} anchor - jQuery object for the element's anchor point. 1089 * @param {String} position - a string relating to the desired position of the element, relative to it's anchor 1090 * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element. 1091 * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element. 1092 * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset. 1093 * TODO alter/rewrite to work with `em` values as well/instead of pixels 1094 */ 1095 1096 1097function GetOffsets(element, anchor, position, vOffset, hOffset, isOverflow) { 1098 console.log("NOTE: GetOffsets is deprecated in favor of GetExplicitOffsets and will be removed in 6.5"); 1099 1100 switch (position) { 1101 case 'top': 1102 return rtl() ? GetExplicitOffsets(element, anchor, 'top', 'left', vOffset, hOffset, isOverflow) : GetExplicitOffsets(element, anchor, 'top', 'right', vOffset, hOffset, isOverflow); 1103 1104 case 'bottom': 1105 return rtl() ? GetExplicitOffsets(element, anchor, 'bottom', 'left', vOffset, hOffset, isOverflow) : GetExplicitOffsets(element, anchor, 'bottom', 'right', vOffset, hOffset, isOverflow); 1106 1107 case 'center top': 1108 return GetExplicitOffsets(element, anchor, 'top', 'center', vOffset, hOffset, isOverflow); 1109 1110 case 'center bottom': 1111 return GetExplicitOffsets(element, anchor, 'bottom', 'center', vOffset, hOffset, isOverflow); 1112 1113 case 'center left': 1114 return GetExplicitOffsets(element, anchor, 'left', 'center', vOffset, hOffset, isOverflow); 1115 1116 case 'center right': 1117 return GetExplicitOffsets(element, anchor, 'right', 'center', vOffset, hOffset, isOverflow); 1118 1119 case 'left bottom': 1120 return GetExplicitOffsets(element, anchor, 'bottom', 'left', vOffset, hOffset, isOverflow); 1121 1122 case 'right bottom': 1123 return GetExplicitOffsets(element, anchor, 'bottom', 'right', vOffset, hOffset, isOverflow); 1124 // Backwards compatibility... this along with the reveal and reveal full 1125 // classes are the only ones that didn't reference anchor 1126 1127 case 'center': 1128 return { 1129 left: $eleDims.windowDims.offset.left + $eleDims.windowDims.width / 2 - $eleDims.width / 2 + hOffset, 1130 top: $eleDims.windowDims.offset.top + $eleDims.windowDims.height / 2 - ($eleDims.height / 2 + vOffset) 1131 }; 1132 1133 case 'reveal': 1134 return { 1135 left: ($eleDims.windowDims.width - $eleDims.width) / 2 + hOffset, 1136 top: $eleDims.windowDims.offset.top + vOffset 1137 }; 1138 1139 case 'reveal full': 1140 return { 1141 left: $eleDims.windowDims.offset.left, 1142 top: $eleDims.windowDims.offset.top 1143 }; 1144 break; 1145 1146 default: 1147 return { 1148 left: rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width - hOffset : $anchorDims.offset.left + hOffset, 1149 top: $anchorDims.offset.top + $anchorDims.height + vOffset 1150 }; 1151 } 1152} 1153 1154function GetExplicitOffsets(element, anchor, position, alignment, vOffset, hOffset, isOverflow) { 1155 var $eleDims = GetDimensions(element), 1156 $anchorDims = anchor ? GetDimensions(anchor) : null; 1157 var topVal, leftVal; // set position related attribute 1158 1159 switch (position) { 1160 case 'top': 1161 topVal = $anchorDims.offset.top - ($eleDims.height + vOffset); 1162 break; 1163 1164 case 'bottom': 1165 topVal = $anchorDims.offset.top + $anchorDims.height + vOffset; 1166 break; 1167 1168 case 'left': 1169 leftVal = $anchorDims.offset.left - ($eleDims.width + hOffset); 1170 break; 1171 1172 case 'right': 1173 leftVal = $anchorDims.offset.left + $anchorDims.width + hOffset; 1174 break; 1175 } // set alignment related attribute 1176 1177 1178 switch (position) { 1179 case 'top': 1180 case 'bottom': 1181 switch (alignment) { 1182 case 'left': 1183 leftVal = $anchorDims.offset.left + hOffset; 1184 break; 1185 1186 case 'right': 1187 leftVal = $anchorDims.offset.left - $eleDims.width + $anchorDims.width - hOffset; 1188 break; 1189 1190 case 'center': 1191 leftVal = isOverflow ? hOffset : $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2 + hOffset; 1192 break; 1193 } 1194 1195 break; 1196 1197 case 'right': 1198 case 'left': 1199 switch (alignment) { 1200 case 'bottom': 1201 topVal = $anchorDims.offset.top - vOffset + $anchorDims.height - $eleDims.height; 1202 break; 1203 1204 case 'top': 1205 topVal = $anchorDims.offset.top + vOffset; 1206 break; 1207 1208 case 'center': 1209 topVal = $anchorDims.offset.top + vOffset + $anchorDims.height / 2 - $eleDims.height / 2; 1210 break; 1211 } 1212 1213 break; 1214 } 1215 1216 return { 1217 top: topVal, 1218 left: leftVal 1219 }; 1220} 1221/** 1222 * Runs a callback function when images are fully loaded. 1223 * @param {Object} images - Image(s) to check if loaded. 1224 * @param {Func} callback - Function to execute when image is fully loaded. 1225 */ 1226 1227 1228function onImagesLoaded(images, callback) { 1229 var unloaded = images.length; 1230 1231 if (unloaded === 0) { 1232 callback(); 1233 } 1234 1235 images.each(function () { 1236 // Check if image is loaded 1237 if (this.complete && typeof this.naturalWidth !== 'undefined') { 1238 singleImageLoaded(); 1239 } else { 1240 // If the above check failed, simulate loading on detached element. 1241 var image = new Image(); // Still count image as loaded if it finalizes with an error. 1242 1243 var events = "load.zf.images error.zf.images"; 1244 jquery__WEBPACK_IMPORTED_MODULE_0___default()(image).one(events, function me(event) { 1245 // Unbind the event listeners. We're using 'one' but only one of the two events will have fired. 1246 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).off(events, me); 1247 singleImageLoaded(); 1248 }); 1249 image.src = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('src'); 1250 } 1251 }); 1252 1253 function singleImageLoaded() { 1254 unloaded--; 1255 1256 if (unloaded === 0) { 1257 callback(); 1258 } 1259 } 1260} 1261/******************************************* 1262 * * 1263 * This util was created by Marius Olbertz * 1264 * Please thank Marius on GitHub /owlbertz * 1265 * or the web http://www.mariusolbertz.de/ * 1266 * * 1267 ******************************************/ 1268 1269 1270var keyCodes = { 1271 9: 'TAB', 1272 13: 'ENTER', 1273 27: 'ESCAPE', 1274 32: 'SPACE', 1275 35: 'END', 1276 36: 'HOME', 1277 37: 'ARROW_LEFT', 1278 38: 'ARROW_UP', 1279 39: 'ARROW_RIGHT', 1280 40: 'ARROW_DOWN' 1281}; 1282var commands = {}; // Functions pulled out to be referenceable from internals 1283 1284function findFocusable($element) { 1285 if (!$element) { 1286 return false; 1287 } 1288 1289 return $element.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]').filter(function () { 1290 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is(':visible') || jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('tabindex') < 0) { 1291 return false; 1292 } //only have visible elements and those that have a tabindex greater or equal 0 1293 1294 1295 return true; 1296 }); 1297} 1298 1299function parseKey(event) { 1300 var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase(); // Remove un-printable characters, e.g. for `fromCharCode` calls for CTRL only events 1301 1302 key = key.replace(/\W+/, ''); 1303 if (event.shiftKey) key = "SHIFT_".concat(key); 1304 if (event.ctrlKey) key = "CTRL_".concat(key); 1305 if (event.altKey) key = "ALT_".concat(key); // Remove trailing underscore, in case only modifiers were used (e.g. only `CTRL_ALT`) 1306 1307 key = key.replace(/_$/, ''); 1308 return key; 1309} 1310 1311var Keyboard = { 1312 keys: getKeyCodes(keyCodes), 1313 1314 /** 1315 * Parses the (keyboard) event and returns a String that represents its key 1316 * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE 1317 * @param {Event} event - the event generated by the event handler 1318 * @return String key - String that represents the key pressed 1319 */ 1320 parseKey: parseKey, 1321 1322 /** 1323 * Handles the given (keyboard) event 1324 * @param {Event} event - the event generated by the event handler 1325 * @param {String} component - Foundation component's name, e.g. Slider or Reveal 1326 * @param {Objects} functions - collection of functions that are to be executed 1327 */ 1328 handleKey: function handleKey(event, component, functions) { 1329 var commandList = commands[component], 1330 keyCode = this.parseKey(event), 1331 cmds, 1332 command, 1333 fn; 1334 if (!commandList) return console.warn('Component not defined!'); 1335 1336 if (typeof commandList.ltr === 'undefined') { 1337 // this component does not differentiate between ltr and rtl 1338 cmds = commandList; // use plain list 1339 } else { 1340 // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa 1341 if (rtl()) cmds = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, commandList.ltr, commandList.rtl);else cmds = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, commandList.rtl, commandList.ltr); 1342 } 1343 1344 command = cmds[keyCode]; 1345 fn = functions[command]; 1346 1347 if (fn && typeof fn === 'function') { 1348 // execute function if exists 1349 var returnValue = fn.apply(); 1350 1351 if (functions.handled || typeof functions.handled === 'function') { 1352 // execute function when event was handled 1353 functions.handled(returnValue); 1354 } 1355 } else { 1356 if (functions.unhandled || typeof functions.unhandled === 'function') { 1357 // execute function when event was not handled 1358 functions.unhandled(); 1359 } 1360 } 1361 }, 1362 1363 /** 1364 * Finds all focusable elements within the given `$element` 1365 * @param {jQuery} $element - jQuery object to search within 1366 * @return {jQuery} $focusable - all focusable elements within `$element` 1367 */ 1368 findFocusable: findFocusable, 1369 1370 /** 1371 * Returns the component name name 1372 * @param {Object} component - Foundation component, e.g. Slider or Reveal 1373 * @return String componentName 1374 */ 1375 register: function register(componentName, cmds) { 1376 commands[componentName] = cmds; 1377 }, 1378 // TODO9438: These references to Keyboard need to not require global. Will 'this' work in this context? 1379 // 1380 1381 /** 1382 * Traps the focus in the given element. 1383 * @param {jQuery} $element jQuery object to trap the foucs into. 1384 */ 1385 trapFocus: function trapFocus($element) { 1386 var $focusable = findFocusable($element), 1387 $firstFocusable = $focusable.eq(0), 1388 $lastFocusable = $focusable.eq(-1); 1389 $element.on('keydown.zf.trapfocus', function (event) { 1390 if (event.target === $lastFocusable[0] && parseKey(event) === 'TAB') { 1391 event.preventDefault(); 1392 $firstFocusable.focus(); 1393 } else if (event.target === $firstFocusable[0] && parseKey(event) === 'SHIFT_TAB') { 1394 event.preventDefault(); 1395 $lastFocusable.focus(); 1396 } 1397 }); 1398 }, 1399 1400 /** 1401 * Releases the trapped focus from the given element. 1402 * @param {jQuery} $element jQuery object to release the focus for. 1403 */ 1404 releaseFocus: function releaseFocus($element) { 1405 $element.off('keydown.zf.trapfocus'); 1406 } 1407}; 1408/* 1409 * Constants for easier comparing. 1410 * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE 1411 */ 1412 1413function getKeyCodes(kcs) { 1414 var k = {}; 1415 1416 for (var kc in kcs) { 1417 k[kcs[kc]] = kcs[kc]; 1418 } 1419 1420 return k; 1421} 1422/** 1423 * Motion module. 1424 * @module foundation.motion 1425 */ 1426 1427 1428var initClasses = ['mui-enter', 'mui-leave']; 1429var activeClasses = ['mui-enter-active', 'mui-leave-active']; 1430var Motion = { 1431 animateIn: function animateIn(element, animation, cb) { 1432 animate(true, element, animation, cb); 1433 }, 1434 animateOut: function animateOut(element, animation, cb) { 1435 animate(false, element, animation, cb); 1436 } 1437}; 1438 1439function Move(duration, elem, fn) { 1440 var anim, 1441 prog, 1442 start = null; // console.log('called'); 1443 1444 if (duration === 0) { 1445 fn.apply(elem); 1446 elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]); 1447 return; 1448 } 1449 1450 function move(ts) { 1451 if (!start) start = ts; // console.log(start, ts); 1452 1453 prog = ts - start; 1454 fn.apply(elem); 1455 1456 if (prog < duration) { 1457 anim = window.requestAnimationFrame(move, elem); 1458 } else { 1459 window.cancelAnimationFrame(anim); 1460 elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]); 1461 } 1462 } 1463 1464 anim = window.requestAnimationFrame(move); 1465} 1466/** 1467 * Animates an element in or out using a CSS transition class. 1468 * @function 1469 * @private 1470 * @param {Boolean} isIn - Defines if the animation is in or out. 1471 * @param {Object} element - jQuery or HTML object to animate. 1472 * @param {String} animation - CSS class to use. 1473 * @param {Function} cb - Callback to run when animation is finished. 1474 */ 1475 1476 1477function animate(isIn, element, animation, cb) { 1478 element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(element).eq(0); 1479 if (!element.length) return; 1480 var initClass = isIn ? initClasses[0] : initClasses[1]; 1481 var activeClass = isIn ? activeClasses[0] : activeClasses[1]; // Set up the animation 1482 1483 reset(); 1484 element.addClass(animation).css('transition', 'none'); 1485 requestAnimationFrame(function () { 1486 element.addClass(initClass); 1487 if (isIn) element.show(); 1488 }); // Start the animation 1489 1490 requestAnimationFrame(function () { 1491 element[0].offsetWidth; 1492 element.css('transition', '').addClass(activeClass); 1493 }); // Clean up the animation when it finishes 1494 1495 element.one(transitionend(element), finish); // Hides the element (for out animations), resets the element, and runs a callback 1496 1497 function finish() { 1498 if (!isIn) element.hide(); 1499 reset(); 1500 if (cb) cb.apply(element); 1501 } // Resets transitions and removes motion-specific classes 1502 1503 1504 function reset() { 1505 element[0].style.transitionDuration = 0; 1506 element.removeClass("".concat(initClass, " ").concat(activeClass, " ").concat(animation)); 1507 } 1508} 1509 1510var Nest = { 1511 Feather: function Feather(menu) { 1512 var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'zf'; 1513 menu.attr('role', 'menubar'); 1514 var items = menu.find('li').attr({ 1515 'role': 'menuitem' 1516 }), 1517 subMenuClass = "is-".concat(type, "-submenu"), 1518 subItemClass = "".concat(subMenuClass, "-item"), 1519 hasSubClass = "is-".concat(type, "-submenu-parent"), 1520 applyAria = type !== 'accordion'; // Accordions handle their own ARIA attriutes. 1521 1522 items.each(function () { 1523 var $item = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 1524 $sub = $item.children('ul'); 1525 1526 if ($sub.length) { 1527 $item.addClass(hasSubClass); 1528 $sub.addClass("submenu ".concat(subMenuClass)).attr({ 1529 'data-submenu': '' 1530 }); 1531 1532 if (applyAria) { 1533 $item.attr({ 1534 'aria-haspopup': true, 1535 'aria-label': $item.children('a:first').text() 1536 }); // Note: Drilldowns behave differently in how they hide, and so need 1537 // additional attributes. We should look if this possibly over-generalized 1538 // utility (Nest) is appropriate when we rework menus in 6.4 1539 1540 if (type === 'drilldown') { 1541 $item.attr({ 1542 'aria-expanded': false 1543 }); 1544 } 1545 } 1546 1547 $sub.addClass("submenu ".concat(subMenuClass)).attr({ 1548 'data-submenu': '', 1549 'role': 'menubar' 1550 }); 1551 1552 if (type === 'drilldown') { 1553 $sub.attr({ 1554 'aria-hidden': true 1555 }); 1556 } 1557 } 1558 1559 if ($item.parent('[data-submenu]').length) { 1560 $item.addClass("is-submenu-item ".concat(subItemClass)); 1561 } 1562 }); 1563 return; 1564 }, 1565 Burn: function Burn(menu, type) { 1566 var //items = menu.find('li'), 1567 subMenuClass = "is-".concat(type, "-submenu"), 1568 subItemClass = "".concat(subMenuClass, "-item"), 1569 hasSubClass = "is-".concat(type, "-submenu-parent"); 1570 menu.find('>li, > li > ul, .menu, .menu > li, [data-submenu] > li').removeClass("".concat(subMenuClass, " ").concat(subItemClass, " ").concat(hasSubClass, " is-submenu-item submenu is-active")).removeAttr('data-submenu').css('display', ''); 1571 } 1572}; 1573 1574function Timer(elem, options, cb) { 1575 var _this = this, 1576 duration = options.duration, 1577 //options is an object for easily adding features later. 1578 nameSpace = Object.keys(elem.data())[0] || 'timer', 1579 remain = -1, 1580 start, 1581 timer; 1582 1583 this.isPaused = false; 1584 1585 this.restart = function () { 1586 remain = -1; 1587 clearTimeout(timer); 1588 this.start(); 1589 }; 1590 1591 this.start = function () { 1592 this.isPaused = false; // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. 1593 1594 clearTimeout(timer); 1595 remain = remain <= 0 ? duration : remain; 1596 elem.data('paused', false); 1597 start = Date.now(); 1598 timer = setTimeout(function () { 1599 if (options.infinite) { 1600 _this.restart(); //rerun the timer. 1601 1602 } 1603 1604 if (cb && typeof cb === 'function') { 1605 cb(); 1606 } 1607 }, remain); 1608 elem.trigger("timerstart.zf.".concat(nameSpace)); 1609 }; 1610 1611 this.pause = function () { 1612 this.isPaused = true; //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. 1613 1614 clearTimeout(timer); 1615 elem.data('paused', true); 1616 var end = Date.now(); 1617 remain = remain - (end - start); 1618 elem.trigger("timerpaused.zf.".concat(nameSpace)); 1619 }; 1620} 1621 1622var Touch = {}; 1623var startPosX, 1624 startPosY, 1625 startTime, 1626 elapsedTime, 1627 startEvent, 1628 isMoving = false, 1629 didMoved = false; 1630 1631function onTouchEnd(e) { 1632 this.removeEventListener('touchmove', onTouchMove); 1633 this.removeEventListener('touchend', onTouchEnd); // If the touch did not move, consider it as a "tap" 1634 1635 if (!didMoved) { 1636 var tapEvent = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.Event('tap', startEvent || e); 1637 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).trigger(tapEvent); 1638 } 1639 1640 startEvent = null; 1641 isMoving = false; 1642 didMoved = false; 1643} 1644 1645function onTouchMove(e) { 1646 if (jquery__WEBPACK_IMPORTED_MODULE_0___default.a.spotSwipe.preventDefault) { 1647 e.preventDefault(); 1648 } 1649 1650 if (isMoving) { 1651 var x = e.touches[0].pageX; 1652 var y = e.touches[0].pageY; 1653 var dx = startPosX - x; 1654 var dir; 1655 didMoved = true; 1656 elapsedTime = new Date().getTime() - startTime; 1657 1658 if (Math.abs(dx) >= jquery__WEBPACK_IMPORTED_MODULE_0___default.a.spotSwipe.moveThreshold && elapsedTime <= jquery__WEBPACK_IMPORTED_MODULE_0___default.a.spotSwipe.timeThreshold) { 1659 dir = dx > 0 ? 'left' : 'right'; 1660 } // else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) { 1661 // dir = dy > 0 ? 'down' : 'up'; 1662 // } 1663 1664 1665 if (dir) { 1666 e.preventDefault(); 1667 onTouchEnd.apply(this, arguments); 1668 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).trigger(jquery__WEBPACK_IMPORTED_MODULE_0___default.a.Event('swipe', e), dir).trigger(jquery__WEBPACK_IMPORTED_MODULE_0___default.a.Event("swipe".concat(dir), e)); 1669 } 1670 } 1671} 1672 1673function onTouchStart(e) { 1674 if (e.touches.length == 1) { 1675 startPosX = e.touches[0].pageX; 1676 startPosY = e.touches[0].pageY; 1677 startEvent = e; 1678 isMoving = true; 1679 didMoved = false; 1680 startTime = new Date().getTime(); 1681 this.addEventListener('touchmove', onTouchMove, false); 1682 this.addEventListener('touchend', onTouchEnd, false); 1683 } 1684} 1685 1686function init() { 1687 this.addEventListener && this.addEventListener('touchstart', onTouchStart, false); 1688} 1689 1690var SpotSwipe = 1691/*#__PURE__*/ 1692function () { 1693 function SpotSwipe($$$1) { 1694 _classCallCheck(this, SpotSwipe); 1695 1696 this.version = '1.0.0'; 1697 this.enabled = 'ontouchstart' in document.documentElement; 1698 this.preventDefault = false; 1699 this.moveThreshold = 75; 1700 this.timeThreshold = 200; 1701 this.$ = $$$1; 1702 1703 this._init(); 1704 } 1705 1706 _createClass(SpotSwipe, [{ 1707 key: "_init", 1708 value: function _init() { 1709 var $$$1 = this.$; 1710 $$$1.event.special.swipe = { 1711 setup: init 1712 }; 1713 $$$1.event.special.tap = { 1714 setup: init 1715 }; 1716 $$$1.each(['left', 'up', 'down', 'right'], function () { 1717 $$$1.event.special["swipe".concat(this)] = { 1718 setup: function setup() { 1719 $$$1(this).on('swipe', $$$1.noop); 1720 } 1721 }; 1722 }); 1723 } 1724 }]); 1725 1726 return SpotSwipe; 1727}(); 1728/**************************************************** 1729 * As far as I can tell, both setupSpotSwipe and * 1730 * setupTouchHandler should be idempotent, * 1731 * because they directly replace functions & * 1732 * values, and do not add event handlers directly. * 1733 ****************************************************/ 1734 1735 1736Touch.setupSpotSwipe = function ($$$1) { 1737 $$$1.spotSwipe = new SpotSwipe($$$1); 1738}; 1739/**************************************************** 1740 * Method for adding pseudo drag events to elements * 1741 ***************************************************/ 1742 1743 1744Touch.setupTouchHandler = function ($$$1) { 1745 $$$1.fn.addTouch = function () { 1746 this.each(function (i, el) { 1747 $$$1(el).bind('touchstart touchmove touchend touchcancel', function (event) { 1748 //we pass the original event object because the jQuery event 1749 //object is normalized to w3c specs and does not provide the TouchList 1750 handleTouch(event); 1751 }); 1752 }); 1753 1754 var handleTouch = function handleTouch(event) { 1755 var touches = event.changedTouches, 1756 first = touches[0], 1757 eventTypes = { 1758 touchstart: 'mousedown', 1759 touchmove: 'mousemove', 1760 touchend: 'mouseup' 1761 }, 1762 type = eventTypes[event.type], 1763 simulatedEvent; 1764 1765 if ('MouseEvent' in window && typeof window.MouseEvent === 'function') { 1766 simulatedEvent = new window.MouseEvent(type, { 1767 'bubbles': true, 1768 'cancelable': true, 1769 'screenX': first.screenX, 1770 'screenY': first.screenY, 1771 'clientX': first.clientX, 1772 'clientY': first.clientY 1773 }); 1774 } else { 1775 simulatedEvent = document.createEvent('MouseEvent'); 1776 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0 1777 /*left*/ 1778 , null); 1779 } 1780 1781 first.target.dispatchEvent(simulatedEvent); 1782 }; 1783 }; 1784}; 1785 1786Touch.init = function ($$$1) { 1787 if (typeof $$$1.spotSwipe === 'undefined') { 1788 Touch.setupSpotSwipe($$$1); 1789 Touch.setupTouchHandler($$$1); 1790 } 1791}; 1792 1793var MutationObserver = function () { 1794 var prefixes = ['WebKit', 'Moz', 'O', 'Ms', '']; 1795 1796 for (var i = 0; i < prefixes.length; i++) { 1797 if ("".concat(prefixes[i], "MutationObserver") in window) { 1798 return window["".concat(prefixes[i], "MutationObserver")]; 1799 } 1800 } 1801 1802 return false; 1803}(); 1804 1805var triggers = function triggers(el, type) { 1806 el.data(type).split(' ').forEach(function (id) { 1807 jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(id))[type === 'close' ? 'trigger' : 'triggerHandler']("".concat(type, ".zf.trigger"), [el]); 1808 }); 1809}; 1810 1811var Triggers = { 1812 Listeners: { 1813 Basic: {}, 1814 Global: {} 1815 }, 1816 Initializers: {} 1817}; 1818Triggers.Listeners.Basic = { 1819 openListener: function openListener() { 1820 triggers(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 'open'); 1821 }, 1822 closeListener: function closeListener() { 1823 var id = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('close'); 1824 1825 if (id) { 1826 triggers(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 'close'); 1827 } else { 1828 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).trigger('close.zf.trigger'); 1829 } 1830 }, 1831 toggleListener: function toggleListener() { 1832 var id = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('toggle'); 1833 1834 if (id) { 1835 triggers(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 'toggle'); 1836 } else { 1837 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).trigger('toggle.zf.trigger'); 1838 } 1839 }, 1840 closeableListener: function closeableListener(e) { 1841 e.stopPropagation(); 1842 var animation = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('closable'); 1843 1844 if (animation !== '') { 1845 Motion.animateOut(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), animation, function () { 1846 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).trigger('closed.zf'); 1847 }); 1848 } else { 1849 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).fadeOut().trigger('closed.zf'); 1850 } 1851 }, 1852 toggleFocusListener: function toggleFocusListener() { 1853 var id = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('toggle-focus'); 1854 jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(id)).triggerHandler('toggle.zf.trigger', [jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)]); 1855 } 1856}; // Elements with [data-open] will reveal a plugin that supports it when clicked. 1857 1858Triggers.Initializers.addOpenListener = function ($elem) { 1859 $elem.off('click.zf.trigger', Triggers.Listeners.Basic.openListener); 1860 $elem.on('click.zf.trigger', '[data-open]', Triggers.Listeners.Basic.openListener); 1861}; // Elements with [data-close] will close a plugin that supports it when clicked. 1862// If used without a value on [data-close], the event will bubble, allowing it to close a parent component. 1863 1864 1865Triggers.Initializers.addCloseListener = function ($elem) { 1866 $elem.off('click.zf.trigger', Triggers.Listeners.Basic.closeListener); 1867 $elem.on('click.zf.trigger', '[data-close]', Triggers.Listeners.Basic.closeListener); 1868}; // Elements with [data-toggle] will toggle a plugin that supports it when clicked. 1869 1870 1871Triggers.Initializers.addToggleListener = function ($elem) { 1872 $elem.off('click.zf.trigger', Triggers.Listeners.Basic.toggleListener); 1873 $elem.on('click.zf.trigger', '[data-toggle]', Triggers.Listeners.Basic.toggleListener); 1874}; // Elements with [data-closable] will respond to close.zf.trigger events. 1875 1876 1877Triggers.Initializers.addCloseableListener = function ($elem) { 1878 $elem.off('close.zf.trigger', Triggers.Listeners.Basic.closeableListener); 1879 $elem.on('close.zf.trigger', '[data-closeable], [data-closable]', Triggers.Listeners.Basic.closeableListener); 1880}; // Elements with [data-toggle-focus] will respond to coming in and out of focus 1881 1882 1883Triggers.Initializers.addToggleFocusListener = function ($elem) { 1884 $elem.off('focus.zf.trigger blur.zf.trigger', Triggers.Listeners.Basic.toggleFocusListener); 1885 $elem.on('focus.zf.trigger blur.zf.trigger', '[data-toggle-focus]', Triggers.Listeners.Basic.toggleFocusListener); 1886}; // More Global/complex listeners and triggers 1887 1888 1889Triggers.Listeners.Global = { 1890 resizeListener: function resizeListener($nodes) { 1891 if (!MutationObserver) { 1892 //fallback for IE 9 1893 $nodes.each(function () { 1894 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).triggerHandler('resizeme.zf.trigger'); 1895 }); 1896 } //trigger all listening elements and signal a resize event 1897 1898 1899 $nodes.attr('data-events', "resize"); 1900 }, 1901 scrollListener: function scrollListener($nodes) { 1902 if (!MutationObserver) { 1903 //fallback for IE 9 1904 $nodes.each(function () { 1905 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).triggerHandler('scrollme.zf.trigger'); 1906 }); 1907 } //trigger all listening elements and signal a scroll event 1908 1909 1910 $nodes.attr('data-events', "scroll"); 1911 }, 1912 closeMeListener: function closeMeListener(e, pluginId) { 1913 var plugin = e.namespace.split('.')[0]; 1914 var plugins = jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-".concat(plugin, "]")).not("[data-yeti-box=\"".concat(pluginId, "\"]")); 1915 plugins.each(function () { 1916 var _this = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 1917 1918 _this.triggerHandler('close.zf.trigger', [_this]); 1919 }); 1920 } // Global, parses whole document. 1921 1922}; 1923 1924Triggers.Initializers.addClosemeListener = function (pluginName) { 1925 var yetiBoxes = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-yeti-box]'), 1926 plugNames = ['dropdown', 'tooltip', 'reveal']; 1927 1928 if (pluginName) { 1929 if (typeof pluginName === 'string') { 1930 plugNames.push(pluginName); 1931 } else if (_typeof(pluginName) === 'object' && typeof pluginName[0] === 'string') ;else { 1932 console.error('Plugin names must be strings'); 1933 } 1934 } 1935 1936 if (yetiBoxes.length) { 1937 var listeners = plugNames.map(function (name) { 1938 return "closeme.zf.".concat(name); 1939 }).join(' '); 1940 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(listeners).on(listeners, Triggers.Listeners.Global.closeMeListener); 1941 } 1942}; 1943 1944function debounceGlobalListener(debounce, trigger, listener) { 1945 var timer, 1946 args = Array.prototype.slice.call(arguments, 3); 1947 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(trigger).on(trigger, function (e) { 1948 if (timer) { 1949 clearTimeout(timer); 1950 } 1951 1952 timer = setTimeout(function () { 1953 listener.apply(null, args); 1954 }, debounce || 10); //default time to emit scroll event 1955 }); 1956} 1957 1958Triggers.Initializers.addResizeListener = function (debounce) { 1959 var $nodes = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-resize]'); 1960 1961 if ($nodes.length) { 1962 debounceGlobalListener(debounce, 'resize.zf.trigger', Triggers.Listeners.Global.resizeListener, $nodes); 1963 } 1964}; 1965 1966Triggers.Initializers.addScrollListener = function (debounce) { 1967 var $nodes = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-scroll]'); 1968 1969 if ($nodes.length) { 1970 debounceGlobalListener(debounce, 'scroll.zf.trigger', Triggers.Listeners.Global.scrollListener, $nodes); 1971 } 1972}; 1973 1974Triggers.Initializers.addMutationEventsListener = function ($elem) { 1975 if (!MutationObserver) { 1976 return false; 1977 } 1978 1979 var $nodes = $elem.find('[data-resize], [data-scroll], [data-mutate]'); //element callback 1980 1981 var listeningElementsMutation = function listeningElementsMutation(mutationRecordsList) { 1982 var $target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(mutationRecordsList[0].target); //trigger the event handler for the element depending on type 1983 1984 switch (mutationRecordsList[0].type) { 1985 case "attributes": 1986 if ($target.attr("data-events") === "scroll" && mutationRecordsList[0].attributeName === "data-events") { 1987 $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]); 1988 } 1989 1990 if ($target.attr("data-events") === "resize" && mutationRecordsList[0].attributeName === "data-events") { 1991 $target.triggerHandler('resizeme.zf.trigger', [$target]); 1992 } 1993 1994 if (mutationRecordsList[0].attributeName === "style") { 1995 $target.closest("[data-mutate]").attr("data-events", "mutate"); 1996 $target.closest("[data-mutate]").triggerHandler('mutateme.zf.trigger', [$target.closest("[data-mutate]")]); 1997 } 1998 1999 break; 2000 2001 case "childList": 2002 $target.closest("[data-mutate]").attr("data-events", "mutate"); 2003 $target.closest("[data-mutate]").triggerHandler('mutateme.zf.trigger', [$target.closest("[data-mutate]")]); 2004 break; 2005 2006 default: 2007 return false; 2008 //nothing 2009 } 2010 }; 2011 2012 if ($nodes.length) { 2013 //for each element that needs to listen for resizing, scrolling, or mutation add a single observer 2014 for (var i = 0; i <= $nodes.length - 1; i++) { 2015 var elementObserver = new MutationObserver(listeningElementsMutation); 2016 elementObserver.observe($nodes[i], { 2017 attributes: true, 2018 childList: true, 2019 characterData: false, 2020 subtree: true, 2021 attributeFilter: ["data-events", "style"] 2022 }); 2023 } 2024 } 2025}; 2026 2027Triggers.Initializers.addSimpleListeners = function () { 2028 var $document = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document); 2029 Triggers.Initializers.addOpenListener($document); 2030 Triggers.Initializers.addCloseListener($document); 2031 Triggers.Initializers.addToggleListener($document); 2032 Triggers.Initializers.addCloseableListener($document); 2033 Triggers.Initializers.addToggleFocusListener($document); 2034}; 2035 2036Triggers.Initializers.addGlobalListeners = function () { 2037 var $document = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document); 2038 Triggers.Initializers.addMutationEventsListener($document); 2039 Triggers.Initializers.addResizeListener(); 2040 Triggers.Initializers.addScrollListener(); 2041 Triggers.Initializers.addClosemeListener(); 2042}; 2043 2044Triggers.init = function ($$$1, Foundation) { 2045 onLoad($$$1(window), function () { 2046 if ($$$1.triggersInitialized !== true) { 2047 Triggers.Initializers.addSimpleListeners(); 2048 Triggers.Initializers.addGlobalListeners(); 2049 $$$1.triggersInitialized = true; 2050 } 2051 }); 2052 2053 if (Foundation) { 2054 Foundation.Triggers = Triggers; // Legacy included to be backwards compatible for now. 2055 2056 Foundation.IHearYou = Triggers.Initializers.addGlobalListeners; 2057 } 2058}; // {function} _setup (replaces previous constructor), 2059// {function} _destroy (replaces previous destroy) 2060 2061 2062var Plugin = 2063/*#__PURE__*/ 2064function () { 2065 function Plugin(element, options) { 2066 _classCallCheck(this, Plugin); 2067 2068 this._setup(element, options); 2069 2070 var pluginName = getPluginName(this); 2071 this.uuid = GetYoDigits(6, pluginName); 2072 2073 if (!this.$element.attr("data-".concat(pluginName))) { 2074 this.$element.attr("data-".concat(pluginName), this.uuid); 2075 } 2076 2077 if (!this.$element.data('zfPlugin')) { 2078 this.$element.data('zfPlugin', this); 2079 } 2080 /** 2081 * Fires when the plugin has initialized. 2082 * @event Plugin#init 2083 */ 2084 2085 2086 this.$element.trigger("init.zf.".concat(pluginName)); 2087 } 2088 2089 _createClass(Plugin, [{ 2090 key: "destroy", 2091 value: function destroy() { 2092 this._destroy(); 2093 2094 var pluginName = getPluginName(this); 2095 this.$element.removeAttr("data-".concat(pluginName)).removeData('zfPlugin') 2096 /** 2097 * Fires when the plugin has been destroyed. 2098 * @event Plugin#destroyed 2099 */ 2100 .trigger("destroyed.zf.".concat(pluginName)); 2101 2102 for (var prop in this) { 2103 this[prop] = null; //clean up script to prep for garbage collection. 2104 } 2105 } 2106 }]); 2107 2108 return Plugin; 2109}(); // Convert PascalCase to kebab-case 2110// Thank you: http://stackoverflow.com/a/8955580 2111 2112 2113function hyphenate$1(str) { 2114 return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 2115} 2116 2117function getPluginName(obj) { 2118 if (typeof obj.constructor.name !== 'undefined') { 2119 return hyphenate$1(obj.constructor.name); 2120 } else { 2121 return hyphenate$1(obj.className); 2122 } 2123} 2124/** 2125 * Abide module. 2126 * @module foundation.abide 2127 */ 2128 2129 2130var Abide = 2131/*#__PURE__*/ 2132function (_Plugin) { 2133 _inherits(Abide, _Plugin); 2134 2135 function Abide() { 2136 _classCallCheck(this, Abide); 2137 2138 return _possibleConstructorReturn(this, _getPrototypeOf(Abide).apply(this, arguments)); 2139 } 2140 2141 _createClass(Abide, [{ 2142 key: "_setup", 2143 2144 /** 2145 * Creates a new instance of Abide. 2146 * @class 2147 * @name Abide 2148 * @fires Abide#init 2149 * @param {Object} element - jQuery object to add the trigger to. 2150 * @param {Object} options - Overrides to the default plugin settings. 2151 */ 2152 value: function _setup(element) { 2153 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2154 this.$element = element; 2155 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(true, {}, Abide.defaults, this.$element.data(), options); 2156 this.className = 'Abide'; // ie9 back compat 2157 2158 this._init(); 2159 } 2160 /** 2161 * Initializes the Abide plugin and calls functions to get Abide functioning on load. 2162 * @private 2163 */ 2164 2165 }, { 2166 key: "_init", 2167 value: function _init() { 2168 var _this2 = this; 2169 2170 this.$inputs = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.merge( // Consider as input to validate: 2171 this.$element.find('input').not('[type=submit]'), // * all input fields expect submit 2172 this.$element.find('textarea, select') // * all textareas and select fields 2173 ); 2174 var $globalErrors = this.$element.find('[data-abide-error]'); // Add a11y attributes to all fields 2175 2176 if (this.options.a11yAttributes) { 2177 this.$inputs.each(function (i, input) { 2178 return _this2.addA11yAttributes(jquery__WEBPACK_IMPORTED_MODULE_0___default()(input)); 2179 }); 2180 $globalErrors.each(function (i, error) { 2181 return _this2.addGlobalErrorA11yAttributes(jquery__WEBPACK_IMPORTED_MODULE_0___default()(error)); 2182 }); 2183 } 2184 2185 this._events(); 2186 } 2187 /** 2188 * Initializes events for Abide. 2189 * @private 2190 */ 2191 2192 }, { 2193 key: "_events", 2194 value: function _events() { 2195 var _this3 = this; 2196 2197 this.$element.off('.abide').on('reset.zf.abide', function () { 2198 _this3.resetForm(); 2199 }).on('submit.zf.abide', function () { 2200 return _this3.validateForm(); 2201 }); 2202 2203 if (this.options.validateOn === 'fieldChange') { 2204 this.$inputs.off('change.zf.abide').on('change.zf.abide', function (e) { 2205 _this3.validateInput(jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target)); 2206 }); 2207 } 2208 2209 if (this.options.liveValidate) { 2210 this.$inputs.off('input.zf.abide').on('input.zf.abide', function (e) { 2211 _this3.validateInput(jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target)); 2212 }); 2213 } 2214 2215 if (this.options.validateOnBlur) { 2216 this.$inputs.off('blur.zf.abide').on('blur.zf.abide', function (e) { 2217 _this3.validateInput(jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target)); 2218 }); 2219 } 2220 } 2221 /** 2222 * Calls necessary functions to update Abide upon DOM change 2223 * @private 2224 */ 2225 2226 }, { 2227 key: "_reflow", 2228 value: function _reflow() { 2229 this._init(); 2230 } 2231 /** 2232 * Checks whether or not a form element has the required attribute and if it's checked or not 2233 * @param {Object} element - jQuery object to check for required attribute 2234 * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty 2235 */ 2236 2237 }, { 2238 key: "requiredCheck", 2239 value: function requiredCheck($el) { 2240 if (!$el.attr('required')) return true; 2241 var isGood = true; 2242 2243 switch ($el[0].type) { 2244 case 'checkbox': 2245 isGood = $el[0].checked; 2246 break; 2247 2248 case 'select': 2249 case 'select-one': 2250 case 'select-multiple': 2251 var opt = $el.find('option:selected'); 2252 if (!opt.length || !opt.val()) isGood = false; 2253 break; 2254 2255 default: 2256 if (!$el.val() || !$el.val().length) isGood = false; 2257 } 2258 2259 return isGood; 2260 } 2261 /** 2262 * Get: 2263 * - Based on $el, the first element(s) corresponding to `formErrorSelector` in this order: 2264 * 1. The element's direct sibling('s). 2265 * 2. The element's parent's children. 2266 * - Element(s) with the attribute `[data-form-error-for]` set with the element's id. 2267 * 2268 * This allows for multiple form errors per input, though if none are found, no form errors will be shown. 2269 * 2270 * @param {Object} $el - jQuery object to use as reference to find the form error selector. 2271 * @returns {Object} jQuery object with the selector. 2272 */ 2273 2274 }, { 2275 key: "findFormError", 2276 value: function findFormError($el) { 2277 var id = $el[0].id; 2278 var $error = $el.siblings(this.options.formErrorSelector); 2279 2280 if (!$error.length) { 2281 $error = $el.parent().find(this.options.formErrorSelector); 2282 } 2283 2284 if (id) { 2285 $error = $error.add(this.$element.find("[data-form-error-for=\"".concat(id, "\"]"))); 2286 } 2287 2288 return $error; 2289 } 2290 /** 2291 * Get the first element in this order: 2292 * 2. The <label> with the attribute `[for="someInputId"]` 2293 * 3. The `.closest()` <label> 2294 * 2295 * @param {Object} $el - jQuery object to check for required attribute 2296 * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty 2297 */ 2298 2299 }, { 2300 key: "findLabel", 2301 value: function findLabel($el) { 2302 var id = $el[0].id; 2303 var $label = this.$element.find("label[for=\"".concat(id, "\"]")); 2304 2305 if (!$label.length) { 2306 return $el.closest('label'); 2307 } 2308 2309 return $label; 2310 } 2311 /** 2312 * Get the set of labels associated with a set of radio els in this order 2313 * 2. The <label> with the attribute `[for="someInputId"]` 2314 * 3. The `.closest()` <label> 2315 * 2316 * @param {Object} $el - jQuery object to check for required attribute 2317 * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty 2318 */ 2319 2320 }, { 2321 key: "findRadioLabels", 2322 value: function findRadioLabels($els) { 2323 var _this4 = this; 2324 2325 var labels = $els.map(function (i, el) { 2326 var id = el.id; 2327 2328 var $label = _this4.$element.find("label[for=\"".concat(id, "\"]")); 2329 2330 if (!$label.length) { 2331 $label = jquery__WEBPACK_IMPORTED_MODULE_0___default()(el).closest('label'); 2332 } 2333 2334 return $label[0]; 2335 }); 2336 return jquery__WEBPACK_IMPORTED_MODULE_0___default()(labels); 2337 } 2338 /** 2339 * Adds the CSS error class as specified by the Abide settings to the label, input, and the form 2340 * @param {Object} $el - jQuery object to add the class to 2341 */ 2342 2343 }, { 2344 key: "addErrorClasses", 2345 value: function addErrorClasses($el) { 2346 var $label = this.findLabel($el); 2347 var $formError = this.findFormError($el); 2348 2349 if ($label.length) { 2350 $label.addClass(this.options.labelErrorClass); 2351 } 2352 2353 if ($formError.length) { 2354 $formError.addClass(this.options.formErrorClass); 2355 } 2356 2357 $el.addClass(this.options.inputErrorClass).attr({ 2358 'data-invalid': '', 2359 'aria-invalid': true 2360 }); 2361 } 2362 /** 2363 * Adds [for] and [role=alert] attributes to all form error targetting $el, 2364 * and [aria-describedby] attribute to $el toward the first form error. 2365 * @param {Object} $el - jQuery object 2366 */ 2367 2368 }, { 2369 key: "addA11yAttributes", 2370 value: function addA11yAttributes($el) { 2371 var $errors = this.findFormError($el); 2372 var $labels = $errors.filter('label'); 2373 var $error = $errors.first(); 2374 if (!$errors.length) return; // Set [aria-describedby] on the input toward the first form error if it is not set 2375 2376 if (typeof $el.attr('aria-describedby') === 'undefined') { 2377 // Get the first error ID or create one 2378 var errorId = $error.attr('id'); 2379 2380 if (typeof errorId === 'undefined') { 2381 errorId = GetYoDigits(6, 'abide-error'); 2382 $error.attr('id', errorId); 2383 } 2384 2385 $el.attr('aria-describedby', errorId); 2386 } 2387 2388 if ($labels.filter('[for]').length < $labels.length) { 2389 // Get the input ID or create one 2390 var elemId = $el.attr('id'); 2391 2392 if (typeof elemId === 'undefined') { 2393 elemId = GetYoDigits(6, 'abide-input'); 2394 $el.attr('id', elemId); 2395 } 2396 2397 $labels.each(function (i, label) { 2398 var $label = jquery__WEBPACK_IMPORTED_MODULE_0___default()(label); 2399 if (typeof $label.attr('for') === 'undefined') $label.attr('for', elemId); 2400 }); 2401 } // For each error targeting $el, set [role=alert] if it is not set. 2402 2403 2404 $errors.each(function (i, label) { 2405 var $label = jquery__WEBPACK_IMPORTED_MODULE_0___default()(label); 2406 if (typeof $label.attr('role') === 'undefined') $label.attr('role', 'alert'); 2407 }).end(); 2408 } 2409 /** 2410 * Adds [aria-live] attribute to the given global form error $el. 2411 * @param {Object} $el - jQuery object to add the attribute to 2412 */ 2413 2414 }, { 2415 key: "addGlobalErrorA11yAttributes", 2416 value: function addGlobalErrorA11yAttributes($el) { 2417 if (typeof $el.attr('aria-live') === 'undefined') $el.attr('aria-live', this.options.a11yErrorLevel); 2418 } 2419 /** 2420 * Remove CSS error classes etc from an entire radio button group 2421 * @param {String} groupName - A string that specifies the name of a radio button group 2422 * 2423 */ 2424 2425 }, { 2426 key: "removeRadioErrorClasses", 2427 value: function removeRadioErrorClasses(groupName) { 2428 var $els = this.$element.find(":radio[name=\"".concat(groupName, "\"]")); 2429 var $labels = this.findRadioLabels($els); 2430 var $formErrors = this.findFormError($els); 2431 2432 if ($labels.length) { 2433 $labels.removeClass(this.options.labelErrorClass); 2434 } 2435 2436 if ($formErrors.length) { 2437 $formErrors.removeClass(this.options.formErrorClass); 2438 } 2439 2440 $els.removeClass(this.options.inputErrorClass).attr({ 2441 'data-invalid': null, 2442 'aria-invalid': null 2443 }); 2444 } 2445 /** 2446 * Removes CSS error class as specified by the Abide settings from the label, input, and the form 2447 * @param {Object} $el - jQuery object to remove the class from 2448 */ 2449 2450 }, { 2451 key: "removeErrorClasses", 2452 value: function removeErrorClasses($el) { 2453 // radios need to clear all of the els 2454 if ($el[0].type == 'radio') { 2455 return this.removeRadioErrorClasses($el.attr('name')); 2456 } 2457 2458 var $label = this.findLabel($el); 2459 var $formError = this.findFormError($el); 2460 2461 if ($label.length) { 2462 $label.removeClass(this.options.labelErrorClass); 2463 } 2464 2465 if ($formError.length) { 2466 $formError.removeClass(this.options.formErrorClass); 2467 } 2468 2469 $el.removeClass(this.options.inputErrorClass).attr({ 2470 'data-invalid': null, 2471 'aria-invalid': null 2472 }); 2473 } 2474 /** 2475 * Goes through a form to find inputs and proceeds to validate them in ways specific to their type. 2476 * Ignores inputs with data-abide-ignore, type="hidden" or disabled attributes set 2477 * @fires Abide#invalid 2478 * @fires Abide#valid 2479 * @param {Object} element - jQuery object to validate, should be an HTML input 2480 * @returns {Boolean} goodToGo - If the input is valid or not. 2481 */ 2482 2483 }, { 2484 key: "validateInput", 2485 value: function validateInput($el) { 2486 var clearRequire = this.requiredCheck($el), 2487 validated = false, 2488 customValidator = true, 2489 validator = $el.attr('data-validator'), 2490 equalTo = true; // don't validate ignored inputs or hidden inputs or disabled inputs 2491 2492 if ($el.is('[data-abide-ignore]') || $el.is('[type="hidden"]') || $el.is('[disabled]')) { 2493 return true; 2494 } 2495 2496 switch ($el[0].type) { 2497 case 'radio': 2498 validated = this.validateRadio($el.attr('name')); 2499 break; 2500 2501 case 'checkbox': 2502 validated = clearRequire; 2503 break; 2504 2505 case 'select': 2506 case 'select-one': 2507 case 'select-multiple': 2508 validated = clearRequire; 2509 break; 2510 2511 default: 2512 validated = this.validateText($el); 2513 } 2514 2515 if (validator) { 2516 customValidator = this.matchValidation($el, validator, $el.attr('required')); 2517 } 2518 2519 if ($el.attr('data-equalto')) { 2520 equalTo = this.options.validators.equalTo($el); 2521 } 2522 2523 var goodToGo = [clearRequire, validated, customValidator, equalTo].indexOf(false) === -1; 2524 var message = (goodToGo ? 'valid' : 'invalid') + '.zf.abide'; 2525 2526 if (goodToGo) { 2527 // Re-validate inputs that depend on this one with equalto 2528 var dependentElements = this.$element.find("[data-equalto=\"".concat($el.attr('id'), "\"]")); 2529 2530 if (dependentElements.length) { 2531 var _this = this; 2532 2533 dependentElements.each(function () { 2534 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).val()) { 2535 _this.validateInput(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 2536 } 2537 }); 2538 } 2539 } 2540 2541 this[goodToGo ? 'removeErrorClasses' : 'addErrorClasses']($el); 2542 /** 2543 * Fires when the input is done checking for validation. Event trigger is either `valid.zf.abide` or `invalid.zf.abide` 2544 * Trigger includes the DOM element of the input. 2545 * @event Abide#valid 2546 * @event Abide#invalid 2547 */ 2548 2549 $el.trigger(message, [$el]); 2550 return goodToGo; 2551 } 2552 /** 2553 * Goes through a form and if there are any invalid inputs, it will display the form error element 2554 * @returns {Boolean} noError - true if no errors were detected... 2555 * @fires Abide#formvalid 2556 * @fires Abide#forminvalid 2557 */ 2558 2559 }, { 2560 key: "validateForm", 2561 value: function validateForm() { 2562 var _this5 = this; 2563 2564 var acc = []; 2565 2566 var _this = this; 2567 2568 this.$inputs.each(function () { 2569 acc.push(_this.validateInput(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this))); 2570 }); 2571 var noError = acc.indexOf(false) === -1; 2572 this.$element.find('[data-abide-error]').each(function (i, elem) { 2573 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(elem); // Ensure a11y attributes are set 2574 2575 if (_this5.options.a11yAttributes) _this5.addGlobalErrorA11yAttributes($elem); // Show or hide the error 2576 2577 $elem.css('display', noError ? 'none' : 'block'); 2578 }); 2579 /** 2580 * Fires when the form is finished validating. Event trigger is either `formvalid.zf.abide` or `forminvalid.zf.abide`. 2581 * Trigger includes the element of the form. 2582 * @event Abide#formvalid 2583 * @event Abide#forminvalid 2584 */ 2585 2586 this.$element.trigger((noError ? 'formvalid' : 'forminvalid') + '.zf.abide', [this.$element]); 2587 return noError; 2588 } 2589 /** 2590 * Determines whether or a not a text input is valid based on the pattern specified in the attribute. If no matching pattern is found, returns true. 2591 * @param {Object} $el - jQuery object to validate, should be a text input HTML element 2592 * @param {String} pattern - string value of one of the RegEx patterns in Abide.options.patterns 2593 * @returns {Boolean} Boolean value depends on whether or not the input value matches the pattern specified 2594 */ 2595 2596 }, { 2597 key: "validateText", 2598 value: function validateText($el, pattern) { 2599 // A pattern can be passed to this function, or it will be infered from the input's "pattern" attribute, or it's "type" attribute 2600 pattern = pattern || $el.attr('pattern') || $el.attr('type'); 2601 var inputText = $el.val(); 2602 var valid = false; 2603 2604 if (inputText.length) { 2605 // If the pattern attribute on the element is in Abide's list of patterns, then test that regexp 2606 if (this.options.patterns.hasOwnProperty(pattern)) { 2607 valid = this.options.patterns[pattern].test(inputText); 2608 } // If the pattern name isn't also the type attribute of the field, then test it as a regexp 2609 else if (pattern !== $el.attr('type')) { 2610 valid = new RegExp(pattern).test(inputText); 2611 } else { 2612 valid = true; 2613 } 2614 } // An empty field is valid if it's not required 2615 else if (!$el.prop('required')) { 2616 valid = true; 2617 } 2618 2619 return valid; 2620 } 2621 /** 2622 * Determines whether or a not a radio input is valid based on whether or not it is required and selected. Although the function targets a single `<input>`, it validates by checking the `required` and `checked` properties of all radio buttons in its group. 2623 * @param {String} groupName - A string that specifies the name of a radio button group 2624 * @returns {Boolean} Boolean value depends on whether or not at least one radio input has been selected (if it's required) 2625 */ 2626 2627 }, { 2628 key: "validateRadio", 2629 value: function validateRadio(groupName) { 2630 // If at least one radio in the group has the `required` attribute, the group is considered required 2631 // Per W3C spec, all radio buttons in a group should have `required`, but we're being nice 2632 var $group = this.$element.find(":radio[name=\"".concat(groupName, "\"]")); 2633 var valid = false, 2634 required = false; // For the group to be required, at least one radio needs to be required 2635 2636 $group.each(function (i, e) { 2637 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(e).attr('required')) { 2638 required = true; 2639 } 2640 }); 2641 if (!required) valid = true; 2642 2643 if (!valid) { 2644 // For the group to be valid, at least one radio needs to be checked 2645 $group.each(function (i, e) { 2646 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(e).prop('checked')) { 2647 valid = true; 2648 } 2649 }); 2650 } 2651 2652 return valid; 2653 } 2654 /** 2655 * Determines if a selected input passes a custom validation function. Multiple validations can be used, if passed to the element with `data-validator="foo bar baz"` in a space separated listed. 2656 * @param {Object} $el - jQuery input element. 2657 * @param {String} validators - a string of function names matching functions in the Abide.options.validators object. 2658 * @param {Boolean} required - self explanatory? 2659 * @returns {Boolean} - true if validations passed. 2660 */ 2661 2662 }, { 2663 key: "matchValidation", 2664 value: function matchValidation($el, validators, required) { 2665 var _this6 = this; 2666 2667 required = required ? true : false; 2668 var clear = validators.split(' ').map(function (v) { 2669 return _this6.options.validators[v]($el, required, $el.parent()); 2670 }); 2671 return clear.indexOf(false) === -1; 2672 } 2673 /** 2674 * Resets form inputs and styles 2675 * @fires Abide#formreset 2676 */ 2677 2678 }, { 2679 key: "resetForm", 2680 value: function resetForm() { 2681 var $form = this.$element, 2682 opts = this.options; 2683 jquery__WEBPACK_IMPORTED_MODULE_0___default()(".".concat(opts.labelErrorClass), $form).not('small').removeClass(opts.labelErrorClass); 2684 jquery__WEBPACK_IMPORTED_MODULE_0___default()(".".concat(opts.inputErrorClass), $form).not('small').removeClass(opts.inputErrorClass); 2685 jquery__WEBPACK_IMPORTED_MODULE_0___default()("".concat(opts.formErrorSelector, ".").concat(opts.formErrorClass)).removeClass(opts.formErrorClass); 2686 $form.find('[data-abide-error]').css('display', 'none'); 2687 jquery__WEBPACK_IMPORTED_MODULE_0___default()(':input', $form).not(':button, :submit, :reset, :hidden, :radio, :checkbox, [data-abide-ignore]').val('').attr({ 2688 'data-invalid': null, 2689 'aria-invalid': null 2690 }); 2691 jquery__WEBPACK_IMPORTED_MODULE_0___default()(':input:radio', $form).not('[data-abide-ignore]').prop('checked', false).attr({ 2692 'data-invalid': null, 2693 'aria-invalid': null 2694 }); 2695 jquery__WEBPACK_IMPORTED_MODULE_0___default()(':input:checkbox', $form).not('[data-abide-ignore]').prop('checked', false).attr({ 2696 'data-invalid': null, 2697 'aria-invalid': null 2698 }); 2699 /** 2700 * Fires when the form has been reset. 2701 * @event Abide#formreset 2702 */ 2703 2704 $form.trigger('formreset.zf.abide', [$form]); 2705 } 2706 /** 2707 * Destroys an instance of Abide. 2708 * Removes error styles and classes from elements, without resetting their values. 2709 */ 2710 2711 }, { 2712 key: "_destroy", 2713 value: function _destroy() { 2714 var _this = this; 2715 2716 this.$element.off('.abide').find('[data-abide-error]').css('display', 'none'); 2717 this.$inputs.off('.abide').each(function () { 2718 _this.removeErrorClasses(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 2719 }); 2720 } 2721 }]); 2722 2723 return Abide; 2724}(Plugin); 2725/** 2726 * Default settings for plugin 2727 */ 2728 2729 2730Abide.defaults = { 2731 /** 2732 * The default event to validate inputs. Checkboxes and radios validate immediately. 2733 * Remove or change this value for manual validation. 2734 * @option 2735 * @type {?string} 2736 * @default 'fieldChange' 2737 */ 2738 validateOn: 'fieldChange', 2739 2740 /** 2741 * Class to be applied to input labels on failed validation. 2742 * @option 2743 * @type {string} 2744 * @default 'is-invalid-label' 2745 */ 2746 labelErrorClass: 'is-invalid-label', 2747 2748 /** 2749 * Class to be applied to inputs on failed validation. 2750 * @option 2751 * @type {string} 2752 * @default 'is-invalid-input' 2753 */ 2754 inputErrorClass: 'is-invalid-input', 2755 2756 /** 2757 * Class selector to use to target Form Errors for show/hide. 2758 * @option 2759 * @type {string} 2760 * @default '.form-error' 2761 */ 2762 formErrorSelector: '.form-error', 2763 2764 /** 2765 * Class added to Form Errors on failed validation. 2766 * @option 2767 * @type {string} 2768 * @default 'is-visible' 2769 */ 2770 formErrorClass: 'is-visible', 2771 2772 /** 2773 * If true, automatically insert when possible: 2774 * - `[aria-describedby]` on fields 2775 * - `[role=alert]` on form errors and `[for]` on form error labels 2776 * - `[aria-live]` on global errors `[data-abide-error]` (see option `a11yErrorLevel`). 2777 * @option 2778 * @type {boolean} 2779 * @default true 2780 */ 2781 a11yAttributes: true, 2782 2783 /** 2784 * [aria-live] attribute value to be applied on global errors `[data-abide-error]`. 2785 * Options are: 'assertive', 'polite' and 'off'/null 2786 * @option 2787 * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions 2788 * @type {string} 2789 * @default 'assertive' 2790 */ 2791 a11yErrorLevel: 'assertive', 2792 2793 /** 2794 * Set to true to validate text inputs on any value change. 2795 * @option 2796 * @type {boolean} 2797 * @default false 2798 */ 2799 liveValidate: false, 2800 2801 /** 2802 * Set to true to validate inputs on blur. 2803 * @option 2804 * @type {boolean} 2805 * @default false 2806 */ 2807 validateOnBlur: false, 2808 patterns: { 2809 alpha: /^[a-zA-Z]+$/, 2810 alpha_numeric: /^[a-zA-Z0-9]+$/, 2811 integer: /^[-+]?\d+$/, 2812 number: /^[-+]?\d*(?:[\.\,]\d+)?$/, 2813 // amex, visa, diners 2814 card: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(?:222[1-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/, 2815 cvv: /^([0-9]){3,4}$/, 2816 // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address 2817 email: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/, 2818 // From CommonRegexJS (@talyssonoc) 2819 // https://github.com/talyssonoc/CommonRegexJS/blob/e2901b9f57222bc14069dc8f0598d5f412555411/lib/commonregex.js#L76 2820 // For more restrictive URL Regexs, see https://mathiasbynens.be/demo/url-regex. 2821 url: /^((?:(https?|ftps?|file|ssh|sftp):\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))$/, 2822 // abc.de 2823 domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/, 2824 datetime: /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/, 2825 // YYYY-MM-DD 2826 date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/, 2827 // HH:MM:SS 2828 time: /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/, 2829 dateISO: /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/, 2830 // MM/DD/YYYY 2831 month_day_year: /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/, 2832 // DD/MM/YYYY 2833 day_month_year: /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/, 2834 // #FFF or #FFFFFF 2835 color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/, 2836 // Domain || URL 2837 website: { 2838 test: function test(text) { 2839 return Abide.defaults.patterns['domain'].test(text) || Abide.defaults.patterns['url'].test(text); 2840 } 2841 } 2842 }, 2843 2844 /** 2845 * Optional validation functions to be used. `equalTo` being the only default included function. 2846 * Functions should return only a boolean if the input is valid or not. Functions are given the following arguments: 2847 * el : The jQuery element to validate. 2848 * required : Boolean value of the required attribute be present or not. 2849 * parent : The direct parent of the input. 2850 * @option 2851 */ 2852 validators: { 2853 equalTo: function equalTo(el, required, parent) { 2854 return jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(el.attr('data-equalto'))).val() === el.val(); 2855 } 2856 } 2857}; 2858/** 2859 * Accordion module. 2860 * @module foundation.accordion 2861 * @requires foundation.util.keyboard 2862 */ 2863 2864var Accordion = 2865/*#__PURE__*/ 2866function (_Plugin) { 2867 _inherits(Accordion, _Plugin); 2868 2869 function Accordion() { 2870 _classCallCheck(this, Accordion); 2871 2872 return _possibleConstructorReturn(this, _getPrototypeOf(Accordion).apply(this, arguments)); 2873 } 2874 2875 _createClass(Accordion, [{ 2876 key: "_setup", 2877 2878 /** 2879 * Creates a new instance of an accordion. 2880 * @class 2881 * @name Accordion 2882 * @fires Accordion#init 2883 * @param {jQuery} element - jQuery object to make into an accordion. 2884 * @param {Object} options - a plain object with settings to override the default options. 2885 */ 2886 value: function _setup(element, options) { 2887 this.$element = element; 2888 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Accordion.defaults, this.$element.data(), options); 2889 this.className = 'Accordion'; // ie9 back compat 2890 2891 this._init(); 2892 2893 Keyboard.register('Accordion', { 2894 'ENTER': 'toggle', 2895 'SPACE': 'toggle', 2896 'ARROW_DOWN': 'next', 2897 'ARROW_UP': 'previous' 2898 }); 2899 } 2900 /** 2901 * Initializes the accordion by animating the preset active pane(s). 2902 * @private 2903 */ 2904 2905 }, { 2906 key: "_init", 2907 value: function _init() { 2908 var _this2 = this; 2909 2910 this._isInitializing = true; 2911 this.$element.attr('role', 'tablist'); 2912 this.$tabs = this.$element.children('[data-accordion-item]'); 2913 this.$tabs.each(function (idx, el) { 2914 var $el = jquery__WEBPACK_IMPORTED_MODULE_0___default()(el), 2915 $content = $el.children('[data-tab-content]'), 2916 id = $content[0].id || GetYoDigits(6, 'accordion'), 2917 linkId = el.id ? "".concat(el.id, "-label") : "".concat(id, "-label"); 2918 $el.find('a:first').attr({ 2919 'aria-controls': id, 2920 'role': 'tab', 2921 'id': linkId, 2922 'aria-expanded': false, 2923 'aria-selected': false 2924 }); 2925 $content.attr({ 2926 'role': 'tabpanel', 2927 'aria-labelledby': linkId, 2928 'aria-hidden': true, 2929 'id': id 2930 }); 2931 }); 2932 var $initActive = this.$element.find('.is-active').children('[data-tab-content]'); 2933 2934 if ($initActive.length) { 2935 // Save up the initial hash to return to it later when going back in history 2936 this._initialAnchor = $initActive.prev('a').attr('href'); 2937 2938 this._openSingleTab($initActive); 2939 } 2940 2941 this._checkDeepLink = function () { 2942 var anchor = window.location.hash; 2943 2944 if (!anchor.length) { 2945 // If we are still initializing and there is no anchor, then there is nothing to do 2946 if (_this2._isInitializing) return; // Otherwise, move to the initial anchor 2947 2948 if (_this2._initialAnchor) anchor = _this2._initialAnchor; 2949 } 2950 2951 var $anchor = anchor && jquery__WEBPACK_IMPORTED_MODULE_0___default()(anchor); 2952 2953 var $link = anchor && _this2.$element.find("[href$=\"".concat(anchor, "\"]")); // Whether the anchor element that has been found is part of this element 2954 2955 2956 var isOwnAnchor = !!($anchor.length && $link.length); // If there is an anchor for the hash, open it (if not already active) 2957 2958 if ($anchor && $link && $link.length) { 2959 if (!$link.parent('[data-accordion-item]').hasClass('is-active')) { 2960 _this2._openSingleTab($anchor); 2961 } 2962 } // Otherwise, close everything 2963 else { 2964 _this2._closeAllTabs(); 2965 } 2966 2967 if (isOwnAnchor) { 2968 // Roll up a little to show the titles 2969 if (_this2.options.deepLinkSmudge) { 2970 onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 2971 var offset = _this2.$element.offset(); 2972 2973 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').animate({ 2974 scrollTop: offset.top 2975 }, _this2.options.deepLinkSmudgeDelay); 2976 }); 2977 } 2978 /** 2979 * Fires when the plugin has deeplinked at pageload 2980 * @event Accordion#deeplink 2981 */ 2982 2983 2984 _this2.$element.trigger('deeplink.zf.accordion', [$link, $anchor]); 2985 } 2986 }; //use browser to open a tab, if it exists in this tabset 2987 2988 2989 if (this.options.deepLink) { 2990 this._checkDeepLink(); 2991 } 2992 2993 this._events(); 2994 2995 this._isInitializing = false; 2996 } 2997 /** 2998 * Adds event handlers for items within the accordion. 2999 * @private 3000 */ 3001 3002 }, { 3003 key: "_events", 3004 value: function _events() { 3005 var _this = this; 3006 3007 this.$tabs.each(function () { 3008 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 3009 var $tabContent = $elem.children('[data-tab-content]'); 3010 3011 if ($tabContent.length) { 3012 $elem.children('a').off('click.zf.accordion keydown.zf.accordion').on('click.zf.accordion', function (e) { 3013 e.preventDefault(); 3014 3015 _this.toggle($tabContent); 3016 }).on('keydown.zf.accordion', function (e) { 3017 Keyboard.handleKey(e, 'Accordion', { 3018 toggle: function toggle() { 3019 _this.toggle($tabContent); 3020 }, 3021 next: function next() { 3022 var $a = $elem.next().find('a').focus(); 3023 3024 if (!_this.options.multiExpand) { 3025 $a.trigger('click.zf.accordion'); 3026 } 3027 }, 3028 previous: function previous() { 3029 var $a = $elem.prev().find('a').focus(); 3030 3031 if (!_this.options.multiExpand) { 3032 $a.trigger('click.zf.accordion'); 3033 } 3034 }, 3035 handled: function handled() { 3036 e.preventDefault(); 3037 e.stopPropagation(); 3038 } 3039 }); 3040 }); 3041 } 3042 }); 3043 3044 if (this.options.deepLink) { 3045 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('hashchange', this._checkDeepLink); 3046 } 3047 } 3048 /** 3049 * Toggles the selected content pane's open/close state. 3050 * @param {jQuery} $target - jQuery object of the pane to toggle (`.accordion-content`). 3051 * @function 3052 */ 3053 3054 }, { 3055 key: "toggle", 3056 value: function toggle($target) { 3057 if ($target.closest('[data-accordion]').is('[disabled]')) { 3058 console.info('Cannot toggle an accordion that is disabled.'); 3059 return; 3060 } 3061 3062 if ($target.parent().hasClass('is-active')) { 3063 this.up($target); 3064 } else { 3065 this.down($target); 3066 } //either replace or update browser history 3067 3068 3069 if (this.options.deepLink) { 3070 var anchor = $target.prev('a').attr('href'); 3071 3072 if (this.options.updateHistory) { 3073 history.pushState({}, '', anchor); 3074 } else { 3075 history.replaceState({}, '', anchor); 3076 } 3077 } 3078 } 3079 /** 3080 * Opens the accordion tab defined by `$target`. 3081 * @param {jQuery} $target - Accordion pane to open (`.accordion-content`). 3082 * @fires Accordion#down 3083 * @function 3084 */ 3085 3086 }, { 3087 key: "down", 3088 value: function down($target) { 3089 if ($target.closest('[data-accordion]').is('[disabled]')) { 3090 console.info('Cannot call down on an accordion that is disabled.'); 3091 return; 3092 } 3093 3094 if (this.options.multiExpand) this._openTab($target);else this._openSingleTab($target); 3095 } 3096 /** 3097 * Closes the tab defined by `$target`. 3098 * It may be ignored if the Accordion options don't allow it. 3099 * 3100 * @param {jQuery} $target - Accordion tab to close (`.accordion-content`). 3101 * @fires Accordion#up 3102 * @function 3103 */ 3104 3105 }, { 3106 key: "up", 3107 value: function up($target) { 3108 if (this.$element.is('[disabled]')) { 3109 console.info('Cannot call up on an accordion that is disabled.'); 3110 return; 3111 } // Don't close the item if it is already closed 3112 3113 3114 var $targetItem = $target.parent(); 3115 if (!$targetItem.hasClass('is-active')) return; // Don't close the item if there is no other active item (unless with `allowAllClosed`) 3116 3117 var $othersItems = $targetItem.siblings(); 3118 if (!this.options.allowAllClosed && !$othersItems.hasClass('is-active')) return; 3119 3120 this._closeTab($target); 3121 } 3122 /** 3123 * Make the tab defined by `$target` the only opened tab, closing all others tabs. 3124 * @param {jQuery} $target - Accordion tab to open (`.accordion-content`). 3125 * @function 3126 * @private 3127 */ 3128 3129 }, { 3130 key: "_openSingleTab", 3131 value: function _openSingleTab($target) { 3132 // Close all the others active tabs. 3133 var $activeContents = this.$element.children('.is-active').children('[data-tab-content]'); 3134 3135 if ($activeContents.length) { 3136 this._closeTab($activeContents.not($target)); 3137 } // Then open the target. 3138 3139 3140 this._openTab($target); 3141 } 3142 /** 3143 * Opens the tab defined by `$target`. 3144 * @param {jQuery} $target - Accordion tab to open (`.accordion-content`). 3145 * @fires Accordion#down 3146 * @function 3147 * @private 3148 */ 3149 3150 }, { 3151 key: "_openTab", 3152 value: function _openTab($target) { 3153 var _this3 = this; 3154 3155 var $targetItem = $target.parent(); 3156 var targetContentId = $target.attr('aria-labelledby'); 3157 $target.attr('aria-hidden', false); 3158 $targetItem.addClass('is-active'); 3159 jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(targetContentId)).attr({ 3160 'aria-expanded': true, 3161 'aria-selected': true 3162 }); 3163 $target.slideDown(this.options.slideSpeed, function () { 3164 /** 3165 * Fires when the tab is done opening. 3166 * @event Accordion#down 3167 */ 3168 _this3.$element.trigger('down.zf.accordion', [$target]); 3169 }); 3170 } 3171 /** 3172 * Closes the tab defined by `$target`. 3173 * @param {jQuery} $target - Accordion tab to close (`.accordion-content`). 3174 * @fires Accordion#up 3175 * @function 3176 * @private 3177 */ 3178 3179 }, { 3180 key: "_closeTab", 3181 value: function _closeTab($target) { 3182 var _this4 = this; 3183 3184 var $targetItem = $target.parent(); 3185 var targetContentId = $target.attr('aria-labelledby'); 3186 $target.attr('aria-hidden', true); 3187 $targetItem.removeClass('is-active'); 3188 jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(targetContentId)).attr({ 3189 'aria-expanded': false, 3190 'aria-selected': false 3191 }); 3192 $target.slideUp(this.options.slideSpeed, function () { 3193 /** 3194 * Fires when the tab is done collapsing up. 3195 * @event Accordion#up 3196 */ 3197 _this4.$element.trigger('up.zf.accordion', [$target]); 3198 }); 3199 } 3200 /** 3201 * Closes all active tabs 3202 * @fires Accordion#up 3203 * @function 3204 * @private 3205 */ 3206 3207 }, { 3208 key: "_closeAllTabs", 3209 value: function _closeAllTabs() { 3210 var $activeTabs = this.$element.children('.is-active').children('[data-tab-content]'); 3211 3212 if ($activeTabs.length) { 3213 this._closeTab($activeTabs); 3214 } 3215 } 3216 /** 3217 * Destroys an instance of an accordion. 3218 * @fires Accordion#destroyed 3219 * @function 3220 */ 3221 3222 }, { 3223 key: "_destroy", 3224 value: function _destroy() { 3225 this.$element.find('[data-tab-content]').stop(true).slideUp(0).css('display', ''); 3226 this.$element.find('a').off('.zf.accordion'); 3227 3228 if (this.options.deepLink) { 3229 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('hashchange', this._checkDeepLink); 3230 } 3231 } 3232 }]); 3233 3234 return Accordion; 3235}(Plugin); 3236 3237Accordion.defaults = { 3238 /** 3239 * Amount of time to animate the opening of an accordion pane. 3240 * @option 3241 * @type {number} 3242 * @default 250 3243 */ 3244 slideSpeed: 250, 3245 3246 /** 3247 * Allow the accordion to have multiple open panes. 3248 * @option 3249 * @type {boolean} 3250 * @default false 3251 */ 3252 multiExpand: false, 3253 3254 /** 3255 * Allow the accordion to close all panes. 3256 * @option 3257 * @type {boolean} 3258 * @default false 3259 */ 3260 allowAllClosed: false, 3261 3262 /** 3263 * Link the location hash to the open pane. 3264 * Set the location hash when the opened pane changes, and open and scroll to the corresponding pane when the location changes. 3265 * @option 3266 * @type {boolean} 3267 * @default false 3268 */ 3269 deepLink: false, 3270 3271 /** 3272 * If `deepLink` is enabled, adjust the deep link scroll to make sure the top of the accordion panel is visible 3273 * @option 3274 * @type {boolean} 3275 * @default false 3276 */ 3277 deepLinkSmudge: false, 3278 3279 /** 3280 * If `deepLinkSmudge` is enabled, animation time (ms) for the deep link adjustment 3281 * @option 3282 * @type {number} 3283 * @default 300 3284 */ 3285 deepLinkSmudgeDelay: 300, 3286 3287 /** 3288 * If `deepLink` is enabled, update the browser history with the open accordion 3289 * @option 3290 * @type {boolean} 3291 * @default false 3292 */ 3293 updateHistory: false 3294}; 3295/** 3296 * AccordionMenu module. 3297 * @module foundation.accordionMenu 3298 * @requires foundation.util.keyboard 3299 * @requires foundation.util.nest 3300 */ 3301 3302var AccordionMenu = 3303/*#__PURE__*/ 3304function (_Plugin) { 3305 _inherits(AccordionMenu, _Plugin); 3306 3307 function AccordionMenu() { 3308 _classCallCheck(this, AccordionMenu); 3309 3310 return _possibleConstructorReturn(this, _getPrototypeOf(AccordionMenu).apply(this, arguments)); 3311 } 3312 3313 _createClass(AccordionMenu, [{ 3314 key: "_setup", 3315 3316 /** 3317 * Creates a new instance of an accordion menu. 3318 * @class 3319 * @name AccordionMenu 3320 * @fires AccordionMenu#init 3321 * @param {jQuery} element - jQuery object to make into an accordion menu. 3322 * @param {Object} options - Overrides to the default plugin settings. 3323 */ 3324 value: function _setup(element, options) { 3325 this.$element = element; 3326 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, AccordionMenu.defaults, this.$element.data(), options); 3327 this.className = 'AccordionMenu'; // ie9 back compat 3328 3329 this._init(); 3330 3331 Keyboard.register('AccordionMenu', { 3332 'ENTER': 'toggle', 3333 'SPACE': 'toggle', 3334 'ARROW_RIGHT': 'open', 3335 'ARROW_UP': 'up', 3336 'ARROW_DOWN': 'down', 3337 'ARROW_LEFT': 'close', 3338 'ESCAPE': 'closeAll' 3339 }); 3340 } 3341 /** 3342 * Initializes the accordion menu by hiding all nested menus. 3343 * @private 3344 */ 3345 3346 }, { 3347 key: "_init", 3348 value: function _init() { 3349 Nest.Feather(this.$element, 'accordion'); 3350 3351 var _this = this; 3352 3353 this.$element.find('[data-submenu]').not('.is-active').slideUp(0); //.find('a').css('padding-left', '1rem'); 3354 3355 this.$element.attr({ 3356 'role': 'tree', 3357 'aria-multiselectable': this.options.multiOpen 3358 }); 3359 this.$menuLinks = this.$element.find('.is-accordion-submenu-parent'); 3360 this.$menuLinks.each(function () { 3361 var linkId = this.id || GetYoDigits(6, 'acc-menu-link'), 3362 $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 3363 $sub = $elem.children('[data-submenu]'), 3364 subId = $sub[0].id || GetYoDigits(6, 'acc-menu'), 3365 isActive = $sub.hasClass('is-active'); 3366 3367 if (_this.options.parentLink) { 3368 var $anchor = $elem.children('a'); 3369 $anchor.clone().prependTo($sub).wrap('<li data-is-parent-link class="is-submenu-parent-item is-submenu-item is-accordion-submenu-item"></li>'); 3370 } 3371 3372 if (_this.options.submenuToggle) { 3373 $elem.addClass('has-submenu-toggle'); 3374 $elem.children('a').after('<button id="' + linkId + '" class="submenu-toggle" aria-controls="' + subId + '" aria-expanded="' + isActive + '" title="' + _this.options.submenuToggleText + '"><span class="submenu-toggle-text">' + _this.options.submenuToggleText + '</span></button>'); 3375 } else { 3376 $elem.attr({ 3377 'aria-controls': subId, 3378 'aria-expanded': isActive, 3379 'id': linkId 3380 }); 3381 } 3382 3383 $sub.attr({ 3384 'aria-labelledby': linkId, 3385 'aria-hidden': !isActive, 3386 'role': 'group', 3387 'id': subId 3388 }); 3389 }); 3390 this.$element.find('li').attr({ 3391 'role': 'treeitem' 3392 }); 3393 var initPanes = this.$element.find('.is-active'); 3394 3395 if (initPanes.length) { 3396 var _this = this; 3397 3398 initPanes.each(function () { 3399 _this.down(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 3400 }); 3401 } 3402 3403 this._events(); 3404 } 3405 /** 3406 * Adds event handlers for items within the menu. 3407 * @private 3408 */ 3409 3410 }, { 3411 key: "_events", 3412 value: function _events() { 3413 var _this = this; 3414 3415 this.$element.find('li').each(function () { 3416 var $submenu = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).children('[data-submenu]'); 3417 3418 if ($submenu.length) { 3419 if (_this.options.submenuToggle) { 3420 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).children('.submenu-toggle').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function (e) { 3421 _this.toggle($submenu); 3422 }); 3423 } else { 3424 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).children('a').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function (e) { 3425 e.preventDefault(); 3426 3427 _this.toggle($submenu); 3428 }); 3429 } 3430 } 3431 }).on('keydown.zf.accordionmenu', function (e) { 3432 var $element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 3433 $elements = $element.parent('ul').children('li'), 3434 $prevElement, 3435 $nextElement, 3436 $target = $element.children('[data-submenu]'); 3437 $elements.each(function (i) { 3438 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is($element)) { 3439 $prevElement = $elements.eq(Math.max(0, i - 1)).find('a').first(); 3440 $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)).find('a').first(); 3441 3442 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).children('[data-submenu]:visible').length) { 3443 // has open sub menu 3444 $nextElement = $element.find('li:first-child').find('a').first(); 3445 } 3446 3447 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is(':first-child')) { 3448 // is first element of sub menu 3449 $prevElement = $element.parents('li').first().find('a').first(); 3450 } else if ($prevElement.parents('li').first().children('[data-submenu]:visible').length) { 3451 // if previous element has open sub menu 3452 $prevElement = $prevElement.parents('li').find('li:last-child').find('a').first(); 3453 } 3454 3455 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is(':last-child')) { 3456 // is last element of sub menu 3457 $nextElement = $element.parents('li').first().next('li').find('a').first(); 3458 } 3459 3460 return; 3461 } 3462 }); 3463 Keyboard.handleKey(e, 'AccordionMenu', { 3464 open: function open() { 3465 if ($target.is(':hidden')) { 3466 _this.down($target); 3467 3468 $target.find('li').first().find('a').first().focus(); 3469 } 3470 }, 3471 close: function close() { 3472 if ($target.length && !$target.is(':hidden')) { 3473 // close active sub of this item 3474 _this.up($target); 3475 } else if ($element.parent('[data-submenu]').length) { 3476 // close currently open sub 3477 _this.up($element.parent('[data-submenu]')); 3478 3479 $element.parents('li').first().find('a').first().focus(); 3480 } 3481 }, 3482 up: function up() { 3483 $prevElement.focus(); 3484 return true; 3485 }, 3486 down: function down() { 3487 $nextElement.focus(); 3488 return true; 3489 }, 3490 toggle: function toggle() { 3491 if (_this.options.submenuToggle) { 3492 return false; 3493 } 3494 3495 if ($element.children('[data-submenu]').length) { 3496 _this.toggle($element.children('[data-submenu]')); 3497 3498 return true; 3499 } 3500 }, 3501 closeAll: function closeAll() { 3502 _this.hideAll(); 3503 }, 3504 handled: function handled(preventDefault) { 3505 if (preventDefault) { 3506 e.preventDefault(); 3507 } 3508 3509 e.stopImmediatePropagation(); 3510 } 3511 }); 3512 }); //.attr('tabindex', 0); 3513 } 3514 /** 3515 * Closes all panes of the menu. 3516 * @function 3517 */ 3518 3519 }, { 3520 key: "hideAll", 3521 value: function hideAll() { 3522 this.up(this.$element.find('[data-submenu]')); 3523 } 3524 /** 3525 * Opens all panes of the menu. 3526 * @function 3527 */ 3528 3529 }, { 3530 key: "showAll", 3531 value: function showAll() { 3532 this.down(this.$element.find('[data-submenu]')); 3533 } 3534 /** 3535 * Toggles the open/close state of a submenu. 3536 * @function 3537 * @param {jQuery} $target - the submenu to toggle 3538 */ 3539 3540 }, { 3541 key: "toggle", 3542 value: function toggle($target) { 3543 if (!$target.is(':animated')) { 3544 if (!$target.is(':hidden')) { 3545 this.up($target); 3546 } else { 3547 this.down($target); 3548 } 3549 } 3550 } 3551 /** 3552 * Opens the sub-menu defined by `$target`. 3553 * @param {jQuery} $target - Sub-menu to open. 3554 * @fires AccordionMenu#down 3555 */ 3556 3557 }, { 3558 key: "down", 3559 value: function down($target) { 3560 var _this2 = this; 3561 3562 if (!this.options.multiOpen) { 3563 this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target))); 3564 } 3565 3566 $target.addClass('is-active').attr({ 3567 'aria-hidden': false 3568 }); 3569 3570 if (this.options.submenuToggle) { 3571 $target.prev('.submenu-toggle').attr({ 3572 'aria-expanded': true 3573 }); 3574 } else { 3575 $target.parent('.is-accordion-submenu-parent').attr({ 3576 'aria-expanded': true 3577 }); 3578 } 3579 3580 $target.slideDown(this.options.slideSpeed, function () { 3581 /** 3582 * Fires when the menu is done opening. 3583 * @event AccordionMenu#down 3584 */ 3585 _this2.$element.trigger('down.zf.accordionMenu', [$target]); 3586 }); 3587 } 3588 /** 3589 * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well. 3590 * @param {jQuery} $target - Sub-menu to close. 3591 * @fires AccordionMenu#up 3592 */ 3593 3594 }, { 3595 key: "up", 3596 value: function up($target) { 3597 var _this3 = this; 3598 3599 var $submenus = $target.find('[data-submenu]'); 3600 var $allmenus = $target.add($submenus); 3601 $submenus.slideUp(0); 3602 $allmenus.removeClass('is-active').attr('aria-hidden', true); 3603 3604 if (this.options.submenuToggle) { 3605 $allmenus.prev('.submenu-toggle').attr('aria-expanded', false); 3606 } else { 3607 $allmenus.parent('.is-accordion-submenu-parent').attr('aria-expanded', false); 3608 } 3609 3610 $target.slideUp(this.options.slideSpeed, function () { 3611 /** 3612 * Fires when the menu is done collapsing up. 3613 * @event AccordionMenu#up 3614 */ 3615 _this3.$element.trigger('up.zf.accordionMenu', [$target]); 3616 }); 3617 } 3618 /** 3619 * Destroys an instance of accordion menu. 3620 * @fires AccordionMenu#destroyed 3621 */ 3622 3623 }, { 3624 key: "_destroy", 3625 value: function _destroy() { 3626 this.$element.find('[data-submenu]').slideDown(0).css('display', ''); 3627 this.$element.find('a').off('click.zf.accordionMenu'); 3628 this.$element.find('[data-is-parent-link]').detach(); 3629 3630 if (this.options.submenuToggle) { 3631 this.$element.find('.has-submenu-toggle').removeClass('has-submenu-toggle'); 3632 this.$element.find('.submenu-toggle').remove(); 3633 } 3634 3635 Nest.Burn(this.$element, 'accordion'); 3636 } 3637 }]); 3638 3639 return AccordionMenu; 3640}(Plugin); 3641 3642AccordionMenu.defaults = { 3643 /** 3644 * Adds the parent link to the submenu. 3645 * @option 3646 * @type {boolean} 3647 * @default false 3648 */ 3649 parentLink: false, 3650 3651 /** 3652 * Amount of time to animate the opening of a submenu in ms. 3653 * @option 3654 * @type {number} 3655 * @default 250 3656 */ 3657 slideSpeed: 250, 3658 3659 /** 3660 * Adds a separate submenu toggle button. This allows the parent item to have a link. 3661 * @option 3662 * @example true 3663 */ 3664 submenuToggle: false, 3665 3666 /** 3667 * The text used for the submenu toggle if enabled. This is used for screen readers only. 3668 * @option 3669 * @example true 3670 */ 3671 submenuToggleText: 'Toggle menu', 3672 3673 /** 3674 * Allow the menu to have multiple open panes. 3675 * @option 3676 * @type {boolean} 3677 * @default true 3678 */ 3679 multiOpen: true 3680}; 3681/** 3682 * Drilldown module. 3683 * @module foundation.drilldown 3684 * @requires foundation.util.keyboard 3685 * @requires foundation.util.nest 3686 * @requires foundation.util.box 3687 */ 3688 3689var Drilldown = 3690/*#__PURE__*/ 3691function (_Plugin) { 3692 _inherits(Drilldown, _Plugin); 3693 3694 function Drilldown() { 3695 _classCallCheck(this, Drilldown); 3696 3697 return _possibleConstructorReturn(this, _getPrototypeOf(Drilldown).apply(this, arguments)); 3698 } 3699 3700 _createClass(Drilldown, [{ 3701 key: "_setup", 3702 3703 /** 3704 * Creates a new instance of a drilldown menu. 3705 * @class 3706 * @name Drilldown 3707 * @param {jQuery} element - jQuery object to make into an accordion menu. 3708 * @param {Object} options - Overrides to the default plugin settings. 3709 */ 3710 value: function _setup(element, options) { 3711 this.$element = element; 3712 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Drilldown.defaults, this.$element.data(), options); 3713 this.className = 'Drilldown'; // ie9 back compat 3714 3715 this._init(); 3716 3717 Keyboard.register('Drilldown', { 3718 'ENTER': 'open', 3719 'SPACE': 'open', 3720 'ARROW_RIGHT': 'next', 3721 'ARROW_UP': 'up', 3722 'ARROW_DOWN': 'down', 3723 'ARROW_LEFT': 'previous', 3724 'ESCAPE': 'close', 3725 'TAB': 'down', 3726 'SHIFT_TAB': 'up' 3727 }); 3728 } 3729 /** 3730 * Initializes the drilldown by creating jQuery collections of elements 3731 * @private 3732 */ 3733 3734 }, { 3735 key: "_init", 3736 value: function _init() { 3737 Nest.Feather(this.$element, 'drilldown'); 3738 3739 if (this.options.autoApplyClass) { 3740 this.$element.addClass('drilldown'); 3741 } 3742 3743 this.$element.attr({ 3744 'role': 'tree', 3745 'aria-multiselectable': false 3746 }); 3747 this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a'); 3748 this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]').attr('role', 'group'); 3749 this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'treeitem').find('a'); // Set the main menu as current by default (unless a submenu is selected) 3750 // Used to set the wrapper height when the drilldown is closed/reopened from any (sub)menu 3751 3752 this.$currentMenu = this.$element; 3753 this.$element.attr('data-mutate', this.$element.attr('data-drilldown') || GetYoDigits(6, 'drilldown')); 3754 3755 this._prepareMenu(); 3756 3757 this._registerEvents(); 3758 3759 this._keyboardEvents(); 3760 } 3761 /** 3762 * prepares drilldown menu by setting attributes to links and elements 3763 * sets a min height to prevent content jumping 3764 * wraps the element if not already wrapped 3765 * @private 3766 * @function 3767 */ 3768 3769 }, { 3770 key: "_prepareMenu", 3771 value: function _prepareMenu() { 3772 var _this = this; // if(!this.options.holdOpen){ 3773 // this._menuLinkEvents(); 3774 // } 3775 3776 3777 this.$submenuAnchors.each(function () { 3778 var $link = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 3779 var $sub = $link.parent(); 3780 3781 if (_this.options.parentLink) { 3782 $link.clone().prependTo($sub.children('[data-submenu]')).wrap('<li data-is-parent-link class="is-submenu-parent-item is-submenu-item is-drilldown-submenu-item" role="menuitem"></li>'); 3783 } 3784 3785 $link.data('savedHref', $link.attr('href')).removeAttr('href').attr('tabindex', 0); 3786 $link.children('[data-submenu]').attr({ 3787 'aria-hidden': true, 3788 'tabindex': 0, 3789 'role': 'group' 3790 }); 3791 3792 _this._events($link); 3793 }); 3794 this.$submenus.each(function () { 3795 var $menu = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 3796 $back = $menu.find('.js-drilldown-back'); 3797 3798 if (!$back.length) { 3799 switch (_this.options.backButtonPosition) { 3800 case "bottom": 3801 $menu.append(_this.options.backButton); 3802 break; 3803 3804 case "top": 3805 $menu.prepend(_this.options.backButton); 3806 break; 3807 3808 default: 3809 console.error("Unsupported backButtonPosition value '" + _this.options.backButtonPosition + "'"); 3810 } 3811 } 3812 3813 _this._back($menu); 3814 }); 3815 this.$submenus.addClass('invisible'); 3816 3817 if (!this.options.autoHeight) { 3818 this.$submenus.addClass('drilldown-submenu-cover-previous'); 3819 } // create a wrapper on element if it doesn't exist. 3820 3821 3822 if (!this.$element.parent().hasClass('is-drilldown')) { 3823 this.$wrapper = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.options.wrapper).addClass('is-drilldown'); 3824 if (this.options.animateHeight) this.$wrapper.addClass('animate-height'); 3825 this.$element.wrap(this.$wrapper); 3826 } // set wrapper 3827 3828 3829 this.$wrapper = this.$element.parent(); 3830 this.$wrapper.css(this._getMaxDims()); 3831 } 3832 }, { 3833 key: "_resize", 3834 value: function _resize() { 3835 this.$wrapper.css({ 3836 'max-width': 'none', 3837 'min-height': 'none' 3838 }); // _getMaxDims has side effects (boo) but calling it should update all other necessary heights & widths 3839 3840 this.$wrapper.css(this._getMaxDims()); 3841 } 3842 /** 3843 * Adds event handlers to elements in the menu. 3844 * @function 3845 * @private 3846 * @param {jQuery} $elem - the current menu item to add handlers to. 3847 */ 3848 3849 }, { 3850 key: "_events", 3851 value: function _events($elem) { 3852 var _this = this; 3853 3854 $elem.off('click.zf.drilldown').on('click.zf.drilldown', function (e) { 3855 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')) { 3856 e.stopImmediatePropagation(); 3857 e.preventDefault(); 3858 } // if(e.target !== e.currentTarget.firstElementChild){ 3859 // return false; 3860 // } 3861 3862 3863 _this._show($elem.parent('li')); 3864 3865 if (_this.options.closeOnClick) { 3866 var $body = jquery__WEBPACK_IMPORTED_MODULE_0___default()('body'); 3867 $body.off('.zf.drilldown').on('click.zf.drilldown', function (e) { 3868 if (e.target === _this.$element[0] || jquery__WEBPACK_IMPORTED_MODULE_0___default.a.contains(_this.$element[0], e.target)) { 3869 return; 3870 } 3871 3872 e.preventDefault(); 3873 3874 _this._hideAll(); 3875 3876 $body.off('.zf.drilldown'); 3877 }); 3878 } 3879 }); 3880 } 3881 /** 3882 * Adds event handlers to the menu element. 3883 * @function 3884 * @private 3885 */ 3886 3887 }, { 3888 key: "_registerEvents", 3889 value: function _registerEvents() { 3890 if (this.options.scrollTop) { 3891 this._bindHandler = this._scrollTop.bind(this); 3892 this.$element.on('open.zf.drilldown hide.zf.drilldown closed.zf.drilldown', this._bindHandler); 3893 } 3894 3895 this.$element.on('mutateme.zf.trigger', this._resize.bind(this)); 3896 } 3897 /** 3898 * Scroll to Top of Element or data-scroll-top-element 3899 * @function 3900 * @fires Drilldown#scrollme 3901 */ 3902 3903 }, { 3904 key: "_scrollTop", 3905 value: function _scrollTop() { 3906 var _this = this; 3907 3908 var $scrollTopElement = _this.options.scrollTopElement != '' ? jquery__WEBPACK_IMPORTED_MODULE_0___default()(_this.options.scrollTopElement) : _this.$element, 3909 scrollPos = parseInt($scrollTopElement.offset().top + _this.options.scrollTopOffset, 10); 3910 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').stop(true).animate({ 3911 scrollTop: scrollPos 3912 }, _this.options.animationDuration, _this.options.animationEasing, function () { 3913 /** 3914 * Fires after the menu has scrolled 3915 * @event Drilldown#scrollme 3916 */ 3917 if (this === jquery__WEBPACK_IMPORTED_MODULE_0___default()('html')[0]) _this.$element.trigger('scrollme.zf.drilldown'); 3918 }); 3919 } 3920 /** 3921 * Adds keydown event listener to `li`'s in the menu. 3922 * @private 3923 */ 3924 3925 }, { 3926 key: "_keyboardEvents", 3927 value: function _keyboardEvents() { 3928 var _this = this; 3929 3930 this.$menuItems.add(this.$element.find('.js-drilldown-back > a, .is-submenu-parent-item > a')).on('keydown.zf.drilldown', function (e) { 3931 var $element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 3932 $elements = $element.parent('li').parent('ul').children('li').children('a'), 3933 $prevElement, 3934 $nextElement; 3935 $elements.each(function (i) { 3936 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is($element)) { 3937 $prevElement = $elements.eq(Math.max(0, i - 1)); 3938 $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)); 3939 return; 3940 } 3941 }); 3942 Keyboard.handleKey(e, 'Drilldown', { 3943 next: function next() { 3944 if ($element.is(_this.$submenuAnchors)) { 3945 _this._show($element.parent('li')); 3946 3947 $element.parent('li').one(transitionend($element), function () { 3948 $element.parent('li').find('ul li a').not('.js-drilldown-back a').first().focus(); 3949 }); 3950 return true; 3951 } 3952 }, 3953 previous: function previous() { 3954 _this._hide($element.parent('li').parent('ul')); 3955 3956 $element.parent('li').parent('ul').one(transitionend($element), function () { 3957 setTimeout(function () { 3958 $element.parent('li').parent('ul').parent('li').children('a').first().focus(); 3959 }, 1); 3960 }); 3961 return true; 3962 }, 3963 up: function up() { 3964 $prevElement.focus(); // Don't tap focus on first element in root ul 3965 3966 return !$element.is(_this.$element.find('> li:first-child > a')); 3967 }, 3968 down: function down() { 3969 $nextElement.focus(); // Don't tap focus on last element in root ul 3970 3971 return !$element.is(_this.$element.find('> li:last-child > a')); 3972 }, 3973 close: function close() { 3974 // Don't close on element in root ul 3975 if (!$element.is(_this.$element.find('> li > a'))) { 3976 _this._hide($element.parent().parent()); 3977 3978 $element.parent().parent().siblings('a').focus(); 3979 } 3980 }, 3981 open: function open() { 3982 if (_this.options.parentLink && $element.attr('href')) { 3983 // Link with href 3984 return false; 3985 } else if (!$element.is(_this.$menuItems)) { 3986 // not menu item means back button 3987 _this._hide($element.parent('li').parent('ul')); 3988 3989 $element.parent('li').parent('ul').one(transitionend($element), function () { 3990 setTimeout(function () { 3991 $element.parent('li').parent('ul').parent('li').children('a').first().focus(); 3992 }, 1); 3993 }); 3994 return true; 3995 } else if ($element.is(_this.$submenuAnchors)) { 3996 // Sub menu item 3997 _this._show($element.parent('li')); 3998 3999 $element.parent('li').one(transitionend($element), function () { 4000 $element.parent('li').find('ul li a').not('.js-drilldown-back a').first().focus(); 4001 }); 4002 return true; 4003 } 4004 }, 4005 handled: function handled(preventDefault) { 4006 if (preventDefault) { 4007 e.preventDefault(); 4008 } 4009 4010 e.stopImmediatePropagation(); 4011 } 4012 }); 4013 }); // end keyboardAccess 4014 } 4015 /** 4016 * Closes all open elements, and returns to root menu. 4017 * @function 4018 * @fires Drilldown#closed 4019 */ 4020 4021 }, { 4022 key: "_hideAll", 4023 value: function _hideAll() { 4024 var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing'); 4025 if (this.options.autoHeight) this.$wrapper.css({ 4026 height: $elem.parent().closest('ul').data('calcHeight') 4027 }); 4028 $elem.one(transitionend($elem), function (e) { 4029 $elem.removeClass('is-active is-closing'); 4030 }); 4031 /** 4032 * Fires when the menu is fully closed. 4033 * @event Drilldown#closed 4034 */ 4035 4036 this.$element.trigger('closed.zf.drilldown'); 4037 } 4038 /** 4039 * Adds event listener for each `back` button, and closes open menus. 4040 * @function 4041 * @fires Drilldown#back 4042 * @param {jQuery} $elem - the current sub-menu to add `back` event. 4043 */ 4044 4045 }, { 4046 key: "_back", 4047 value: function _back($elem) { 4048 var _this = this; 4049 4050 $elem.off('click.zf.drilldown'); 4051 $elem.children('.js-drilldown-back').on('click.zf.drilldown', function (e) { 4052 e.stopImmediatePropagation(); // console.log('mouseup on back'); 4053 4054 _this._hide($elem); // If there is a parent submenu, call show 4055 4056 4057 var parentSubMenu = $elem.parent('li').parent('ul').parent('li'); 4058 4059 if (parentSubMenu.length) { 4060 _this._show(parentSubMenu); 4061 } 4062 }); 4063 } 4064 /** 4065 * Adds event listener to menu items w/o submenus to close open menus on click. 4066 * @function 4067 * @private 4068 */ 4069 4070 }, { 4071 key: "_menuLinkEvents", 4072 value: function _menuLinkEvents() { 4073 var _this = this; 4074 4075 this.$menuItems.not('.is-drilldown-submenu-parent').off('click.zf.drilldown').on('click.zf.drilldown', function (e) { 4076 // e.stopImmediatePropagation(); 4077 setTimeout(function () { 4078 _this._hideAll(); 4079 }, 0); 4080 }); 4081 } 4082 /** 4083 * Sets the CSS classes for submenu to show it. 4084 * @function 4085 * @private 4086 * @param {jQuery} $elem - the target submenu (`ul` tag) 4087 * @param {boolean} trigger - trigger drilldown event 4088 */ 4089 4090 }, { 4091 key: "_setShowSubMenuClasses", 4092 value: function _setShowSubMenuClasses($elem, trigger) { 4093 $elem.addClass('is-active').removeClass('invisible').attr('aria-hidden', false); 4094 $elem.parent('li').attr('aria-expanded', true); 4095 4096 if (trigger === true) { 4097 this.$element.trigger('open.zf.drilldown', [$elem]); 4098 } 4099 } 4100 /** 4101 * Sets the CSS classes for submenu to hide it. 4102 * @function 4103 * @private 4104 * @param {jQuery} $elem - the target submenu (`ul` tag) 4105 * @param {boolean} trigger - trigger drilldown event 4106 */ 4107 4108 }, { 4109 key: "_setHideSubMenuClasses", 4110 value: function _setHideSubMenuClasses($elem, trigger) { 4111 $elem.removeClass('is-active').addClass('invisible').attr('aria-hidden', true); 4112 $elem.parent('li').attr('aria-expanded', false); 4113 4114 if (trigger === true) { 4115 $elem.trigger('hide.zf.drilldown', [$elem]); 4116 } 4117 } 4118 /** 4119 * Opens a specific drilldown (sub)menu no matter which (sub)menu in it is currently visible. 4120 * Compared to _show() this lets you jump into any submenu without clicking through every submenu on the way to it. 4121 * @function 4122 * @fires Drilldown#open 4123 * @param {jQuery} $elem - the target (sub)menu (`ul` tag) 4124 * @param {boolean} autoFocus - if true the first link in the target (sub)menu gets auto focused 4125 */ 4126 4127 }, { 4128 key: "_showMenu", 4129 value: function _showMenu($elem, autoFocus) { 4130 var _this = this; // Reset drilldown 4131 4132 4133 var $expandedSubmenus = this.$element.find('li[aria-expanded="true"] > ul[data-submenu]'); 4134 $expandedSubmenus.each(function (index) { 4135 _this._setHideSubMenuClasses(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 4136 }); // Save the menu as the currently displayed one. 4137 4138 this.$currentMenu = $elem; // If target menu is root, focus first link & exit 4139 4140 if ($elem.is('[data-drilldown]')) { 4141 if (autoFocus === true) $elem.find('li[role="treeitem"] > a').first().focus(); 4142 if (this.options.autoHeight) this.$wrapper.css('height', $elem.data('calcHeight')); 4143 return; 4144 } // Find all submenus on way to root incl. the element itself 4145 4146 4147 var $submenus = $elem.children().first().parentsUntil('[data-drilldown]', '[data-submenu]'); // Open target menu and all submenus on its way to root 4148 4149 $submenus.each(function (index) { 4150 // Update height of first child (target menu) if autoHeight option true 4151 if (index === 0 && _this.options.autoHeight) { 4152 _this.$wrapper.css('height', jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('calcHeight')); 4153 } 4154 4155 var isLastChild = index == $submenus.length - 1; // Add transitionsend listener to last child (root due to reverse order) to open target menu's first link 4156 // Last child makes sure the event gets always triggered even if going through several menus 4157 4158 if (isLastChild === true) { 4159 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).one(transitionend(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)), function () { 4160 if (autoFocus === true) { 4161 $elem.find('li[role="treeitem"] > a').first().focus(); 4162 } 4163 }); 4164 } 4165 4166 _this._setShowSubMenuClasses(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), isLastChild); 4167 }); 4168 } 4169 /** 4170 * Opens a submenu. 4171 * @function 4172 * @fires Drilldown#open 4173 * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag. 4174 */ 4175 4176 }, { 4177 key: "_show", 4178 value: function _show($elem) { 4179 var $submenu = $elem.children('[data-submenu]'); 4180 $elem.attr('aria-expanded', true); 4181 this.$currentMenu = $submenu; 4182 $submenu.addClass('is-active').removeClass('invisible').attr('aria-hidden', false); 4183 4184 if (this.options.autoHeight) { 4185 this.$wrapper.css({ 4186 height: $submenu.data('calcHeight') 4187 }); 4188 } 4189 /** 4190 * Fires when the submenu has opened. 4191 * @event Drilldown#open 4192 */ 4193 4194 4195 this.$element.trigger('open.zf.drilldown', [$elem]); 4196 } 4197 /** 4198 * Hides a submenu 4199 * @function 4200 * @fires Drilldown#hide 4201 * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag. 4202 */ 4203 4204 }, { 4205 key: "_hide", 4206 value: function _hide($elem) { 4207 if (this.options.autoHeight) this.$wrapper.css({ 4208 height: $elem.parent().closest('ul').data('calcHeight') 4209 }); 4210 $elem.parent('li').attr('aria-expanded', false); 4211 $elem.attr('aria-hidden', true); 4212 $elem.addClass('is-closing').one(transitionend($elem), function () { 4213 $elem.removeClass('is-active is-closing'); 4214 $elem.blur().addClass('invisible'); 4215 }); 4216 /** 4217 * Fires when the submenu has closed. 4218 * @event Drilldown#hide 4219 */ 4220 4221 $elem.trigger('hide.zf.drilldown', [$elem]); 4222 } 4223 /** 4224 * Iterates through the nested menus to calculate the min-height, and max-width for the menu. 4225 * Prevents content jumping. 4226 * @function 4227 * @private 4228 */ 4229 4230 }, { 4231 key: "_getMaxDims", 4232 value: function _getMaxDims() { 4233 var maxHeight = 0, 4234 result = {}, 4235 _this = this; // Recalculate menu heights and total max height 4236 4237 4238 this.$submenus.add(this.$element).each(function () { 4239 var numOfElems = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).children('li').length; 4240 var height = Box.GetDimensions(this).height; 4241 maxHeight = height > maxHeight ? height : maxHeight; 4242 4243 if (_this.options.autoHeight) { 4244 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('calcHeight', height); 4245 } 4246 }); 4247 if (this.options.autoHeight) result['height'] = this.$currentMenu.data('calcHeight');else result['min-height'] = "".concat(maxHeight, "px"); 4248 result['max-width'] = "".concat(this.$element[0].getBoundingClientRect().width, "px"); 4249 return result; 4250 } 4251 /** 4252 * Destroys the Drilldown Menu 4253 * @function 4254 */ 4255 4256 }, { 4257 key: "_destroy", 4258 value: function _destroy() { 4259 if (this.options.scrollTop) this.$element.off('.zf.drilldown', this._bindHandler); 4260 4261 this._hideAll(); 4262 4263 this.$element.off('mutateme.zf.trigger'); 4264 Nest.Burn(this.$element, 'drilldown'); 4265 this.$element.unwrap().find('.js-drilldown-back, .is-submenu-parent-item').remove().end().find('.is-active, .is-closing, .is-drilldown-submenu').removeClass('is-active is-closing is-drilldown-submenu').end().find('[data-submenu]').removeAttr('aria-hidden tabindex role'); 4266 this.$submenuAnchors.each(function () { 4267 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).off('.zf.drilldown'); 4268 }); 4269 this.$element.find('[data-is-parent-link]').detach(); 4270 this.$submenus.removeClass('drilldown-submenu-cover-previous invisible'); 4271 this.$element.find('a').each(function () { 4272 var $link = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this); 4273 $link.removeAttr('tabindex'); 4274 4275 if ($link.data('savedHref')) { 4276 $link.attr('href', $link.data('savedHref')).removeData('savedHref'); 4277 } else { 4278 return; 4279 } 4280 }); 4281 } 4282 }]); 4283 4284 return Drilldown; 4285}(Plugin); 4286 4287Drilldown.defaults = { 4288 /** 4289 * Drilldowns depend on styles in order to function properly; in the default build of Foundation these are 4290 * on the `drilldown` class. This option auto-applies this class to the drilldown upon initialization. 4291 * @option 4292 * @type {boolian} 4293 * @default true 4294 */ 4295 autoApplyClass: true, 4296 4297 /** 4298 * Markup used for JS generated back button. Prepended or appended (see backButtonPosition) to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting. 4299 * @option 4300 * @type {string} 4301 * @default '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>' 4302 */ 4303 backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>', 4304 4305 /** 4306 * Position the back button either at the top or bottom of drilldown submenus. Can be `'left'` or `'bottom'`. 4307 * @option 4308 * @type {string} 4309 * @default top 4310 */ 4311 backButtonPosition: 'top', 4312 4313 /** 4314 * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting. 4315 * @option 4316 * @type {string} 4317 * @default '<div></div>' 4318 */ 4319 wrapper: '<div></div>', 4320 4321 /** 4322 * Adds the parent link to the submenu. 4323 * @option 4324 * @type {boolean} 4325 * @default false 4326 */ 4327 parentLink: false, 4328 4329 /** 4330 * Allow the menu to return to root list on body click. 4331 * @option 4332 * @type {boolean} 4333 * @default false 4334 */ 4335 closeOnClick: false, 4336 4337 /** 4338 * Allow the menu to auto adjust height. 4339 * @option 4340 * @type {boolean} 4341 * @default false 4342 */ 4343 autoHeight: false, 4344 4345 /** 4346 * Animate the auto adjust height. 4347 * @option 4348 * @type {boolean} 4349 * @default false 4350 */ 4351 animateHeight: false, 4352 4353 /** 4354 * Scroll to the top of the menu after opening a submenu or navigating back using the menu back button 4355 * @option 4356 * @type {boolean} 4357 * @default false 4358 */ 4359 scrollTop: false, 4360 4361 /** 4362 * String jquery selector (for example 'body') of element to take offset().top from, if empty string the drilldown menu offset().top is taken 4363 * @option 4364 * @type {string} 4365 * @default '' 4366 */ 4367 scrollTopElement: '', 4368 4369 /** 4370 * ScrollTop offset 4371 * @option 4372 * @type {number} 4373 * @default 0 4374 */ 4375 scrollTopOffset: 0, 4376 4377 /** 4378 * Scroll animation duration 4379 * @option 4380 * @type {number} 4381 * @default 500 4382 */ 4383 animationDuration: 500, 4384 4385 /** 4386 * Scroll animation easing. Can be `'swing'` or `'linear'`. 4387 * @option 4388 * @type {string} 4389 * @see {@link https://api.jquery.com/animate|JQuery animate} 4390 * @default 'swing' 4391 */ 4392 animationEasing: 'swing' // holdOpen: false 4393 4394}; 4395var POSITIONS = ['left', 'right', 'top', 'bottom']; 4396var VERTICAL_ALIGNMENTS = ['top', 'bottom', 'center']; 4397var HORIZONTAL_ALIGNMENTS = ['left', 'right', 'center']; 4398var ALIGNMENTS = { 4399 'left': VERTICAL_ALIGNMENTS, 4400 'right': VERTICAL_ALIGNMENTS, 4401 'top': HORIZONTAL_ALIGNMENTS, 4402 'bottom': HORIZONTAL_ALIGNMENTS 4403}; 4404 4405function nextItem(item, array) { 4406 var currentIdx = array.indexOf(item); 4407 4408 if (currentIdx === array.length - 1) { 4409 return array[0]; 4410 } else { 4411 return array[currentIdx + 1]; 4412 } 4413} 4414 4415var Positionable = 4416/*#__PURE__*/ 4417function (_Plugin) { 4418 _inherits(Positionable, _Plugin); 4419 4420 function Positionable() { 4421 _classCallCheck(this, Positionable); 4422 4423 return _possibleConstructorReturn(this, _getPrototypeOf(Positionable).apply(this, arguments)); 4424 } 4425 4426 _createClass(Positionable, [{ 4427 key: "_init", 4428 4429 /** 4430 * Abstract class encapsulating the tether-like explicit positioning logic 4431 * including repositioning based on overlap. 4432 * Expects classes to define defaults for vOffset, hOffset, position, 4433 * alignment, allowOverlap, and allowBottomOverlap. They can do this by 4434 * extending the defaults, or (for now recommended due to the way docs are 4435 * generated) by explicitly declaring them. 4436 * 4437 **/ 4438 value: function _init() { 4439 this.triedPositions = {}; 4440 this.position = this.options.position === 'auto' ? this._getDefaultPosition() : this.options.position; 4441 this.alignment = this.options.alignment === 'auto' ? this._getDefaultAlignment() : this.options.alignment; 4442 this.originalPosition = this.position; 4443 this.originalAlignment = this.alignment; 4444 } 4445 }, { 4446 key: "_getDefaultPosition", 4447 value: function _getDefaultPosition() { 4448 return 'bottom'; 4449 } 4450 }, { 4451 key: "_getDefaultAlignment", 4452 value: function _getDefaultAlignment() { 4453 switch (this.position) { 4454 case 'bottom': 4455 case 'top': 4456 return rtl() ? 'right' : 'left'; 4457 4458 case 'left': 4459 case 'right': 4460 return 'bottom'; 4461 } 4462 } 4463 /** 4464 * Adjusts the positionable possible positions by iterating through alignments 4465 * and positions. 4466 * @function 4467 * @private 4468 */ 4469 4470 }, { 4471 key: "_reposition", 4472 value: function _reposition() { 4473 if (this._alignmentsExhausted(this.position)) { 4474 this.position = nextItem(this.position, POSITIONS); 4475 this.alignment = ALIGNMENTS[this.position][0]; 4476 } else { 4477 this._realign(); 4478 } 4479 } 4480 /** 4481 * Adjusts the dropdown pane possible positions by iterating through alignments 4482 * on the current position. 4483 * @function 4484 * @private 4485 */ 4486 4487 }, { 4488 key: "_realign", 4489 value: function _realign() { 4490 this._addTriedPosition(this.position, this.alignment); 4491 4492 this.alignment = nextItem(this.alignment, ALIGNMENTS[this.position]); 4493 } 4494 }, { 4495 key: "_addTriedPosition", 4496 value: function _addTriedPosition(position, alignment) { 4497 this.triedPositions[position] = this.triedPositions[position] || []; 4498 this.triedPositions[position].push(alignment); 4499 } 4500 }, { 4501 key: "_positionsExhausted", 4502 value: function _positionsExhausted() { 4503 var isExhausted = true; 4504 4505 for (var i = 0; i < POSITIONS.length; i++) { 4506 isExhausted = isExhausted && this._alignmentsExhausted(POSITIONS[i]); 4507 } 4508 4509 return isExhausted; 4510 } 4511 }, { 4512 key: "_alignmentsExhausted", 4513 value: function _alignmentsExhausted(position) { 4514 return this.triedPositions[position] && this.triedPositions[position].length == ALIGNMENTS[position].length; 4515 } // When we're trying to center, we don't want to apply offset that's going to 4516 // take us just off center, so wrap around to return 0 for the appropriate 4517 // offset in those alignments. TODO: Figure out if we want to make this 4518 // configurable behavior... it feels more intuitive, especially for tooltips, but 4519 // it's possible someone might actually want to start from center and then nudge 4520 // slightly off. 4521 4522 }, { 4523 key: "_getVOffset", 4524 value: function _getVOffset() { 4525 return this.options.vOffset; 4526 } 4527 }, { 4528 key: "_getHOffset", 4529 value: function _getHOffset() { 4530 return this.options.hOffset; 4531 } 4532 }, { 4533 key: "_setPosition", 4534 value: function _setPosition($anchor, $element, $parent) { 4535 if ($anchor.attr('aria-expanded') === 'false') { 4536 return false; 4537 } 4538 4539 var $eleDims = Box.GetDimensions($element), 4540 $anchorDims = Box.GetDimensions($anchor); 4541 4542 if (!this.options.allowOverlap) { 4543 // restore original position & alignment before checking overlap 4544 this.position = this.originalPosition; 4545 this.alignment = this.originalAlignment; 4546 } 4547 4548 $element.offset(Box.GetExplicitOffsets($element, $anchor, this.position, this.alignment, this._getVOffset(), this._getHOffset())); 4549 4550 if (!this.options.allowOverlap) { 4551 var minOverlap = 100000000; // default coordinates to how we start, in case we can't figure out better 4552 4553 var minCoordinates = { 4554 position: this.position, 4555 alignment: this.alignment 4556 }; 4557 4558 while (!this._positionsExhausted()) { 4559 var overlap = Box.OverlapArea($element, $parent, false, false, this.options.allowBottomOverlap); 4560 4561 if (overlap === 0) { 4562 return; 4563 } 4564 4565 if (overlap < minOverlap) { 4566 minOverlap = overlap; 4567 minCoordinates = { 4568 position: this.position, 4569 alignment: this.alignment 4570 }; 4571 } 4572 4573 this._reposition(); 4574 4575 $element.offset(Box.GetExplicitOffsets($element, $anchor, this.position, this.alignment, this._getVOffset(), this._getHOffset())); 4576 } // If we get through the entire loop, there was no non-overlapping 4577 // position available. Pick the version with least overlap. 4578 4579 4580 this.position = minCoordinates.position; 4581 this.alignment = minCoordinates.alignment; 4582 $element.offset(Box.GetExplicitOffsets($element, $anchor, this.position, this.alignment, this._getVOffset(), this._getHOffset())); 4583 } 4584 } 4585 }]); 4586 4587 return Positionable; 4588}(Plugin); 4589 4590Positionable.defaults = { 4591 /** 4592 * Position of positionable relative to anchor. Can be left, right, bottom, top, or auto. 4593 * @option 4594 * @type {string} 4595 * @default 'auto' 4596 */ 4597 position: 'auto', 4598 4599 /** 4600 * Alignment of positionable relative to anchor. Can be left, right, bottom, top, center, or auto. 4601 * @option 4602 * @type {string} 4603 * @default 'auto' 4604 */ 4605 alignment: 'auto', 4606 4607 /** 4608 * Allow overlap of container/window. If false, dropdown positionable first 4609 * try to position as defined by data-position and data-alignment, but 4610 * reposition if it would cause an overflow. 4611 * @option 4612 * @type {boolean} 4613 * @default false 4614 */ 4615 allowOverlap: false, 4616 4617 /** 4618 * Allow overlap of only the bottom of the container. This is the most common 4619 * behavior for dropdowns, allowing the dropdown to extend the bottom of the 4620 * screen but not otherwise influence or break out of the container. 4621 * @option 4622 * @type {boolean} 4623 * @default true 4624 */ 4625 allowBottomOverlap: true, 4626 4627 /** 4628 * Number of pixels the positionable should be separated vertically from anchor 4629 * @option 4630 * @type {number} 4631 * @default 0 4632 */ 4633 vOffset: 0, 4634 4635 /** 4636 * Number of pixels the positionable should be separated horizontally from anchor 4637 * @option 4638 * @type {number} 4639 * @default 0 4640 */ 4641 hOffset: 0 4642}; 4643/** 4644 * Dropdown module. 4645 * @module foundation.dropdown 4646 * @requires foundation.util.keyboard 4647 * @requires foundation.util.box 4648 * @requires foundation.util.triggers 4649 */ 4650 4651var Dropdown = 4652/*#__PURE__*/ 4653function (_Positionable) { 4654 _inherits(Dropdown, _Positionable); 4655 4656 function Dropdown() { 4657 _classCallCheck(this, Dropdown); 4658 4659 return _possibleConstructorReturn(this, _getPrototypeOf(Dropdown).apply(this, arguments)); 4660 } 4661 4662 _createClass(Dropdown, [{ 4663 key: "_setup", 4664 4665 /** 4666 * Creates a new instance of a dropdown. 4667 * @class 4668 * @name Dropdown 4669 * @param {jQuery} element - jQuery object to make into a dropdown. 4670 * Object should be of the dropdown panel, rather than its anchor. 4671 * @param {Object} options - Overrides to the default plugin settings. 4672 */ 4673 value: function _setup(element, options) { 4674 this.$element = element; 4675 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Dropdown.defaults, this.$element.data(), options); 4676 this.className = 'Dropdown'; // ie9 back compat 4677 // Triggers init is idempotent, just need to make sure it is initialized 4678 4679 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 4680 4681 this._init(); 4682 4683 Keyboard.register('Dropdown', { 4684 'ENTER': 'toggle', 4685 'SPACE': 'toggle', 4686 'ESCAPE': 'close' 4687 }); 4688 } 4689 /** 4690 * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor. 4691 * @function 4692 * @private 4693 */ 4694 4695 }, { 4696 key: "_init", 4697 value: function _init() { 4698 var $id = this.$element.attr('id'); 4699 this.$anchors = jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-toggle=\"".concat($id, "\"]")).length ? jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-toggle=\"".concat($id, "\"]")) : jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-open=\"".concat($id, "\"]")); 4700 this.$anchors.attr({ 4701 'aria-controls': $id, 4702 'data-is-focus': false, 4703 'data-yeti-box': $id, 4704 'aria-haspopup': true, 4705 'aria-expanded': false 4706 }); 4707 4708 this._setCurrentAnchor(this.$anchors.first()); 4709 4710 if (this.options.parentClass) { 4711 this.$parent = this.$element.parents('.' + this.options.parentClass); 4712 } else { 4713 this.$parent = null; 4714 } // Set [aria-labelledby] on the Dropdown if it is not set 4715 4716 4717 if (typeof this.$element.attr('aria-labelledby') === 'undefined') { 4718 // Get the anchor ID or create one 4719 if (typeof this.$currentAnchor.attr('id') === 'undefined') { 4720 this.$currentAnchor.attr('id', GetYoDigits(6, 'dd-anchor')); 4721 } 4722 4723 this.$element.attr('aria-labelledby', this.$currentAnchor.attr('id')); 4724 } 4725 4726 this.$element.attr({ 4727 'aria-hidden': 'true', 4728 'data-yeti-box': $id, 4729 'data-resize': $id 4730 }); 4731 4732 _get(_getPrototypeOf(Dropdown.prototype), "_init", this).call(this); 4733 4734 this._events(); 4735 } 4736 }, { 4737 key: "_getDefaultPosition", 4738 value: function _getDefaultPosition() { 4739 // handle legacy classnames 4740 var position = this.$element[0].className.match(/(top|left|right|bottom)/g); 4741 4742 if (position) { 4743 return position[0]; 4744 } else { 4745 return 'bottom'; 4746 } 4747 } 4748 }, { 4749 key: "_getDefaultAlignment", 4750 value: function _getDefaultAlignment() { 4751 // handle legacy float approach 4752 var horizontalPosition = /float-(\S+)/.exec(this.$currentAnchor.attr('class')); 4753 4754 if (horizontalPosition) { 4755 return horizontalPosition[1]; 4756 } 4757 4758 return _get(_getPrototypeOf(Dropdown.prototype), "_getDefaultAlignment", this).call(this); 4759 } 4760 /** 4761 * Sets the position and orientation of the dropdown pane, checks for collisions if allow-overlap is not true. 4762 * Recursively calls itself if a collision is detected, with a new position class. 4763 * @function 4764 * @private 4765 */ 4766 4767 }, { 4768 key: "_setPosition", 4769 value: function _setPosition() { 4770 this.$element.removeClass("has-position-".concat(this.position, " has-alignment-").concat(this.alignment)); 4771 4772 _get(_getPrototypeOf(Dropdown.prototype), "_setPosition", this).call(this, this.$currentAnchor, this.$element, this.$parent); 4773 4774 this.$element.addClass("has-position-".concat(this.position, " has-alignment-").concat(this.alignment)); 4775 } 4776 /** 4777 * Make it a current anchor. 4778 * Current anchor as the reference for the position of Dropdown panes. 4779 * @param {HTML} el - DOM element of the anchor. 4780 * @function 4781 * @private 4782 */ 4783 4784 }, { 4785 key: "_setCurrentAnchor", 4786 value: function _setCurrentAnchor(el) { 4787 this.$currentAnchor = jquery__WEBPACK_IMPORTED_MODULE_0___default()(el); 4788 } 4789 /** 4790 * Adds event listeners to the element utilizing the triggers utility library. 4791 * @function 4792 * @private 4793 */ 4794 4795 }, { 4796 key: "_events", 4797 value: function _events() { 4798 var _this = this; 4799 4800 this.$element.on({ 4801 'open.zf.trigger': this.open.bind(this), 4802 'close.zf.trigger': this.close.bind(this), 4803 'toggle.zf.trigger': this.toggle.bind(this), 4804 'resizeme.zf.trigger': this._setPosition.bind(this) 4805 }); 4806 this.$anchors.off('click.zf.trigger').on('click.zf.trigger', function () { 4807 _this._setCurrentAnchor(this); 4808 }); 4809 4810 if (this.options.hover) { 4811 this.$anchors.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () { 4812 _this._setCurrentAnchor(this); 4813 4814 var bodyData = jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').data(); 4815 4816 if (typeof bodyData.whatinput === 'undefined' || bodyData.whatinput === 'mouse') { 4817 clearTimeout(_this.timeout); 4818 _this.timeout = setTimeout(function () { 4819 _this.open(); 4820 4821 _this.$anchors.data('hover', true); 4822 }, _this.options.hoverDelay); 4823 } 4824 }).on('mouseleave.zf.dropdown', ignoreMousedisappear(function () { 4825 clearTimeout(_this.timeout); 4826 _this.timeout = setTimeout(function () { 4827 _this.close(); 4828 4829 _this.$anchors.data('hover', false); 4830 }, _this.options.hoverDelay); 4831 })); 4832 4833 if (this.options.hoverPane) { 4834 this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () { 4835 clearTimeout(_this.timeout); 4836 }).on('mouseleave.zf.dropdown', ignoreMousedisappear(function () { 4837 clearTimeout(_this.timeout); 4838 _this.timeout = setTimeout(function () { 4839 _this.close(); 4840 4841 _this.$anchors.data('hover', false); 4842 }, _this.options.hoverDelay); 4843 })); 4844 } 4845 } 4846 4847 this.$anchors.add(this.$element).on('keydown.zf.dropdown', function (e) { 4848 var $target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 4849 visibleFocusableElements = Keyboard.findFocusable(_this.$element); 4850 Keyboard.handleKey(e, 'Dropdown', { 4851 open: function open() { 4852 if ($target.is(_this.$anchors) && !$target.is('input, textarea')) { 4853 _this.open(); 4854 4855 _this.$element.attr('tabindex', -1).focus(); 4856 4857 e.preventDefault(); 4858 } 4859 }, 4860 close: function close() { 4861 _this.close(); 4862 4863 _this.$anchors.focus(); 4864 } 4865 }); 4866 }); 4867 } 4868 /** 4869 * Adds an event handler to the body to close any dropdowns on a click. 4870 * @function 4871 * @private 4872 */ 4873 4874 }, { 4875 key: "_addBodyHandler", 4876 value: function _addBodyHandler() { 4877 var $body = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.body).not(this.$element), 4878 _this = this; 4879 4880 $body.off('click.zf.dropdown').on('click.zf.dropdown', function (e) { 4881 if (_this.$anchors.is(e.target) || _this.$anchors.find(e.target).length) { 4882 return; 4883 } 4884 4885 if (_this.$element.is(e.target) || _this.$element.find(e.target).length) { 4886 return; 4887 } 4888 4889 _this.close(); 4890 4891 $body.off('click.zf.dropdown'); 4892 }); 4893 } 4894 /** 4895 * Opens the dropdown pane, and fires a bubbling event to close other dropdowns. 4896 * @function 4897 * @fires Dropdown#closeme 4898 * @fires Dropdown#show 4899 */ 4900 4901 }, { 4902 key: "open", 4903 value: function open() { 4904 // var _this = this; 4905 4906 /** 4907 * Fires to close other open dropdowns, typically when dropdown is opening 4908 * @event Dropdown#closeme 4909 */ 4910 this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id')); 4911 this.$anchors.addClass('hover').attr({ 4912 'aria-expanded': true 4913 }); // this.$element/*.show()*/; 4914 4915 this.$element.addClass('is-opening'); 4916 4917 this._setPosition(); 4918 4919 this.$element.removeClass('is-opening').addClass('is-open').attr({ 4920 'aria-hidden': false 4921 }); 4922 4923 if (this.options.autoFocus) { 4924 var $focusable = Keyboard.findFocusable(this.$element); 4925 4926 if ($focusable.length) { 4927 $focusable.eq(0).focus(); 4928 } 4929 } 4930 4931 if (this.options.closeOnClick) { 4932 this._addBodyHandler(); 4933 } 4934 4935 if (this.options.trapFocus) { 4936 Keyboard.trapFocus(this.$element); 4937 } 4938 /** 4939 * Fires once the dropdown is visible. 4940 * @event Dropdown#show 4941 */ 4942 4943 4944 this.$element.trigger('show.zf.dropdown', [this.$element]); 4945 } 4946 /** 4947 * Closes the open dropdown pane. 4948 * @function 4949 * @fires Dropdown#hide 4950 */ 4951 4952 }, { 4953 key: "close", 4954 value: function close() { 4955 if (!this.$element.hasClass('is-open')) { 4956 return false; 4957 } 4958 4959 this.$element.removeClass('is-open').attr({ 4960 'aria-hidden': true 4961 }); 4962 this.$anchors.removeClass('hover').attr('aria-expanded', false); 4963 /** 4964 * Fires once the dropdown is no longer visible. 4965 * @event Dropdown#hide 4966 */ 4967 4968 this.$element.trigger('hide.zf.dropdown', [this.$element]); 4969 4970 if (this.options.trapFocus) { 4971 Keyboard.releaseFocus(this.$element); 4972 } 4973 } 4974 /** 4975 * Toggles the dropdown pane's visibility. 4976 * @function 4977 */ 4978 4979 }, { 4980 key: "toggle", 4981 value: function toggle() { 4982 if (this.$element.hasClass('is-open')) { 4983 if (this.$anchors.data('hover')) return; 4984 this.close(); 4985 } else { 4986 this.open(); 4987 } 4988 } 4989 /** 4990 * Destroys the dropdown. 4991 * @function 4992 */ 4993 4994 }, { 4995 key: "_destroy", 4996 value: function _destroy() { 4997 this.$element.off('.zf.trigger').hide(); 4998 this.$anchors.off('.zf.dropdown'); 4999 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.body).off('click.zf.dropdown'); 5000 } 5001 }]); 5002 5003 return Dropdown; 5004}(Positionable); 5005 5006Dropdown.defaults = { 5007 /** 5008 * Class that designates bounding container of Dropdown (default: window) 5009 * @option 5010 * @type {?string} 5011 * @default null 5012 */ 5013 parentClass: null, 5014 5015 /** 5016 * Amount of time to delay opening a submenu on hover event. 5017 * @option 5018 * @type {number} 5019 * @default 250 5020 */ 5021 hoverDelay: 250, 5022 5023 /** 5024 * Allow submenus to open on hover events 5025 * @option 5026 * @type {boolean} 5027 * @default false 5028 */ 5029 hover: false, 5030 5031 /** 5032 * Don't close dropdown when hovering over dropdown pane 5033 * @option 5034 * @type {boolean} 5035 * @default false 5036 */ 5037 hoverPane: false, 5038 5039 /** 5040 * Number of pixels between the dropdown pane and the triggering element on open. 5041 * @option 5042 * @type {number} 5043 * @default 0 5044 */ 5045 vOffset: 0, 5046 5047 /** 5048 * Number of pixels between the dropdown pane and the triggering element on open. 5049 * @option 5050 * @type {number} 5051 * @default 0 5052 */ 5053 hOffset: 0, 5054 5055 /** 5056 * Position of dropdown. Can be left, right, bottom, top, or auto. 5057 * @option 5058 * @type {string} 5059 * @default 'auto' 5060 */ 5061 position: 'auto', 5062 5063 /** 5064 * Alignment of dropdown relative to anchor. Can be left, right, bottom, top, center, or auto. 5065 * @option 5066 * @type {string} 5067 * @default 'auto' 5068 */ 5069 alignment: 'auto', 5070 5071 /** 5072 * Allow overlap of container/window. If false, dropdown will first try to position as defined by data-position and data-alignment, but reposition if it would cause an overflow. 5073 * @option 5074 * @type {boolean} 5075 * @default false 5076 */ 5077 allowOverlap: false, 5078 5079 /** 5080 * Allow overlap of only the bottom of the container. This is the most common 5081 * behavior for dropdowns, allowing the dropdown to extend the bottom of the 5082 * screen but not otherwise influence or break out of the container. 5083 * @option 5084 * @type {boolean} 5085 * @default true 5086 */ 5087 allowBottomOverlap: true, 5088 5089 /** 5090 * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands. 5091 * @option 5092 * @type {boolean} 5093 * @default false 5094 */ 5095 trapFocus: false, 5096 5097 /** 5098 * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening. 5099 * @option 5100 * @type {boolean} 5101 * @default false 5102 */ 5103 autoFocus: false, 5104 5105 /** 5106 * Allows a click on the body to close the dropdown. 5107 * @option 5108 * @type {boolean} 5109 * @default false 5110 */ 5111 closeOnClick: false 5112}; 5113/** 5114 * DropdownMenu module. 5115 * @module foundation.dropdown-menu 5116 * @requires foundation.util.keyboard 5117 * @requires foundation.util.box 5118 * @requires foundation.util.nest 5119 */ 5120 5121var DropdownMenu = 5122/*#__PURE__*/ 5123function (_Plugin) { 5124 _inherits(DropdownMenu, _Plugin); 5125 5126 function DropdownMenu() { 5127 _classCallCheck(this, DropdownMenu); 5128 5129 return _possibleConstructorReturn(this, _getPrototypeOf(DropdownMenu).apply(this, arguments)); 5130 } 5131 5132 _createClass(DropdownMenu, [{ 5133 key: "_setup", 5134 5135 /** 5136 * Creates a new instance of DropdownMenu. 5137 * @class 5138 * @name DropdownMenu 5139 * @fires DropdownMenu#init 5140 * @param {jQuery} element - jQuery object to make into a dropdown menu. 5141 * @param {Object} options - Overrides to the default plugin settings. 5142 */ 5143 value: function _setup(element, options) { 5144 this.$element = element; 5145 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, DropdownMenu.defaults, this.$element.data(), options); 5146 this.className = 'DropdownMenu'; // ie9 back compat 5147 5148 this._init(); 5149 5150 Keyboard.register('DropdownMenu', { 5151 'ENTER': 'open', 5152 'SPACE': 'open', 5153 'ARROW_RIGHT': 'next', 5154 'ARROW_UP': 'up', 5155 'ARROW_DOWN': 'down', 5156 'ARROW_LEFT': 'previous', 5157 'ESCAPE': 'close' 5158 }); 5159 } 5160 /** 5161 * Initializes the plugin, and calls _prepareMenu 5162 * @private 5163 * @function 5164 */ 5165 5166 }, { 5167 key: "_init", 5168 value: function _init() { 5169 Nest.Feather(this.$element, 'dropdown'); 5170 var subs = this.$element.find('li.is-dropdown-submenu-parent'); 5171 this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub'); 5172 this.$menuItems = this.$element.find('[role="menuitem"]'); 5173 this.$tabs = this.$element.children('[role="menuitem"]'); 5174 this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass); 5175 5176 if (this.options.alignment === 'auto') { 5177 if (this.$element.hasClass(this.options.rightClass) || rtl() || this.$element.parents('.top-bar-right').is('*')) { 5178 this.options.alignment = 'right'; 5179 subs.addClass('opens-left'); 5180 } else { 5181 this.options.alignment = 'left'; 5182 subs.addClass('opens-right'); 5183 } 5184 } else { 5185 if (this.options.alignment === 'right') { 5186 subs.addClass('opens-left'); 5187 } else { 5188 subs.addClass('opens-right'); 5189 } 5190 } 5191 5192 this.changed = false; 5193 5194 this._events(); 5195 } 5196 }, { 5197 key: "_isVertical", 5198 value: function _isVertical() { 5199 return this.$tabs.css('display') === 'block' || this.$element.css('flex-direction') === 'column'; 5200 } 5201 }, { 5202 key: "_isRtl", 5203 value: function _isRtl() { 5204 return this.$element.hasClass('align-right') || rtl() && !this.$element.hasClass('align-left'); 5205 } 5206 /** 5207 * Adds event listeners to elements within the menu 5208 * @private 5209 * @function 5210 */ 5211 5212 }, { 5213 key: "_events", 5214 value: function _events() { 5215 var _this = this, 5216 hasTouch = 'ontouchstart' in window || typeof window.ontouchstart !== 'undefined', 5217 parClass = 'is-dropdown-submenu-parent'; // used for onClick and in the keyboard handlers 5218 5219 5220 var handleClickFn = function handleClickFn(e) { 5221 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).parentsUntil('ul', ".".concat(parClass)), 5222 hasSub = $elem.hasClass(parClass), 5223 hasClicked = $elem.attr('data-is-click') === 'true', 5224 $sub = $elem.children('.is-dropdown-submenu'); 5225 5226 if (hasSub) { 5227 if (hasClicked) { 5228 if (!_this.options.closeOnClick || !_this.options.clickOpen && !hasTouch || _this.options.forceFollow && hasTouch) { 5229 return; 5230 } else { 5231 e.stopImmediatePropagation(); 5232 e.preventDefault(); 5233 5234 _this._hide($elem); 5235 } 5236 } else { 5237 e.preventDefault(); 5238 e.stopImmediatePropagation(); 5239 5240 _this._show($sub); 5241 5242 $elem.add($elem.parentsUntil(_this.$element, ".".concat(parClass))).attr('data-is-click', true); 5243 } 5244 } 5245 }; 5246 5247 if (this.options.clickOpen || hasTouch) { 5248 this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', handleClickFn); 5249 } // Handle Leaf element Clicks 5250 5251 5252 if (_this.options.closeOnClickInside) { 5253 this.$menuItems.on('click.zf.dropdownmenu', function (e) { 5254 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 5255 hasSub = $elem.hasClass(parClass); 5256 5257 if (!hasSub) { 5258 _this._hide(); 5259 } 5260 }); 5261 } 5262 5263 if (!this.options.disableHover) { 5264 this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) { 5265 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 5266 hasSub = $elem.hasClass(parClass); 5267 5268 if (hasSub) { 5269 clearTimeout($elem.data('_delay')); 5270 $elem.data('_delay', setTimeout(function () { 5271 _this._show($elem.children('.is-dropdown-submenu')); 5272 }, _this.options.hoverDelay)); 5273 } 5274 }).on('mouseleave.zf.dropdownMenu', ignoreMousedisappear(function (e) { 5275 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 5276 hasSub = $elem.hasClass(parClass); 5277 5278 if (hasSub && _this.options.autoclose) { 5279 if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) { 5280 return false; 5281 } 5282 5283 clearTimeout($elem.data('_delay')); 5284 $elem.data('_delay', setTimeout(function () { 5285 _this._hide($elem); 5286 }, _this.options.closingTime)); 5287 } 5288 })); 5289 } 5290 5291 this.$menuItems.on('keydown.zf.dropdownmenu', function (e) { 5292 var $element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).parentsUntil('ul', '[role="menuitem"]'), 5293 isTab = _this.$tabs.index($element) > -1, 5294 $elements = isTab ? _this.$tabs : $element.siblings('li').add($element), 5295 $prevElement, 5296 $nextElement; 5297 $elements.each(function (i) { 5298 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is($element)) { 5299 $prevElement = $elements.eq(i - 1); 5300 $nextElement = $elements.eq(i + 1); 5301 return; 5302 } 5303 }); 5304 5305 var nextSibling = function nextSibling() { 5306 $nextElement.children('a:first').focus(); 5307 e.preventDefault(); 5308 }, 5309 prevSibling = function prevSibling() { 5310 $prevElement.children('a:first').focus(); 5311 e.preventDefault(); 5312 }, 5313 openSub = function openSub() { 5314 var $sub = $element.children('ul.is-dropdown-submenu'); 5315 5316 if ($sub.length) { 5317 _this._show($sub); 5318 5319 $element.find('li > a:first').focus(); 5320 e.preventDefault(); 5321 } else { 5322 return; 5323 } 5324 }, 5325 closeSub = function closeSub() { 5326 //if ($element.is(':first-child')) { 5327 var close = $element.parent('ul').parent('li'); 5328 close.children('a:first').focus(); 5329 5330 _this._hide(close); 5331 5332 e.preventDefault(); //} 5333 }; 5334 5335 var functions = { 5336 open: openSub, 5337 close: function close() { 5338 _this._hide(_this.$element); 5339 5340 _this.$menuItems.eq(0).children('a').focus(); // focus to first element 5341 5342 5343 e.preventDefault(); 5344 }, 5345 handled: function handled() { 5346 e.stopImmediatePropagation(); 5347 } 5348 }; 5349 5350 if (isTab) { 5351 if (_this._isVertical()) { 5352 // vertical menu 5353 if (_this._isRtl()) { 5354 // right aligned 5355 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5356 down: nextSibling, 5357 up: prevSibling, 5358 next: closeSub, 5359 previous: openSub 5360 }); 5361 } else { 5362 // left aligned 5363 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5364 down: nextSibling, 5365 up: prevSibling, 5366 next: openSub, 5367 previous: closeSub 5368 }); 5369 } 5370 } else { 5371 // horizontal menu 5372 if (_this._isRtl()) { 5373 // right aligned 5374 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5375 next: prevSibling, 5376 previous: nextSibling, 5377 down: openSub, 5378 up: closeSub 5379 }); 5380 } else { 5381 // left aligned 5382 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5383 next: nextSibling, 5384 previous: prevSibling, 5385 down: openSub, 5386 up: closeSub 5387 }); 5388 } 5389 } 5390 } else { 5391 // not tabs -> one sub 5392 if (_this._isRtl()) { 5393 // right aligned 5394 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5395 next: closeSub, 5396 previous: openSub, 5397 down: nextSibling, 5398 up: prevSibling 5399 }); 5400 } else { 5401 // left aligned 5402 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend(functions, { 5403 next: openSub, 5404 previous: closeSub, 5405 down: nextSibling, 5406 up: prevSibling 5407 }); 5408 } 5409 } 5410 5411 Keyboard.handleKey(e, 'DropdownMenu', functions); 5412 }); 5413 } 5414 /** 5415 * Adds an event handler to the body to close any dropdowns on a click. 5416 * @function 5417 * @private 5418 */ 5419 5420 }, { 5421 key: "_addBodyHandler", 5422 value: function _addBodyHandler() { 5423 var $body = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.body), 5424 _this = this; 5425 5426 $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu').on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function (e) { 5427 var $link = _this.$element.find(e.target); 5428 5429 if ($link.length) { 5430 return; 5431 } 5432 5433 _this._hide(); 5434 5435 $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu'); 5436 }); 5437 } 5438 /** 5439 * Opens a dropdown pane, and checks for collisions first. 5440 * @param {jQuery} $sub - ul element that is a submenu to show 5441 * @function 5442 * @private 5443 * @fires Dropdownmenu#show 5444 */ 5445 5446 }, { 5447 key: "_show", 5448 value: function _show($sub) { 5449 var idx = this.$tabs.index(this.$tabs.filter(function (i, el) { 5450 return jquery__WEBPACK_IMPORTED_MODULE_0___default()(el).find($sub).length > 0; 5451 })); 5452 var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent'); 5453 5454 this._hide($sibs, idx); 5455 5456 $sub.css('visibility', 'hidden').addClass('js-dropdown-active').parent('li.is-dropdown-submenu-parent').addClass('is-active'); 5457 var clear = Box.ImNotTouchingYou($sub, null, true); 5458 5459 if (!clear) { 5460 var oldClass = this.options.alignment === 'left' ? '-right' : '-left', 5461 $parentLi = $sub.parent('.is-dropdown-submenu-parent'); 5462 $parentLi.removeClass("opens".concat(oldClass)).addClass("opens-".concat(this.options.alignment)); 5463 clear = Box.ImNotTouchingYou($sub, null, true); 5464 5465 if (!clear) { 5466 $parentLi.removeClass("opens-".concat(this.options.alignment)).addClass('opens-inner'); 5467 } 5468 5469 this.changed = true; 5470 } 5471 5472 $sub.css('visibility', ''); 5473 5474 if (this.options.closeOnClick) { 5475 this._addBodyHandler(); 5476 } 5477 /** 5478 * Fires when the new dropdown pane is visible. 5479 * @event Dropdownmenu#show 5480 */ 5481 5482 5483 this.$element.trigger('show.zf.dropdownmenu', [$sub]); 5484 } 5485 /** 5486 * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything. 5487 * @function 5488 * @param {jQuery} $elem - element with a submenu to hide 5489 * @param {Number} idx - index of the $tabs collection to hide 5490 * @private 5491 */ 5492 5493 }, { 5494 key: "_hide", 5495 value: function _hide($elem, idx) { 5496 var $toClose; 5497 5498 if ($elem && $elem.length) { 5499 $toClose = $elem; 5500 } else if (typeof idx !== 'undefined') { 5501 $toClose = this.$tabs.not(function (i, el) { 5502 return i === idx; 5503 }); 5504 } else { 5505 $toClose = this.$element; 5506 } 5507 5508 var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0; 5509 5510 if (somethingToClose) { 5511 $toClose.find('li.is-active').add($toClose).attr({ 5512 'data-is-click': false 5513 }).removeClass('is-active'); 5514 $toClose.find('ul.js-dropdown-active').removeClass('js-dropdown-active'); 5515 5516 if (this.changed || $toClose.find('opens-inner').length) { 5517 var oldClass = this.options.alignment === 'left' ? 'right' : 'left'; 5518 $toClose.find('li.is-dropdown-submenu-parent').add($toClose).removeClass("opens-inner opens-".concat(this.options.alignment)).addClass("opens-".concat(oldClass)); 5519 this.changed = false; 5520 } 5521 /** 5522 * Fires when the open menus are closed. 5523 * @event Dropdownmenu#hide 5524 */ 5525 5526 5527 this.$element.trigger('hide.zf.dropdownmenu', [$toClose]); 5528 } 5529 } 5530 /** 5531 * Destroys the plugin. 5532 * @function 5533 */ 5534 5535 }, { 5536 key: "_destroy", 5537 value: function _destroy() { 5538 this.$menuItems.off('.zf.dropdownmenu').removeAttr('data-is-click').removeClass('is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner'); 5539 jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.body).off('.zf.dropdownmenu'); 5540 Nest.Burn(this.$element, 'dropdown'); 5541 } 5542 }]); 5543 5544 return DropdownMenu; 5545}(Plugin); 5546/** 5547 * Default settings for plugin 5548 */ 5549 5550 5551DropdownMenu.defaults = { 5552 /** 5553 * Disallows hover events from opening submenus 5554 * @option 5555 * @type {boolean} 5556 * @default false 5557 */ 5558 disableHover: false, 5559 5560 /** 5561 * Allow a submenu to automatically close on a mouseleave event, if not clicked open. 5562 * @option 5563 * @type {boolean} 5564 * @default true 5565 */ 5566 autoclose: true, 5567 5568 /** 5569 * Amount of time to delay opening a submenu on hover event. 5570 * @option 5571 * @type {number} 5572 * @default 50 5573 */ 5574 hoverDelay: 50, 5575 5576 /** 5577 * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu. 5578 * @option 5579 * @type {boolean} 5580 * @default false 5581 */ 5582 clickOpen: false, 5583 5584 /** 5585 * Amount of time to delay closing a submenu on a mouseleave event. 5586 * @option 5587 * @type {number} 5588 * @default 500 5589 */ 5590 closingTime: 500, 5591 5592 /** 5593 * Position of the menu relative to what direction the submenus should open. Handled by JS. Can be `'auto'`, `'left'` or `'right'`. 5594 * @option 5595 * @type {string} 5596 * @default 'auto' 5597 */ 5598 alignment: 'auto', 5599 5600 /** 5601 * Allow clicks on the body to close any open submenus. 5602 * @option 5603 * @type {boolean} 5604 * @default true 5605 */ 5606 closeOnClick: true, 5607 5608 /** 5609 * Allow clicks on leaf anchor links to close any open submenus. 5610 * @option 5611 * @type {boolean} 5612 * @default true 5613 */ 5614 closeOnClickInside: true, 5615 5616 /** 5617 * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class. 5618 * @option 5619 * @type {string} 5620 * @default 'vertical' 5621 */ 5622 verticalClass: 'vertical', 5623 5624 /** 5625 * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class. 5626 * @option 5627 * @type {string} 5628 * @default 'align-right' 5629 */ 5630 rightClass: 'align-right', 5631 5632 /** 5633 * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile. 5634 * @option 5635 * @type {boolean} 5636 * @default true 5637 */ 5638 forceFollow: true 5639}; 5640/** 5641 * Equalizer module. 5642 * @module foundation.equalizer 5643 * @requires foundation.util.mediaQuery 5644 * @requires foundation.util.imageLoader if equalizer contains images 5645 */ 5646 5647var Equalizer = 5648/*#__PURE__*/ 5649function (_Plugin) { 5650 _inherits(Equalizer, _Plugin); 5651 5652 function Equalizer() { 5653 _classCallCheck(this, Equalizer); 5654 5655 return _possibleConstructorReturn(this, _getPrototypeOf(Equalizer).apply(this, arguments)); 5656 } 5657 5658 _createClass(Equalizer, [{ 5659 key: "_setup", 5660 5661 /** 5662 * Creates a new instance of Equalizer. 5663 * @class 5664 * @name Equalizer 5665 * @fires Equalizer#init 5666 * @param {Object} element - jQuery object to add the trigger to. 5667 * @param {Object} options - Overrides to the default plugin settings. 5668 */ 5669 value: function _setup(element, options) { 5670 this.$element = element; 5671 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Equalizer.defaults, this.$element.data(), options); 5672 this.className = 'Equalizer'; // ie9 back compat 5673 5674 this._init(); 5675 } 5676 /** 5677 * Initializes the Equalizer plugin and calls functions to get equalizer functioning on load. 5678 * @private 5679 */ 5680 5681 }, { 5682 key: "_init", 5683 value: function _init() { 5684 var eqId = this.$element.attr('data-equalizer') || ''; 5685 var $watched = this.$element.find("[data-equalizer-watch=\"".concat(eqId, "\"]")); 5686 5687 MediaQuery._init(); 5688 5689 this.$watched = $watched.length ? $watched : this.$element.find('[data-equalizer-watch]'); 5690 this.$element.attr('data-resize', eqId || GetYoDigits(6, 'eq')); 5691 this.$element.attr('data-mutate', eqId || GetYoDigits(6, 'eq')); 5692 this.hasNested = this.$element.find('[data-equalizer]').length > 0; 5693 this.isNested = this.$element.parentsUntil(document.body, '[data-equalizer]').length > 0; 5694 this.isOn = false; 5695 this._bindHandler = { 5696 onResizeMeBound: this._onResizeMe.bind(this), 5697 onPostEqualizedBound: this._onPostEqualized.bind(this) 5698 }; 5699 var imgs = this.$element.find('img'); 5700 var tooSmall; 5701 5702 if (this.options.equalizeOn) { 5703 tooSmall = this._checkMQ(); 5704 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', this._checkMQ.bind(this)); 5705 } else { 5706 this._events(); 5707 } 5708 5709 if (typeof tooSmall !== 'undefined' && tooSmall === false || typeof tooSmall === 'undefined') { 5710 if (imgs.length) { 5711 onImagesLoaded(imgs, this._reflow.bind(this)); 5712 } else { 5713 this._reflow(); 5714 } 5715 } 5716 } 5717 /** 5718 * Removes event listeners if the breakpoint is too small. 5719 * @private 5720 */ 5721 5722 }, { 5723 key: "_pauseEvents", 5724 value: function _pauseEvents() { 5725 this.isOn = false; 5726 this.$element.off({ 5727 '.zf.equalizer': this._bindHandler.onPostEqualizedBound, 5728 'resizeme.zf.trigger': this._bindHandler.onResizeMeBound, 5729 'mutateme.zf.trigger': this._bindHandler.onResizeMeBound 5730 }); 5731 } 5732 /** 5733 * function to handle $elements resizeme.zf.trigger, with bound this on _bindHandler.onResizeMeBound 5734 * @private 5735 */ 5736 5737 }, { 5738 key: "_onResizeMe", 5739 value: function _onResizeMe(e) { 5740 this._reflow(); 5741 } 5742 /** 5743 * function to handle $elements postequalized.zf.equalizer, with bound this on _bindHandler.onPostEqualizedBound 5744 * @private 5745 */ 5746 5747 }, { 5748 key: "_onPostEqualized", 5749 value: function _onPostEqualized(e) { 5750 if (e.target !== this.$element[0]) { 5751 this._reflow(); 5752 } 5753 } 5754 /** 5755 * Initializes events for Equalizer. 5756 * @private 5757 */ 5758 5759 }, { 5760 key: "_events", 5761 value: function _events() { 5762 this._pauseEvents(); 5763 5764 if (this.hasNested) { 5765 this.$element.on('postequalized.zf.equalizer', this._bindHandler.onPostEqualizedBound); 5766 } else { 5767 this.$element.on('resizeme.zf.trigger', this._bindHandler.onResizeMeBound); 5768 this.$element.on('mutateme.zf.trigger', this._bindHandler.onResizeMeBound); 5769 } 5770 5771 this.isOn = true; 5772 } 5773 /** 5774 * Checks the current breakpoint to the minimum required size. 5775 * @private 5776 */ 5777 5778 }, { 5779 key: "_checkMQ", 5780 value: function _checkMQ() { 5781 var tooSmall = !MediaQuery.is(this.options.equalizeOn); 5782 5783 if (tooSmall) { 5784 if (this.isOn) { 5785 this._pauseEvents(); 5786 5787 this.$watched.css('height', 'auto'); 5788 } 5789 } else { 5790 if (!this.isOn) { 5791 this._events(); 5792 } 5793 } 5794 5795 return tooSmall; 5796 } 5797 /** 5798 * A noop version for the plugin 5799 * @private 5800 */ 5801 5802 }, { 5803 key: "_killswitch", 5804 value: function _killswitch() { 5805 return; 5806 } 5807 /** 5808 * Calls necessary functions to update Equalizer upon DOM change 5809 * @private 5810 */ 5811 5812 }, { 5813 key: "_reflow", 5814 value: function _reflow() { 5815 if (!this.options.equalizeOnStack) { 5816 if (this._isStacked()) { 5817 this.$watched.css('height', 'auto'); 5818 return false; 5819 } 5820 } 5821 5822 if (this.options.equalizeByRow) { 5823 this.getHeightsByRow(this.applyHeightByRow.bind(this)); 5824 } else { 5825 this.getHeights(this.applyHeight.bind(this)); 5826 } 5827 } 5828 /** 5829 * Manually determines if the first 2 elements are *NOT* stacked. 5830 * @private 5831 */ 5832 5833 }, { 5834 key: "_isStacked", 5835 value: function _isStacked() { 5836 if (!this.$watched[0] || !this.$watched[1]) { 5837 return true; 5838 } 5839 5840 return this.$watched[0].getBoundingClientRect().top !== this.$watched[1].getBoundingClientRect().top; 5841 } 5842 /** 5843 * Finds the outer heights of children contained within an Equalizer parent and returns them in an array 5844 * @param {Function} cb - A non-optional callback to return the heights array to. 5845 * @returns {Array} heights - An array of heights of children within Equalizer container 5846 */ 5847 5848 }, { 5849 key: "getHeights", 5850 value: function getHeights(cb) { 5851 var heights = []; 5852 5853 for (var i = 0, len = this.$watched.length; i < len; i++) { 5854 this.$watched[i].style.height = 'auto'; 5855 heights.push(this.$watched[i].offsetHeight); 5856 } 5857 5858 cb(heights); 5859 } 5860 /** 5861 * Finds the outer heights of children contained within an Equalizer parent and returns them in an array 5862 * @param {Function} cb - A non-optional callback to return the heights array to. 5863 * @returns {Array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child 5864 */ 5865 5866 }, { 5867 key: "getHeightsByRow", 5868 value: function getHeightsByRow(cb) { 5869 var lastElTopOffset = this.$watched.length ? this.$watched.first().offset().top : 0, 5870 groups = [], 5871 group = 0; //group by Row 5872 5873 groups[group] = []; 5874 5875 for (var i = 0, len = this.$watched.length; i < len; i++) { 5876 this.$watched[i].style.height = 'auto'; //maybe could use this.$watched[i].offsetTop 5877 5878 var elOffsetTop = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.$watched[i]).offset().top; 5879 5880 if (elOffsetTop != lastElTopOffset) { 5881 group++; 5882 groups[group] = []; 5883 lastElTopOffset = elOffsetTop; 5884 } 5885 5886 groups[group].push([this.$watched[i], this.$watched[i].offsetHeight]); 5887 } 5888 5889 for (var j = 0, ln = groups.length; j < ln; j++) { 5890 var heights = jquery__WEBPACK_IMPORTED_MODULE_0___default()(groups[j]).map(function () { 5891 return this[1]; 5892 }).get(); 5893 var max = Math.max.apply(null, heights); 5894 groups[j].push(max); 5895 } 5896 5897 cb(groups); 5898 } 5899 /** 5900 * Changes the CSS height property of each child in an Equalizer parent to match the tallest 5901 * @param {array} heights - An array of heights of children within Equalizer container 5902 * @fires Equalizer#preequalized 5903 * @fires Equalizer#postequalized 5904 */ 5905 5906 }, { 5907 key: "applyHeight", 5908 value: function applyHeight(heights) { 5909 var max = Math.max.apply(null, heights); 5910 /** 5911 * Fires before the heights are applied 5912 * @event Equalizer#preequalized 5913 */ 5914 5915 this.$element.trigger('preequalized.zf.equalizer'); 5916 this.$watched.css('height', max); 5917 /** 5918 * Fires when the heights have been applied 5919 * @event Equalizer#postequalized 5920 */ 5921 5922 this.$element.trigger('postequalized.zf.equalizer'); 5923 } 5924 /** 5925 * Changes the CSS height property of each child in an Equalizer parent to match the tallest by row 5926 * @param {array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child 5927 * @fires Equalizer#preequalized 5928 * @fires Equalizer#preequalizedrow 5929 * @fires Equalizer#postequalizedrow 5930 * @fires Equalizer#postequalized 5931 */ 5932 5933 }, { 5934 key: "applyHeightByRow", 5935 value: function applyHeightByRow(groups) { 5936 /** 5937 * Fires before the heights are applied 5938 */ 5939 this.$element.trigger('preequalized.zf.equalizer'); 5940 5941 for (var i = 0, len = groups.length; i < len; i++) { 5942 var groupsILength = groups[i].length, 5943 max = groups[i][groupsILength - 1]; 5944 5945 if (groupsILength <= 2) { 5946 jquery__WEBPACK_IMPORTED_MODULE_0___default()(groups[i][0][0]).css({ 5947 'height': 'auto' 5948 }); 5949 continue; 5950 } 5951 /** 5952 * Fires before the heights per row are applied 5953 * @event Equalizer#preequalizedrow 5954 */ 5955 5956 5957 this.$element.trigger('preequalizedrow.zf.equalizer'); 5958 5959 for (var j = 0, lenJ = groupsILength - 1; j < lenJ; j++) { 5960 jquery__WEBPACK_IMPORTED_MODULE_0___default()(groups[i][j][0]).css({ 5961 'height': max 5962 }); 5963 } 5964 /** 5965 * Fires when the heights per row have been applied 5966 * @event Equalizer#postequalizedrow 5967 */ 5968 5969 5970 this.$element.trigger('postequalizedrow.zf.equalizer'); 5971 } 5972 /** 5973 * Fires when the heights have been applied 5974 */ 5975 5976 5977 this.$element.trigger('postequalized.zf.equalizer'); 5978 } 5979 /** 5980 * Destroys an instance of Equalizer. 5981 * @function 5982 */ 5983 5984 }, { 5985 key: "_destroy", 5986 value: function _destroy() { 5987 this._pauseEvents(); 5988 5989 this.$watched.css('height', 'auto'); 5990 } 5991 }]); 5992 5993 return Equalizer; 5994}(Plugin); 5995/** 5996 * Default settings for plugin 5997 */ 5998 5999 6000Equalizer.defaults = { 6001 /** 6002 * Enable height equalization when stacked on smaller screens. 6003 * @option 6004 * @type {boolean} 6005 * @default false 6006 */ 6007 equalizeOnStack: false, 6008 6009 /** 6010 * Enable height equalization row by row. 6011 * @option 6012 * @type {boolean} 6013 * @default false 6014 */ 6015 equalizeByRow: false, 6016 6017 /** 6018 * String representing the minimum breakpoint size the plugin should equalize heights on. 6019 * @option 6020 * @type {string} 6021 * @default '' 6022 */ 6023 equalizeOn: '' 6024}; 6025/** 6026 * Interchange module. 6027 * @module foundation.interchange 6028 * @requires foundation.util.mediaQuery 6029 */ 6030 6031var Interchange = 6032/*#__PURE__*/ 6033function (_Plugin) { 6034 _inherits(Interchange, _Plugin); 6035 6036 function Interchange() { 6037 _classCallCheck(this, Interchange); 6038 6039 return _possibleConstructorReturn(this, _getPrototypeOf(Interchange).apply(this, arguments)); 6040 } 6041 6042 _createClass(Interchange, [{ 6043 key: "_setup", 6044 6045 /** 6046 * Creates a new instance of Interchange. 6047 * @class 6048 * @name Interchange 6049 * @fires Interchange#init 6050 * @param {Object} element - jQuery object to add the trigger to. 6051 * @param {Object} options - Overrides to the default plugin settings. 6052 */ 6053 value: function _setup(element, options) { 6054 this.$element = element; 6055 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Interchange.defaults, options); 6056 this.rules = []; 6057 this.currentPath = ''; 6058 this.className = 'Interchange'; // ie9 back compat 6059 6060 this._init(); 6061 6062 this._events(); 6063 } 6064 /** 6065 * Initializes the Interchange plugin and calls functions to get interchange functioning on load. 6066 * @function 6067 * @private 6068 */ 6069 6070 }, { 6071 key: "_init", 6072 value: function _init() { 6073 MediaQuery._init(); 6074 6075 var id = this.$element[0].id || GetYoDigits(6, 'interchange'); 6076 this.$element.attr({ 6077 'data-resize': id, 6078 'id': id 6079 }); 6080 6081 this._addBreakpoints(); 6082 6083 this._generateRules(); 6084 6085 this._reflow(); 6086 } 6087 /** 6088 * Initializes events for Interchange. 6089 * @function 6090 * @private 6091 */ 6092 6093 }, { 6094 key: "_events", 6095 value: function _events() { 6096 var _this2 = this; 6097 6098 this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', function () { 6099 return _this2._reflow(); 6100 }); 6101 } 6102 /** 6103 * Calls necessary functions to update Interchange upon DOM change 6104 * @function 6105 * @private 6106 */ 6107 6108 }, { 6109 key: "_reflow", 6110 value: function _reflow() { 6111 var match; // Iterate through each rule, but only save the last match 6112 6113 for (var i in this.rules) { 6114 if (this.rules.hasOwnProperty(i)) { 6115 var rule = this.rules[i]; 6116 6117 if (window.matchMedia(rule.query).matches) { 6118 match = rule; 6119 } 6120 } 6121 } 6122 6123 if (match) { 6124 this.replace(match.path); 6125 } 6126 } 6127 /** 6128 * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object. 6129 * @function 6130 * @private 6131 */ 6132 6133 }, { 6134 key: "_addBreakpoints", 6135 value: function _addBreakpoints() { 6136 for (var i in MediaQuery.queries) { 6137 if (MediaQuery.queries.hasOwnProperty(i)) { 6138 var query = MediaQuery.queries[i]; 6139 Interchange.SPECIAL_QUERIES[query.name] = query.value; 6140 } 6141 } 6142 } 6143 /** 6144 * Checks the Interchange element for the provided media query + content pairings 6145 * @function 6146 * @private 6147 * @param {Object} element - jQuery object that is an Interchange instance 6148 * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys 6149 */ 6150 6151 }, { 6152 key: "_generateRules", 6153 value: function _generateRules(element) { 6154 var rulesList = []; 6155 var rules; 6156 6157 if (this.options.rules) { 6158 rules = this.options.rules; 6159 } else { 6160 rules = this.$element.data('interchange'); 6161 } 6162 6163 rules = typeof rules === 'string' ? rules.match(/\[.*?, .*?\]/g) : rules; 6164 6165 for (var i in rules) { 6166 if (rules.hasOwnProperty(i)) { 6167 var rule = rules[i].slice(1, -1).split(', '); 6168 var path = rule.slice(0, -1).join(''); 6169 var query = rule[rule.length - 1]; 6170 6171 if (Interchange.SPECIAL_QUERIES[query]) { 6172 query = Interchange.SPECIAL_QUERIES[query]; 6173 } 6174 6175 rulesList.push({ 6176 path: path, 6177 query: query 6178 }); 6179 } 6180 } 6181 6182 this.rules = rulesList; 6183 } 6184 /** 6185 * Update the `src` property of an image, or change the HTML of a container, to the specified path. 6186 * @function 6187 * @param {String} path - Path to the image or HTML partial. 6188 * @fires Interchange#replaced 6189 */ 6190 6191 }, { 6192 key: "replace", 6193 value: function replace(path) { 6194 if (this.currentPath === path) return; 6195 6196 var _this = this, 6197 trigger = 'replaced.zf.interchange'; // Replacing images 6198 6199 6200 if (this.$element[0].nodeName === 'IMG') { 6201 this.$element.attr('src', path).on('load', function () { 6202 _this.currentPath = path; 6203 }).trigger(trigger); 6204 } // Replacing background images 6205 else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) { 6206 path = path.replace(/\(/g, '%28').replace(/\)/g, '%29'); 6207 this.$element.css({ 6208 'background-image': 'url(' + path + ')' 6209 }).trigger(trigger); 6210 } // Replacing HTML 6211 else { 6212 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.get(path, function (response) { 6213 _this.$element.html(response).trigger(trigger); 6214 6215 jquery__WEBPACK_IMPORTED_MODULE_0___default()(response).foundation(); 6216 _this.currentPath = path; 6217 }); 6218 } 6219 /** 6220 * Fires when content in an Interchange element is done being loaded. 6221 * @event Interchange#replaced 6222 */ 6223 // this.$element.trigger('replaced.zf.interchange'); 6224 6225 } 6226 /** 6227 * Destroys an instance of interchange. 6228 * @function 6229 */ 6230 6231 }, { 6232 key: "_destroy", 6233 value: function _destroy() { 6234 this.$element.off('resizeme.zf.trigger'); 6235 } 6236 }]); 6237 6238 return Interchange; 6239}(Plugin); 6240/** 6241 * Default settings for plugin 6242 */ 6243 6244 6245Interchange.defaults = { 6246 /** 6247 * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation. 6248 * @option 6249 * @type {?array} 6250 * @default null 6251 */ 6252 rules: null 6253}; 6254Interchange.SPECIAL_QUERIES = { 6255 'landscape': 'screen and (orientation: landscape)', 6256 'portrait': 'screen and (orientation: portrait)', 6257 'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)' 6258}; 6259/** 6260 * SmoothScroll module. 6261 * @module foundation.smooth-scroll 6262 */ 6263 6264var SmoothScroll = 6265/*#__PURE__*/ 6266function (_Plugin) { 6267 _inherits(SmoothScroll, _Plugin); 6268 6269 function SmoothScroll() { 6270 _classCallCheck(this, SmoothScroll); 6271 6272 return _possibleConstructorReturn(this, _getPrototypeOf(SmoothScroll).apply(this, arguments)); 6273 } 6274 6275 _createClass(SmoothScroll, [{ 6276 key: "_setup", 6277 6278 /** 6279 * Creates a new instance of SmoothScroll. 6280 * @class 6281 * @name SmoothScroll 6282 * @fires SmoothScroll#init 6283 * @param {Object} element - jQuery object to add the trigger to. 6284 * @param {Object} options - Overrides to the default plugin settings. 6285 */ 6286 value: function _setup(element, options) { 6287 this.$element = element; 6288 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, SmoothScroll.defaults, this.$element.data(), options); 6289 this.className = 'SmoothScroll'; // ie9 back compat 6290 6291 this._init(); 6292 } 6293 /** 6294 * Initialize the SmoothScroll plugin 6295 * @private 6296 */ 6297 6298 }, { 6299 key: "_init", 6300 value: function _init() { 6301 var id = this.$element[0].id || GetYoDigits(6, 'smooth-scroll'); 6302 this.$element.attr({ 6303 id: id 6304 }); 6305 6306 this._events(); 6307 } 6308 /** 6309 * Initializes events for SmoothScroll. 6310 * @private 6311 */ 6312 6313 }, { 6314 key: "_events", 6315 value: function _events() { 6316 this.$element.on('click.zf.smoothScroll', this._handleLinkClick); 6317 this.$element.on('click.zf.smoothScroll', 'a[href^="#"]', this._handleLinkClick); 6318 } 6319 /** 6320 * Handle the given event to smoothly scroll to the anchor pointed by the event target. 6321 * @param {*} e - event 6322 * @function 6323 * @private 6324 */ 6325 6326 }, { 6327 key: "_handleLinkClick", 6328 value: function _handleLinkClick(e) { 6329 var _this = this; // Follow the link if it does not point to an anchor. 6330 6331 6332 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.currentTarget).is('a[href^="#"]')) return; 6333 var arrival = e.currentTarget.getAttribute('href'); 6334 this._inTransition = true; 6335 SmoothScroll.scrollToLoc(arrival, this.options, function () { 6336 _this._inTransition = false; 6337 }); 6338 e.preventDefault(); 6339 } 6340 }, { 6341 key: "_destroy", 6342 6343 /** 6344 * Destroys the SmoothScroll instance. 6345 * @function 6346 */ 6347 value: function _destroy() { 6348 this.$element.off('click.zf.smoothScroll', this._handleLinkClick); 6349 this.$element.off('click.zf.smoothScroll', 'a[href^="#"]', this._handleLinkClick); 6350 } 6351 }], [{ 6352 key: "scrollToLoc", 6353 6354 /** 6355 * Function to scroll to a given location on the page. 6356 * @param {String} loc - A properly formatted jQuery id selector. Example: '#foo' 6357 * @param {Object} options - The options to use. 6358 * @param {Function} callback - The callback function. 6359 * @static 6360 * @function 6361 */ 6362 value: function scrollToLoc(loc) { 6363 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : SmoothScroll.defaults; 6364 var callback = arguments.length > 2 ? arguments[2] : undefined; 6365 var $loc = jquery__WEBPACK_IMPORTED_MODULE_0___default()(loc); // Do nothing if target does not exist to prevent errors 6366 6367 if (!$loc.length) return false; 6368 var scrollPos = Math.round($loc.offset().top - options.threshold / 2 - options.offset); 6369 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').stop(true).animate({ 6370 scrollTop: scrollPos 6371 }, options.animationDuration, options.animationEasing, function () { 6372 if (typeof callback === 'function') { 6373 callback(); 6374 } 6375 }); 6376 } 6377 }]); 6378 6379 return SmoothScroll; 6380}(Plugin); 6381/** 6382 * Default settings for plugin. 6383 */ 6384 6385 6386SmoothScroll.defaults = { 6387 /** 6388 * Amount of time, in ms, the animated scrolling should take between locations. 6389 * @option 6390 * @type {number} 6391 * @default 500 6392 */ 6393 animationDuration: 500, 6394 6395 /** 6396 * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`. 6397 * @option 6398 * @type {string} 6399 * @default 'linear' 6400 * @see {@link https://api.jquery.com/animate|Jquery animate} 6401 */ 6402 animationEasing: 'linear', 6403 6404 /** 6405 * Number of pixels to use as a marker for location changes. 6406 * @option 6407 * @type {number} 6408 * @default 50 6409 */ 6410 threshold: 50, 6411 6412 /** 6413 * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar. 6414 * @option 6415 * @type {number} 6416 * @default 0 6417 */ 6418 offset: 0 6419}; 6420/** 6421 * Magellan module. 6422 * @module foundation.magellan 6423 * @requires foundation.smoothScroll 6424 */ 6425 6426var Magellan = 6427/*#__PURE__*/ 6428function (_Plugin) { 6429 _inherits(Magellan, _Plugin); 6430 6431 function Magellan() { 6432 _classCallCheck(this, Magellan); 6433 6434 return _possibleConstructorReturn(this, _getPrototypeOf(Magellan).apply(this, arguments)); 6435 } 6436 6437 _createClass(Magellan, [{ 6438 key: "_setup", 6439 6440 /** 6441 * Creates a new instance of Magellan. 6442 * @class 6443 * @name Magellan 6444 * @fires Magellan#init 6445 * @param {Object} element - jQuery object to add the trigger to. 6446 * @param {Object} options - Overrides to the default plugin settings. 6447 */ 6448 value: function _setup(element, options) { 6449 this.$element = element; 6450 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Magellan.defaults, this.$element.data(), options); 6451 this.className = 'Magellan'; // ie9 back compat 6452 6453 this._init(); 6454 6455 this.calcPoints(); 6456 } 6457 /** 6458 * Initializes the Magellan plugin and calls functions to get equalizer functioning on load. 6459 * @private 6460 */ 6461 6462 }, { 6463 key: "_init", 6464 value: function _init() { 6465 var id = this.$element[0].id || GetYoDigits(6, 'magellan'); 6466 this.$targets = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-magellan-target]'); 6467 this.$links = this.$element.find('a'); 6468 this.$element.attr({ 6469 'data-resize': id, 6470 'data-scroll': id, 6471 'id': id 6472 }); 6473 this.$active = jquery__WEBPACK_IMPORTED_MODULE_0___default()(); 6474 this.scrollPos = parseInt(window.pageYOffset, 10); 6475 6476 this._events(); 6477 } 6478 /** 6479 * Calculates an array of pixel values that are the demarcation lines between locations on the page. 6480 * Can be invoked if new elements are added or the size of a location changes. 6481 * @function 6482 */ 6483 6484 }, { 6485 key: "calcPoints", 6486 value: function calcPoints() { 6487 var _this = this, 6488 body = document.body, 6489 html = document.documentElement; 6490 6491 this.points = []; 6492 this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight)); 6493 this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)); 6494 this.$targets.each(function () { 6495 var $tar = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 6496 pt = Math.round($tar.offset().top - _this.options.threshold); 6497 $tar.targetPoint = pt; 6498 6499 _this.points.push(pt); 6500 }); 6501 } 6502 /** 6503 * Initializes events for Magellan. 6504 * @private 6505 */ 6506 6507 }, { 6508 key: "_events", 6509 value: function _events() { 6510 var _this = this, 6511 $body = jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body'), 6512 opts = { 6513 duration: _this.options.animationDuration, 6514 easing: _this.options.animationEasing 6515 }; 6516 6517 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).one('load', function () { 6518 if (_this.options.deepLinking) { 6519 if (location.hash) { 6520 _this.scrollToLoc(location.hash); 6521 } 6522 } 6523 6524 _this.calcPoints(); 6525 6526 _this._updateActive(); 6527 }); 6528 _this.onLoadListener = onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 6529 _this.$element.on({ 6530 'resizeme.zf.trigger': _this.reflow.bind(_this), 6531 'scrollme.zf.trigger': _this._updateActive.bind(_this) 6532 }).on('click.zf.magellan', 'a[href^="#"]', function (e) { 6533 e.preventDefault(); 6534 var arrival = this.getAttribute('href'); 6535 6536 _this.scrollToLoc(arrival); 6537 }); 6538 }); 6539 6540 this._deepLinkScroll = function (e) { 6541 if (_this.options.deepLinking) { 6542 _this.scrollToLoc(window.location.hash); 6543 } 6544 }; 6545 6546 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('hashchange', this._deepLinkScroll); 6547 } 6548 /** 6549 * Function to scroll to a given location on the page. 6550 * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo' 6551 * @function 6552 */ 6553 6554 }, { 6555 key: "scrollToLoc", 6556 value: function scrollToLoc(loc) { 6557 this._inTransition = true; 6558 6559 var _this = this; 6560 6561 var options = { 6562 animationEasing: this.options.animationEasing, 6563 animationDuration: this.options.animationDuration, 6564 threshold: this.options.threshold, 6565 offset: this.options.offset 6566 }; 6567 SmoothScroll.scrollToLoc(loc, options, function () { 6568 _this._inTransition = false; 6569 }); 6570 } 6571 /** 6572 * Calls necessary functions to update Magellan upon DOM change 6573 * @function 6574 */ 6575 6576 }, { 6577 key: "reflow", 6578 value: function reflow() { 6579 this.calcPoints(); 6580 6581 this._updateActive(); 6582 } 6583 /** 6584 * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled. 6585 * @private 6586 * @function 6587 * @fires Magellan#update 6588 */ 6589 6590 }, { 6591 key: "_updateActive", 6592 value: function _updateActive() 6593 /*evt, elem, scrollPos*/ 6594 { 6595 var _this2 = this; 6596 6597 if (this._inTransition) return; 6598 var newScrollPos = parseInt(window.pageYOffset, 10); 6599 var isScrollingUp = this.scrollPos > newScrollPos; 6600 this.scrollPos = newScrollPos; 6601 var activeIdx; // Before the first point: no link 6602 6603 if (newScrollPos < this.points[0]) ; 6604 /* do nothing */ 6605 // At the bottom of the page: last link 6606 else if (newScrollPos + this.winHeight === this.docHeight) { 6607 activeIdx = this.points.length - 1; 6608 } // Otherwhise, use the last visible link 6609 else { 6610 var visibleLinks = this.points.filter(function (p, i) { 6611 return p - _this2.options.offset - (isScrollingUp ? _this2.options.threshold : 0) <= newScrollPos; 6612 }); 6613 activeIdx = visibleLinks.length ? visibleLinks.length - 1 : 0; 6614 } // Get the new active link 6615 6616 var $oldActive = this.$active; 6617 var activeHash = ''; 6618 6619 if (typeof activeIdx !== 'undefined') { 6620 this.$active = this.$links.filter('[href="#' + this.$targets.eq(activeIdx).data('magellan-target') + '"]'); 6621 if (this.$active.length) activeHash = this.$active[0].getAttribute('href'); 6622 } else { 6623 this.$active = jquery__WEBPACK_IMPORTED_MODULE_0___default()(); 6624 } 6625 6626 var isNewActive = !(!this.$active.length && !$oldActive.length) && !this.$active.is($oldActive); 6627 var isNewHash = activeHash !== window.location.hash; // Update the active link element 6628 6629 if (isNewActive) { 6630 $oldActive.removeClass(this.options.activeClass); 6631 this.$active.addClass(this.options.activeClass); 6632 } // Update the hash (it may have changed with the same active link) 6633 6634 6635 if (this.options.deepLinking && isNewHash) { 6636 if (window.history.pushState) { 6637 // Set or remove the hash (see: https://stackoverflow.com/a/5298684/4317384 6638 var url = activeHash ? activeHash : window.location.pathname + window.location.search; 6639 window.history.pushState(null, null, url); 6640 } else { 6641 window.location.hash = activeHash; 6642 } 6643 } 6644 6645 if (isNewActive) { 6646 /** 6647 * Fires when magellan is finished updating to the new active element. 6648 * @event Magellan#update 6649 */ 6650 this.$element.trigger('update.zf.magellan', [this.$active]); 6651 } 6652 } 6653 /** 6654 * Destroys an instance of Magellan and resets the url of the window. 6655 * @function 6656 */ 6657 6658 }, { 6659 key: "_destroy", 6660 value: function _destroy() { 6661 this.$element.off('.zf.trigger .zf.magellan').find(".".concat(this.options.activeClass)).removeClass(this.options.activeClass); 6662 6663 if (this.options.deepLinking) { 6664 var hash = this.$active[0].getAttribute('href'); 6665 window.location.hash.replace(hash, ''); 6666 } 6667 6668 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('hashchange', this._deepLinkScroll); 6669 if (this.onLoadListener) jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.onLoadListener); 6670 } 6671 }]); 6672 6673 return Magellan; 6674}(Plugin); 6675/** 6676 * Default settings for plugin 6677 */ 6678 6679 6680Magellan.defaults = { 6681 /** 6682 * Amount of time, in ms, the animated scrolling should take between locations. 6683 * @option 6684 * @type {number} 6685 * @default 500 6686 */ 6687 animationDuration: 500, 6688 6689 /** 6690 * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`. 6691 * @option 6692 * @type {string} 6693 * @default 'linear' 6694 * @see {@link https://api.jquery.com/animate|Jquery animate} 6695 */ 6696 animationEasing: 'linear', 6697 6698 /** 6699 * Number of pixels to use as a marker for location changes. 6700 * @option 6701 * @type {number} 6702 * @default 50 6703 */ 6704 threshold: 50, 6705 6706 /** 6707 * Class applied to the active locations link on the magellan container. 6708 * @option 6709 * @type {string} 6710 * @default 'is-active' 6711 */ 6712 activeClass: 'is-active', 6713 6714 /** 6715 * Allows the script to manipulate the url of the current page, and if supported, alter the history. 6716 * @option 6717 * @type {boolean} 6718 * @default false 6719 */ 6720 deepLinking: false, 6721 6722 /** 6723 * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar. 6724 * @option 6725 * @type {number} 6726 * @default 0 6727 */ 6728 offset: 0 6729}; 6730/** 6731 * OffCanvas module. 6732 * @module foundation.offcanvas 6733 * @requires foundation.util.keyboard 6734 * @requires foundation.util.mediaQuery 6735 * @requires foundation.util.triggers 6736 */ 6737 6738var OffCanvas = 6739/*#__PURE__*/ 6740function (_Plugin) { 6741 _inherits(OffCanvas, _Plugin); 6742 6743 function OffCanvas() { 6744 _classCallCheck(this, OffCanvas); 6745 6746 return _possibleConstructorReturn(this, _getPrototypeOf(OffCanvas).apply(this, arguments)); 6747 } 6748 6749 _createClass(OffCanvas, [{ 6750 key: "_setup", 6751 6752 /** 6753 * Creates a new instance of an off-canvas wrapper. 6754 * @class 6755 * @name OffCanvas 6756 * @fires OffCanvas#init 6757 * @param {Object} element - jQuery object to initialize. 6758 * @param {Object} options - Overrides to the default plugin settings. 6759 */ 6760 value: function _setup(element, options) { 6761 var _this2 = this; 6762 6763 this.className = 'OffCanvas'; // ie9 back compat 6764 6765 this.$element = element; 6766 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, OffCanvas.defaults, this.$element.data(), options); 6767 this.contentClasses = { 6768 base: [], 6769 reveal: [] 6770 }; 6771 this.$lastTrigger = jquery__WEBPACK_IMPORTED_MODULE_0___default()(); 6772 this.$triggers = jquery__WEBPACK_IMPORTED_MODULE_0___default()(); 6773 this.position = 'left'; 6774 this.$content = jquery__WEBPACK_IMPORTED_MODULE_0___default()(); 6775 this.nested = !!this.options.nested; // Defines the CSS transition/position classes of the off-canvas content container. 6776 6777 jquery__WEBPACK_IMPORTED_MODULE_0___default()(['push', 'overlap']).each(function (index, val) { 6778 _this2.contentClasses.base.push('has-transition-' + val); 6779 }); 6780 jquery__WEBPACK_IMPORTED_MODULE_0___default()(['left', 'right', 'top', 'bottom']).each(function (index, val) { 6781 _this2.contentClasses.base.push('has-position-' + val); 6782 6783 _this2.contentClasses.reveal.push('has-reveal-' + val); 6784 }); // Triggers init is idempotent, just need to make sure it is initialized 6785 6786 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 6787 6788 MediaQuery._init(); 6789 6790 this._init(); 6791 6792 this._events(); 6793 6794 Keyboard.register('OffCanvas', { 6795 'ESCAPE': 'close' 6796 }); 6797 } 6798 /** 6799 * Initializes the off-canvas wrapper by adding the exit overlay (if needed). 6800 * @function 6801 * @private 6802 */ 6803 6804 }, { 6805 key: "_init", 6806 value: function _init() { 6807 var id = this.$element.attr('id'); 6808 this.$element.attr('aria-hidden', 'true'); // Find off-canvas content, either by ID (if specified), by siblings or by closest selector (fallback) 6809 6810 if (this.options.contentId) { 6811 this.$content = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#' + this.options.contentId); 6812 } else if (this.$element.siblings('[data-off-canvas-content]').length) { 6813 this.$content = this.$element.siblings('[data-off-canvas-content]').first(); 6814 } else { 6815 this.$content = this.$element.closest('[data-off-canvas-content]').first(); 6816 } 6817 6818 if (!this.options.contentId) { 6819 // Assume that the off-canvas element is nested if it isn't a sibling of the content 6820 this.nested = this.$element.siblings('[data-off-canvas-content]').length === 0; 6821 } else if (this.options.contentId && this.options.nested === null) { 6822 // Warning if using content ID without setting the nested option 6823 // Once the element is nested it is required to work properly in this case 6824 console.warn('Remember to use the nested option if using the content ID option!'); 6825 } 6826 6827 if (this.nested === true) { 6828 // Force transition overlap if nested 6829 this.options.transition = 'overlap'; // Remove appropriate classes if already assigned in markup 6830 6831 this.$element.removeClass('is-transition-push'); 6832 } 6833 6834 this.$element.addClass("is-transition-".concat(this.options.transition, " is-closed")); // Find triggers that affect this element and add aria-expanded to them 6835 6836 this.$triggers = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).find('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-expanded', 'false').attr('aria-controls', id); // Get position by checking for related CSS class 6837 6838 this.position = this.$element.is('.position-left, .position-top, .position-right, .position-bottom') ? this.$element.attr('class').match(/position\-(left|top|right|bottom)/)[1] : this.position; // Add an overlay over the content if necessary 6839 6840 if (this.options.contentOverlay === true) { 6841 var overlay = document.createElement('div'); 6842 var overlayPosition = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.$element).css("position") === 'fixed' ? 'is-overlay-fixed' : 'is-overlay-absolute'; 6843 overlay.setAttribute('class', 'js-off-canvas-overlay ' + overlayPosition); 6844 this.$overlay = jquery__WEBPACK_IMPORTED_MODULE_0___default()(overlay); 6845 6846 if (overlayPosition === 'is-overlay-fixed') { 6847 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.$overlay).insertAfter(this.$element); 6848 } else { 6849 this.$content.append(this.$overlay); 6850 } 6851 } // Get the revealOn option from the class. 6852 6853 6854 var revealOnRegExp = new RegExp(RegExpEscape(this.options.revealClass) + '([^\\s]+)', 'g'); 6855 var revealOnClass = revealOnRegExp.exec(this.$element[0].className); 6856 6857 if (revealOnClass) { 6858 this.options.isRevealed = true; 6859 this.options.revealOn = this.options.revealOn || revealOnClass[1]; 6860 } // Ensure the `reveal-on-*` class is set. 6861 6862 6863 if (this.options.isRevealed === true && this.options.revealOn) { 6864 this.$element.first().addClass("".concat(this.options.revealClass).concat(this.options.revealOn)); 6865 6866 this._setMQChecker(); 6867 } 6868 6869 if (this.options.transitionTime) { 6870 this.$element.css('transition-duration', this.options.transitionTime); 6871 } // Initally remove all transition/position CSS classes from off-canvas content container. 6872 6873 6874 this._removeContentClasses(); 6875 } 6876 /** 6877 * Adds event handlers to the off-canvas wrapper and the exit overlay. 6878 * @function 6879 * @private 6880 */ 6881 6882 }, { 6883 key: "_events", 6884 value: function _events() { 6885 this.$element.off('.zf.trigger .zf.offcanvas').on({ 6886 'open.zf.trigger': this.open.bind(this), 6887 'close.zf.trigger': this.close.bind(this), 6888 'toggle.zf.trigger': this.toggle.bind(this), 6889 'keydown.zf.offcanvas': this._handleKeyboard.bind(this) 6890 }); 6891 6892 if (this.options.closeOnClick === true) { 6893 var $target = this.options.contentOverlay ? this.$overlay : this.$content; 6894 $target.on({ 6895 'click.zf.offcanvas': this.close.bind(this) 6896 }); 6897 } 6898 } 6899 /** 6900 * Applies event listener for elements that will reveal at certain breakpoints. 6901 * @private 6902 */ 6903 6904 }, { 6905 key: "_setMQChecker", 6906 value: function _setMQChecker() { 6907 var _this = this; 6908 6909 this.onLoadListener = onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 6910 if (MediaQuery.atLeast(_this.options.revealOn)) { 6911 _this.reveal(true); 6912 } 6913 }); 6914 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', function () { 6915 if (MediaQuery.atLeast(_this.options.revealOn)) { 6916 _this.reveal(true); 6917 } else { 6918 _this.reveal(false); 6919 } 6920 }); 6921 } 6922 /** 6923 * Removes the CSS transition/position classes of the off-canvas content container. 6924 * Removing the classes is important when another off-canvas gets opened that uses the same content container. 6925 * @param {Boolean} hasReveal - true if related off-canvas element is revealed. 6926 * @private 6927 */ 6928 6929 }, { 6930 key: "_removeContentClasses", 6931 value: function _removeContentClasses(hasReveal) { 6932 if (typeof hasReveal !== 'boolean') { 6933 this.$content.removeClass(this.contentClasses.base.join(' ')); 6934 } else if (hasReveal === false) { 6935 this.$content.removeClass("has-reveal-".concat(this.position)); 6936 } 6937 } 6938 /** 6939 * Adds the CSS transition/position classes of the off-canvas content container, based on the opening off-canvas element. 6940 * Beforehand any transition/position class gets removed. 6941 * @param {Boolean} hasReveal - true if related off-canvas element is revealed. 6942 * @private 6943 */ 6944 6945 }, { 6946 key: "_addContentClasses", 6947 value: function _addContentClasses(hasReveal) { 6948 this._removeContentClasses(hasReveal); 6949 6950 if (typeof hasReveal !== 'boolean') { 6951 this.$content.addClass("has-transition-".concat(this.options.transition, " has-position-").concat(this.position)); 6952 } else if (hasReveal === true) { 6953 this.$content.addClass("has-reveal-".concat(this.position)); 6954 } 6955 } 6956 /** 6957 * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open. 6958 * @param {Boolean} isRevealed - true if element should be revealed. 6959 * @function 6960 */ 6961 6962 }, { 6963 key: "reveal", 6964 value: function reveal(isRevealed) { 6965 if (isRevealed) { 6966 this.close(); 6967 this.isRevealed = true; 6968 this.$element.attr('aria-hidden', 'false'); 6969 this.$element.off('open.zf.trigger toggle.zf.trigger'); 6970 this.$element.removeClass('is-closed'); 6971 } else { 6972 this.isRevealed = false; 6973 this.$element.attr('aria-hidden', 'true'); 6974 this.$element.off('open.zf.trigger toggle.zf.trigger').on({ 6975 'open.zf.trigger': this.open.bind(this), 6976 'toggle.zf.trigger': this.toggle.bind(this) 6977 }); 6978 this.$element.addClass('is-closed'); 6979 } 6980 6981 this._addContentClasses(isRevealed); 6982 } 6983 /** 6984 * Stops scrolling of the body when offcanvas is open on mobile Safari and other troublesome browsers. 6985 * @private 6986 */ 6987 6988 }, { 6989 key: "_stopScrolling", 6990 value: function _stopScrolling(event) { 6991 return false; 6992 } // Taken and adapted from http://stackoverflow.com/questions/16889447/prevent-full-page-scrolling-ios 6993 // Only really works for y, not sure how to extend to x or if we need to. 6994 6995 }, { 6996 key: "_recordScrollable", 6997 value: function _recordScrollable(event) { 6998 var elem = this; // called from event handler context with this as elem 6999 // If the element is scrollable (content overflows), then... 7000 7001 if (elem.scrollHeight !== elem.clientHeight) { 7002 // If we're at the top, scroll down one pixel to allow scrolling up 7003 if (elem.scrollTop === 0) { 7004 elem.scrollTop = 1; 7005 } // If we're at the bottom, scroll up one pixel to allow scrolling down 7006 7007 7008 if (elem.scrollTop === elem.scrollHeight - elem.clientHeight) { 7009 elem.scrollTop = elem.scrollHeight - elem.clientHeight - 1; 7010 } 7011 } 7012 7013 elem.allowUp = elem.scrollTop > 0; 7014 elem.allowDown = elem.scrollTop < elem.scrollHeight - elem.clientHeight; 7015 elem.lastY = event.originalEvent.pageY; 7016 } 7017 }, { 7018 key: "_stopScrollPropagation", 7019 value: function _stopScrollPropagation(event) { 7020 var elem = this; // called from event handler context with this as elem 7021 7022 var up = event.pageY < elem.lastY; 7023 var down = !up; 7024 elem.lastY = event.pageY; 7025 7026 if (up && elem.allowUp || down && elem.allowDown) { 7027 event.stopPropagation(); 7028 } else { 7029 event.preventDefault(); 7030 } 7031 } 7032 /** 7033 * Opens the off-canvas menu. 7034 * @function 7035 * @param {Object} event - Event object passed from listener. 7036 * @param {jQuery} trigger - element that triggered the off-canvas to open. 7037 * @fires Offcanvas#opened 7038 * @todo also trigger 'open' event? 7039 */ 7040 7041 }, { 7042 key: "open", 7043 value: function open(event, trigger) { 7044 if (this.$element.hasClass('is-open') || this.isRevealed) { 7045 return; 7046 } 7047 7048 var _this = this; 7049 7050 if (trigger) { 7051 this.$lastTrigger = trigger; 7052 } 7053 7054 if (this.options.forceTo === 'top') { 7055 window.scrollTo(0, 0); 7056 } else if (this.options.forceTo === 'bottom') { 7057 window.scrollTo(0, document.body.scrollHeight); 7058 } 7059 7060 if (this.options.transitionTime && this.options.transition !== 'overlap') { 7061 this.$element.siblings('[data-off-canvas-content]').css('transition-duration', this.options.transitionTime); 7062 } else { 7063 this.$element.siblings('[data-off-canvas-content]').css('transition-duration', ''); 7064 } 7065 7066 this.$element.addClass('is-open').removeClass('is-closed'); 7067 this.$triggers.attr('aria-expanded', 'true'); 7068 this.$element.attr('aria-hidden', 'false'); 7069 this.$content.addClass('is-open-' + this.position); // If `contentScroll` is set to false, add class and disable scrolling on touch devices. 7070 7071 if (this.options.contentScroll === false) { 7072 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').addClass('is-off-canvas-open').on('touchmove', this._stopScrolling); 7073 this.$element.on('touchstart', this._recordScrollable); 7074 this.$element.on('touchmove', this._stopScrollPropagation); 7075 } 7076 7077 if (this.options.contentOverlay === true) { 7078 this.$overlay.addClass('is-visible'); 7079 } 7080 7081 if (this.options.closeOnClick === true && this.options.contentOverlay === true) { 7082 this.$overlay.addClass('is-closable'); 7083 } 7084 7085 if (this.options.autoFocus === true) { 7086 this.$element.one(transitionend(this.$element), function () { 7087 if (!_this.$element.hasClass('is-open')) { 7088 return; // exit if prematurely closed 7089 } 7090 7091 var canvasFocus = _this.$element.find('[data-autofocus]'); 7092 7093 if (canvasFocus.length) { 7094 canvasFocus.eq(0).focus(); 7095 } else { 7096 _this.$element.find('a, button').eq(0).focus(); 7097 } 7098 }); 7099 } 7100 7101 if (this.options.trapFocus === true) { 7102 this.$content.attr('tabindex', '-1'); 7103 Keyboard.trapFocus(this.$element); 7104 } 7105 7106 this._addContentClasses(); 7107 /** 7108 * Fires when the off-canvas menu opens. 7109 * @event Offcanvas#opened 7110 */ 7111 7112 7113 this.$element.trigger('opened.zf.offcanvas'); 7114 } 7115 /** 7116 * Closes the off-canvas menu. 7117 * @function 7118 * @param {Function} cb - optional cb to fire after closure. 7119 * @fires Offcanvas#closed 7120 */ 7121 7122 }, { 7123 key: "close", 7124 value: function close(cb) { 7125 if (!this.$element.hasClass('is-open') || this.isRevealed) { 7126 return; 7127 } 7128 7129 var _this = this; 7130 7131 this.$element.removeClass('is-open'); 7132 this.$element.attr('aria-hidden', 'true') 7133 /** 7134 * Fires when the off-canvas menu opens. 7135 * @event Offcanvas#closed 7136 */ 7137 .trigger('closed.zf.offcanvas'); 7138 this.$content.removeClass('is-open-left is-open-top is-open-right is-open-bottom'); // If `contentScroll` is set to false, remove class and re-enable scrolling on touch devices. 7139 7140 if (this.options.contentScroll === false) { 7141 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').removeClass('is-off-canvas-open').off('touchmove', this._stopScrolling); 7142 this.$element.off('touchstart', this._recordScrollable); 7143 this.$element.off('touchmove', this._stopScrollPropagation); 7144 } 7145 7146 if (this.options.contentOverlay === true) { 7147 this.$overlay.removeClass('is-visible'); 7148 } 7149 7150 if (this.options.closeOnClick === true && this.options.contentOverlay === true) { 7151 this.$overlay.removeClass('is-closable'); 7152 } 7153 7154 this.$triggers.attr('aria-expanded', 'false'); 7155 7156 if (this.options.trapFocus === true) { 7157 this.$content.removeAttr('tabindex'); 7158 Keyboard.releaseFocus(this.$element); 7159 } // Listen to transitionEnd and add class when done. 7160 7161 7162 this.$element.one(transitionend(this.$element), function (e) { 7163 _this.$element.addClass('is-closed'); 7164 7165 _this._removeContentClasses(); 7166 }); 7167 } 7168 /** 7169 * Toggles the off-canvas menu open or closed. 7170 * @function 7171 * @param {Object} event - Event object passed from listener. 7172 * @param {jQuery} trigger - element that triggered the off-canvas to open. 7173 */ 7174 7175 }, { 7176 key: "toggle", 7177 value: function toggle(event, trigger) { 7178 if (this.$element.hasClass('is-open')) { 7179 this.close(event, trigger); 7180 } else { 7181 this.open(event, trigger); 7182 } 7183 } 7184 /** 7185 * Handles keyboard input when detected. When the escape key is pressed, the off-canvas menu closes, and focus is restored to the element that opened the menu. 7186 * @function 7187 * @private 7188 */ 7189 7190 }, { 7191 key: "_handleKeyboard", 7192 value: function _handleKeyboard(e) { 7193 var _this3 = this; 7194 7195 Keyboard.handleKey(e, 'OffCanvas', { 7196 close: function close() { 7197 _this3.close(); 7198 7199 _this3.$lastTrigger.focus(); 7200 7201 return true; 7202 }, 7203 handled: function handled() { 7204 e.stopPropagation(); 7205 e.preventDefault(); 7206 } 7207 }); 7208 } 7209 /** 7210 * Destroys the offcanvas plugin. 7211 * @function 7212 */ 7213 7214 }, { 7215 key: "_destroy", 7216 value: function _destroy() { 7217 this.close(); 7218 this.$element.off('.zf.trigger .zf.offcanvas'); 7219 this.$overlay.off('.zf.offcanvas'); 7220 if (this.onLoadListener) jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.onLoadListener); 7221 } 7222 }]); 7223 7224 return OffCanvas; 7225}(Plugin); 7226 7227OffCanvas.defaults = { 7228 /** 7229 * Allow the user to click outside of the menu to close it. 7230 * @option 7231 * @type {boolean} 7232 * @default true 7233 */ 7234 closeOnClick: true, 7235 7236 /** 7237 * Adds an overlay on top of `[data-off-canvas-content]`. 7238 * @option 7239 * @type {boolean} 7240 * @default true 7241 */ 7242 contentOverlay: true, 7243 7244 /** 7245 * Target an off-canvas content container by ID that may be placed anywhere. If null the closest content container will be taken. 7246 * @option 7247 * @type {?string} 7248 * @default null 7249 */ 7250 contentId: null, 7251 7252 /** 7253 * Define the off-canvas element is nested in an off-canvas content. This is required when using the contentId option for a nested element. 7254 * @option 7255 * @type {boolean} 7256 * @default null 7257 */ 7258 nested: null, 7259 7260 /** 7261 * Enable/disable scrolling of the main content when an off canvas panel is open. 7262 * @option 7263 * @type {boolean} 7264 * @default true 7265 */ 7266 contentScroll: true, 7267 7268 /** 7269 * Amount of time in ms the open and close transition requires. If none selected, pulls from body style. 7270 * @option 7271 * @type {number} 7272 * @default null 7273 */ 7274 transitionTime: null, 7275 7276 /** 7277 * Type of transition for the offcanvas menu. Options are 'push', 'detached' or 'slide'. 7278 * @option 7279 * @type {string} 7280 * @default push 7281 */ 7282 transition: 'push', 7283 7284 /** 7285 * Force the page to scroll to top or bottom on open. 7286 * @option 7287 * @type {?string} 7288 * @default null 7289 */ 7290 forceTo: null, 7291 7292 /** 7293 * Allow the offcanvas to remain open for certain breakpoints. 7294 * @option 7295 * @type {boolean} 7296 * @default false 7297 */ 7298 isRevealed: false, 7299 7300 /** 7301 * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class with the `revealClass` option. 7302 * @option 7303 * @type {?string} 7304 * @default null 7305 */ 7306 revealOn: null, 7307 7308 /** 7309 * Force focus to the offcanvas on open. If true, will focus the opening trigger on close. 7310 * @option 7311 * @type {boolean} 7312 * @default true 7313 */ 7314 autoFocus: true, 7315 7316 /** 7317 * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`. 7318 * @option 7319 * @type {string} 7320 * @default reveal-for- 7321 * @todo improve the regex testing for this. 7322 */ 7323 revealClass: 'reveal-for-', 7324 7325 /** 7326 * Triggers optional focus trapping when opening an offcanvas. Sets tabindex of [data-off-canvas-content] to -1 for accessibility purposes. 7327 * @option 7328 * @type {boolean} 7329 * @default false 7330 */ 7331 trapFocus: false 7332}; 7333/** 7334 * Orbit module. 7335 * @module foundation.orbit 7336 * @requires foundation.util.keyboard 7337 * @requires foundation.util.motion 7338 * @requires foundation.util.timer 7339 * @requires foundation.util.imageLoader 7340 * @requires foundation.util.touch 7341 */ 7342 7343var Orbit = 7344/*#__PURE__*/ 7345function (_Plugin) { 7346 _inherits(Orbit, _Plugin); 7347 7348 function Orbit() { 7349 _classCallCheck(this, Orbit); 7350 7351 return _possibleConstructorReturn(this, _getPrototypeOf(Orbit).apply(this, arguments)); 7352 } 7353 7354 _createClass(Orbit, [{ 7355 key: "_setup", 7356 7357 /** 7358 * Creates a new instance of an orbit carousel. 7359 * @class 7360 * @name Orbit 7361 * @param {jQuery} element - jQuery object to make into an Orbit Carousel. 7362 * @param {Object} options - Overrides to the default plugin settings. 7363 */ 7364 value: function _setup(element, options) { 7365 this.$element = element; 7366 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Orbit.defaults, this.$element.data(), options); 7367 this.className = 'Orbit'; // ie9 back compat 7368 7369 Touch.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); // Touch init is idempotent, we just need to make sure it's initialied. 7370 7371 this._init(); 7372 7373 Keyboard.register('Orbit', { 7374 'ltr': { 7375 'ARROW_RIGHT': 'next', 7376 'ARROW_LEFT': 'previous' 7377 }, 7378 'rtl': { 7379 'ARROW_LEFT': 'next', 7380 'ARROW_RIGHT': 'previous' 7381 } 7382 }); 7383 } 7384 /** 7385 * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation. 7386 * @function 7387 * @private 7388 */ 7389 7390 }, { 7391 key: "_init", 7392 value: function _init() { 7393 // @TODO: consider discussion on PR #9278 about DOM pollution by changeSlide 7394 this._reset(); 7395 7396 this.$wrapper = this.$element.find(".".concat(this.options.containerClass)); 7397 this.$slides = this.$element.find(".".concat(this.options.slideClass)); 7398 var $images = this.$element.find('img'), 7399 initActive = this.$slides.filter('.is-active'), 7400 id = this.$element[0].id || GetYoDigits(6, 'orbit'); 7401 this.$element.attr({ 7402 'data-resize': id, 7403 'id': id 7404 }); 7405 7406 if (!initActive.length) { 7407 this.$slides.eq(0).addClass('is-active'); 7408 } 7409 7410 if (!this.options.useMUI) { 7411 this.$slides.addClass('no-motionui'); 7412 } 7413 7414 if ($images.length) { 7415 onImagesLoaded($images, this._prepareForOrbit.bind(this)); 7416 } else { 7417 this._prepareForOrbit(); //hehe 7418 7419 } 7420 7421 if (this.options.bullets) { 7422 this._loadBullets(); 7423 } 7424 7425 this._events(); 7426 7427 if (this.options.autoPlay && this.$slides.length > 1) { 7428 this.geoSync(); 7429 } 7430 7431 if (this.options.accessible) { 7432 // allow wrapper to be focusable to enable arrow navigation 7433 this.$wrapper.attr('tabindex', 0); 7434 } 7435 } 7436 /** 7437 * Creates a jQuery collection of bullets, if they are being used. 7438 * @function 7439 * @private 7440 */ 7441 7442 }, { 7443 key: "_loadBullets", 7444 value: function _loadBullets() { 7445 this.$bullets = this.$element.find(".".concat(this.options.boxOfBullets)).find('button'); 7446 } 7447 /** 7448 * Sets a `timer` object on the orbit, and starts the counter for the next slide. 7449 * @function 7450 */ 7451 7452 }, { 7453 key: "geoSync", 7454 value: function geoSync() { 7455 var _this = this; 7456 7457 this.timer = new Timer(this.$element, { 7458 duration: this.options.timerDelay, 7459 infinite: false 7460 }, function () { 7461 _this.changeSlide(true); 7462 }); 7463 this.timer.start(); 7464 } 7465 /** 7466 * Sets wrapper and slide heights for the orbit. 7467 * @function 7468 * @private 7469 */ 7470 7471 }, { 7472 key: "_prepareForOrbit", 7473 value: function _prepareForOrbit() { 7474 this._setWrapperHeight(); 7475 } 7476 /** 7477 * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height. 7478 * @function 7479 * @private 7480 * @param {Function} cb - a callback function to fire when complete. 7481 */ 7482 7483 }, { 7484 key: "_setWrapperHeight", 7485 value: function _setWrapperHeight(cb) { 7486 //rewrite this to `for` loop 7487 var max = 0, 7488 temp, 7489 counter = 0, 7490 _this = this; 7491 7492 this.$slides.each(function () { 7493 temp = this.getBoundingClientRect().height; 7494 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr('data-slide', counter); // hide all slides but the active one 7495 7496 if (!/mui/g.test(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)[0].className) && _this.$slides.filter('.is-active')[0] !== _this.$slides.eq(counter)[0]) { 7497 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).css({ 7498 'display': 'none' 7499 }); 7500 } 7501 7502 max = temp > max ? temp : max; 7503 counter++; 7504 }); 7505 7506 if (counter === this.$slides.length) { 7507 this.$wrapper.css({ 7508 'height': max 7509 }); //only change the wrapper height property once. 7510 7511 if (cb) { 7512 cb(max); 7513 } //fire callback with max height dimension. 7514 7515 } 7516 } 7517 /** 7518 * Sets the max-height of each slide. 7519 * @function 7520 * @private 7521 */ 7522 7523 }, { 7524 key: "_setSlideHeight", 7525 value: function _setSlideHeight(height) { 7526 this.$slides.each(function () { 7527 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).css('max-height', height); 7528 }); 7529 } 7530 /** 7531 * Adds event listeners to basically everything within the element. 7532 * @function 7533 * @private 7534 */ 7535 7536 }, { 7537 key: "_events", 7538 value: function _events() { 7539 var _this = this; //*************************************** 7540 //**Now using custom event - thanks to:** 7541 //** Yohai Ararat of Toronto ** 7542 //*************************************** 7543 // 7544 7545 7546 this.$element.off('.resizeme.zf.trigger').on({ 7547 'resizeme.zf.trigger': this._prepareForOrbit.bind(this) 7548 }); 7549 7550 if (this.$slides.length > 1) { 7551 if (this.options.swipe) { 7552 this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit').on('swipeleft.zf.orbit', function (e) { 7553 e.preventDefault(); 7554 7555 _this.changeSlide(true); 7556 }).on('swiperight.zf.orbit', function (e) { 7557 e.preventDefault(); 7558 7559 _this.changeSlide(false); 7560 }); 7561 } //*************************************** 7562 7563 7564 if (this.options.autoPlay) { 7565 this.$slides.on('click.zf.orbit', function () { 7566 _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true); 7567 7568 _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start'](); 7569 }); 7570 7571 if (this.options.pauseOnHover) { 7572 this.$element.on('mouseenter.zf.orbit', function () { 7573 _this.timer.pause(); 7574 }).on('mouseleave.zf.orbit', function () { 7575 if (!_this.$element.data('clickedOn')) { 7576 _this.timer.start(); 7577 } 7578 }); 7579 } 7580 } 7581 7582 if (this.options.navButtons) { 7583 var $controls = this.$element.find(".".concat(this.options.nextClass, ", .").concat(this.options.prevClass)); 7584 $controls.attr('tabindex', 0) //also need to handle enter/return and spacebar key presses 7585 .on('click.zf.orbit touchend.zf.orbit', function (e) { 7586 e.preventDefault(); 7587 7588 _this.changeSlide(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).hasClass(_this.options.nextClass)); 7589 }); 7590 } 7591 7592 if (this.options.bullets) { 7593 this.$bullets.on('click.zf.orbit touchend.zf.orbit', function () { 7594 if (/is-active/g.test(this.className)) { 7595 return false; 7596 } //if this is active, kick out of function. 7597 7598 7599 var idx = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('slide'), 7600 ltr = idx > _this.$slides.filter('.is-active').data('slide'), 7601 $slide = _this.$slides.eq(idx); 7602 7603 _this.changeSlide(ltr, $slide, idx); 7604 }); 7605 } 7606 7607 if (this.options.accessible) { 7608 this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function (e) { 7609 // handle keyboard event with keyboard util 7610 Keyboard.handleKey(e, 'Orbit', { 7611 next: function next() { 7612 _this.changeSlide(true); 7613 }, 7614 previous: function previous() { 7615 _this.changeSlide(false); 7616 }, 7617 handled: function handled() { 7618 // if bullet is focused, make sure focus moves 7619 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).is(_this.$bullets)) { 7620 _this.$bullets.filter('.is-active').focus(); 7621 } 7622 } 7623 }); 7624 }); 7625 } 7626 } 7627 } 7628 /** 7629 * Resets Orbit so it can be reinitialized 7630 */ 7631 7632 }, { 7633 key: "_reset", 7634 value: function _reset() { 7635 // Don't do anything if there are no slides (first run) 7636 if (typeof this.$slides == 'undefined') { 7637 return; 7638 } 7639 7640 if (this.$slides.length > 1) { 7641 // Remove old events 7642 this.$element.off('.zf.orbit').find('*').off('.zf.orbit'); // Restart timer if autoPlay is enabled 7643 7644 if (this.options.autoPlay) { 7645 this.timer.restart(); 7646 } // Reset all sliddes 7647 7648 7649 this.$slides.each(function (el) { 7650 jquery__WEBPACK_IMPORTED_MODULE_0___default()(el).removeClass('is-active is-active is-in').removeAttr('aria-live').hide(); 7651 }); // Show the first slide 7652 7653 this.$slides.first().addClass('is-active').show(); // Triggers when the slide has finished animating 7654 7655 this.$element.trigger('slidechange.zf.orbit', [this.$slides.first()]); // Select first bullet if bullets are present 7656 7657 if (this.options.bullets) { 7658 this._updateBullets(0); 7659 } 7660 } 7661 } 7662 /** 7663 * Changes the current slide to a new one. 7664 * @function 7665 * @param {Boolean} isLTR - if true the slide moves from right to left, if false the slide moves from left to right. 7666 * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected. 7667 * @param {Number} idx - the index of the new slide in its collection, if one chosen. 7668 * @fires Orbit#slidechange 7669 */ 7670 7671 }, { 7672 key: "changeSlide", 7673 value: function changeSlide(isLTR, chosenSlide, idx) { 7674 if (!this.$slides) { 7675 return; 7676 } // Don't freak out if we're in the middle of cleanup 7677 7678 7679 var $curSlide = this.$slides.filter('.is-active').eq(0); 7680 7681 if (/mui/g.test($curSlide[0].className)) { 7682 return false; 7683 } //if the slide is currently animating, kick out of the function 7684 7685 7686 var $firstSlide = this.$slides.first(), 7687 $lastSlide = this.$slides.last(), 7688 dirIn = isLTR ? 'Right' : 'Left', 7689 dirOut = isLTR ? 'Left' : 'Right', 7690 _this = this, 7691 $newSlide; 7692 7693 if (!chosenSlide) { 7694 //most of the time, this will be auto played or clicked from the navButtons. 7695 $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!! 7696 this.options.infiniteWrap ? $curSlide.next(".".concat(this.options.slideClass)).length ? $curSlide.next(".".concat(this.options.slideClass)) : $firstSlide : $curSlide.next(".".concat(this.options.slideClass)) : //pick next slide if moving left to right 7697 this.options.infiniteWrap ? $curSlide.prev(".".concat(this.options.slideClass)).length ? $curSlide.prev(".".concat(this.options.slideClass)) : $lastSlide : $curSlide.prev(".".concat(this.options.slideClass)); //pick prev slide if moving right to left 7698 } else { 7699 $newSlide = chosenSlide; 7700 } 7701 7702 if ($newSlide.length) { 7703 /** 7704 * Triggers before the next slide starts animating in and only if a next slide has been found. 7705 * @event Orbit#beforeslidechange 7706 */ 7707 this.$element.trigger('beforeslidechange.zf.orbit', [$curSlide, $newSlide]); 7708 7709 if (this.options.bullets) { 7710 idx = idx || this.$slides.index($newSlide); //grab index to update bullets 7711 7712 this._updateBullets(idx); 7713 } 7714 7715 if (this.options.useMUI && !this.$element.is(':hidden')) { 7716 Motion.animateIn($newSlide.addClass('is-active'), this.options["animInFrom".concat(dirIn)], function () { 7717 $newSlide.css({ 7718 'display': 'block' 7719 }).attr('aria-live', 'polite'); 7720 }); 7721 Motion.animateOut($curSlide.removeClass('is-active'), this.options["animOutTo".concat(dirOut)], function () { 7722 $curSlide.removeAttr('aria-live'); 7723 7724 if (_this.options.autoPlay && !_this.timer.isPaused) { 7725 _this.timer.restart(); 7726 } //do stuff? 7727 7728 }); 7729 } else { 7730 $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide(); 7731 $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show(); 7732 7733 if (this.options.autoPlay && !this.timer.isPaused) { 7734 this.timer.restart(); 7735 } 7736 } 7737 /** 7738 * Triggers when the slide has finished animating in. 7739 * @event Orbit#slidechange 7740 */ 7741 7742 7743 this.$element.trigger('slidechange.zf.orbit', [$newSlide]); 7744 } 7745 } 7746 /** 7747 * Updates the active state of the bullets, if displayed. 7748 * @function 7749 * @private 7750 * @param {Number} idx - the index of the current slide. 7751 */ 7752 7753 }, { 7754 key: "_updateBullets", 7755 value: function _updateBullets(idx) { 7756 var $oldBullet = this.$element.find(".".concat(this.options.boxOfBullets)).find('.is-active').removeClass('is-active').blur(), 7757 span = $oldBullet.find('span:last').detach(), 7758 $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span); 7759 } 7760 /** 7761 * Destroys the carousel and hides the element. 7762 * @function 7763 */ 7764 7765 }, { 7766 key: "_destroy", 7767 value: function _destroy() { 7768 this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide(); 7769 } 7770 }]); 7771 7772 return Orbit; 7773}(Plugin); 7774 7775Orbit.defaults = { 7776 /** 7777 * Tells the JS to look for and loadBullets. 7778 * @option 7779 * @type {boolean} 7780 * @default true 7781 */ 7782 bullets: true, 7783 7784 /** 7785 * Tells the JS to apply event listeners to nav buttons 7786 * @option 7787 * @type {boolean} 7788 * @default true 7789 */ 7790 navButtons: true, 7791 7792 /** 7793 * motion-ui animation class to apply 7794 * @option 7795 * @type {string} 7796 * @default 'slide-in-right' 7797 */ 7798 animInFromRight: 'slide-in-right', 7799 7800 /** 7801 * motion-ui animation class to apply 7802 * @option 7803 * @type {string} 7804 * @default 'slide-out-right' 7805 */ 7806 animOutToRight: 'slide-out-right', 7807 7808 /** 7809 * motion-ui animation class to apply 7810 * @option 7811 * @type {string} 7812 * @default 'slide-in-left' 7813 * 7814 */ 7815 animInFromLeft: 'slide-in-left', 7816 7817 /** 7818 * motion-ui animation class to apply 7819 * @option 7820 * @type {string} 7821 * @default 'slide-out-left' 7822 */ 7823 animOutToLeft: 'slide-out-left', 7824 7825 /** 7826 * Allows Orbit to automatically animate on page load. 7827 * @option 7828 * @type {boolean} 7829 * @default true 7830 */ 7831 autoPlay: true, 7832 7833 /** 7834 * Amount of time, in ms, between slide transitions 7835 * @option 7836 * @type {number} 7837 * @default 5000 7838 */ 7839 timerDelay: 5000, 7840 7841 /** 7842 * Allows Orbit to infinitely loop through the slides 7843 * @option 7844 * @type {boolean} 7845 * @default true 7846 */ 7847 infiniteWrap: true, 7848 7849 /** 7850 * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library 7851 * @option 7852 * @type {boolean} 7853 * @default true 7854 */ 7855 swipe: true, 7856 7857 /** 7858 * Allows the timing function to pause animation on hover. 7859 * @option 7860 * @type {boolean} 7861 * @default true 7862 */ 7863 pauseOnHover: true, 7864 7865 /** 7866 * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys 7867 * @option 7868 * @type {boolean} 7869 * @default true 7870 */ 7871 accessible: true, 7872 7873 /** 7874 * Class applied to the container of Orbit 7875 * @option 7876 * @type {string} 7877 * @default 'orbit-container' 7878 */ 7879 containerClass: 'orbit-container', 7880 7881 /** 7882 * Class applied to individual slides. 7883 * @option 7884 * @type {string} 7885 * @default 'orbit-slide' 7886 */ 7887 slideClass: 'orbit-slide', 7888 7889 /** 7890 * Class applied to the bullet container. You're welcome. 7891 * @option 7892 * @type {string} 7893 * @default 'orbit-bullets' 7894 */ 7895 boxOfBullets: 'orbit-bullets', 7896 7897 /** 7898 * Class applied to the `next` navigation button. 7899 * @option 7900 * @type {string} 7901 * @default 'orbit-next' 7902 */ 7903 nextClass: 'orbit-next', 7904 7905 /** 7906 * Class applied to the `previous` navigation button. 7907 * @option 7908 * @type {string} 7909 * @default 'orbit-previous' 7910 */ 7911 prevClass: 'orbit-previous', 7912 7913 /** 7914 * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatibility. 7915 * @option 7916 * @type {boolean} 7917 * @default true 7918 */ 7919 useMUI: true 7920}; 7921var MenuPlugins = { 7922 dropdown: { 7923 cssClass: 'dropdown', 7924 plugin: DropdownMenu 7925 }, 7926 drilldown: { 7927 cssClass: 'drilldown', 7928 plugin: Drilldown 7929 }, 7930 accordion: { 7931 cssClass: 'accordion-menu', 7932 plugin: AccordionMenu 7933 } 7934}; // import "foundation.util.triggers.js"; 7935 7936/** 7937 * ResponsiveMenu module. 7938 * @module foundation.responsiveMenu 7939 * @requires foundation.util.triggers 7940 * @requires foundation.util.mediaQuery 7941 */ 7942 7943var ResponsiveMenu = 7944/*#__PURE__*/ 7945function (_Plugin) { 7946 _inherits(ResponsiveMenu, _Plugin); 7947 7948 function ResponsiveMenu() { 7949 _classCallCheck(this, ResponsiveMenu); 7950 7951 return _possibleConstructorReturn(this, _getPrototypeOf(ResponsiveMenu).apply(this, arguments)); 7952 } 7953 7954 _createClass(ResponsiveMenu, [{ 7955 key: "_setup", 7956 7957 /** 7958 * Creates a new instance of a responsive menu. 7959 * @class 7960 * @name ResponsiveMenu 7961 * @fires ResponsiveMenu#init 7962 * @param {jQuery} element - jQuery object to make into a dropdown menu. 7963 * @param {Object} options - Overrides to the default plugin settings. 7964 */ 7965 value: function _setup(element, options) { 7966 this.$element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(element); 7967 this.rules = this.$element.data('responsive-menu'); 7968 this.currentMq = null; 7969 this.currentPlugin = null; 7970 this.className = 'ResponsiveMenu'; // ie9 back compat 7971 7972 this._init(); 7973 7974 this._events(); 7975 } 7976 /** 7977 * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element. 7978 * @function 7979 * @private 7980 */ 7981 7982 }, { 7983 key: "_init", 7984 value: function _init() { 7985 MediaQuery._init(); // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules 7986 7987 7988 if (typeof this.rules === 'string') { 7989 var rulesTree = {}; // Parse rules from "classes" pulled from data attribute 7990 7991 var rules = this.rules.split(' '); // Iterate through every rule found 7992 7993 for (var i = 0; i < rules.length; i++) { 7994 var rule = rules[i].split('-'); 7995 var ruleSize = rule.length > 1 ? rule[0] : 'small'; 7996 var rulePlugin = rule.length > 1 ? rule[1] : rule[0]; 7997 7998 if (MenuPlugins[rulePlugin] !== null) { 7999 rulesTree[ruleSize] = MenuPlugins[rulePlugin]; 8000 } 8001 } 8002 8003 this.rules = rulesTree; 8004 } 8005 8006 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default.a.isEmptyObject(this.rules)) { 8007 this._checkMediaQueries(); 8008 } // Add data-mutate since children may need it. 8009 8010 8011 this.$element.attr('data-mutate', this.$element.attr('data-mutate') || GetYoDigits(6, 'responsive-menu')); 8012 } 8013 /** 8014 * Initializes events for the Menu. 8015 * @function 8016 * @private 8017 */ 8018 8019 }, { 8020 key: "_events", 8021 value: function _events() { 8022 var _this = this; 8023 8024 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', function () { 8025 _this._checkMediaQueries(); 8026 }); // $(window).on('resize.zf.ResponsiveMenu', function() { 8027 // _this._checkMediaQueries(); 8028 // }); 8029 } 8030 /** 8031 * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out. 8032 * @function 8033 * @private 8034 */ 8035 8036 }, { 8037 key: "_checkMediaQueries", 8038 value: function _checkMediaQueries() { 8039 var matchedMq, 8040 _this = this; // Iterate through each rule and find the last matching rule 8041 8042 8043 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.each(this.rules, function (key) { 8044 if (MediaQuery.atLeast(key)) { 8045 matchedMq = key; 8046 } 8047 }); // No match? No dice 8048 8049 if (!matchedMq) return; // Plugin already initialized? We good 8050 8051 if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return; // Remove existing plugin-specific CSS classes 8052 8053 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.each(MenuPlugins, function (key, value) { 8054 _this.$element.removeClass(value.cssClass); 8055 }); // Add the CSS class for the new plugin 8056 8057 this.$element.addClass(this.rules[matchedMq].cssClass); // Create an instance of the new plugin 8058 8059 if (this.currentPlugin) this.currentPlugin.destroy(); 8060 this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {}); 8061 } 8062 /** 8063 * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out. 8064 * @function 8065 */ 8066 8067 }, { 8068 key: "_destroy", 8069 value: function _destroy() { 8070 this.currentPlugin.destroy(); 8071 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('.zf.ResponsiveMenu'); 8072 } 8073 }]); 8074 8075 return ResponsiveMenu; 8076}(Plugin); 8077 8078ResponsiveMenu.defaults = {}; 8079/** 8080 * ResponsiveToggle module. 8081 * @module foundation.responsiveToggle 8082 * @requires foundation.util.mediaQuery 8083 * @requires foundation.util.motion 8084 */ 8085 8086var ResponsiveToggle = 8087/*#__PURE__*/ 8088function (_Plugin) { 8089 _inherits(ResponsiveToggle, _Plugin); 8090 8091 function ResponsiveToggle() { 8092 _classCallCheck(this, ResponsiveToggle); 8093 8094 return _possibleConstructorReturn(this, _getPrototypeOf(ResponsiveToggle).apply(this, arguments)); 8095 } 8096 8097 _createClass(ResponsiveToggle, [{ 8098 key: "_setup", 8099 8100 /** 8101 * Creates a new instance of Tab Bar. 8102 * @class 8103 * @name ResponsiveToggle 8104 * @fires ResponsiveToggle#init 8105 * @param {jQuery} element - jQuery object to attach tab bar functionality to. 8106 * @param {Object} options - Overrides to the default plugin settings. 8107 */ 8108 value: function _setup(element, options) { 8109 this.$element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(element); 8110 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, ResponsiveToggle.defaults, this.$element.data(), options); 8111 this.className = 'ResponsiveToggle'; // ie9 back compat 8112 8113 this._init(); 8114 8115 this._events(); 8116 } 8117 /** 8118 * Initializes the tab bar by finding the target element, toggling element, and running update(). 8119 * @function 8120 * @private 8121 */ 8122 8123 }, { 8124 key: "_init", 8125 value: function _init() { 8126 MediaQuery._init(); 8127 8128 var targetID = this.$element.data('responsive-toggle'); 8129 8130 if (!targetID) { 8131 console.error('Your tab bar needs an ID of a Menu as the value of data-tab-bar.'); 8132 } 8133 8134 this.$targetMenu = jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(targetID)); 8135 this.$toggler = this.$element.find('[data-toggle]').filter(function () { 8136 var target = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).data('toggle'); 8137 return target === targetID || target === ""; 8138 }); 8139 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, this.options, this.$targetMenu.data()); // If they were set, parse the animation classes 8140 8141 if (this.options.animate) { 8142 var input = this.options.animate.split(' '); 8143 this.animationIn = input[0]; 8144 this.animationOut = input[1] || null; 8145 } 8146 8147 this._update(); 8148 } 8149 /** 8150 * Adds necessary event handlers for the tab bar to work. 8151 * @function 8152 * @private 8153 */ 8154 8155 }, { 8156 key: "_events", 8157 value: function _events() { 8158 this._updateMqHandler = this._update.bind(this); 8159 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', this._updateMqHandler); 8160 this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this)); 8161 } 8162 /** 8163 * Checks the current media query to determine if the tab bar should be visible or hidden. 8164 * @function 8165 * @private 8166 */ 8167 8168 }, { 8169 key: "_update", 8170 value: function _update() { 8171 // Mobile 8172 if (!MediaQuery.atLeast(this.options.hideFor)) { 8173 this.$element.show(); 8174 this.$targetMenu.hide(); 8175 } // Desktop 8176 else { 8177 this.$element.hide(); 8178 this.$targetMenu.show(); 8179 } 8180 } 8181 /** 8182 * Toggles the element attached to the tab bar. The toggle only happens if the screen is small enough to allow it. 8183 * @function 8184 * @fires ResponsiveToggle#toggled 8185 */ 8186 8187 }, { 8188 key: "toggleMenu", 8189 value: function toggleMenu() { 8190 var _this2 = this; 8191 8192 if (!MediaQuery.atLeast(this.options.hideFor)) { 8193 /** 8194 * Fires when the element attached to the tab bar toggles. 8195 * @event ResponsiveToggle#toggled 8196 */ 8197 if (this.options.animate) { 8198 if (this.$targetMenu.is(':hidden')) { 8199 Motion.animateIn(this.$targetMenu, this.animationIn, function () { 8200 _this2.$element.trigger('toggled.zf.responsiveToggle'); 8201 8202 _this2.$targetMenu.find('[data-mutate]').triggerHandler('mutateme.zf.trigger'); 8203 }); 8204 } else { 8205 Motion.animateOut(this.$targetMenu, this.animationOut, function () { 8206 _this2.$element.trigger('toggled.zf.responsiveToggle'); 8207 }); 8208 } 8209 } else { 8210 this.$targetMenu.toggle(0); 8211 this.$targetMenu.find('[data-mutate]').trigger('mutateme.zf.trigger'); 8212 this.$element.trigger('toggled.zf.responsiveToggle'); 8213 } 8214 } 8215 } 8216 }, { 8217 key: "_destroy", 8218 value: function _destroy() { 8219 this.$element.off('.zf.responsiveToggle'); 8220 this.$toggler.off('.zf.responsiveToggle'); 8221 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('changed.zf.mediaquery', this._updateMqHandler); 8222 } 8223 }]); 8224 8225 return ResponsiveToggle; 8226}(Plugin); 8227 8228ResponsiveToggle.defaults = { 8229 /** 8230 * The breakpoint after which the menu is always shown, and the tab bar is hidden. 8231 * @option 8232 * @type {string} 8233 * @default 'medium' 8234 */ 8235 hideFor: 'medium', 8236 8237 /** 8238 * To decide if the toggle should be animated or not. 8239 * @option 8240 * @type {boolean} 8241 * @default false 8242 */ 8243 animate: false 8244}; 8245/** 8246 * Reveal module. 8247 * @module foundation.reveal 8248 * @requires foundation.util.keyboard 8249 * @requires foundation.util.triggers 8250 * @requires foundation.util.mediaQuery 8251 * @requires foundation.util.motion if using animations 8252 */ 8253 8254var Reveal = 8255/*#__PURE__*/ 8256function (_Plugin) { 8257 _inherits(Reveal, _Plugin); 8258 8259 function Reveal() { 8260 _classCallCheck(this, Reveal); 8261 8262 return _possibleConstructorReturn(this, _getPrototypeOf(Reveal).apply(this, arguments)); 8263 } 8264 8265 _createClass(Reveal, [{ 8266 key: "_setup", 8267 8268 /** 8269 * Creates a new instance of Reveal. 8270 * @class 8271 * @name Reveal 8272 * @param {jQuery} element - jQuery object to use for the modal. 8273 * @param {Object} options - optional parameters. 8274 */ 8275 value: function _setup(element, options) { 8276 this.$element = element; 8277 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Reveal.defaults, this.$element.data(), options); 8278 this.className = 'Reveal'; // ie9 back compat 8279 8280 this._init(); // Triggers init is idempotent, just need to make sure it is initialized 8281 8282 8283 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 8284 Keyboard.register('Reveal', { 8285 'ESCAPE': 'close' 8286 }); 8287 } 8288 /** 8289 * Initializes the modal by adding the overlay and close buttons, (if selected). 8290 * @private 8291 */ 8292 8293 }, { 8294 key: "_init", 8295 value: function _init() { 8296 var _this2 = this; 8297 8298 MediaQuery._init(); 8299 8300 this.id = this.$element.attr('id'); 8301 this.isActive = false; 8302 this.cached = { 8303 mq: MediaQuery.current 8304 }; 8305 this.$anchor = jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-open=\"".concat(this.id, "\"]")).length ? jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-open=\"".concat(this.id, "\"]")) : jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-toggle=\"".concat(this.id, "\"]")); 8306 this.$anchor.attr({ 8307 'aria-controls': this.id, 8308 'aria-haspopup': true, 8309 'tabindex': 0 8310 }); 8311 8312 if (this.options.fullScreen || this.$element.hasClass('full')) { 8313 this.options.fullScreen = true; 8314 this.options.overlay = false; 8315 } 8316 8317 if (this.options.overlay && !this.$overlay) { 8318 this.$overlay = this._makeOverlay(this.id); 8319 } 8320 8321 this.$element.attr({ 8322 'role': 'dialog', 8323 'aria-hidden': true, 8324 'data-yeti-box': this.id, 8325 'data-resize': this.id 8326 }); 8327 8328 if (this.$overlay) { 8329 this.$element.detach().appendTo(this.$overlay); 8330 } else { 8331 this.$element.detach().appendTo(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.options.appendTo)); 8332 this.$element.addClass('without-overlay'); 8333 } 8334 8335 this._events(); 8336 8337 if (this.options.deepLink && window.location.hash === "#".concat(this.id)) { 8338 this.onLoadListener = onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 8339 return _this2.open(); 8340 }); 8341 } 8342 } 8343 /** 8344 * Creates an overlay div to display behind the modal. 8345 * @private 8346 */ 8347 8348 }, { 8349 key: "_makeOverlay", 8350 value: function _makeOverlay() { 8351 var additionalOverlayClasses = ''; 8352 8353 if (this.options.additionalOverlayClasses) { 8354 additionalOverlayClasses = ' ' + this.options.additionalOverlayClasses; 8355 } 8356 8357 return jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div></div>').addClass('reveal-overlay' + additionalOverlayClasses).appendTo(this.options.appendTo); 8358 } 8359 /** 8360 * Updates position of modal 8361 * TODO: Figure out if we actually need to cache these values or if it doesn't matter 8362 * @private 8363 */ 8364 8365 }, { 8366 key: "_updatePosition", 8367 value: function _updatePosition() { 8368 var width = this.$element.outerWidth(); 8369 var outerWidth = jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).width(); 8370 var height = this.$element.outerHeight(); 8371 var outerHeight = jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).height(); 8372 var left, 8373 top = null; 8374 8375 if (this.options.hOffset === 'auto') { 8376 left = parseInt((outerWidth - width) / 2, 10); 8377 } else { 8378 left = parseInt(this.options.hOffset, 10); 8379 } 8380 8381 if (this.options.vOffset === 'auto') { 8382 if (height > outerHeight) { 8383 top = parseInt(Math.min(100, outerHeight / 10), 10); 8384 } else { 8385 top = parseInt((outerHeight - height) / 4, 10); 8386 } 8387 } else if (this.options.vOffset !== null) { 8388 top = parseInt(this.options.vOffset, 10); 8389 } 8390 8391 if (top !== null) { 8392 this.$element.css({ 8393 top: top + 'px' 8394 }); 8395 } // only worry about left if we don't have an overlay or we have a horizontal offset, 8396 // otherwise we're perfectly in the middle 8397 8398 8399 if (!this.$overlay || this.options.hOffset !== 'auto') { 8400 this.$element.css({ 8401 left: left + 'px' 8402 }); 8403 this.$element.css({ 8404 margin: '0px' 8405 }); 8406 } 8407 } 8408 /** 8409 * Adds event handlers for the modal. 8410 * @private 8411 */ 8412 8413 }, { 8414 key: "_events", 8415 value: function _events() { 8416 var _this3 = this; 8417 8418 var _this = this; 8419 8420 this.$element.on({ 8421 'open.zf.trigger': this.open.bind(this), 8422 'close.zf.trigger': function closeZfTrigger(event, $element) { 8423 if (event.target === _this.$element[0] || jquery__WEBPACK_IMPORTED_MODULE_0___default()(event.target).parents('[data-closable]')[0] === $element) { 8424 // only close reveal when it's explicitly called 8425 return _this3.close.apply(_this3); 8426 } 8427 }, 8428 'toggle.zf.trigger': this.toggle.bind(this), 8429 'resizeme.zf.trigger': function resizemeZfTrigger() { 8430 _this._updatePosition(); 8431 } 8432 }); 8433 8434 if (this.options.closeOnClick && this.options.overlay) { 8435 this.$overlay.off('.zf.reveal').on('click.zf.reveal', function (e) { 8436 if (e.target === _this.$element[0] || jquery__WEBPACK_IMPORTED_MODULE_0___default.a.contains(_this.$element[0], e.target) || !jquery__WEBPACK_IMPORTED_MODULE_0___default.a.contains(document, e.target)) { 8437 return; 8438 } 8439 8440 _this.close(); 8441 }); 8442 } 8443 8444 if (this.options.deepLink) { 8445 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on("hashchange.zf.reveal:".concat(this.id), this._handleState.bind(this)); 8446 } 8447 } 8448 /** 8449 * Handles modal methods on back/forward button clicks or any other event that triggers hashchange. 8450 * @private 8451 */ 8452 8453 }, { 8454 key: "_handleState", 8455 value: function _handleState(e) { 8456 if (window.location.hash === '#' + this.id && !this.isActive) { 8457 this.open(); 8458 } else { 8459 this.close(); 8460 } 8461 } 8462 /** 8463 * Disables the scroll when Reveal is shown to prevent the background from shifting 8464 * @param {number} scrollTop - Scroll to visually apply, window current scroll by default 8465 */ 8466 8467 }, { 8468 key: "_disableScroll", 8469 value: function _disableScroll(scrollTop) { 8470 scrollTop = scrollTop || jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollTop(); 8471 8472 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).height() > jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).height()) { 8473 jquery__WEBPACK_IMPORTED_MODULE_0___default()("html").css("top", -scrollTop); 8474 } 8475 } 8476 /** 8477 * Reenables the scroll when Reveal closes 8478 * @param {number} scrollTop - Scroll to restore, html "top" property by default (as set by `_disableScroll`) 8479 */ 8480 8481 }, { 8482 key: "_enableScroll", 8483 value: function _enableScroll(scrollTop) { 8484 scrollTop = scrollTop || parseInt(jquery__WEBPACK_IMPORTED_MODULE_0___default()("html").css("top")); 8485 8486 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).height() > jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).height()) { 8487 jquery__WEBPACK_IMPORTED_MODULE_0___default()("html").css("top", ""); 8488 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollTop(-scrollTop); 8489 } 8490 } 8491 /** 8492 * Opens the modal controlled by `this.$anchor`, and closes all others by default. 8493 * @function 8494 * @fires Reveal#closeme 8495 * @fires Reveal#open 8496 */ 8497 8498 }, { 8499 key: "open", 8500 value: function open() { 8501 var _this4 = this; // either update or replace browser history 8502 8503 8504 var hash = "#".concat(this.id); 8505 8506 if (this.options.deepLink && window.location.hash !== hash) { 8507 if (window.history.pushState) { 8508 if (this.options.updateHistory) { 8509 window.history.pushState({}, '', hash); 8510 } else { 8511 window.history.replaceState({}, '', hash); 8512 } 8513 } else { 8514 window.location.hash = hash; 8515 } 8516 } // Remember anchor that opened it to set focus back later, have general anchors as fallback 8517 8518 8519 this.$activeAnchor = jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.activeElement).is(this.$anchor) ? jquery__WEBPACK_IMPORTED_MODULE_0___default()(document.activeElement) : this.$anchor; 8520 this.isActive = true; // Make elements invisible, but remove display: none so we can get size and positioning 8521 8522 this.$element.css({ 8523 'visibility': 'hidden' 8524 }).show().scrollTop(0); 8525 8526 if (this.options.overlay) { 8527 this.$overlay.css({ 8528 'visibility': 'hidden' 8529 }).show(); 8530 } 8531 8532 this._updatePosition(); 8533 8534 this.$element.hide().css({ 8535 'visibility': '' 8536 }); 8537 8538 if (this.$overlay) { 8539 this.$overlay.css({ 8540 'visibility': '' 8541 }).hide(); 8542 8543 if (this.$element.hasClass('fast')) { 8544 this.$overlay.addClass('fast'); 8545 } else if (this.$element.hasClass('slow')) { 8546 this.$overlay.addClass('slow'); 8547 } 8548 } 8549 8550 if (!this.options.multipleOpened) { 8551 /** 8552 * Fires immediately before the modal opens. 8553 * Closes any other modals that are currently open 8554 * @event Reveal#closeme 8555 */ 8556 this.$element.trigger('closeme.zf.reveal', this.id); 8557 } 8558 8559 this._disableScroll(); 8560 8561 var _this = this; // Motion UI method of reveal 8562 8563 8564 if (this.options.animationIn) { 8565 var afterAnimation = function afterAnimation() { 8566 _this.$element.attr({ 8567 'aria-hidden': false, 8568 'tabindex': -1 8569 }).focus(); 8570 8571 _this._addGlobalClasses(); 8572 8573 Keyboard.trapFocus(_this.$element); 8574 }; 8575 8576 if (this.options.overlay) { 8577 Motion.animateIn(this.$overlay, 'fade-in'); 8578 } 8579 8580 Motion.animateIn(this.$element, this.options.animationIn, function () { 8581 if (_this4.$element) { 8582 // protect against object having been removed 8583 _this4.focusableElements = Keyboard.findFocusable(_this4.$element); 8584 afterAnimation(); 8585 } 8586 }); 8587 } // jQuery method of reveal 8588 else { 8589 if (this.options.overlay) { 8590 this.$overlay.show(0); 8591 } 8592 8593 this.$element.show(this.options.showDelay); 8594 } // handle accessibility 8595 8596 8597 this.$element.attr({ 8598 'aria-hidden': false, 8599 'tabindex': -1 8600 }).focus(); 8601 Keyboard.trapFocus(this.$element); 8602 8603 this._addGlobalClasses(); 8604 8605 this._addGlobalListeners(); 8606 /** 8607 * Fires when the modal has successfully opened. 8608 * @event Reveal#open 8609 */ 8610 8611 8612 this.$element.trigger('open.zf.reveal'); 8613 } 8614 /** 8615 * Adds classes and listeners on document required by open modals. 8616 * 8617 * The following classes are added and updated: 8618 * - `.is-reveal-open` - Prevents the scroll on document 8619 * - `.zf-has-scroll` - Displays a disabled scrollbar on document if required like if the 8620 * scroll was not disabled. This prevent a "shift" of the page content due 8621 * the scrollbar disappearing when the modal opens. 8622 * 8623 * @private 8624 */ 8625 8626 }, { 8627 key: "_addGlobalClasses", 8628 value: function _addGlobalClasses() { 8629 var updateScrollbarClass = function updateScrollbarClass() { 8630 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').toggleClass('zf-has-scroll', !!(jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).height() > jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).height())); 8631 }; 8632 8633 this.$element.on('resizeme.zf.trigger.revealScrollbarListener', function () { 8634 return updateScrollbarClass(); 8635 }); 8636 updateScrollbarClass(); 8637 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').addClass('is-reveal-open'); 8638 } 8639 /** 8640 * Removes classes and listeners on document that were required by open modals. 8641 * @private 8642 */ 8643 8644 }, { 8645 key: "_removeGlobalClasses", 8646 value: function _removeGlobalClasses() { 8647 this.$element.off('resizeme.zf.trigger.revealScrollbarListener'); 8648 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').removeClass('is-reveal-open'); 8649 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html').removeClass('zf-has-scroll'); 8650 } 8651 /** 8652 * Adds extra event handlers for the body and window if necessary. 8653 * @private 8654 */ 8655 8656 }, { 8657 key: "_addGlobalListeners", 8658 value: function _addGlobalListeners() { 8659 var _this = this; 8660 8661 if (!this.$element) { 8662 return; 8663 } // If we're in the middle of cleanup, don't freak out 8664 8665 8666 this.focusableElements = Keyboard.findFocusable(this.$element); 8667 8668 if (!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen) { 8669 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').on('click.zf.reveal', function (e) { 8670 if (e.target === _this.$element[0] || jquery__WEBPACK_IMPORTED_MODULE_0___default.a.contains(_this.$element[0], e.target) || !jquery__WEBPACK_IMPORTED_MODULE_0___default.a.contains(document, e.target)) { 8671 return; 8672 } 8673 8674 _this.close(); 8675 }); 8676 } 8677 8678 if (this.options.closeOnEsc) { 8679 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('keydown.zf.reveal', function (e) { 8680 Keyboard.handleKey(e, 'Reveal', { 8681 close: function close() { 8682 if (_this.options.closeOnEsc) { 8683 _this.close(); 8684 } 8685 } 8686 }); 8687 }); 8688 } 8689 } 8690 /** 8691 * Closes the modal. 8692 * @function 8693 * @fires Reveal#closed 8694 */ 8695 8696 }, { 8697 key: "close", 8698 value: function close() { 8699 if (!this.isActive || !this.$element.is(':visible')) { 8700 return false; 8701 } 8702 8703 var _this = this; // Motion UI method of hiding 8704 8705 8706 if (this.options.animationOut) { 8707 if (this.options.overlay) { 8708 Motion.animateOut(this.$overlay, 'fade-out'); 8709 } 8710 8711 Motion.animateOut(this.$element, this.options.animationOut, finishUp); 8712 } // jQuery method of hiding 8713 else { 8714 this.$element.hide(this.options.hideDelay); 8715 8716 if (this.options.overlay) { 8717 this.$overlay.hide(0, finishUp); 8718 } else { 8719 finishUp(); 8720 } 8721 } // Conditionals to remove extra event listeners added on open 8722 8723 8724 if (this.options.closeOnEsc) { 8725 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('keydown.zf.reveal'); 8726 } 8727 8728 if (!this.options.overlay && this.options.closeOnClick) { 8729 jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').off('click.zf.reveal'); 8730 } 8731 8732 this.$element.off('keydown.zf.reveal'); 8733 8734 function finishUp() { 8735 // Get the current top before the modal is closed and restore the scroll after. 8736 // TODO: use component properties instead of HTML properties 8737 // See https://github.com/zurb/foundation-sites/pull/10786 8738 var scrollTop = parseInt(jquery__WEBPACK_IMPORTED_MODULE_0___default()("html").css("top")); 8739 8740 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()('.reveal:visible').length === 0) { 8741 _this._removeGlobalClasses(); // also remove .is-reveal-open from the html element when there is no opened reveal 8742 8743 } 8744 8745 Keyboard.releaseFocus(_this.$element); 8746 8747 _this.$element.attr('aria-hidden', true); 8748 8749 _this._enableScroll(scrollTop); 8750 /** 8751 * Fires when the modal is done closing. 8752 * @event Reveal#closed 8753 */ 8754 8755 8756 _this.$element.trigger('closed.zf.reveal'); 8757 } 8758 /** 8759 * Resets the modal content 8760 * This prevents a running video to keep going in the background 8761 */ 8762 8763 8764 if (this.options.resetOnClose) { 8765 this.$element.html(this.$element.html()); 8766 } 8767 8768 this.isActive = false; // If deepLink and we did not switched to an other modal... 8769 8770 if (_this.options.deepLink && window.location.hash === "#".concat(this.id)) { 8771 // Remove the history hash 8772 if (window.history.replaceState) { 8773 var urlWithoutHash = window.location.pathname + window.location.search; 8774 8775 if (this.options.updateHistory) { 8776 window.history.pushState({}, '', urlWithoutHash); // remove the hash 8777 } else { 8778 window.history.replaceState('', document.title, urlWithoutHash); 8779 } 8780 } else { 8781 window.location.hash = ''; 8782 } 8783 } 8784 8785 this.$activeAnchor.focus(); 8786 } 8787 /** 8788 * Toggles the open/closed state of a modal. 8789 * @function 8790 */ 8791 8792 }, { 8793 key: "toggle", 8794 value: function toggle() { 8795 if (this.isActive) { 8796 this.close(); 8797 } else { 8798 this.open(); 8799 } 8800 } 8801 }, { 8802 key: "_destroy", 8803 8804 /** 8805 * Destroys an instance of a modal. 8806 * @function 8807 */ 8808 value: function _destroy() { 8809 if (this.options.overlay) { 8810 this.$element.appendTo(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.options.appendTo)); // move $element outside of $overlay to prevent error unregisterPlugin() 8811 8812 this.$overlay.hide().off().remove(); 8813 } 8814 8815 this.$element.hide().off(); 8816 this.$anchor.off('.zf'); 8817 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(".zf.reveal:".concat(this.id)); 8818 if (this.onLoadListener) jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.onLoadListener); 8819 8820 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()('.reveal:visible').length === 0) { 8821 this._removeGlobalClasses(); // also remove .is-reveal-open from the html element when there is no opened reveal 8822 8823 } 8824 } 8825 }]); 8826 8827 return Reveal; 8828}(Plugin); 8829 8830Reveal.defaults = { 8831 /** 8832 * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide. 8833 * @option 8834 * @type {string} 8835 * @default '' 8836 */ 8837 animationIn: '', 8838 8839 /** 8840 * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide. 8841 * @option 8842 * @type {string} 8843 * @default '' 8844 */ 8845 animationOut: '', 8846 8847 /** 8848 * Time, in ms, to delay the opening of a modal after a click if no animation used. 8849 * @option 8850 * @type {number} 8851 * @default 0 8852 */ 8853 showDelay: 0, 8854 8855 /** 8856 * Time, in ms, to delay the closing of a modal after a click if no animation used. 8857 * @option 8858 * @type {number} 8859 * @default 0 8860 */ 8861 hideDelay: 0, 8862 8863 /** 8864 * Allows a click on the body/overlay to close the modal. 8865 * @option 8866 * @type {boolean} 8867 * @default true 8868 */ 8869 closeOnClick: true, 8870 8871 /** 8872 * Allows the modal to close if the user presses the `ESCAPE` key. 8873 * @option 8874 * @type {boolean} 8875 * @default true 8876 */ 8877 closeOnEsc: true, 8878 8879 /** 8880 * If true, allows multiple modals to be displayed at once. 8881 * @option 8882 * @type {boolean} 8883 * @default false 8884 */ 8885 multipleOpened: false, 8886 8887 /** 8888 * Distance, in pixels, the modal should push down from the top of the screen. 8889 * @option 8890 * @type {number|string} 8891 * @default auto 8892 */ 8893 vOffset: 'auto', 8894 8895 /** 8896 * Distance, in pixels, the modal should push in from the side of the screen. 8897 * @option 8898 * @type {number|string} 8899 * @default auto 8900 */ 8901 hOffset: 'auto', 8902 8903 /** 8904 * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well. 8905 * @option 8906 * @type {boolean} 8907 * @default false 8908 */ 8909 fullScreen: false, 8910 8911 /** 8912 * Allows the modal to generate an overlay div, which will cover the view when modal opens. 8913 * @option 8914 * @type {boolean} 8915 * @default true 8916 */ 8917 overlay: true, 8918 8919 /** 8920 * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api, otherwise, videos will continue to play in the background. 8921 * @option 8922 * @type {boolean} 8923 * @default false 8924 */ 8925 resetOnClose: false, 8926 8927 /** 8928 * Link the location hash to the modal. 8929 * Set the location hash when the modal is opened/closed, and open/close the modal when the location changes. 8930 * @option 8931 * @type {boolean} 8932 * @default false 8933 */ 8934 deepLink: false, 8935 8936 /** 8937 * If `deepLink` is enabled, update the browser history with the open modal 8938 * @option 8939 * @default false 8940 */ 8941 updateHistory: false, 8942 8943 /** 8944 * Allows the modal to append to custom div. 8945 * @option 8946 * @type {string} 8947 * @default "body" 8948 */ 8949 appendTo: "body", 8950 8951 /** 8952 * Allows adding additional class names to the reveal overlay. 8953 * @option 8954 * @type {string} 8955 * @default '' 8956 */ 8957 additionalOverlayClasses: '' 8958}; 8959/** 8960 * Slider module. 8961 * @module foundation.slider 8962 * @requires foundation.util.motion 8963 * @requires foundation.util.triggers 8964 * @requires foundation.util.keyboard 8965 * @requires foundation.util.touch 8966 */ 8967 8968var Slider = 8969/*#__PURE__*/ 8970function (_Plugin) { 8971 _inherits(Slider, _Plugin); 8972 8973 function Slider() { 8974 _classCallCheck(this, Slider); 8975 8976 return _possibleConstructorReturn(this, _getPrototypeOf(Slider).apply(this, arguments)); 8977 } 8978 8979 _createClass(Slider, [{ 8980 key: "_setup", 8981 8982 /** 8983 * Creates a new instance of a slider control. 8984 * @class 8985 * @name Slider 8986 * @param {jQuery} element - jQuery object to make into a slider control. 8987 * @param {Object} options - Overrides to the default plugin settings. 8988 */ 8989 value: function _setup(element, options) { 8990 this.$element = element; 8991 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Slider.defaults, this.$element.data(), options); 8992 this.className = 'Slider'; // ie9 back compat 8993 // Touch and Triggers inits are idempotent, we just need to make sure it's initialied. 8994 8995 Touch.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 8996 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 8997 8998 this._init(); 8999 9000 Keyboard.register('Slider', { 9001 'ltr': { 9002 'ARROW_RIGHT': 'increase', 9003 'ARROW_UP': 'increase', 9004 'ARROW_DOWN': 'decrease', 9005 'ARROW_LEFT': 'decrease', 9006 'SHIFT_ARROW_RIGHT': 'increase_fast', 9007 'SHIFT_ARROW_UP': 'increase_fast', 9008 'SHIFT_ARROW_DOWN': 'decrease_fast', 9009 'SHIFT_ARROW_LEFT': 'decrease_fast', 9010 'HOME': 'min', 9011 'END': 'max' 9012 }, 9013 'rtl': { 9014 'ARROW_LEFT': 'increase', 9015 'ARROW_RIGHT': 'decrease', 9016 'SHIFT_ARROW_LEFT': 'increase_fast', 9017 'SHIFT_ARROW_RIGHT': 'decrease_fast' 9018 } 9019 }); 9020 } 9021 /** 9022 * Initilizes the plugin by reading/setting attributes, creating collections and setting the initial position of the handle(s). 9023 * @function 9024 * @private 9025 */ 9026 9027 }, { 9028 key: "_init", 9029 value: function _init() { 9030 this.inputs = this.$element.find('input'); 9031 this.handles = this.$element.find('[data-slider-handle]'); 9032 this.$handle = this.handles.eq(0); 9033 this.$input = this.inputs.length ? this.inputs.eq(0) : jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(this.$handle.attr('aria-controls'))); 9034 this.$fill = this.$element.find('[data-slider-fill]').css(this.options.vertical ? 'height' : 'width', 0); 9035 9036 if (this.options.disabled || this.$element.hasClass(this.options.disabledClass)) { 9037 this.options.disabled = true; 9038 this.$element.addClass(this.options.disabledClass); 9039 } 9040 9041 if (!this.inputs.length) { 9042 this.inputs = jquery__WEBPACK_IMPORTED_MODULE_0___default()().add(this.$input); 9043 this.options.binding = true; 9044 } 9045 9046 this._setInitAttr(0); 9047 9048 if (this.handles[1]) { 9049 this.options.doubleSided = true; 9050 this.$handle2 = this.handles.eq(1); 9051 this.$input2 = this.inputs.length > 1 ? this.inputs.eq(1) : jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(this.$handle2.attr('aria-controls'))); 9052 9053 if (!this.inputs[1]) { 9054 this.inputs = this.inputs.add(this.$input2); 9055 } 9056 9057 this._setInitAttr(1); 9058 } // Set handle positions 9059 9060 9061 this.setHandles(); 9062 9063 this._events(); 9064 } 9065 }, { 9066 key: "setHandles", 9067 value: function setHandles() { 9068 var _this2 = this; 9069 9070 if (this.handles[1]) { 9071 this._setHandlePos(this.$handle, this.inputs.eq(0).val(), true, function () { 9072 _this2._setHandlePos(_this2.$handle2, _this2.inputs.eq(1).val(), true); 9073 }); 9074 } else { 9075 this._setHandlePos(this.$handle, this.inputs.eq(0).val(), true); 9076 } 9077 } 9078 }, { 9079 key: "_reflow", 9080 value: function _reflow() { 9081 this.setHandles(); 9082 } 9083 /** 9084 * @function 9085 * @private 9086 * @param {Number} value - floating point (the value) to be transformed using to a relative position on the slider (the inverse of _value) 9087 */ 9088 9089 }, { 9090 key: "_pctOfBar", 9091 value: function _pctOfBar(value) { 9092 var pctOfBar = percent(value - this.options.start, this.options.end - this.options.start); 9093 9094 switch (this.options.positionValueFunction) { 9095 case "pow": 9096 pctOfBar = this._logTransform(pctOfBar); 9097 break; 9098 9099 case "log": 9100 pctOfBar = this._powTransform(pctOfBar); 9101 break; 9102 } 9103 9104 return pctOfBar.toFixed(2); 9105 } 9106 /** 9107 * @function 9108 * @private 9109 * @param {Number} pctOfBar - floating point, the relative position of the slider (typically between 0-1) to be transformed to a value 9110 */ 9111 9112 }, { 9113 key: "_value", 9114 value: function _value(pctOfBar) { 9115 switch (this.options.positionValueFunction) { 9116 case "pow": 9117 pctOfBar = this._powTransform(pctOfBar); 9118 break; 9119 9120 case "log": 9121 pctOfBar = this._logTransform(pctOfBar); 9122 break; 9123 } 9124 9125 var value = (this.options.end - this.options.start) * pctOfBar + parseFloat(this.options.start); 9126 return value; 9127 } 9128 /** 9129 * @function 9130 * @private 9131 * @param {Number} value - floating point (typically between 0-1) to be transformed using the log function 9132 */ 9133 9134 }, { 9135 key: "_logTransform", 9136 value: function _logTransform(value) { 9137 return baseLog(this.options.nonLinearBase, value * (this.options.nonLinearBase - 1) + 1); 9138 } 9139 /** 9140 * @function 9141 * @private 9142 * @param {Number} value - floating point (typically between 0-1) to be transformed using the power function 9143 */ 9144 9145 }, { 9146 key: "_powTransform", 9147 value: function _powTransform(value) { 9148 return (Math.pow(this.options.nonLinearBase, value) - 1) / (this.options.nonLinearBase - 1); 9149 } 9150 /** 9151 * Sets the position of the selected handle and fill bar. 9152 * @function 9153 * @private 9154 * @param {jQuery} $hndl - the selected handle to move. 9155 * @param {Number} location - floating point between the start and end values of the slider bar. 9156 * @param {Function} cb - callback function to fire on completion. 9157 * @fires Slider#moved 9158 * @fires Slider#changed 9159 */ 9160 9161 }, { 9162 key: "_setHandlePos", 9163 value: function _setHandlePos($hndl, location, noInvert, cb) { 9164 // don't move if the slider has been disabled since its initialization 9165 if (this.$element.hasClass(this.options.disabledClass)) { 9166 return; 9167 } //might need to alter that slightly for bars that will have odd number selections. 9168 9169 9170 location = parseFloat(location); //on input change events, convert string to number...grumble. 9171 // prevent slider from running out of bounds, if value exceeds the limits set through options, override the value to min/max 9172 9173 if (location < this.options.start) { 9174 location = this.options.start; 9175 } else if (location > this.options.end) { 9176 location = this.options.end; 9177 } 9178 9179 var isDbl = this.options.doubleSided; //this is for single-handled vertical sliders, it adjusts the value to account for the slider being "upside-down" 9180 //for click and drag events, it's weird due to the scale(-1, 1) css property 9181 9182 if (this.options.vertical && !noInvert) { 9183 location = this.options.end - location; 9184 } 9185 9186 if (isDbl) { 9187 //this block is to prevent 2 handles from crossing eachother. Could/should be improved. 9188 if (this.handles.index($hndl) === 0) { 9189 var h2Val = parseFloat(this.$handle2.attr('aria-valuenow')); 9190 location = location >= h2Val ? h2Val - this.options.step : location; 9191 } else { 9192 var h1Val = parseFloat(this.$handle.attr('aria-valuenow')); 9193 location = location <= h1Val ? h1Val + this.options.step : location; 9194 } 9195 } 9196 9197 var _this = this, 9198 vert = this.options.vertical, 9199 hOrW = vert ? 'height' : 'width', 9200 lOrT = vert ? 'top' : 'left', 9201 handleDim = $hndl[0].getBoundingClientRect()[hOrW], 9202 elemDim = this.$element[0].getBoundingClientRect()[hOrW], 9203 //percentage of bar min/max value based on click or drag point 9204 pctOfBar = this._pctOfBar(location), 9205 //number of actual pixels to shift the handle, based on the percentage obtained above 9206 pxToMove = (elemDim - handleDim) * pctOfBar, 9207 //percentage of bar to shift the handle 9208 movement = (percent(pxToMove, elemDim) * 100).toFixed(this.options.decimal); //fixing the decimal value for the location number, is passed to other methods as a fixed floating-point value 9209 9210 9211 location = parseFloat(location.toFixed(this.options.decimal)); // declare empty object for css adjustments, only used with 2 handled-sliders 9212 9213 var css = {}; 9214 9215 this._setValues($hndl, location); // TODO update to calculate based on values set to respective inputs?? 9216 9217 9218 if (isDbl) { 9219 var isLeftHndl = this.handles.index($hndl) === 0, 9220 //empty variable, will be used for min-height/width for fill bar 9221 dim, 9222 //percentage w/h of the handle compared to the slider bar 9223 handlePct = ~~(percent(handleDim, elemDim) * 100); //if left handle, the math is slightly different than if it's the right handle, and the left/top property needs to be changed for the fill bar 9224 9225 if (isLeftHndl) { 9226 //left or top percentage value to apply to the fill bar. 9227 css[lOrT] = "".concat(movement, "%"); //calculate the new min-height/width for the fill bar. 9228 9229 dim = parseFloat(this.$handle2[0].style[lOrT]) - movement + handlePct; //this callback is necessary to prevent errors and allow the proper placement and initialization of a 2-handled slider 9230 //plus, it means we don't care if 'dim' isNaN on init, it won't be in the future. 9231 9232 if (cb && typeof cb === 'function') { 9233 cb(); 9234 } //this is only needed for the initialization of 2 handled sliders 9235 9236 } else { 9237 //just caching the value of the left/bottom handle's left/top property 9238 var handlePos = parseFloat(this.$handle[0].style[lOrT]); //calculate the new min-height/width for the fill bar. Use isNaN to prevent false positives for numbers <= 0 9239 //based on the percentage of movement of the handle being manipulated, less the opposing handle's left/top position, plus the percentage w/h of the handle itself 9240 9241 dim = movement - (isNaN(handlePos) ? (this.options.initialStart - this.options.start) / ((this.options.end - this.options.start) / 100) : handlePos) + handlePct; 9242 } // assign the min-height/width to our css object 9243 9244 9245 css["min-".concat(hOrW)] = "".concat(dim, "%"); 9246 } 9247 9248 this.$element.one('finished.zf.animate', function () { 9249 /** 9250 * Fires when the handle is done moving. 9251 * @event Slider#moved 9252 */ 9253 _this.$element.trigger('moved.zf.slider', [$hndl]); 9254 }); //because we don't know exactly how the handle will be moved, check the amount of time it should take to move. 9255 9256 var moveTime = this.$element.data('dragging') ? 1000 / 60 : this.options.moveTime; 9257 Move(moveTime, $hndl, function () { 9258 // adjusting the left/top property of the handle, based on the percentage calculated above 9259 // if movement isNaN, that is because the slider is hidden and we cannot determine handle width, 9260 // fall back to next best guess. 9261 if (isNaN(movement)) { 9262 $hndl.css(lOrT, "".concat(pctOfBar * 100, "%")); 9263 } else { 9264 $hndl.css(lOrT, "".concat(movement, "%")); 9265 } 9266 9267 if (!_this.options.doubleSided) { 9268 //if single-handled, a simple method to expand the fill bar 9269 _this.$fill.css(hOrW, "".concat(pctOfBar * 100, "%")); 9270 } else { 9271 //otherwise, use the css object we created above 9272 _this.$fill.css(css); 9273 } 9274 }); 9275 /** 9276 * Fires when the value has not been change for a given time. 9277 * @event Slider#changed 9278 */ 9279 9280 clearTimeout(_this.timeout); 9281 _this.timeout = setTimeout(function () { 9282 _this.$element.trigger('changed.zf.slider', [$hndl]); 9283 }, _this.options.changedDelay); 9284 } 9285 /** 9286 * Sets the initial attribute for the slider element. 9287 * @function 9288 * @private 9289 * @param {Number} idx - index of the current handle/input to use. 9290 */ 9291 9292 }, { 9293 key: "_setInitAttr", 9294 value: function _setInitAttr(idx) { 9295 var initVal = idx === 0 ? this.options.initialStart : this.options.initialEnd; 9296 var id = this.inputs.eq(idx).attr('id') || GetYoDigits(6, 'slider'); 9297 this.inputs.eq(idx).attr({ 9298 'id': id, 9299 'max': this.options.end, 9300 'min': this.options.start, 9301 'step': this.options.step 9302 }); 9303 this.inputs.eq(idx).val(initVal); 9304 this.handles.eq(idx).attr({ 9305 'role': 'slider', 9306 'aria-controls': id, 9307 'aria-valuemax': this.options.end, 9308 'aria-valuemin': this.options.start, 9309 'aria-valuenow': initVal, 9310 'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal', 9311 'tabindex': 0 9312 }); 9313 } 9314 /** 9315 * Sets the input and `aria-valuenow` values for the slider element. 9316 * @function 9317 * @private 9318 * @param {jQuery} $handle - the currently selected handle. 9319 * @param {Number} val - floating point of the new value. 9320 */ 9321 9322 }, { 9323 key: "_setValues", 9324 value: function _setValues($handle, val) { 9325 var idx = this.options.doubleSided ? this.handles.index($handle) : 0; 9326 this.inputs.eq(idx).val(val); 9327 $handle.attr('aria-valuenow', val); 9328 } 9329 /** 9330 * Handles events on the slider element. 9331 * Calculates the new location of the current handle. 9332 * If there are two handles and the bar was clicked, it determines which handle to move. 9333 * @function 9334 * @private 9335 * @param {Object} e - the `event` object passed from the listener. 9336 * @param {jQuery} $handle - the current handle to calculate for, if selected. 9337 * @param {Number} val - floating point number for the new value of the slider. 9338 * TODO clean this up, there's a lot of repeated code between this and the _setHandlePos fn. 9339 */ 9340 9341 }, { 9342 key: "_handleEvent", 9343 value: function _handleEvent(e, $handle, val) { 9344 var value, hasVal; 9345 9346 if (!val) { 9347 //click or drag events 9348 e.preventDefault(); 9349 9350 var _this = this, 9351 vertical = this.options.vertical, 9352 param = vertical ? 'height' : 'width', 9353 direction = vertical ? 'top' : 'left', 9354 eventOffset = vertical ? e.pageY : e.pageX, 9355 halfOfHandle = this.$handle[0].getBoundingClientRect()[param] / 2, 9356 barDim = this.$element[0].getBoundingClientRect()[param], 9357 windowScroll = vertical ? jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollTop() : jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollLeft(); 9358 9359 var elemOffset = this.$element.offset()[direction]; // touch events emulated by the touch util give position relative to screen, add window.scroll to event coordinates... 9360 // best way to guess this is simulated is if clientY == pageY 9361 9362 if (e.clientY === e.pageY) { 9363 eventOffset = eventOffset + windowScroll; 9364 } 9365 9366 var eventFromBar = eventOffset - elemOffset; 9367 var barXY; 9368 9369 if (eventFromBar < 0) { 9370 barXY = 0; 9371 } else if (eventFromBar > barDim) { 9372 barXY = barDim; 9373 } else { 9374 barXY = eventFromBar; 9375 } 9376 9377 var offsetPct = percent(barXY, barDim); 9378 value = this._value(offsetPct); // turn everything around for RTL, yay math! 9379 9380 if (rtl() && !this.options.vertical) { 9381 value = this.options.end - value; 9382 } 9383 9384 value = _this._adjustValue(null, value); //boolean flag for the setHandlePos fn, specifically for vertical sliders 9385 9386 hasVal = false; 9387 9388 if (!$handle) { 9389 //figure out which handle it is, pass it to the next function. 9390 var firstHndlPos = absPosition(this.$handle, direction, barXY, param), 9391 secndHndlPos = absPosition(this.$handle2, direction, barXY, param); 9392 $handle = firstHndlPos <= secndHndlPos ? this.$handle : this.$handle2; 9393 } 9394 } else { 9395 //change event on input 9396 value = this._adjustValue(null, val); 9397 hasVal = true; 9398 } 9399 9400 this._setHandlePos($handle, value, hasVal); 9401 } 9402 /** 9403 * Adjustes value for handle in regard to step value. returns adjusted value 9404 * @function 9405 * @private 9406 * @param {jQuery} $handle - the selected handle. 9407 * @param {Number} value - value to adjust. used if $handle is falsy 9408 */ 9409 9410 }, { 9411 key: "_adjustValue", 9412 value: function _adjustValue($handle, value) { 9413 var val, 9414 step = this.options.step, 9415 div = parseFloat(step / 2), 9416 left, 9417 prev_val, 9418 next_val; 9419 9420 if (!!$handle) { 9421 val = parseFloat($handle.attr('aria-valuenow')); 9422 } else { 9423 val = value; 9424 } 9425 9426 if (val >= 0) { 9427 left = val % step; 9428 } else { 9429 left = step + val % step; 9430 } 9431 9432 prev_val = val - left; 9433 next_val = prev_val + step; 9434 9435 if (left === 0) { 9436 return val; 9437 } 9438 9439 val = val >= prev_val + div ? next_val : prev_val; 9440 return val; 9441 } 9442 /** 9443 * Adds event listeners to the slider elements. 9444 * @function 9445 * @private 9446 */ 9447 9448 }, { 9449 key: "_events", 9450 value: function _events() { 9451 this._eventsForHandle(this.$handle); 9452 9453 if (this.handles[1]) { 9454 this._eventsForHandle(this.$handle2); 9455 } 9456 } 9457 /** 9458 * Adds event listeners a particular handle 9459 * @function 9460 * @private 9461 * @param {jQuery} $handle - the current handle to apply listeners to. 9462 */ 9463 9464 }, { 9465 key: "_eventsForHandle", 9466 value: function _eventsForHandle($handle) { 9467 var _this = this, 9468 curHandle; 9469 9470 var handleChangeEvent = function handleChangeEvent(e) { 9471 var idx = _this.inputs.index(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 9472 9473 _this._handleEvent(e, _this.handles.eq(idx), jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).val()); 9474 }; // IE only triggers the change event when the input loses focus which strictly follows the HTML specification 9475 // listen for the enter key and trigger a change 9476 // @see https://html.spec.whatwg.org/multipage/input.html#common-input-element-events 9477 9478 9479 this.inputs.off('keyup.zf.slider').on('keyup.zf.slider', function (e) { 9480 if (e.keyCode == 13) handleChangeEvent.call(this, e); 9481 }); 9482 this.inputs.off('change.zf.slider').on('change.zf.slider', handleChangeEvent); 9483 9484 if (this.options.clickSelect) { 9485 this.$element.off('click.zf.slider').on('click.zf.slider', function (e) { 9486 if (_this.$element.data('dragging')) { 9487 return false; 9488 } 9489 9490 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).is('[data-slider-handle]')) { 9491 if (_this.options.doubleSided) { 9492 _this._handleEvent(e); 9493 } else { 9494 _this._handleEvent(e, _this.$handle); 9495 } 9496 } 9497 }); 9498 } 9499 9500 if (this.options.draggable) { 9501 this.handles.addTouch(); 9502 var $body = jquery__WEBPACK_IMPORTED_MODULE_0___default()('body'); 9503 $handle.off('mousedown.zf.slider').on('mousedown.zf.slider', function (e) { 9504 $handle.addClass('is-dragging'); 9505 9506 _this.$fill.addClass('is-dragging'); // 9507 9508 9509 _this.$element.data('dragging', true); 9510 9511 curHandle = jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.currentTarget); 9512 $body.on('mousemove.zf.slider', function (e) { 9513 e.preventDefault(); 9514 9515 _this._handleEvent(e, curHandle); 9516 }).on('mouseup.zf.slider', function (e) { 9517 _this._handleEvent(e, curHandle); 9518 9519 $handle.removeClass('is-dragging'); 9520 9521 _this.$fill.removeClass('is-dragging'); 9522 9523 _this.$element.data('dragging', false); 9524 9525 $body.off('mousemove.zf.slider mouseup.zf.slider'); 9526 }); 9527 }) // prevent events triggered by touch 9528 .on('selectstart.zf.slider touchmove.zf.slider', function (e) { 9529 e.preventDefault(); 9530 }); 9531 } 9532 9533 $handle.off('keydown.zf.slider').on('keydown.zf.slider', function (e) { 9534 var _$handle = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 9535 idx = _this.options.doubleSided ? _this.handles.index(_$handle) : 0, 9536 oldValue = parseFloat(_this.inputs.eq(idx).val()), 9537 newValue; // handle keyboard event with keyboard util 9538 9539 9540 Keyboard.handleKey(e, 'Slider', { 9541 decrease: function decrease() { 9542 newValue = oldValue - _this.options.step; 9543 }, 9544 increase: function increase() { 9545 newValue = oldValue + _this.options.step; 9546 }, 9547 decrease_fast: function decrease_fast() { 9548 newValue = oldValue - _this.options.step * 10; 9549 }, 9550 increase_fast: function increase_fast() { 9551 newValue = oldValue + _this.options.step * 10; 9552 }, 9553 min: function min() { 9554 newValue = _this.options.start; 9555 }, 9556 max: function max() { 9557 newValue = _this.options.end; 9558 }, 9559 handled: function handled() { 9560 // only set handle pos when event was handled specially 9561 e.preventDefault(); 9562 9563 _this._setHandlePos(_$handle, newValue, true); 9564 } 9565 }); 9566 /*if (newValue) { // if pressed key has special function, update value 9567 e.preventDefault(); 9568 _this._setHandlePos(_$handle, newValue); 9569 }*/ 9570 }); 9571 } 9572 /** 9573 * Destroys the slider plugin. 9574 */ 9575 9576 }, { 9577 key: "_destroy", 9578 value: function _destroy() { 9579 this.handles.off('.zf.slider'); 9580 this.inputs.off('.zf.slider'); 9581 this.$element.off('.zf.slider'); 9582 clearTimeout(this.timeout); 9583 } 9584 }]); 9585 9586 return Slider; 9587}(Plugin); 9588 9589Slider.defaults = { 9590 /** 9591 * Minimum value for the slider scale. 9592 * @option 9593 * @type {number} 9594 * @default 0 9595 */ 9596 start: 0, 9597 9598 /** 9599 * Maximum value for the slider scale. 9600 * @option 9601 * @type {number} 9602 * @default 100 9603 */ 9604 end: 100, 9605 9606 /** 9607 * Minimum value change per change event. 9608 * @option 9609 * @type {number} 9610 * @default 1 9611 */ 9612 step: 1, 9613 9614 /** 9615 * Value at which the handle/input *(left handle/first input)* should be set to on initialization. 9616 * @option 9617 * @type {number} 9618 * @default 0 9619 */ 9620 initialStart: 0, 9621 9622 /** 9623 * Value at which the right handle/second input should be set to on initialization. 9624 * @option 9625 * @type {number} 9626 * @default 100 9627 */ 9628 initialEnd: 100, 9629 9630 /** 9631 * Allows the input to be located outside the container and visible. Set to by the JS 9632 * @option 9633 * @type {boolean} 9634 * @default false 9635 */ 9636 binding: false, 9637 9638 /** 9639 * Allows the user to click/tap on the slider bar to select a value. 9640 * @option 9641 * @type {boolean} 9642 * @default true 9643 */ 9644 clickSelect: true, 9645 9646 /** 9647 * Set to true and use the `vertical` class to change alignment to vertical. 9648 * @option 9649 * @type {boolean} 9650 * @default false 9651 */ 9652 vertical: false, 9653 9654 /** 9655 * Allows the user to drag the slider handle(s) to select a value. 9656 * @option 9657 * @type {boolean} 9658 * @default true 9659 */ 9660 draggable: true, 9661 9662 /** 9663 * Disables the slider and prevents event listeners from being applied. Double checked by JS with `disabledClass`. 9664 * @option 9665 * @type {boolean} 9666 * @default false 9667 */ 9668 disabled: false, 9669 9670 /** 9671 * Allows the use of two handles. Double checked by the JS. Changes some logic handling. 9672 * @option 9673 * @type {boolean} 9674 * @default false 9675 */ 9676 doubleSided: false, 9677 9678 /** 9679 * Potential future feature. 9680 */ 9681 // steps: 100, 9682 9683 /** 9684 * Number of decimal places the plugin should go to for floating point precision. 9685 * @option 9686 * @type {number} 9687 * @default 2 9688 */ 9689 decimal: 2, 9690 9691 /** 9692 * Time delay for dragged elements. 9693 */ 9694 // dragDelay: 0, 9695 9696 /** 9697 * Time, in ms, to animate the movement of a slider handle if user clicks/taps on the bar. Needs to be manually set if updating the transition time in the Sass settings. 9698 * @option 9699 * @type {number} 9700 * @default 200 9701 */ 9702 moveTime: 200, 9703 //update this if changing the transition time in the sass 9704 9705 /** 9706 * Class applied to disabled sliders. 9707 * @option 9708 * @type {string} 9709 * @default 'disabled' 9710 */ 9711 disabledClass: 'disabled', 9712 9713 /** 9714 * Will invert the default layout for a vertical<span data-tooltip title="who would do this???"> </span>slider. 9715 * @option 9716 * @type {boolean} 9717 * @default false 9718 */ 9719 invertVertical: false, 9720 9721 /** 9722 * Milliseconds before the `changed.zf-slider` event is triggered after value change. 9723 * @option 9724 * @type {number} 9725 * @default 500 9726 */ 9727 changedDelay: 500, 9728 9729 /** 9730 * Basevalue for non-linear sliders 9731 * @option 9732 * @type {number} 9733 * @default 5 9734 */ 9735 nonLinearBase: 5, 9736 9737 /** 9738 * Basevalue for non-linear sliders, possible values are: `'linear'`, `'pow'` & `'log'`. Pow and Log use the nonLinearBase setting. 9739 * @option 9740 * @type {string} 9741 * @default 'linear' 9742 */ 9743 positionValueFunction: 'linear' 9744}; 9745 9746function percent(frac, num) { 9747 return frac / num; 9748} 9749 9750function absPosition($handle, dir, clickPos, param) { 9751 return Math.abs($handle.position()[dir] + $handle[param]() / 2 - clickPos); 9752} 9753 9754function baseLog(base, value) { 9755 return Math.log(value) / Math.log(base); 9756} 9757/** 9758 * Sticky module. 9759 * @module foundation.sticky 9760 * @requires foundation.util.triggers 9761 * @requires foundation.util.mediaQuery 9762 */ 9763 9764 9765var Sticky = 9766/*#__PURE__*/ 9767function (_Plugin) { 9768 _inherits(Sticky, _Plugin); 9769 9770 function Sticky() { 9771 _classCallCheck(this, Sticky); 9772 9773 return _possibleConstructorReturn(this, _getPrototypeOf(Sticky).apply(this, arguments)); 9774 } 9775 9776 _createClass(Sticky, [{ 9777 key: "_setup", 9778 9779 /** 9780 * Creates a new instance of a sticky thing. 9781 * @class 9782 * @name Sticky 9783 * @param {jQuery} element - jQuery object to make sticky. 9784 * @param {Object} options - options object passed when creating the element programmatically. 9785 */ 9786 value: function _setup(element, options) { 9787 this.$element = element; 9788 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Sticky.defaults, this.$element.data(), options); 9789 this.className = 'Sticky'; // ie9 back compat 9790 // Triggers init is idempotent, just need to make sure it is initialized 9791 9792 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 9793 9794 this._init(); 9795 } 9796 /** 9797 * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes 9798 * @function 9799 * @private 9800 */ 9801 9802 }, { 9803 key: "_init", 9804 value: function _init() { 9805 MediaQuery._init(); 9806 9807 var $parent = this.$element.parent('[data-sticky-container]'), 9808 id = this.$element[0].id || GetYoDigits(6, 'sticky'), 9809 _this = this; 9810 9811 if ($parent.length) { 9812 this.$container = $parent; 9813 } else { 9814 this.wasWrapped = true; 9815 this.$element.wrap(this.options.container); 9816 this.$container = this.$element.parent(); 9817 } 9818 9819 this.$container.addClass(this.options.containerClass); 9820 this.$element.addClass(this.options.stickyClass).attr({ 9821 'data-resize': id, 9822 'data-mutate': id 9823 }); 9824 9825 if (this.options.anchor !== '') { 9826 jquery__WEBPACK_IMPORTED_MODULE_0___default()('#' + _this.options.anchor).attr({ 9827 'data-mutate': id 9828 }); 9829 } 9830 9831 this.scrollCount = this.options.checkEvery; 9832 this.isStuck = false; 9833 this.onLoadListener = onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 9834 //We calculate the container height to have correct values for anchor points offset calculation. 9835 _this.containerHeight = _this.$element.css("display") == "none" ? 0 : _this.$element[0].getBoundingClientRect().height; 9836 9837 _this.$container.css('height', _this.containerHeight); 9838 9839 _this.elemHeight = _this.containerHeight; 9840 9841 if (_this.options.anchor !== '') { 9842 _this.$anchor = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#' + _this.options.anchor); 9843 } else { 9844 _this._parsePoints(); 9845 } 9846 9847 _this._setSizes(function () { 9848 var scroll = window.pageYOffset; 9849 9850 _this._calc(false, scroll); //Unstick the element will ensure that proper classes are set. 9851 9852 9853 if (!_this.isStuck) { 9854 _this._removeSticky(scroll >= _this.topPoint ? false : true); 9855 } 9856 }); 9857 9858 _this._events(id.split('-').reverse().join('-')); 9859 }); 9860 } 9861 /** 9862 * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on. 9863 * @function 9864 * @private 9865 */ 9866 9867 }, { 9868 key: "_parsePoints", 9869 value: function _parsePoints() { 9870 var top = this.options.topAnchor == "" ? 1 : this.options.topAnchor, 9871 btm = this.options.btmAnchor == "" ? document.documentElement.scrollHeight : this.options.btmAnchor, 9872 pts = [top, btm], 9873 breaks = {}; 9874 9875 for (var i = 0, len = pts.length; i < len && pts[i]; i++) { 9876 var pt; 9877 9878 if (typeof pts[i] === 'number') { 9879 pt = pts[i]; 9880 } else { 9881 var place = pts[i].split(':'), 9882 anchor = jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(place[0])); 9883 pt = anchor.offset().top; 9884 9885 if (place[1] && place[1].toLowerCase() === 'bottom') { 9886 pt += anchor[0].getBoundingClientRect().height; 9887 } 9888 } 9889 9890 breaks[i] = pt; 9891 } 9892 9893 this.points = breaks; 9894 return; 9895 } 9896 /** 9897 * Adds event handlers for the scrolling element. 9898 * @private 9899 * @param {String} id - pseudo-random id for unique scroll event listener. 9900 */ 9901 9902 }, { 9903 key: "_events", 9904 value: function _events(id) { 9905 var _this = this, 9906 scrollListener = this.scrollListener = "scroll.zf.".concat(id); 9907 9908 if (this.isOn) { 9909 return; 9910 } 9911 9912 if (this.canStick) { 9913 this.isOn = true; 9914 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(scrollListener).on(scrollListener, function (e) { 9915 if (_this.scrollCount === 0) { 9916 _this.scrollCount = _this.options.checkEvery; 9917 9918 _this._setSizes(function () { 9919 _this._calc(false, window.pageYOffset); 9920 }); 9921 } else { 9922 _this.scrollCount--; 9923 9924 _this._calc(false, window.pageYOffset); 9925 } 9926 }); 9927 } 9928 9929 this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', function (e, el) { 9930 _this._eventsHandler(id); 9931 }); 9932 this.$element.on('mutateme.zf.trigger', function (e, el) { 9933 _this._eventsHandler(id); 9934 }); 9935 9936 if (this.$anchor) { 9937 this.$anchor.on('mutateme.zf.trigger', function (e, el) { 9938 _this._eventsHandler(id); 9939 }); 9940 } 9941 } 9942 /** 9943 * Handler for events. 9944 * @private 9945 * @param {String} id - pseudo-random id for unique scroll event listener. 9946 */ 9947 9948 }, { 9949 key: "_eventsHandler", 9950 value: function _eventsHandler(id) { 9951 var _this = this, 9952 scrollListener = this.scrollListener = "scroll.zf.".concat(id); 9953 9954 _this._setSizes(function () { 9955 _this._calc(false); 9956 9957 if (_this.canStick) { 9958 if (!_this.isOn) { 9959 _this._events(id); 9960 } 9961 } else if (_this.isOn) { 9962 _this._pauseListeners(scrollListener); 9963 } 9964 }); 9965 } 9966 /** 9967 * Removes event handlers for scroll and change events on anchor. 9968 * @fires Sticky#pause 9969 * @param {String} scrollListener - unique, namespaced scroll listener attached to `window` 9970 */ 9971 9972 }, { 9973 key: "_pauseListeners", 9974 value: function _pauseListeners(scrollListener) { 9975 this.isOn = false; 9976 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(scrollListener); 9977 /** 9978 * Fires when the plugin is paused due to resize event shrinking the view. 9979 * @event Sticky#pause 9980 * @private 9981 */ 9982 9983 this.$element.trigger('pause.zf.sticky'); 9984 } 9985 /** 9986 * Called on every `scroll` event and on `_init` 9987 * fires functions based on booleans and cached values 9988 * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints. 9989 * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`. 9990 */ 9991 9992 }, { 9993 key: "_calc", 9994 value: function _calc(checkSizes, scroll) { 9995 if (checkSizes) { 9996 this._setSizes(); 9997 } 9998 9999 if (!this.canStick) { 10000 if (this.isStuck) { 10001 this._removeSticky(true); 10002 } 10003 10004 return false; 10005 } 10006 10007 if (!scroll) { 10008 scroll = window.pageYOffset; 10009 } 10010 10011 if (scroll >= this.topPoint) { 10012 if (scroll <= this.bottomPoint) { 10013 if (!this.isStuck) { 10014 this._setSticky(); 10015 } 10016 } else { 10017 if (this.isStuck) { 10018 this._removeSticky(false); 10019 } 10020 } 10021 } else { 10022 if (this.isStuck) { 10023 this._removeSticky(true); 10024 } 10025 } 10026 } 10027 /** 10028 * Causes the $element to become stuck. 10029 * Adds `position: fixed;`, and helper classes. 10030 * @fires Sticky#stuckto 10031 * @function 10032 * @private 10033 */ 10034 10035 }, { 10036 key: "_setSticky", 10037 value: function _setSticky() { 10038 var _this = this, 10039 stickTo = this.options.stickTo, 10040 mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom', 10041 notStuckTo = stickTo === 'top' ? 'bottom' : 'top', 10042 css = {}; 10043 10044 css[mrgn] = "".concat(this.options[mrgn], "em"); 10045 css[stickTo] = 0; 10046 css[notStuckTo] = 'auto'; 10047 this.isStuck = true; 10048 this.$element.removeClass("is-anchored is-at-".concat(notStuckTo)).addClass("is-stuck is-at-".concat(stickTo)).css(css) 10049 /** 10050 * Fires when the $element has become `position: fixed;` 10051 * Namespaced to `top` or `bottom`, e.g. `sticky.zf.stuckto:top` 10052 * @event Sticky#stuckto 10053 */ 10054 .trigger("sticky.zf.stuckto:".concat(stickTo)); 10055 this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () { 10056 _this._setSizes(); 10057 }); 10058 } 10059 /** 10060 * Causes the $element to become unstuck. 10061 * Removes `position: fixed;`, and helper classes. 10062 * Adds other helper classes. 10063 * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element. 10064 * @fires Sticky#unstuckfrom 10065 * @private 10066 */ 10067 10068 }, { 10069 key: "_removeSticky", 10070 value: function _removeSticky(isTop) { 10071 var stickTo = this.options.stickTo, 10072 stickToTop = stickTo === 'top', 10073 css = {}, 10074 anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight, 10075 mrgn = stickToTop ? 'marginTop' : 'marginBottom', 10076 topOrBottom = isTop ? 'top' : 'bottom'; 10077 css[mrgn] = 0; 10078 css['bottom'] = 'auto'; 10079 10080 if (isTop) { 10081 css['top'] = 0; 10082 } else { 10083 css['top'] = anchorPt; 10084 } 10085 10086 this.isStuck = false; 10087 this.$element.removeClass("is-stuck is-at-".concat(stickTo)).addClass("is-anchored is-at-".concat(topOrBottom)).css(css) 10088 /** 10089 * Fires when the $element has become anchored. 10090 * Namespaced to `top` or `bottom`, e.g. `sticky.zf.unstuckfrom:bottom` 10091 * @event Sticky#unstuckfrom 10092 */ 10093 .trigger("sticky.zf.unstuckfrom:".concat(topOrBottom)); 10094 } 10095 /** 10096 * Sets the $element and $container sizes for plugin. 10097 * Calls `_setBreakPoints`. 10098 * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`. 10099 * @private 10100 */ 10101 10102 }, { 10103 key: "_setSizes", 10104 value: function _setSizes(cb) { 10105 this.canStick = MediaQuery.is(this.options.stickyOn); 10106 10107 if (!this.canStick) { 10108 if (cb && typeof cb === 'function') { 10109 cb(); 10110 } 10111 } 10112 10113 var newElemWidth = this.$container[0].getBoundingClientRect().width, 10114 comp = window.getComputedStyle(this.$container[0]), 10115 pdngl = parseInt(comp['padding-left'], 10), 10116 pdngr = parseInt(comp['padding-right'], 10); 10117 10118 if (this.$anchor && this.$anchor.length) { 10119 this.anchorHeight = this.$anchor[0].getBoundingClientRect().height; 10120 } else { 10121 this._parsePoints(); 10122 } 10123 10124 this.$element.css({ 10125 'max-width': "".concat(newElemWidth - pdngl - pdngr, "px") 10126 }); 10127 var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight; 10128 10129 if (this.$element.css("display") == "none") { 10130 newContainerHeight = 0; 10131 } 10132 10133 this.containerHeight = newContainerHeight; 10134 this.$container.css({ 10135 height: newContainerHeight 10136 }); 10137 this.elemHeight = newContainerHeight; 10138 10139 if (!this.isStuck) { 10140 if (this.$element.hasClass('is-at-bottom')) { 10141 var anchorPt = (this.points ? this.points[1] - this.$container.offset().top : this.anchorHeight) - this.elemHeight; 10142 this.$element.css('top', anchorPt); 10143 } 10144 } 10145 10146 this._setBreakPoints(newContainerHeight, function () { 10147 if (cb && typeof cb === 'function') { 10148 cb(); 10149 } 10150 }); 10151 } 10152 /** 10153 * Sets the upper and lower breakpoints for the element to become sticky/unsticky. 10154 * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`. 10155 * @param {Function} cb - optional callback function to be called on completion. 10156 * @private 10157 */ 10158 10159 }, { 10160 key: "_setBreakPoints", 10161 value: function _setBreakPoints(elemHeight, cb) { 10162 if (!this.canStick) { 10163 if (cb && typeof cb === 'function') { 10164 cb(); 10165 } else { 10166 return false; 10167 } 10168 } 10169 10170 var mTop = emCalc(this.options.marginTop), 10171 mBtm = emCalc(this.options.marginBottom), 10172 topPoint = this.points ? this.points[0] : this.$anchor.offset().top, 10173 bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight, 10174 // topPoint = this.$anchor.offset().top || this.points[0], 10175 // bottomPoint = topPoint + this.anchorHeight || this.points[1], 10176 winHeight = window.innerHeight; 10177 10178 if (this.options.stickTo === 'top') { 10179 topPoint -= mTop; 10180 bottomPoint -= elemHeight + mTop; 10181 } else if (this.options.stickTo === 'bottom') { 10182 topPoint -= winHeight - (elemHeight + mBtm); 10183 bottomPoint -= winHeight - mBtm; 10184 } 10185 10186 this.topPoint = topPoint; 10187 this.bottomPoint = bottomPoint; 10188 10189 if (cb && typeof cb === 'function') { 10190 cb(); 10191 } 10192 } 10193 /** 10194 * Destroys the current sticky element. 10195 * Resets the element to the top position first. 10196 * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container. 10197 * @function 10198 */ 10199 10200 }, { 10201 key: "_destroy", 10202 value: function _destroy() { 10203 this._removeSticky(true); 10204 10205 this.$element.removeClass("".concat(this.options.stickyClass, " is-anchored is-at-top")).css({ 10206 height: '', 10207 top: '', 10208 bottom: '', 10209 'max-width': '' 10210 }).off('resizeme.zf.trigger').off('mutateme.zf.trigger'); 10211 10212 if (this.$anchor && this.$anchor.length) { 10213 this.$anchor.off('change.zf.sticky'); 10214 } 10215 10216 if (this.scrollListener) jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.scrollListener); 10217 if (this.onLoadListener) jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.onLoadListener); 10218 10219 if (this.wasWrapped) { 10220 this.$element.unwrap(); 10221 } else { 10222 this.$container.removeClass(this.options.containerClass).css({ 10223 height: '' 10224 }); 10225 } 10226 } 10227 }]); 10228 10229 return Sticky; 10230}(Plugin); 10231 10232Sticky.defaults = { 10233 /** 10234 * Customizable container template. Add your own classes for styling and sizing. 10235 * @option 10236 * @type {string} 10237 * @default '<div data-sticky-container></div>' 10238 */ 10239 container: '<div data-sticky-container></div>', 10240 10241 /** 10242 * Location in the view the element sticks to. Can be `'top'` or `'bottom'`. 10243 * @option 10244 * @type {string} 10245 * @default 'top' 10246 */ 10247 stickTo: 'top', 10248 10249 /** 10250 * If anchored to a single element, the id of that element. 10251 * @option 10252 * @type {string} 10253 * @default '' 10254 */ 10255 anchor: '', 10256 10257 /** 10258 * If using more than one element as anchor points, the id of the top anchor. 10259 * @option 10260 * @type {string} 10261 * @default '' 10262 */ 10263 topAnchor: '', 10264 10265 /** 10266 * If using more than one element as anchor points, the id of the bottom anchor. 10267 * @option 10268 * @type {string} 10269 * @default '' 10270 */ 10271 btmAnchor: '', 10272 10273 /** 10274 * Margin, in `em`'s to apply to the top of the element when it becomes sticky. 10275 * @option 10276 * @type {number} 10277 * @default 1 10278 */ 10279 marginTop: 1, 10280 10281 /** 10282 * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky. 10283 * @option 10284 * @type {number} 10285 * @default 1 10286 */ 10287 marginBottom: 1, 10288 10289 /** 10290 * Breakpoint string that is the minimum screen size an element should become sticky. 10291 * @option 10292 * @type {string} 10293 * @default 'medium' 10294 */ 10295 stickyOn: 'medium', 10296 10297 /** 10298 * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`. 10299 * @option 10300 * @type {string} 10301 * @default 'sticky' 10302 */ 10303 stickyClass: 'sticky', 10304 10305 /** 10306 * Class applied to sticky container. Foundation defaults to `sticky-container`. 10307 * @option 10308 * @type {string} 10309 * @default 'sticky-container' 10310 */ 10311 containerClass: 'sticky-container', 10312 10313 /** 10314 * Number of scroll events between the plugin's recalculating sticky points. Setting it to `0` will cause it to recalc every scroll event, setting it to `-1` will prevent recalc on scroll. 10315 * @option 10316 * @type {number} 10317 * @default -1 10318 */ 10319 checkEvery: -1 10320}; 10321/** 10322 * Helper function to calculate em values 10323 * @param Number {em} - number of em's to calculate into pixels 10324 */ 10325 10326function emCalc(em) { 10327 return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em; 10328} 10329/** 10330 * Tabs module. 10331 * @module foundation.tabs 10332 * @requires foundation.util.keyboard 10333 * @requires foundation.util.imageLoader if tabs contain images 10334 */ 10335 10336 10337var Tabs = 10338/*#__PURE__*/ 10339function (_Plugin) { 10340 _inherits(Tabs, _Plugin); 10341 10342 function Tabs() { 10343 _classCallCheck(this, Tabs); 10344 10345 return _possibleConstructorReturn(this, _getPrototypeOf(Tabs).apply(this, arguments)); 10346 } 10347 10348 _createClass(Tabs, [{ 10349 key: "_setup", 10350 10351 /** 10352 * Creates a new instance of tabs. 10353 * @class 10354 * @name Tabs 10355 * @fires Tabs#init 10356 * @param {jQuery} element - jQuery object to make into tabs. 10357 * @param {Object} options - Overrides to the default plugin settings. 10358 */ 10359 value: function _setup(element, options) { 10360 this.$element = element; 10361 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Tabs.defaults, this.$element.data(), options); 10362 this.className = 'Tabs'; // ie9 back compat 10363 10364 this._init(); 10365 10366 Keyboard.register('Tabs', { 10367 'ENTER': 'open', 10368 'SPACE': 'open', 10369 'ARROW_RIGHT': 'next', 10370 'ARROW_UP': 'previous', 10371 'ARROW_DOWN': 'next', 10372 'ARROW_LEFT': 'previous' // 'TAB': 'next', 10373 // 'SHIFT_TAB': 'previous' 10374 10375 }); 10376 } 10377 /** 10378 * Initializes the tabs by showing and focusing (if autoFocus=true) the preset active tab. 10379 * @private 10380 */ 10381 10382 }, { 10383 key: "_init", 10384 value: function _init() { 10385 var _this2 = this; 10386 10387 var _this = this; 10388 10389 this._isInitializing = true; 10390 this.$element.attr({ 10391 'role': 'tablist' 10392 }); 10393 this.$tabTitles = this.$element.find(".".concat(this.options.linkClass)); 10394 this.$tabContent = jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-tabs-content=\"".concat(this.$element[0].id, "\"]")); 10395 this.$tabTitles.each(function () { 10396 var $elem = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 10397 $link = $elem.find('a'), 10398 isActive = $elem.hasClass("".concat(_this.options.linkActiveClass)), 10399 hash = $link.attr('data-tabs-target') || $link[0].hash.slice(1), 10400 linkId = $link[0].id ? $link[0].id : "".concat(hash, "-label"), 10401 $tabContent = jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat(hash)); 10402 $elem.attr({ 10403 'role': 'presentation' 10404 }); 10405 $link.attr({ 10406 'role': 'tab', 10407 'aria-controls': hash, 10408 'aria-selected': isActive, 10409 'id': linkId, 10410 'tabindex': isActive ? '0' : '-1' 10411 }); 10412 $tabContent.attr({ 10413 'role': 'tabpanel', 10414 'aria-labelledby': linkId 10415 }); // Save up the initial hash to return to it later when going back in history 10416 10417 if (isActive) { 10418 _this._initialAnchor = "#".concat(hash); 10419 } 10420 10421 if (!isActive) { 10422 $tabContent.attr('aria-hidden', 'true'); 10423 } 10424 10425 if (isActive && _this.options.autoFocus) { 10426 _this.onLoadListener = onLoad(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window), function () { 10427 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').animate({ 10428 scrollTop: $elem.offset().top 10429 }, _this.options.deepLinkSmudgeDelay, function () { 10430 $link.focus(); 10431 }); 10432 }); 10433 } 10434 }); 10435 10436 if (this.options.matchHeight) { 10437 var $images = this.$tabContent.find('img'); 10438 10439 if ($images.length) { 10440 onImagesLoaded($images, this._setHeight.bind(this)); 10441 } else { 10442 this._setHeight(); 10443 } 10444 } // Current context-bound function to open tabs on page load or history hashchange 10445 10446 10447 this._checkDeepLink = function () { 10448 var anchor = window.location.hash; 10449 10450 if (!anchor.length) { 10451 // If we are still initializing and there is no anchor, then there is nothing to do 10452 if (_this2._isInitializing) return; // Otherwise, move to the initial anchor 10453 10454 if (_this2._initialAnchor) anchor = _this2._initialAnchor; 10455 } 10456 10457 var $anchor = anchor && jquery__WEBPACK_IMPORTED_MODULE_0___default()(anchor); 10458 10459 var $link = anchor && _this2.$element.find('[href$="' + anchor + '"]'); // Whether the anchor element that has been found is part of this element 10460 10461 10462 var isOwnAnchor = !!($anchor.length && $link.length); // If there is an anchor for the hash, select it 10463 10464 if ($anchor && $anchor.length && $link && $link.length) { 10465 _this2.selectTab($anchor, true); 10466 } // Otherwise, collapse everything 10467 else { 10468 _this2._collapse(); 10469 } 10470 10471 if (isOwnAnchor) { 10472 // Roll up a little to show the titles 10473 if (_this2.options.deepLinkSmudge) { 10474 var offset = _this2.$element.offset(); 10475 10476 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').animate({ 10477 scrollTop: offset.top 10478 }, _this2.options.deepLinkSmudgeDelay); 10479 } 10480 /** 10481 * Fires when the plugin has deeplinked at pageload 10482 * @event Tabs#deeplink 10483 */ 10484 10485 10486 _this2.$element.trigger('deeplink.zf.tabs', [$link, $anchor]); 10487 } 10488 }; //use browser to open a tab, if it exists in this tabset 10489 10490 10491 if (this.options.deepLink) { 10492 this._checkDeepLink(); 10493 } 10494 10495 this._events(); 10496 10497 this._isInitializing = false; 10498 } 10499 /** 10500 * Adds event handlers for items within the tabs. 10501 * @private 10502 */ 10503 10504 }, { 10505 key: "_events", 10506 value: function _events() { 10507 this._addKeyHandler(); 10508 10509 this._addClickHandler(); 10510 10511 this._setHeightMqHandler = null; 10512 10513 if (this.options.matchHeight) { 10514 this._setHeightMqHandler = this._setHeight.bind(this); 10515 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', this._setHeightMqHandler); 10516 } 10517 10518 if (this.options.deepLink) { 10519 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('hashchange', this._checkDeepLink); 10520 } 10521 } 10522 /** 10523 * Adds click handlers for items within the tabs. 10524 * @private 10525 */ 10526 10527 }, { 10528 key: "_addClickHandler", 10529 value: function _addClickHandler() { 10530 var _this = this; 10531 10532 this.$element.off('click.zf.tabs').on('click.zf.tabs', ".".concat(this.options.linkClass), function (e) { 10533 e.preventDefault(); 10534 e.stopPropagation(); 10535 10536 _this._handleTabChange(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this)); 10537 }); 10538 } 10539 /** 10540 * Adds keyboard event handlers for items within the tabs. 10541 * @private 10542 */ 10543 10544 }, { 10545 key: "_addKeyHandler", 10546 value: function _addKeyHandler() { 10547 var _this = this; 10548 10549 this.$tabTitles.off('keydown.zf.tabs').on('keydown.zf.tabs', function (e) { 10550 if (e.which === 9) return; 10551 var $element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 10552 $elements = $element.parent('ul').children('li'), 10553 $prevElement, 10554 $nextElement; 10555 $elements.each(function (i) { 10556 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).is($element)) { 10557 if (_this.options.wrapOnKeys) { 10558 $prevElement = i === 0 ? $elements.last() : $elements.eq(i - 1); 10559 $nextElement = i === $elements.length - 1 ? $elements.first() : $elements.eq(i + 1); 10560 } else { 10561 $prevElement = $elements.eq(Math.max(0, i - 1)); 10562 $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)); 10563 } 10564 10565 return; 10566 } 10567 }); // handle keyboard event with keyboard util 10568 10569 Keyboard.handleKey(e, 'Tabs', { 10570 open: function open() { 10571 $element.find('[role="tab"]').focus(); 10572 10573 _this._handleTabChange($element); 10574 }, 10575 previous: function previous() { 10576 $prevElement.find('[role="tab"]').focus(); 10577 10578 _this._handleTabChange($prevElement); 10579 }, 10580 next: function next() { 10581 $nextElement.find('[role="tab"]').focus(); 10582 10583 _this._handleTabChange($nextElement); 10584 }, 10585 handled: function handled() { 10586 e.stopPropagation(); 10587 e.preventDefault(); 10588 } 10589 }); 10590 }); 10591 } 10592 /** 10593 * Opens the tab `$targetContent` defined by `$target`. Collapses active tab. 10594 * @param {jQuery} $target - Tab to open. 10595 * @param {boolean} historyHandled - browser has already handled a history update 10596 * @fires Tabs#change 10597 * @function 10598 */ 10599 10600 }, { 10601 key: "_handleTabChange", 10602 value: function _handleTabChange($target, historyHandled) { 10603 // With `activeCollapse`, if the target is the active Tab, collapse it. 10604 if ($target.hasClass("".concat(this.options.linkActiveClass))) { 10605 if (this.options.activeCollapse) { 10606 this._collapse(); 10607 } 10608 10609 return; 10610 } 10611 10612 var $oldTab = this.$element.find(".".concat(this.options.linkClass, ".").concat(this.options.linkActiveClass)), 10613 $tabLink = $target.find('[role="tab"]'), 10614 target = $tabLink.attr('data-tabs-target'), 10615 anchor = target && target.length ? "#".concat(target) : $tabLink[0].hash, 10616 $targetContent = this.$tabContent.find(anchor); //close old tab 10617 10618 this._collapseTab($oldTab); //open new tab 10619 10620 10621 this._openTab($target); //either replace or update browser history 10622 10623 10624 if (this.options.deepLink && !historyHandled) { 10625 if (this.options.updateHistory) { 10626 history.pushState({}, '', anchor); 10627 } else { 10628 history.replaceState({}, '', anchor); 10629 } 10630 } 10631 /** 10632 * Fires when the plugin has successfully changed tabs. 10633 * @event Tabs#change 10634 */ 10635 10636 10637 this.$element.trigger('change.zf.tabs', [$target, $targetContent]); //fire to children a mutation event 10638 10639 $targetContent.find("[data-mutate]").trigger("mutateme.zf.trigger"); 10640 } 10641 /** 10642 * Opens the tab `$targetContent` defined by `$target`. 10643 * @param {jQuery} $target - Tab to open. 10644 * @function 10645 */ 10646 10647 }, { 10648 key: "_openTab", 10649 value: function _openTab($target) { 10650 var $tabLink = $target.find('[role="tab"]'), 10651 hash = $tabLink.attr('data-tabs-target') || $tabLink[0].hash.slice(1), 10652 $targetContent = this.$tabContent.find("#".concat(hash)); 10653 $target.addClass("".concat(this.options.linkActiveClass)); 10654 $tabLink.attr({ 10655 'aria-selected': 'true', 10656 'tabindex': '0' 10657 }); 10658 $targetContent.addClass("".concat(this.options.panelActiveClass)).removeAttr('aria-hidden'); 10659 } 10660 /** 10661 * Collapses `$targetContent` defined by `$target`. 10662 * @param {jQuery} $target - Tab to collapse. 10663 * @function 10664 */ 10665 10666 }, { 10667 key: "_collapseTab", 10668 value: function _collapseTab($target) { 10669 var $target_anchor = $target.removeClass("".concat(this.options.linkActiveClass)).find('[role="tab"]').attr({ 10670 'aria-selected': 'false', 10671 'tabindex': -1 10672 }); 10673 jquery__WEBPACK_IMPORTED_MODULE_0___default()("#".concat($target_anchor.attr('aria-controls'))).removeClass("".concat(this.options.panelActiveClass)).attr({ 10674 'aria-hidden': 'true' 10675 }); 10676 } 10677 /** 10678 * Collapses the active Tab. 10679 * @fires Tabs#collapse 10680 * @function 10681 */ 10682 10683 }, { 10684 key: "_collapse", 10685 value: function _collapse() { 10686 var $activeTab = this.$element.find(".".concat(this.options.linkClass, ".").concat(this.options.linkActiveClass)); 10687 10688 if ($activeTab.length) { 10689 this._collapseTab($activeTab); 10690 /** 10691 * Fires when the plugin has successfully collapsed tabs. 10692 * @event Tabs#collapse 10693 */ 10694 10695 10696 this.$element.trigger('collapse.zf.tabs', [$activeTab]); 10697 } 10698 } 10699 /** 10700 * Public method for selecting a content pane to display. 10701 * @param {jQuery | String} elem - jQuery object or string of the id of the pane to display. 10702 * @param {boolean} historyHandled - browser has already handled a history update 10703 * @function 10704 */ 10705 10706 }, { 10707 key: "selectTab", 10708 value: function selectTab(elem, historyHandled) { 10709 var idStr; 10710 10711 if (_typeof(elem) === 'object') { 10712 idStr = elem[0].id; 10713 } else { 10714 idStr = elem; 10715 } 10716 10717 if (idStr.indexOf('#') < 0) { 10718 idStr = "#".concat(idStr); 10719 } 10720 10721 var $target = this.$tabTitles.has("[href$=\"".concat(idStr, "\"]")); 10722 10723 this._handleTabChange($target, historyHandled); 10724 } 10725 }, { 10726 key: "_setHeight", 10727 10728 /** 10729 * Sets the height of each panel to the height of the tallest panel. 10730 * If enabled in options, gets called on media query change. 10731 * If loading content via external source, can be called directly or with _reflow. 10732 * If enabled with `data-match-height="true"`, tabs sets to equal height 10733 * @function 10734 * @private 10735 */ 10736 value: function _setHeight() { 10737 var max = 0, 10738 _this = this; // Lock down the `this` value for the root tabs object 10739 10740 10741 this.$tabContent.find(".".concat(this.options.panelClass)).css('height', '').each(function () { 10742 var panel = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this), 10743 isActive = panel.hasClass("".concat(_this.options.panelActiveClass)); // get the options from the parent instead of trying to get them from the child 10744 10745 if (!isActive) { 10746 panel.css({ 10747 'visibility': 'hidden', 10748 'display': 'block' 10749 }); 10750 } 10751 10752 var temp = this.getBoundingClientRect().height; 10753 10754 if (!isActive) { 10755 panel.css({ 10756 'visibility': '', 10757 'display': '' 10758 }); 10759 } 10760 10761 max = temp > max ? temp : max; 10762 }).css('height', "".concat(max, "px")); 10763 } 10764 /** 10765 * Destroys an instance of tabs. 10766 * @fires Tabs#destroyed 10767 */ 10768 10769 }, { 10770 key: "_destroy", 10771 value: function _destroy() { 10772 this.$element.find(".".concat(this.options.linkClass)).off('.zf.tabs').hide().end().find(".".concat(this.options.panelClass)).hide(); 10773 10774 if (this.options.matchHeight) { 10775 if (this._setHeightMqHandler != null) { 10776 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('changed.zf.mediaquery', this._setHeightMqHandler); 10777 } 10778 } 10779 10780 if (this.options.deepLink) { 10781 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('hashchange', this._checkDeepLink); 10782 } 10783 10784 if (this.onLoadListener) { 10785 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off(this.onLoadListener); 10786 } 10787 } 10788 }]); 10789 10790 return Tabs; 10791}(Plugin); 10792 10793Tabs.defaults = { 10794 /** 10795 * Link the location hash to the active pane. 10796 * Set the location hash when the active pane changes, and open the corresponding pane when the location changes. 10797 * @option 10798 * @type {boolean} 10799 * @default false 10800 */ 10801 deepLink: false, 10802 10803 /** 10804 * If `deepLink` is enabled, adjust the deep link scroll to make sure the top of the tab panel is visible 10805 * @option 10806 * @type {boolean} 10807 * @default false 10808 */ 10809 deepLinkSmudge: false, 10810 10811 /** 10812 * If `deepLinkSmudge` is enabled, animation time (ms) for the deep link adjustment 10813 * @option 10814 * @type {number} 10815 * @default 300 10816 */ 10817 deepLinkSmudgeDelay: 300, 10818 10819 /** 10820 * If `deepLink` is enabled, update the browser history with the open tab 10821 * @option 10822 * @type {boolean} 10823 * @default false 10824 */ 10825 updateHistory: false, 10826 10827 /** 10828 * Allows the window to scroll to content of active pane on load. 10829 * Not recommended if more than one tab panel per page. 10830 * @option 10831 * @type {boolean} 10832 * @default false 10833 */ 10834 autoFocus: false, 10835 10836 /** 10837 * Allows keyboard input to 'wrap' around the tab links. 10838 * @option 10839 * @type {boolean} 10840 * @default true 10841 */ 10842 wrapOnKeys: true, 10843 10844 /** 10845 * Allows the tab content panes to match heights if set to true. 10846 * @option 10847 * @type {boolean} 10848 * @default false 10849 */ 10850 matchHeight: false, 10851 10852 /** 10853 * Allows active tabs to collapse when clicked. 10854 * @option 10855 * @type {boolean} 10856 * @default false 10857 */ 10858 activeCollapse: false, 10859 10860 /** 10861 * Class applied to `li`'s in tab link list. 10862 * @option 10863 * @type {string} 10864 * @default 'tabs-title' 10865 */ 10866 linkClass: 'tabs-title', 10867 10868 /** 10869 * Class applied to the active `li` in tab link list. 10870 * @option 10871 * @type {string} 10872 * @default 'is-active' 10873 */ 10874 linkActiveClass: 'is-active', 10875 10876 /** 10877 * Class applied to the content containers. 10878 * @option 10879 * @type {string} 10880 * @default 'tabs-panel' 10881 */ 10882 panelClass: 'tabs-panel', 10883 10884 /** 10885 * Class applied to the active content container. 10886 * @option 10887 * @type {string} 10888 * @default 'is-active' 10889 */ 10890 panelActiveClass: 'is-active' 10891}; 10892/** 10893 * Toggler module. 10894 * @module foundation.toggler 10895 * @requires foundation.util.motion 10896 * @requires foundation.util.triggers 10897 */ 10898 10899var Toggler = 10900/*#__PURE__*/ 10901function (_Plugin) { 10902 _inherits(Toggler, _Plugin); 10903 10904 function Toggler() { 10905 _classCallCheck(this, Toggler); 10906 10907 return _possibleConstructorReturn(this, _getPrototypeOf(Toggler).apply(this, arguments)); 10908 } 10909 10910 _createClass(Toggler, [{ 10911 key: "_setup", 10912 10913 /** 10914 * Creates a new instance of Toggler. 10915 * @class 10916 * @name Toggler 10917 * @fires Toggler#init 10918 * @param {Object} element - jQuery object to add the trigger to. 10919 * @param {Object} options - Overrides to the default plugin settings. 10920 */ 10921 value: function _setup(element, options) { 10922 this.$element = element; 10923 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Toggler.defaults, element.data(), options); 10924 this.className = ''; 10925 this.className = 'Toggler'; // ie9 back compat 10926 // Triggers init is idempotent, just need to make sure it is initialized 10927 10928 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 10929 10930 this._init(); 10931 10932 this._events(); 10933 } 10934 /** 10935 * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate. 10936 * @function 10937 * @private 10938 */ 10939 10940 }, { 10941 key: "_init", 10942 value: function _init() { 10943 var input; // Parse animation classes if they were set 10944 10945 if (this.options.animate) { 10946 input = this.options.animate.split(' '); 10947 this.animationIn = input[0]; 10948 this.animationOut = input[1] || null; 10949 } // Otherwise, parse toggle class 10950 else { 10951 input = this.$element.data('toggler'); // Allow for a . at the beginning of the string 10952 10953 this.className = input[0] === '.' ? input.slice(1) : input; 10954 } // Add ARIA attributes to triggers: 10955 10956 10957 var id = this.$element[0].id, 10958 $triggers = jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-open~=\"".concat(id, "\"], [data-close~=\"").concat(id, "\"], [data-toggle~=\"").concat(id, "\"]")); // - aria-expanded: according to the element visibility. 10959 10960 $triggers.attr('aria-expanded', !this.$element.is(':hidden')); // - aria-controls: adding the element id to it if not already in it. 10961 10962 $triggers.each(function (index, trigger) { 10963 var $trigger = jquery__WEBPACK_IMPORTED_MODULE_0___default()(trigger); 10964 var controls = $trigger.attr('aria-controls') || ''; 10965 var containsId = new RegExp("\\b".concat(RegExpEscape(id), "\\b")).test(controls); 10966 if (!containsId) $trigger.attr('aria-controls', controls ? "".concat(controls, " ").concat(id) : id); 10967 }); 10968 } 10969 /** 10970 * Initializes events for the toggle trigger. 10971 * @function 10972 * @private 10973 */ 10974 10975 }, { 10976 key: "_events", 10977 value: function _events() { 10978 this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this)); 10979 } 10980 /** 10981 * Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off". 10982 * @function 10983 * @fires Toggler#on 10984 * @fires Toggler#off 10985 */ 10986 10987 }, { 10988 key: "toggle", 10989 value: function toggle() { 10990 this[this.options.animate ? '_toggleAnimate' : '_toggleClass'](); 10991 } 10992 }, { 10993 key: "_toggleClass", 10994 value: function _toggleClass() { 10995 this.$element.toggleClass(this.className); 10996 var isOn = this.$element.hasClass(this.className); 10997 10998 if (isOn) { 10999 /** 11000 * Fires if the target element has the class after a toggle. 11001 * @event Toggler#on 11002 */ 11003 this.$element.trigger('on.zf.toggler'); 11004 } else { 11005 /** 11006 * Fires if the target element does not have the class after a toggle. 11007 * @event Toggler#off 11008 */ 11009 this.$element.trigger('off.zf.toggler'); 11010 } 11011 11012 this._updateARIA(isOn); 11013 11014 this.$element.find('[data-mutate]').trigger('mutateme.zf.trigger'); 11015 } 11016 }, { 11017 key: "_toggleAnimate", 11018 value: function _toggleAnimate() { 11019 var _this = this; 11020 11021 if (this.$element.is(':hidden')) { 11022 Motion.animateIn(this.$element, this.animationIn, function () { 11023 _this._updateARIA(true); 11024 11025 this.trigger('on.zf.toggler'); 11026 this.find('[data-mutate]').trigger('mutateme.zf.trigger'); 11027 }); 11028 } else { 11029 Motion.animateOut(this.$element, this.animationOut, function () { 11030 _this._updateARIA(false); 11031 11032 this.trigger('off.zf.toggler'); 11033 this.find('[data-mutate]').trigger('mutateme.zf.trigger'); 11034 }); 11035 } 11036 } 11037 }, { 11038 key: "_updateARIA", 11039 value: function _updateARIA(isOn) { 11040 var id = this.$element[0].id; 11041 jquery__WEBPACK_IMPORTED_MODULE_0___default()("[data-open=\"".concat(id, "\"], [data-close=\"").concat(id, "\"], [data-toggle=\"").concat(id, "\"]")).attr({ 11042 'aria-expanded': isOn ? true : false 11043 }); 11044 } 11045 /** 11046 * Destroys the instance of Toggler on the element. 11047 * @function 11048 */ 11049 11050 }, { 11051 key: "_destroy", 11052 value: function _destroy() { 11053 this.$element.off('.zf.toggler'); 11054 } 11055 }]); 11056 11057 return Toggler; 11058}(Plugin); 11059 11060Toggler.defaults = { 11061 /** 11062 * Tells the plugin if the element should animated when toggled. 11063 * @option 11064 * @type {boolean} 11065 * @default false 11066 */ 11067 animate: false 11068}; 11069/** 11070 * Tooltip module. 11071 * @module foundation.tooltip 11072 * @requires foundation.util.box 11073 * @requires foundation.util.mediaQuery 11074 * @requires foundation.util.triggers 11075 */ 11076 11077var Tooltip = 11078/*#__PURE__*/ 11079function (_Positionable) { 11080 _inherits(Tooltip, _Positionable); 11081 11082 function Tooltip() { 11083 _classCallCheck(this, Tooltip); 11084 11085 return _possibleConstructorReturn(this, _getPrototypeOf(Tooltip).apply(this, arguments)); 11086 } 11087 11088 _createClass(Tooltip, [{ 11089 key: "_setup", 11090 11091 /** 11092 * Creates a new instance of a Tooltip. 11093 * @class 11094 * @name Tooltip 11095 * @fires Tooltip#init 11096 * @param {jQuery} element - jQuery object to attach a tooltip to. 11097 * @param {Object} options - object to extend the default configuration. 11098 */ 11099 value: function _setup(element, options) { 11100 this.$element = element; 11101 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, Tooltip.defaults, this.$element.data(), options); 11102 this.className = 'Tooltip'; // ie9 back compat 11103 11104 this.isActive = false; 11105 this.isClick = false; // Triggers init is idempotent, just need to make sure it is initialized 11106 11107 Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 11108 11109 this._init(); 11110 } 11111 /** 11112 * Initializes the tooltip by setting the creating the tip element, adding it's text, setting private variables and setting attributes on the anchor. 11113 * @private 11114 */ 11115 11116 }, { 11117 key: "_init", 11118 value: function _init() { 11119 MediaQuery._init(); 11120 11121 var elemId = this.$element.attr('aria-describedby') || GetYoDigits(6, 'tooltip'); 11122 this.options.tipText = this.options.tipText || this.$element.attr('title'); 11123 this.template = this.options.template ? jquery__WEBPACK_IMPORTED_MODULE_0___default()(this.options.template) : this._buildTemplate(elemId); 11124 11125 if (this.options.allowHtml) { 11126 this.template.appendTo(document.body).html(this.options.tipText).hide(); 11127 } else { 11128 this.template.appendTo(document.body).text(this.options.tipText).hide(); 11129 } 11130 11131 this.$element.attr({ 11132 'title': '', 11133 'aria-describedby': elemId, 11134 'data-yeti-box': elemId, 11135 'data-toggle': elemId, 11136 'data-resize': elemId 11137 }).addClass(this.options.triggerClass); 11138 11139 _get(_getPrototypeOf(Tooltip.prototype), "_init", this).call(this); 11140 11141 this._events(); 11142 } 11143 }, { 11144 key: "_getDefaultPosition", 11145 value: function _getDefaultPosition() { 11146 // handle legacy classnames 11147 var position = this.$element[0].className.match(/\b(top|left|right|bottom)\b/g); 11148 return position ? position[0] : 'top'; 11149 } 11150 }, { 11151 key: "_getDefaultAlignment", 11152 value: function _getDefaultAlignment() { 11153 return 'center'; 11154 } 11155 }, { 11156 key: "_getHOffset", 11157 value: function _getHOffset() { 11158 if (this.position === 'left' || this.position === 'right') { 11159 return this.options.hOffset + this.options.tooltipWidth; 11160 } else { 11161 return this.options.hOffset; 11162 } 11163 } 11164 }, { 11165 key: "_getVOffset", 11166 value: function _getVOffset() { 11167 if (this.position === 'top' || this.position === 'bottom') { 11168 return this.options.vOffset + this.options.tooltipHeight; 11169 } else { 11170 return this.options.vOffset; 11171 } 11172 } 11173 /** 11174 * builds the tooltip element, adds attributes, and returns the template. 11175 * @private 11176 */ 11177 11178 }, { 11179 key: "_buildTemplate", 11180 value: function _buildTemplate(id) { 11181 var templateClasses = "".concat(this.options.tooltipClass, " ").concat(this.options.templateClasses).trim(); 11182 var $template = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div></div>').addClass(templateClasses).attr({ 11183 'role': 'tooltip', 11184 'aria-hidden': true, 11185 'data-is-active': false, 11186 'data-is-focus': false, 11187 'id': id 11188 }); 11189 return $template; 11190 } 11191 /** 11192 * sets the position class of an element and recursively calls itself until there are no more possible positions to attempt, or the tooltip element is no longer colliding. 11193 * if the tooltip is larger than the screen width, default to full width - any user selected margin 11194 * @private 11195 */ 11196 11197 }, { 11198 key: "_setPosition", 11199 value: function _setPosition() { 11200 _get(_getPrototypeOf(Tooltip.prototype), "_setPosition", this).call(this, this.$element, this.template); 11201 } 11202 /** 11203 * reveals the tooltip, and fires an event to close any other open tooltips on the page 11204 * @fires Tooltip#closeme 11205 * @fires Tooltip#show 11206 * @function 11207 */ 11208 11209 }, { 11210 key: "show", 11211 value: function show() { 11212 if (this.options.showOn !== 'all' && !MediaQuery.is(this.options.showOn)) { 11213 // console.error('The screen is too small to display this tooltip'); 11214 return false; 11215 } 11216 11217 var _this = this; 11218 11219 this.template.css('visibility', 'hidden').show(); 11220 11221 this._setPosition(); 11222 11223 this.template.removeClass('top bottom left right').addClass(this.position); 11224 this.template.removeClass('align-top align-bottom align-left align-right align-center').addClass('align-' + this.alignment); 11225 /** 11226 * Fires to close all other open tooltips on the page 11227 * @event Closeme#tooltip 11228 */ 11229 11230 this.$element.trigger('closeme.zf.tooltip', this.template.attr('id')); 11231 this.template.attr({ 11232 'data-is-active': true, 11233 'aria-hidden': false 11234 }); 11235 _this.isActive = true; // console.log(this.template); 11236 11237 this.template.stop().hide().css('visibility', '').fadeIn(this.options.fadeInDuration, function () {//maybe do stuff? 11238 }); 11239 /** 11240 * Fires when the tooltip is shown 11241 * @event Tooltip#show 11242 */ 11243 11244 this.$element.trigger('show.zf.tooltip'); 11245 } 11246 /** 11247 * Hides the current tooltip, and resets the positioning class if it was changed due to collision 11248 * @fires Tooltip#hide 11249 * @function 11250 */ 11251 11252 }, { 11253 key: "hide", 11254 value: function hide() { 11255 // console.log('hiding', this.$element.data('yeti-box')); 11256 var _this = this; 11257 11258 this.template.stop().attr({ 11259 'aria-hidden': true, 11260 'data-is-active': false 11261 }).fadeOut(this.options.fadeOutDuration, function () { 11262 _this.isActive = false; 11263 _this.isClick = false; 11264 }); 11265 /** 11266 * fires when the tooltip is hidden 11267 * @event Tooltip#hide 11268 */ 11269 11270 this.$element.trigger('hide.zf.tooltip'); 11271 } 11272 /** 11273 * adds event listeners for the tooltip and its anchor 11274 * TODO combine some of the listeners like focus and mouseenter, etc. 11275 * @private 11276 */ 11277 11278 }, { 11279 key: "_events", 11280 value: function _events() { 11281 var _this = this; 11282 11283 var $template = this.template; 11284 var isFocus = false; 11285 11286 if (!this.options.disableHover) { 11287 this.$element.on('mouseenter.zf.tooltip', function (e) { 11288 if (!_this.isActive) { 11289 _this.timeout = setTimeout(function () { 11290 _this.show(); 11291 }, _this.options.hoverDelay); 11292 } 11293 }).on('mouseleave.zf.tooltip', ignoreMousedisappear(function (e) { 11294 clearTimeout(_this.timeout); 11295 11296 if (!isFocus || _this.isClick && !_this.options.clickOpen) { 11297 _this.hide(); 11298 } 11299 })); 11300 } 11301 11302 if (this.options.clickOpen) { 11303 this.$element.on('mousedown.zf.tooltip', function (e) { 11304 e.stopImmediatePropagation(); 11305 if (_this.isClick) ;else { 11306 _this.isClick = true; 11307 11308 if ((_this.options.disableHover || !_this.$element.attr('tabindex')) && !_this.isActive) { 11309 _this.show(); 11310 } 11311 } 11312 }); 11313 } else { 11314 this.$element.on('mousedown.zf.tooltip', function (e) { 11315 e.stopImmediatePropagation(); 11316 _this.isClick = true; 11317 }); 11318 } 11319 11320 if (!this.options.disableForTouch) { 11321 this.$element.on('tap.zf.tooltip touchend.zf.tooltip', function (e) { 11322 _this.isActive ? _this.hide() : _this.show(); 11323 }); 11324 } 11325 11326 this.$element.on({ 11327 // 'toggle.zf.trigger': this.toggle.bind(this), 11328 // 'close.zf.trigger': this.hide.bind(this) 11329 'close.zf.trigger': this.hide.bind(this) 11330 }); 11331 this.$element.on('focus.zf.tooltip', function (e) { 11332 isFocus = true; 11333 11334 if (_this.isClick) { 11335 // If we're not showing open on clicks, we need to pretend a click-launched focus isn't 11336 // a real focus, otherwise on hover and come back we get bad behavior 11337 if (!_this.options.clickOpen) { 11338 isFocus = false; 11339 } 11340 11341 return false; 11342 } else { 11343 _this.show(); 11344 } 11345 }).on('focusout.zf.tooltip', function (e) { 11346 isFocus = false; 11347 _this.isClick = false; 11348 11349 _this.hide(); 11350 }).on('resizeme.zf.trigger', function () { 11351 if (_this.isActive) { 11352 _this._setPosition(); 11353 } 11354 }); 11355 } 11356 /** 11357 * adds a toggle method, in addition to the static show() & hide() functions 11358 * @function 11359 */ 11360 11361 }, { 11362 key: "toggle", 11363 value: function toggle() { 11364 if (this.isActive) { 11365 this.hide(); 11366 } else { 11367 this.show(); 11368 } 11369 } 11370 /** 11371 * Destroys an instance of tooltip, removes template element from the view. 11372 * @function 11373 */ 11374 11375 }, { 11376 key: "_destroy", 11377 value: function _destroy() { 11378 this.$element.attr('title', this.template.text()).off('.zf.trigger .zf.tooltip').removeClass(this.options.triggerClass).removeClass('top right left bottom').removeAttr('aria-describedby data-disable-hover data-resize data-toggle data-tooltip data-yeti-box'); 11379 this.template.remove(); 11380 } 11381 }]); 11382 11383 return Tooltip; 11384}(Positionable); 11385 11386Tooltip.defaults = { 11387 disableForTouch: false, 11388 11389 /** 11390 * Time, in ms, before a tooltip should open on hover. 11391 * @option 11392 * @type {number} 11393 * @default 200 11394 */ 11395 hoverDelay: 200, 11396 11397 /** 11398 * Time, in ms, a tooltip should take to fade into view. 11399 * @option 11400 * @type {number} 11401 * @default 150 11402 */ 11403 fadeInDuration: 150, 11404 11405 /** 11406 * Time, in ms, a tooltip should take to fade out of view. 11407 * @option 11408 * @type {number} 11409 * @default 150 11410 */ 11411 fadeOutDuration: 150, 11412 11413 /** 11414 * Disables hover events from opening the tooltip if set to true 11415 * @option 11416 * @type {boolean} 11417 * @default false 11418 */ 11419 disableHover: false, 11420 11421 /** 11422 * Optional addtional classes to apply to the tooltip template on init. 11423 * @option 11424 * @type {string} 11425 * @default '' 11426 */ 11427 templateClasses: '', 11428 11429 /** 11430 * Non-optional class added to tooltip templates. Foundation default is 'tooltip'. 11431 * @option 11432 * @type {string} 11433 * @default 'tooltip' 11434 */ 11435 tooltipClass: 'tooltip', 11436 11437 /** 11438 * Class applied to the tooltip anchor element. 11439 * @option 11440 * @type {string} 11441 * @default 'has-tip' 11442 */ 11443 triggerClass: 'has-tip', 11444 11445 /** 11446 * Minimum breakpoint size at which to open the tooltip. 11447 * @option 11448 * @type {string} 11449 * @default 'small' 11450 */ 11451 showOn: 'small', 11452 11453 /** 11454 * Custom template to be used to generate markup for tooltip. 11455 * @option 11456 * @type {string} 11457 * @default '' 11458 */ 11459 template: '', 11460 11461 /** 11462 * Text displayed in the tooltip template on open. 11463 * @option 11464 * @type {string} 11465 * @default '' 11466 */ 11467 tipText: '', 11468 touchCloseText: 'Tap to close.', 11469 11470 /** 11471 * Allows the tooltip to remain open if triggered with a click or touch event. 11472 * @option 11473 * @type {boolean} 11474 * @default true 11475 */ 11476 clickOpen: true, 11477 11478 /** 11479 * Position of tooltip. Can be left, right, bottom, top, or auto. 11480 * @option 11481 * @type {string} 11482 * @default 'auto' 11483 */ 11484 position: 'auto', 11485 11486 /** 11487 * Alignment of tooltip relative to anchor. Can be left, right, bottom, top, center, or auto. 11488 * @option 11489 * @type {string} 11490 * @default 'auto' 11491 */ 11492 alignment: 'auto', 11493 11494 /** 11495 * Allow overlap of container/window. If false, tooltip will first try to 11496 * position as defined by data-position and data-alignment, but reposition if 11497 * it would cause an overflow. @option 11498 * @type {boolean} 11499 * @default false 11500 */ 11501 allowOverlap: false, 11502 11503 /** 11504 * Allow overlap of only the bottom of the container. This is the most common 11505 * behavior for dropdowns, allowing the dropdown to extend the bottom of the 11506 * screen but not otherwise influence or break out of the container. 11507 * Less common for tooltips. 11508 * @option 11509 * @type {boolean} 11510 * @default false 11511 */ 11512 allowBottomOverlap: false, 11513 11514 /** 11515 * Distance, in pixels, the template should push away from the anchor on the Y axis. 11516 * @option 11517 * @type {number} 11518 * @default 0 11519 */ 11520 vOffset: 0, 11521 11522 /** 11523 * Distance, in pixels, the template should push away from the anchor on the X axis 11524 * @option 11525 * @type {number} 11526 * @default 0 11527 */ 11528 hOffset: 0, 11529 11530 /** 11531 * Distance, in pixels, the template spacing auto-adjust for a vertical tooltip 11532 * @option 11533 * @type {number} 11534 * @default 14 11535 */ 11536 tooltipHeight: 14, 11537 11538 /** 11539 * Distance, in pixels, the template spacing auto-adjust for a horizontal tooltip 11540 * @option 11541 * @type {number} 11542 * @default 12 11543 */ 11544 tooltipWidth: 12, 11545 11546 /** 11547 * Allow HTML in tooltip. Warning: If you are loading user-generated content into tooltips, 11548 * allowing HTML may open yourself up to XSS attacks. 11549 * @option 11550 * @type {boolean} 11551 * @default false 11552 */ 11553 allowHtml: false 11554}; 11555var MenuPlugins$1 = { 11556 tabs: { 11557 cssClass: 'tabs', 11558 plugin: Tabs 11559 }, 11560 accordion: { 11561 cssClass: 'accordion', 11562 plugin: Accordion 11563 } 11564}; 11565/** 11566 * ResponsiveAccordionTabs module. 11567 * @module foundation.responsiveAccordionTabs 11568 * @requires foundation.util.motion 11569 * @requires foundation.accordion 11570 * @requires foundation.tabs 11571 */ 11572 11573var ResponsiveAccordionTabs = 11574/*#__PURE__*/ 11575function (_Plugin) { 11576 _inherits(ResponsiveAccordionTabs, _Plugin); 11577 11578 function ResponsiveAccordionTabs() { 11579 _classCallCheck(this, ResponsiveAccordionTabs); 11580 11581 return _possibleConstructorReturn(this, _getPrototypeOf(ResponsiveAccordionTabs).apply(this, arguments)); 11582 } 11583 11584 _createClass(ResponsiveAccordionTabs, [{ 11585 key: "_setup", 11586 11587 /** 11588 * Creates a new instance of a responsive accordion tabs. 11589 * @class 11590 * @name ResponsiveAccordionTabs 11591 * @fires ResponsiveAccordionTabs#init 11592 * @param {jQuery} element - jQuery object to make into Responsive Accordion Tabs. 11593 * @param {Object} options - Overrides to the default plugin settings. 11594 */ 11595 value: function _setup(element, options) { 11596 this.$element = jquery__WEBPACK_IMPORTED_MODULE_0___default()(element); 11597 this.options = jquery__WEBPACK_IMPORTED_MODULE_0___default.a.extend({}, this.$element.data(), options); 11598 this.rules = this.$element.data('responsive-accordion-tabs'); 11599 this.currentMq = null; 11600 this.currentPlugin = null; 11601 this.className = 'ResponsiveAccordionTabs'; // ie9 back compat 11602 11603 if (!this.$element.attr('id')) { 11604 this.$element.attr('id', GetYoDigits(6, 'responsiveaccordiontabs')); 11605 } 11606 11607 this._init(); 11608 11609 this._events(); 11610 } 11611 /** 11612 * Initializes the Menu by parsing the classes from the 'data-responsive-accordion-tabs' attribute on the element. 11613 * @function 11614 * @private 11615 */ 11616 11617 }, { 11618 key: "_init", 11619 value: function _init() { 11620 MediaQuery._init(); // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules 11621 11622 11623 if (typeof this.rules === 'string') { 11624 var rulesTree = {}; // Parse rules from "classes" pulled from data attribute 11625 11626 var rules = this.rules.split(' '); // Iterate through every rule found 11627 11628 for (var i = 0; i < rules.length; i++) { 11629 var rule = rules[i].split('-'); 11630 var ruleSize = rule.length > 1 ? rule[0] : 'small'; 11631 var rulePlugin = rule.length > 1 ? rule[1] : rule[0]; 11632 11633 if (MenuPlugins$1[rulePlugin] !== null) { 11634 rulesTree[ruleSize] = MenuPlugins$1[rulePlugin]; 11635 } 11636 } 11637 11638 this.rules = rulesTree; 11639 } 11640 11641 this._getAllOptions(); 11642 11643 if (!jquery__WEBPACK_IMPORTED_MODULE_0___default.a.isEmptyObject(this.rules)) { 11644 this._checkMediaQueries(); 11645 } 11646 } 11647 }, { 11648 key: "_getAllOptions", 11649 value: function _getAllOptions() { 11650 //get all defaults and options 11651 var _this = this; 11652 11653 _this.allOptions = {}; 11654 11655 for (var key in MenuPlugins$1) { 11656 if (MenuPlugins$1.hasOwnProperty(key)) { 11657 var obj = MenuPlugins$1[key]; 11658 11659 try { 11660 var dummyPlugin = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<ul></ul>'); 11661 var tmpPlugin = new obj.plugin(dummyPlugin, _this.options); 11662 11663 for (var keyKey in tmpPlugin.options) { 11664 if (tmpPlugin.options.hasOwnProperty(keyKey) && keyKey !== 'zfPlugin') { 11665 var objObj = tmpPlugin.options[keyKey]; 11666 _this.allOptions[keyKey] = objObj; 11667 } 11668 } 11669 11670 tmpPlugin.destroy(); 11671 } catch (e) {} 11672 } 11673 } 11674 } 11675 /** 11676 * Initializes events for the Menu. 11677 * @function 11678 * @private 11679 */ 11680 11681 }, { 11682 key: "_events", 11683 value: function _events() { 11684 this._changedZfMediaQueryHandler = this._checkMediaQueries.bind(this); 11685 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('changed.zf.mediaquery', this._changedZfMediaQueryHandler); 11686 } 11687 /** 11688 * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out. 11689 * @function 11690 * @private 11691 */ 11692 11693 }, { 11694 key: "_checkMediaQueries", 11695 value: function _checkMediaQueries() { 11696 var matchedMq, 11697 _this = this; // Iterate through each rule and find the last matching rule 11698 11699 11700 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.each(this.rules, function (key) { 11701 if (MediaQuery.atLeast(key)) { 11702 matchedMq = key; 11703 } 11704 }); // No match? No dice 11705 11706 if (!matchedMq) return; // Plugin already initialized? We good 11707 11708 if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return; // Remove existing plugin-specific CSS classes 11709 11710 jquery__WEBPACK_IMPORTED_MODULE_0___default.a.each(MenuPlugins$1, function (key, value) { 11711 _this.$element.removeClass(value.cssClass); 11712 }); // Add the CSS class for the new plugin 11713 11714 this.$element.addClass(this.rules[matchedMq].cssClass); // Create an instance of the new plugin 11715 11716 if (this.currentPlugin) { 11717 //don't know why but on nested elements data zfPlugin get's lost 11718 if (!this.currentPlugin.$element.data('zfPlugin') && this.storezfData) this.currentPlugin.$element.data('zfPlugin', this.storezfData); 11719 this.currentPlugin.destroy(); 11720 } 11721 11722 this._handleMarkup(this.rules[matchedMq].cssClass); 11723 11724 this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {}); 11725 this.storezfData = this.currentPlugin.$element.data('zfPlugin'); 11726 } 11727 }, { 11728 key: "_handleMarkup", 11729 value: function _handleMarkup(toSet) { 11730 var _this = this, 11731 fromString = 'accordion'; 11732 11733 var $panels = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-tabs-content=' + this.$element.attr('id') + ']'); 11734 if ($panels.length) fromString = 'tabs'; 11735 11736 if (fromString === toSet) { 11737 return; 11738 } 11739 11740 var tabsTitle = _this.allOptions.linkClass ? _this.allOptions.linkClass : 'tabs-title'; 11741 var tabsPanel = _this.allOptions.panelClass ? _this.allOptions.panelClass : 'tabs-panel'; 11742 this.$element.removeAttr('role'); 11743 var $liHeads = this.$element.children('.' + tabsTitle + ',[data-accordion-item]').removeClass(tabsTitle).removeClass('accordion-item').removeAttr('data-accordion-item'); 11744 var $liHeadsA = $liHeads.children('a').removeClass('accordion-title'); 11745 11746 if (fromString === 'tabs') { 11747 $panels = $panels.children('.' + tabsPanel).removeClass(tabsPanel).removeAttr('role').removeAttr('aria-hidden').removeAttr('aria-labelledby'); 11748 $panels.children('a').removeAttr('role').removeAttr('aria-controls').removeAttr('aria-selected'); 11749 } else { 11750 $panels = $liHeads.children('[data-tab-content]').removeClass('accordion-content'); 11751 } 11752 11753 $panels.css({ 11754 display: '', 11755 visibility: '' 11756 }); 11757 $liHeads.css({ 11758 display: '', 11759 visibility: '' 11760 }); 11761 11762 if (toSet === 'accordion') { 11763 $panels.each(function (key, value) { 11764 jquery__WEBPACK_IMPORTED_MODULE_0___default()(value).appendTo($liHeads.get(key)).addClass('accordion-content').attr('data-tab-content', '').removeClass('is-active').css({ 11765 height: '' 11766 }); 11767 jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-tabs-content=' + _this.$element.attr('id') + ']').after('<div id="tabs-placeholder-' + _this.$element.attr('id') + '"></div>').detach(); 11768 $liHeads.addClass('accordion-item').attr('data-accordion-item', ''); 11769 $liHeadsA.addClass('accordion-title'); 11770 }); 11771 } else if (toSet === 'tabs') { 11772 var $tabsContent = jquery__WEBPACK_IMPORTED_MODULE_0___default()('[data-tabs-content=' + _this.$element.attr('id') + ']'); 11773 var $placeholder = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#tabs-placeholder-' + _this.$element.attr('id')); 11774 11775 if ($placeholder.length) { 11776 $tabsContent = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div class="tabs-content"></div>').insertAfter($placeholder).attr('data-tabs-content', _this.$element.attr('id')); 11777 $placeholder.remove(); 11778 } else { 11779 $tabsContent = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div class="tabs-content"></div>').insertAfter(_this.$element).attr('data-tabs-content', _this.$element.attr('id')); 11780 } 11781 11782 $panels.each(function (key, value) { 11783 var tempValue = jquery__WEBPACK_IMPORTED_MODULE_0___default()(value).appendTo($tabsContent).addClass(tabsPanel); 11784 var hash = $liHeadsA.get(key).hash.slice(1); 11785 var id = jquery__WEBPACK_IMPORTED_MODULE_0___default()(value).attr('id') || GetYoDigits(6, 'accordion'); 11786 11787 if (hash !== id) { 11788 if (hash !== '') { 11789 jquery__WEBPACK_IMPORTED_MODULE_0___default()(value).attr('id', hash); 11790 } else { 11791 hash = id; 11792 jquery__WEBPACK_IMPORTED_MODULE_0___default()(value).attr('id', hash); 11793 jquery__WEBPACK_IMPORTED_MODULE_0___default()($liHeadsA.get(key)).attr('href', jquery__WEBPACK_IMPORTED_MODULE_0___default()($liHeadsA.get(key)).attr('href').replace('#', '') + '#' + hash); 11794 } 11795 } 11796 11797 var isActive = jquery__WEBPACK_IMPORTED_MODULE_0___default()($liHeads.get(key)).hasClass('is-active'); 11798 11799 if (isActive) { 11800 tempValue.addClass('is-active'); 11801 } 11802 }); 11803 $liHeads.addClass(tabsTitle); 11804 } 11805 } 11806 /** 11807 * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out. 11808 * @function 11809 */ 11810 11811 }, { 11812 key: "_destroy", 11813 value: function _destroy() { 11814 if (this.currentPlugin) this.currentPlugin.destroy(); 11815 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('changed.zf.mediaquery', this._changedZfMediaQueryHandler); 11816 } 11817 }]); 11818 11819 return ResponsiveAccordionTabs; 11820}(Plugin); 11821 11822ResponsiveAccordionTabs.defaults = {}; 11823Foundation.addToJquery(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); // Add Foundation Utils to Foundation global namespace for backwards 11824// compatibility. 11825 11826Foundation.rtl = rtl; 11827Foundation.GetYoDigits = GetYoDigits; 11828Foundation.transitionend = transitionend; 11829Foundation.RegExpEscape = RegExpEscape; 11830Foundation.onLoad = onLoad; 11831Foundation.Box = Box; 11832Foundation.onImagesLoaded = onImagesLoaded; 11833Foundation.Keyboard = Keyboard; 11834Foundation.MediaQuery = MediaQuery; 11835Foundation.Motion = Motion; 11836Foundation.Move = Move; 11837Foundation.Nest = Nest; 11838Foundation.Timer = Timer; // Touch and Triggers previously were almost purely sede effect driven, 11839// so no need to add it to Foundation, just init them. 11840 11841Touch.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a); 11842Triggers.init(jquery__WEBPACK_IMPORTED_MODULE_0___default.a, Foundation); 11843 11844MediaQuery._init(); 11845 11846Foundation.plugin(Abide, 'Abide'); 11847Foundation.plugin(Accordion, 'Accordion'); 11848Foundation.plugin(AccordionMenu, 'AccordionMenu'); 11849Foundation.plugin(Drilldown, 'Drilldown'); 11850Foundation.plugin(Dropdown, 'Dropdown'); 11851Foundation.plugin(DropdownMenu, 'DropdownMenu'); 11852Foundation.plugin(Equalizer, 'Equalizer'); 11853Foundation.plugin(Interchange, 'Interchange'); 11854Foundation.plugin(Magellan, 'Magellan'); 11855Foundation.plugin(OffCanvas, 'OffCanvas'); 11856Foundation.plugin(Orbit, 'Orbit'); 11857Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu'); 11858Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle'); 11859Foundation.plugin(Reveal, 'Reveal'); 11860Foundation.plugin(Slider, 'Slider'); 11861Foundation.plugin(SmoothScroll, 'SmoothScroll'); 11862Foundation.plugin(Sticky, 'Sticky'); 11863Foundation.plugin(Tabs, 'Tabs'); 11864Foundation.plugin(Toggler, 'Toggler'); 11865Foundation.plugin(Tooltip, 'Tooltip'); 11866Foundation.plugin(ResponsiveAccordionTabs, 'ResponsiveAccordionTabs'); 11867/* harmony default export */ __webpack_exports__["default"] = (Foundation); 11868 11869 11870/***/ }), 11871
vendor: 293,375 bytes, lines 11872-22853
11872/***/ "./node_modules/jquery/dist/jquery.js": 11873/*!********************************************!*\ 11874 !*** ./node_modules/jquery/dist/jquery.js ***! 11875 \********************************************/ 11876/*! no static exports found */ 11877/***/ (function(module, exports, __webpack_require__) { 11878 11879/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 11880 11881/*! 11882 * jQuery JavaScript Library v3.6.4 11883 * https://jquery.com/ 11884 * 11885 * Includes Sizzle.js 11886 * https://sizzlejs.com/ 11887 * 11888 * Copyright OpenJS Foundation and other contributors 11889 * Released under the MIT license 11890 * https://jquery.org/license 11891 * 11892 * Date: 2023-03-08T15:28Z 11893 */ 11894( function( global, factory ) { 11895 11896 "use strict"; 11897 11898 if ( typeof module === "object" && typeof module.exports === "object" ) { 11899 11900 // For CommonJS and CommonJS-like environments where a proper `window` 11901 // is present, execute the factory and get jQuery. 11902 // For environments that do not have a `window` with a `document` 11903 // (such as Node.js), expose a factory as module.exports. 11904 // This accentuates the need for the creation of a real `window`. 11905 // e.g. var jQuery = require("jquery")(window); 11906 // See ticket trac-14549 for more info. 11907 module.exports = global.document ? 11908 factory( global, true ) : 11909 function( w ) { 11910 if ( !w.document ) { 11911 throw new Error( "jQuery requires a window with a document" ); 11912 } 11913 return factory( w ); 11914 }; 11915 } else { 11916 factory( global ); 11917 } 11918 11919// Pass this if window is not defined yet 11920} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 11921 11922// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 11923// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 11924// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 11925// enough that all such attempts are guarded in a try block. 11926"use strict"; 11927 11928var arr = []; 11929 11930var getProto = Object.getPrototypeOf; 11931 11932var slice = arr.slice; 11933 11934var flat = arr.flat ? function( array ) { 11935 return arr.flat.call( array ); 11936} : function( array ) { 11937 return arr.concat.apply( [], array ); 11938}; 11939 11940 11941var push = arr.push; 11942 11943var indexOf = arr.indexOf; 11944 11945var class2type = {}; 11946 11947var toString = class2type.toString; 11948 11949var hasOwn = class2type.hasOwnProperty; 11950 11951var fnToString = hasOwn.toString; 11952 11953var ObjectFunctionString = fnToString.call( Object ); 11954 11955var support = {}; 11956 11957var isFunction = function isFunction( obj ) { 11958 11959 // Support: Chrome <=57, Firefox <=52 11960 // In some browsers, typeof returns "function" for HTML <object> elements 11961 // (i.e., `typeof document.createElement( "object" ) === "function"`). 11962 // We don't want to classify *any* DOM node as a function. 11963 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 11964 // Plus for old WebKit, typeof returns "function" for HTML collections 11965 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 11966 return typeof obj === "function" && typeof obj.nodeType !== "number" && 11967 typeof obj.item !== "function"; 11968 }; 11969 11970 11971var isWindow = function isWindow( obj ) { 11972 return obj != null && obj === obj.window; 11973 }; 11974 11975 11976var document = window.document; 11977 11978 11979 11980 var preservedScriptAttributes = { 11981 type: true, 11982 src: true, 11983 nonce: true, 11984 noModule: true 11985 }; 11986 11987 function DOMEval( code, node, doc ) { 11988 doc = doc || document; 11989 11990 var i, val, 11991 script = doc.createElement( "script" ); 11992 11993 script.text = code; 11994 if ( node ) { 11995 for ( i in preservedScriptAttributes ) { 11996 11997 // Support: Firefox 64+, Edge 18+ 11998 // Some browsers don't support the "nonce" property on scripts. 11999 // On the other hand, just using `getAttribute` is not enough as 12000 // the `nonce` attribute is reset to an empty string whenever it 12001 // becomes browsing-context connected. 12002 // See https://github.com/whatwg/html/issues/2369 12003 // See https://html.spec.whatwg.org/#nonce-attributes 12004 // The `node.getAttribute` check was added for the sake of 12005 // `jQuery.globalEval` so that it can fake a nonce-containing node 12006 // via an object. 12007 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 12008 if ( val ) { 12009 script.setAttribute( i, val ); 12010 } 12011 } 12012 } 12013 doc.head.appendChild( script ).parentNode.removeChild( script ); 12014 } 12015 12016 12017function toType( obj ) { 12018 if ( obj == null ) { 12019 return obj + ""; 12020 } 12021 12022 // Support: Android <=2.3 only (functionish RegExp) 12023 return typeof obj === "object" || typeof obj === "function" ? 12024 class2type[ toString.call( obj ) ] || "object" : 12025 typeof obj; 12026} 12027/* global Symbol */ 12028// Defining this global in .eslintrc.json would create a danger of using the global 12029// unguarded in another place, it seems safer to define global only for this module 12030 12031 12032 12033var 12034 version = "3.6.4", 12035 12036 // Define a local copy of jQuery 12037 jQuery = function( selector, context ) { 12038 12039 // The jQuery object is actually just the init constructor 'enhanced' 12040 // Need init if jQuery is called (just allow error to be thrown if not included) 12041 return new jQuery.fn.init( selector, context ); 12042 }; 12043 12044jQuery.fn = jQuery.prototype = { 12045 12046 // The current version of jQuery being used 12047 jquery: version, 12048 12049 constructor: jQuery, 12050 12051 // The default length of a jQuery object is 0 12052 length: 0, 12053 12054 toArray: function() { 12055 return slice.call( this ); 12056 }, 12057 12058 // Get the Nth element in the matched element set OR 12059 // Get the whole matched element set as a clean array 12060 get: function( num ) { 12061 12062 // Return all the elements in a clean array 12063 if ( num == null ) { 12064 return slice.call( this ); 12065 } 12066 12067 // Return just the one element from the set 12068 return num < 0 ? this[ num + this.length ] : this[ num ]; 12069 }, 12070 12071 // Take an array of elements and push it onto the stack 12072 // (returning the new matched element set) 12073 pushStack: function( elems ) { 12074 12075 // Build a new jQuery matched element set 12076 var ret = jQuery.merge( this.constructor(), elems ); 12077 12078 // Add the old object onto the stack (as a reference) 12079 ret.prevObject = this; 12080 12081 // Return the newly-formed element set 12082 return ret; 12083 }, 12084 12085 // Execute a callback for every element in the matched set. 12086 each: function( callback ) { 12087 return jQuery.each( this, callback ); 12088 }, 12089 12090 map: function( callback ) { 12091 return this.pushStack( jQuery.map( this, function( elem, i ) { 12092 return callback.call( elem, i, elem ); 12093 } ) ); 12094 }, 12095 12096 slice: function() { 12097 return this.pushStack( slice.apply( this, arguments ) ); 12098 }, 12099 12100 first: function() { 12101 return this.eq( 0 ); 12102 }, 12103 12104 last: function() { 12105 return this.eq( -1 ); 12106 }, 12107 12108 even: function() { 12109 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 12110 return ( i + 1 ) % 2; 12111 } ) ); 12112 }, 12113 12114 odd: function() { 12115 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 12116 return i % 2; 12117 } ) ); 12118 }, 12119 12120 eq: function( i ) { 12121 var len = this.length, 12122 j = +i + ( i < 0 ? len : 0 ); 12123 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 12124 }, 12125 12126 end: function() { 12127 return this.prevObject || this.constructor(); 12128 }, 12129 12130 // For internal use only. 12131 // Behaves like an Array's method, not like a jQuery method. 12132 push: push, 12133 sort: arr.sort, 12134 splice: arr.splice 12135}; 12136 12137jQuery.extend = jQuery.fn.extend = function() { 12138 var options, name, src, copy, copyIsArray, clone, 12139 target = arguments[ 0 ] || {}, 12140 i = 1, 12141 length = arguments.length, 12142 deep = false; 12143 12144 // Handle a deep copy situation 12145 if ( typeof target === "boolean" ) { 12146 deep = target; 12147 12148 // Skip the boolean and the target 12149 target = arguments[ i ] || {}; 12150 i++; 12151 } 12152 12153 // Handle case when target is a string or something (possible in deep copy) 12154 if ( typeof target !== "object" && !isFunction( target ) ) { 12155 target = {}; 12156 } 12157 12158 // Extend jQuery itself if only one argument is passed 12159 if ( i === length ) { 12160 target = this; 12161 i--; 12162 } 12163 12164 for ( ; i < length; i++ ) { 12165 12166 // Only deal with non-null/undefined values 12167 if ( ( options = arguments[ i ] ) != null ) { 12168 12169 // Extend the base object 12170 for ( name in options ) { 12171 copy = options[ name ]; 12172 12173 // Prevent Object.prototype pollution 12174 // Prevent never-ending loop 12175 if ( name === "__proto__" || target === copy ) { 12176 continue; 12177 } 12178 12179 // Recurse if we're merging plain objects or arrays 12180 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 12181 ( copyIsArray = Array.isArray( copy ) ) ) ) { 12182 src = target[ name ]; 12183 12184 // Ensure proper type for the source value 12185 if ( copyIsArray && !Array.isArray( src ) ) { 12186 clone = []; 12187 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 12188 clone = {}; 12189 } else { 12190 clone = src; 12191 } 12192 copyIsArray = false; 12193 12194 // Never move original objects, clone them 12195 target[ name ] = jQuery.extend( deep, clone, copy ); 12196 12197 // Don't bring in undefined values 12198 } else if ( copy !== undefined ) { 12199 target[ name ] = copy; 12200 } 12201 } 12202 } 12203 } 12204 12205 // Return the modified object 12206 return target; 12207}; 12208 12209jQuery.extend( { 12210 12211 // Unique for each copy of jQuery on the page 12212 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 12213 12214 // Assume jQuery is ready without the ready module 12215 isReady: true, 12216 12217 error: function( msg ) { 12218 throw new Error( msg ); 12219 }, 12220 12221 noop: function() {}, 12222 12223 isPlainObject: function( obj ) { 12224 var proto, Ctor; 12225 12226 // Detect obvious negatives 12227 // Use toString instead of jQuery.type to catch host objects 12228 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 12229 return false; 12230 } 12231 12232 proto = getProto( obj ); 12233 12234 // Objects with no prototype (e.g., `Object.create( null )`) are plain 12235 if ( !proto ) { 12236 return true; 12237 } 12238 12239 // Objects with prototype are plain iff they were constructed by a global Object function 12240 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 12241 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 12242 }, 12243 12244 isEmptyObject: function( obj ) { 12245 var name; 12246 12247 for ( name in obj ) { 12248 return false; 12249 } 12250 return true; 12251 }, 12252 12253 // Evaluates a script in a provided context; falls back to the global one 12254 // if not specified. 12255 globalEval: function( code, options, doc ) { 12256 DOMEval( code, { nonce: options && options.nonce }, doc ); 12257 }, 12258 12259 each: function( obj, callback ) { 12260 var length, i = 0; 12261 12262 if ( isArrayLike( obj ) ) { 12263 length = obj.length; 12264 for ( ; i < length; i++ ) { 12265 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 12266 break; 12267 } 12268 } 12269 } else { 12270 for ( i in obj ) { 12271 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 12272 break; 12273 } 12274 } 12275 } 12276 12277 return obj; 12278 }, 12279 12280 // results is for internal usage only 12281 makeArray: function( arr, results ) { 12282 var ret = results || []; 12283 12284 if ( arr != null ) { 12285 if ( isArrayLike( Object( arr ) ) ) { 12286 jQuery.merge( ret, 12287 typeof arr === "string" ? 12288 [ arr ] : arr 12289 ); 12290 } else { 12291 push.call( ret, arr ); 12292 } 12293 } 12294 12295 return ret; 12296 }, 12297 12298 inArray: function( elem, arr, i ) { 12299 return arr == null ? -1 : indexOf.call( arr, elem, i ); 12300 }, 12301 12302 // Support: Android <=4.0 only, PhantomJS 1 only 12303 // push.apply(_, arraylike) throws on ancient WebKit 12304 merge: function( first, second ) { 12305 var len = +second.length, 12306 j = 0, 12307 i = first.length; 12308 12309 for ( ; j < len; j++ ) { 12310 first[ i++ ] = second[ j ]; 12311 } 12312 12313 first.length = i; 12314 12315 return first; 12316 }, 12317 12318 grep: function( elems, callback, invert ) { 12319 var callbackInverse, 12320 matches = [], 12321 i = 0, 12322 length = elems.length, 12323 callbackExpect = !invert; 12324 12325 // Go through the array, only saving the items 12326 // that pass the validator function 12327 for ( ; i < length; i++ ) { 12328 callbackInverse = !callback( elems[ i ], i ); 12329 if ( callbackInverse !== callbackExpect ) { 12330 matches.push( elems[ i ] ); 12331 } 12332 } 12333 12334 return matches; 12335 }, 12336 12337 // arg is for internal usage only 12338 map: function( elems, callback, arg ) { 12339 var length, value, 12340 i = 0, 12341 ret = []; 12342 12343 // Go through the array, translating each of the items to their new values 12344 if ( isArrayLike( elems ) ) { 12345 length = elems.length; 12346 for ( ; i < length; i++ ) { 12347 value = callback( elems[ i ], i, arg ); 12348 12349 if ( value != null ) { 12350 ret.push( value ); 12351 } 12352 } 12353 12354 // Go through every key on the object, 12355 } else { 12356 for ( i in elems ) { 12357 value = callback( elems[ i ], i, arg ); 12358 12359 if ( value != null ) { 12360 ret.push( value ); 12361 } 12362 } 12363 } 12364 12365 // Flatten any nested arrays 12366 return flat( ret ); 12367 }, 12368 12369 // A global GUID counter for objects 12370 guid: 1, 12371 12372 // jQuery.support is not used in Core but other projects attach their 12373 // properties to it so it needs to exist. 12374 support: support 12375} ); 12376 12377if ( typeof Symbol === "function" ) { 12378 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 12379} 12380 12381// Populate the class2type map 12382jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 12383 function( _i, name ) { 12384 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 12385 } ); 12386 12387function isArrayLike( obj ) { 12388 12389 // Support: real iOS 8.2 only (not reproducible in simulator) 12390 // `in` check used to prevent JIT error (gh-2145) 12391 // hasOwn isn't used here due to false negatives 12392 // regarding Nodelist length in IE 12393 var length = !!obj && "length" in obj && obj.length, 12394 type = toType( obj ); 12395 12396 if ( isFunction( obj ) || isWindow( obj ) ) { 12397 return false; 12398 } 12399 12400 return type === "array" || length === 0 || 12401 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 12402} 12403var Sizzle = 12404/*! 12405 * Sizzle CSS Selector Engine v2.3.10 12406 * https://sizzlejs.com/ 12407 * 12408 * Copyright JS Foundation and other contributors 12409 * Released under the MIT license 12410 * https://js.foundation/ 12411 * 12412 * Date: 2023-02-14 12413 */ 12414( function( window ) { 12415var i, 12416 support, 12417 Expr, 12418 getText, 12419 isXML, 12420 tokenize, 12421 compile, 12422 select, 12423 outermostContext, 12424 sortInput, 12425 hasDuplicate, 12426 12427 // Local document vars 12428 setDocument, 12429 document, 12430 docElem, 12431 documentIsHTML, 12432 rbuggyQSA, 12433 rbuggyMatches, 12434 matches, 12435 contains, 12436 12437 // Instance-specific data 12438 expando = "sizzle" + 1 * new Date(), 12439 preferredDoc = window.document, 12440 dirruns = 0, 12441 done = 0, 12442 classCache = createCache(), 12443 tokenCache = createCache(), 12444 compilerCache = createCache(), 12445 nonnativeSelectorCache = createCache(), 12446 sortOrder = function( a, b ) { 12447 if ( a === b ) { 12448 hasDuplicate = true; 12449 } 12450 return 0; 12451 }, 12452 12453 // Instance methods 12454 hasOwn = ( {} ).hasOwnProperty, 12455 arr = [], 12456 pop = arr.pop, 12457 pushNative = arr.push, 12458 push = arr.push, 12459 slice = arr.slice, 12460 12461 // Use a stripped-down indexOf as it's faster than native 12462 // https://jsperf.com/thor-indexof-vs-for/5 12463 indexOf = function( list, elem ) { 12464 var i = 0, 12465 len = list.length; 12466 for ( ; i < len; i++ ) { 12467 if ( list[ i ] === elem ) { 12468 return i; 12469 } 12470 } 12471 return -1; 12472 }, 12473 12474 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + 12475 "ismap|loop|multiple|open|readonly|required|scoped", 12476 12477 // Regular expressions 12478 12479 // http://www.w3.org/TR/css3-selectors/#whitespace 12480 whitespace = "[\\x20\\t\\r\\n\\f]", 12481 12482 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 12483 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 12484 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 12485 12486 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 12487 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 12488 12489 // Operator (capture 2) 12490 "*([*^$|!~]?=)" + whitespace + 12491 12492 // "Attribute values must be CSS identifiers [capture 5] 12493 // or strings [capture 3 or capture 4]" 12494 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 12495 whitespace + "*\\]", 12496 12497 pseudos = ":(" + identifier + ")(?:\\((" + 12498 12499 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 12500 // 1. quoted (capture 3; capture 4 or capture 5) 12501 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 12502 12503 // 2. simple (capture 6) 12504 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 12505 12506 // 3. anything else (capture 2) 12507 ".*" + 12508 ")\\)|)", 12509 12510 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 12511 rwhitespace = new RegExp( whitespace + "+", "g" ), 12512 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 12513 whitespace + "+$", "g" ), 12514 12515 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 12516 rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + 12517 "*" ), 12518 rdescend = new RegExp( whitespace + "|>" ), 12519 12520 rpseudo = new RegExp( pseudos ), 12521 ridentifier = new RegExp( "^" + identifier + "$" ), 12522 12523 matchExpr = { 12524 "ID": new RegExp( "^#(" + identifier + ")" ), 12525 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 12526 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 12527 "ATTR": new RegExp( "^" + attributes ), 12528 "PSEUDO": new RegExp( "^" + pseudos ), 12529 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 12530 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 12531 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 12532 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 12533 12534 // For use in libraries implementing .is() 12535 // We use this for POS matching in `select` 12536 "needsContext": new RegExp( "^" + whitespace + 12537 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 12538 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 12539 }, 12540 12541 rhtml = /HTML$/i, 12542 rinputs = /^(?:input|select|textarea|button)$/i, 12543 rheader = /^h\d$/i, 12544 12545 rnative = /^[^{]+\{\s*\[native \w/, 12546 12547 // Easily-parseable/retrievable ID or TAG or CLASS selectors 12548 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 12549 12550 rsibling = /[+~]/, 12551 12552 // CSS escapes 12553 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 12554 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), 12555 funescape = function( escape, nonHex ) { 12556 var high = "0x" + escape.slice( 1 ) - 0x10000; 12557 12558 return nonHex ? 12559 12560 // Strip the backslash prefix from a non-hex escape sequence 12561 nonHex : 12562 12563 // Replace a hexadecimal escape sequence with the encoded Unicode code point 12564 // Support: IE <=11+ 12565 // For values outside the Basic Multilingual Plane (BMP), manually construct a 12566 // surrogate pair 12567 high < 0 ? 12568 String.fromCharCode( high + 0x10000 ) : 12569 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 12570 }, 12571 12572 // CSS string/identifier serialization 12573 // https://drafts.csswg.org/cssom/#common-serializing-idioms 12574 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 12575 fcssescape = function( ch, asCodePoint ) { 12576 if ( asCodePoint ) { 12577 12578 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 12579 if ( ch === "\0" ) { 12580 return "\uFFFD"; 12581 } 12582 12583 // Control characters and (dependent upon position) numbers get escaped as code points 12584 return ch.slice( 0, -1 ) + "\\" + 12585 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 12586 } 12587 12588 // Other potentially-special ASCII characters get backslash-escaped 12589 return "\\" + ch; 12590 }, 12591 12592 // Used for iframes 12593 // See setDocument() 12594 // Removing the function wrapper causes a "Permission Denied" 12595 // error in IE 12596 unloadHandler = function() { 12597 setDocument(); 12598 }, 12599 12600 inDisabledFieldset = addCombinator( 12601 function( elem ) { 12602 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 12603 }, 12604 { dir: "parentNode", next: "legend" } 12605 ); 12606 12607// Optimize for push.apply( _, NodeList ) 12608try { 12609 push.apply( 12610 ( arr = slice.call( preferredDoc.childNodes ) ), 12611 preferredDoc.childNodes 12612 ); 12613 12614 // Support: Android<4.0 12615 // Detect silently failing push.apply 12616 // eslint-disable-next-line no-unused-expressions 12617 arr[ preferredDoc.childNodes.length ].nodeType; 12618} catch ( e ) { 12619 push = { apply: arr.length ? 12620 12621 // Leverage slice if possible 12622 function( target, els ) { 12623 pushNative.apply( target, slice.call( els ) ); 12624 } : 12625 12626 // Support: IE<9 12627 // Otherwise append directly 12628 function( target, els ) { 12629 var j = target.length, 12630 i = 0; 12631 12632 // Can't trust NodeList.length 12633 while ( ( target[ j++ ] = els[ i++ ] ) ) {} 12634 target.length = j - 1; 12635 } 12636 }; 12637} 12638 12639function Sizzle( selector, context, results, seed ) { 12640 var m, i, elem, nid, match, groups, newSelector, 12641 newContext = context && context.ownerDocument, 12642 12643 // nodeType defaults to 9, since context defaults to document 12644 nodeType = context ? context.nodeType : 9; 12645 12646 results = results || []; 12647 12648 // Return early from calls with invalid selector or context 12649 if ( typeof selector !== "string" || !selector || 12650 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 12651 12652 return results; 12653 } 12654 12655 // Try to shortcut find operations (as opposed to filters) in HTML documents 12656 if ( !seed ) { 12657 setDocument( context ); 12658 context = context || document; 12659 12660 if ( documentIsHTML ) { 12661 12662 // If the selector is sufficiently simple, try using a "get*By*" DOM method 12663 // (excepting DocumentFragment context, where the methods don't exist) 12664 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 12665 12666 // ID selector 12667 if ( ( m = match[ 1 ] ) ) { 12668 12669 // Document context 12670 if ( nodeType === 9 ) { 12671 if ( ( elem = context.getElementById( m ) ) ) { 12672 12673 // Support: IE, Opera, Webkit 12674 // TODO: identify versions 12675 // getElementById can match elements by name instead of ID 12676 if ( elem.id === m ) { 12677 results.push( elem ); 12678 return results; 12679 } 12680 } else { 12681 return results; 12682 } 12683 12684 // Element context 12685 } else { 12686 12687 // Support: IE, Opera, Webkit 12688 // TODO: identify versions 12689 // getElementById can match elements by name instead of ID 12690 if ( newContext && ( elem = newContext.getElementById( m ) ) && 12691 contains( context, elem ) && 12692 elem.id === m ) { 12693 12694 results.push( elem ); 12695 return results; 12696 } 12697 } 12698 12699 // Type selector 12700 } else if ( match[ 2 ] ) { 12701 push.apply( results, context.getElementsByTagName( selector ) ); 12702 return results; 12703 12704 // Class selector 12705 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && 12706 context.getElementsByClassName ) { 12707 12708 push.apply( results, context.getElementsByClassName( m ) ); 12709 return results; 12710 } 12711 } 12712 12713 // Take advantage of querySelectorAll 12714 if ( support.qsa && 12715 !nonnativeSelectorCache[ selector + " " ] && 12716 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && 12717 12718 // Support: IE 8 only 12719 // Exclude object elements 12720 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { 12721 12722 newSelector = selector; 12723 newContext = context; 12724 12725 // qSA considers elements outside a scoping root when evaluating child or 12726 // descendant combinators, which is not what we want. 12727 // In such cases, we work around the behavior by prefixing every selector in the 12728 // list with an ID selector referencing the scope context. 12729 // The technique has to be used as well when a leading combinator is used 12730 // as such selectors are not recognized by querySelectorAll. 12731 // Thanks to Andrew Dupont for this technique. 12732 if ( nodeType === 1 && 12733 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { 12734 12735 // Expand context for sibling selectors 12736 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 12737 context; 12738 12739 // We can use :scope instead of the ID hack if the browser 12740 // supports it & if we're not changing the context. 12741 if ( newContext !== context || !support.scope ) { 12742 12743 // Capture the context ID, setting it first if necessary 12744 if ( ( nid = context.getAttribute( "id" ) ) ) { 12745 nid = nid.replace( rcssescape, fcssescape ); 12746 } else { 12747 context.setAttribute( "id", ( nid = expando ) ); 12748 } 12749 } 12750 12751 // Prefix every selector in the list 12752 groups = tokenize( selector ); 12753 i = groups.length; 12754 while ( i-- ) { 12755 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 12756 toSelector( groups[ i ] ); 12757 } 12758 newSelector = groups.join( "," ); 12759 } 12760 12761 try { 12762 push.apply( results, 12763 newContext.querySelectorAll( newSelector ) 12764 ); 12765 return results; 12766 } catch ( qsaError ) { 12767 nonnativeSelectorCache( selector, true ); 12768 } finally { 12769 if ( nid === expando ) { 12770 context.removeAttribute( "id" ); 12771 } 12772 } 12773 } 12774 } 12775 } 12776 12777 // All others 12778 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 12779} 12780 12781/** 12782 * Create key-value caches of limited size 12783 * @returns {function(string, object)} Returns the Object data after storing it on itself with 12784 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 12785 * deleting the oldest entry 12786 */ 12787function createCache() { 12788 var keys = []; 12789 12790 function cache( key, value ) { 12791 12792 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 12793 if ( keys.push( key + " " ) > Expr.cacheLength ) { 12794 12795 // Only keep the most recent entries 12796 delete cache[ keys.shift() ]; 12797 } 12798 return ( cache[ key + " " ] = value ); 12799 } 12800 return cache; 12801} 12802 12803/** 12804 * Mark a function for special use by Sizzle 12805 * @param {Function} fn The function to mark 12806 */ 12807function markFunction( fn ) { 12808 fn[ expando ] = true; 12809 return fn; 12810} 12811 12812/** 12813 * Support testing using an element 12814 * @param {Function} fn Passed the created element and returns a boolean result 12815 */ 12816function assert( fn ) { 12817 var el = document.createElement( "fieldset" ); 12818 12819 try { 12820 return !!fn( el ); 12821 } catch ( e ) { 12822 return false; 12823 } finally { 12824 12825 // Remove from its parent by default 12826 if ( el.parentNode ) { 12827 el.parentNode.removeChild( el ); 12828 } 12829 12830 // release memory in IE 12831 el = null; 12832 } 12833} 12834 12835/** 12836 * Adds the same handler for all of the specified attrs 12837 * @param {String} attrs Pipe-separated list of attributes 12838 * @param {Function} handler The method that will be applied 12839 */ 12840function addHandle( attrs, handler ) { 12841 var arr = attrs.split( "|" ), 12842 i = arr.length; 12843 12844 while ( i-- ) { 12845 Expr.attrHandle[ arr[ i ] ] = handler; 12846 } 12847} 12848 12849/** 12850 * Checks document order of two siblings 12851 * @param {Element} a 12852 * @param {Element} b 12853 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 12854 */ 12855function siblingCheck( a, b ) { 12856 var cur = b && a, 12857 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 12858 a.sourceIndex - b.sourceIndex; 12859 12860 // Use IE sourceIndex if available on both nodes 12861 if ( diff ) { 12862 return diff; 12863 } 12864 12865 // Check if b follows a 12866 if ( cur ) { 12867 while ( ( cur = cur.nextSibling ) ) { 12868 if ( cur === b ) { 12869 return -1; 12870 } 12871 } 12872 } 12873 12874 return a ? 1 : -1; 12875} 12876 12877/** 12878 * Returns a function to use in pseudos for input types 12879 * @param {String} type 12880 */ 12881function createInputPseudo( type ) { 12882 return function( elem ) { 12883 var name = elem.nodeName.toLowerCase(); 12884 return name === "input" && elem.type === type; 12885 }; 12886} 12887 12888/** 12889 * Returns a function to use in pseudos for buttons 12890 * @param {String} type 12891 */ 12892function createButtonPseudo( type ) { 12893 return function( elem ) { 12894 var name = elem.nodeName.toLowerCase(); 12895 return ( name === "input" || name === "button" ) && elem.type === type; 12896 }; 12897} 12898 12899/** 12900 * Returns a function to use in pseudos for :enabled/:disabled 12901 * @param {Boolean} disabled true for :disabled; false for :enabled 12902 */ 12903function createDisabledPseudo( disabled ) { 12904 12905 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 12906 return function( elem ) { 12907 12908 // Only certain elements can match :enabled or :disabled 12909 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 12910 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 12911 if ( "form" in elem ) { 12912 12913 // Check for inherited disabledness on relevant non-disabled elements: 12914 // * listed form-associated elements in a disabled fieldset 12915 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 12916 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 12917 // * option elements in a disabled optgroup 12918 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 12919 // All such elements have a "form" property. 12920 if ( elem.parentNode && elem.disabled === false ) { 12921 12922 // Option elements defer to a parent optgroup if present 12923 if ( "label" in elem ) { 12924 if ( "label" in elem.parentNode ) { 12925 return elem.parentNode.disabled === disabled; 12926 } else { 12927 return elem.disabled === disabled; 12928 } 12929 } 12930 12931 // Support: IE 6 - 11 12932 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 12933 return elem.isDisabled === disabled || 12934 12935 // Where there is no isDisabled, check manually 12936 /* jshint -W018 */ 12937 elem.isDisabled !== !disabled && 12938 inDisabledFieldset( elem ) === disabled; 12939 } 12940 12941 return elem.disabled === disabled; 12942 12943 // Try to winnow out elements that can't be disabled before trusting the disabled property. 12944 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 12945 // even exist on them, let alone have a boolean value. 12946 } else if ( "label" in elem ) { 12947 return elem.disabled === disabled; 12948 } 12949 12950 // Remaining elements are neither :enabled nor :disabled 12951 return false; 12952 }; 12953} 12954 12955/** 12956 * Returns a function to use in pseudos for positionals 12957 * @param {Function} fn 12958 */ 12959function createPositionalPseudo( fn ) { 12960 return markFunction( function( argument ) { 12961 argument = +argument; 12962 return markFunction( function( seed, matches ) { 12963 var j, 12964 matchIndexes = fn( [], seed.length, argument ), 12965 i = matchIndexes.length; 12966 12967 // Match elements found at the specified indexes 12968 while ( i-- ) { 12969 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 12970 seed[ j ] = !( matches[ j ] = seed[ j ] ); 12971 } 12972 } 12973 } ); 12974 } ); 12975} 12976 12977/** 12978 * Checks a node for validity as a Sizzle context 12979 * @param {Element|Object=} context 12980 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 12981 */ 12982function testContext( context ) { 12983 return context && typeof context.getElementsByTagName !== "undefined" && context; 12984} 12985 12986// Expose support vars for convenience 12987support = Sizzle.support = {}; 12988 12989/** 12990 * Detects XML nodes 12991 * @param {Element|Object} elem An element or a document 12992 * @returns {Boolean} True iff elem is a non-HTML XML node 12993 */ 12994isXML = Sizzle.isXML = function( elem ) { 12995 var namespace = elem && elem.namespaceURI, 12996 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 12997 12998 // Support: IE <=8 12999 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 13000 // https://bugs.jquery.com/ticket/4833 13001 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 13002}; 13003 13004/** 13005 * Sets document-related variables once based on the current document 13006 * @param {Element|Object} [doc] An element or document object to use to set the document 13007 * @returns {Object} Returns the current document 13008 */ 13009setDocument = Sizzle.setDocument = function( node ) { 13010 var hasCompare, subWindow, 13011 doc = node ? node.ownerDocument || node : preferredDoc; 13012 13013 // Return early if doc is invalid or already selected 13014 // Support: IE 11+, Edge 17 - 18+ 13015 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13016 // two documents; shallow comparisons work. 13017 // eslint-disable-next-line eqeqeq 13018 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 13019 return document; 13020 } 13021 13022 // Update global variables 13023 document = doc; 13024 docElem = document.documentElement; 13025 documentIsHTML = !isXML( document ); 13026 13027 // Support: IE 9 - 11+, Edge 12 - 18+ 13028 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 13029 // Support: IE 11+, Edge 17 - 18+ 13030 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13031 // two documents; shallow comparisons work. 13032 // eslint-disable-next-line eqeqeq 13033 if ( preferredDoc != document && 13034 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 13035 13036 // Support: IE 11, Edge 13037 if ( subWindow.addEventListener ) { 13038 subWindow.addEventListener( "unload", unloadHandler, false ); 13039 13040 // Support: IE 9 - 10 only 13041 } else if ( subWindow.attachEvent ) { 13042 subWindow.attachEvent( "onunload", unloadHandler ); 13043 } 13044 } 13045 13046 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, 13047 // Safari 4 - 5 only, Opera <=11.6 - 12.x only 13048 // IE/Edge & older browsers don't support the :scope pseudo-class. 13049 // Support: Safari 6.0 only 13050 // Safari 6.0 supports :scope but it's an alias of :root there. 13051 support.scope = assert( function( el ) { 13052 docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); 13053 return typeof el.querySelectorAll !== "undefined" && 13054 !el.querySelectorAll( ":scope fieldset div" ).length; 13055 } ); 13056 13057 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 13058 // Make sure the the `:has()` argument is parsed unforgivingly. 13059 // We include `*` in the test to detect buggy implementations that are 13060 // _selectively_ forgiving (specifically when the list includes at least 13061 // one valid selector). 13062 // Note that we treat complete lack of support for `:has()` as if it were 13063 // spec-compliant support, which is fine because use of `:has()` in such 13064 // environments will fail in the qSA path and fall back to jQuery traversal 13065 // anyway. 13066 support.cssHas = assert( function() { 13067 try { 13068 document.querySelector( ":has(*,:jqfake)" ); 13069 return false; 13070 } catch ( e ) { 13071 return true; 13072 } 13073 } ); 13074 13075 /* Attributes 13076 ---------------------------------------------------------------------- */ 13077 13078 // Support: IE<8 13079 // Verify that getAttribute really returns attributes and not properties 13080 // (excepting IE8 booleans) 13081 support.attributes = assert( function( el ) { 13082 el.className = "i"; 13083 return !el.getAttribute( "className" ); 13084 } ); 13085 13086 /* getElement(s)By* 13087 ---------------------------------------------------------------------- */ 13088 13089 // Check if getElementsByTagName("*") returns only elements 13090 support.getElementsByTagName = assert( function( el ) { 13091 el.appendChild( document.createComment( "" ) ); 13092 return !el.getElementsByTagName( "*" ).length; 13093 } ); 13094 13095 // Support: IE<9 13096 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 13097 13098 // Support: IE<10 13099 // Check if getElementById returns elements by name 13100 // The broken getElementById methods don't pick up programmatically-set names, 13101 // so use a roundabout getElementsByName test 13102 support.getById = assert( function( el ) { 13103 docElem.appendChild( el ).id = expando; 13104 return !document.getElementsByName || !document.getElementsByName( expando ).length; 13105 } ); 13106 13107 // ID filter and find 13108 if ( support.getById ) { 13109 Expr.filter[ "ID" ] = function( id ) { 13110 var attrId = id.replace( runescape, funescape ); 13111 return function( elem ) { 13112 return elem.getAttribute( "id" ) === attrId; 13113 }; 13114 }; 13115 Expr.find[ "ID" ] = function( id, context ) { 13116 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 13117 var elem = context.getElementById( id ); 13118 return elem ? [ elem ] : []; 13119 } 13120 }; 13121 } else { 13122 Expr.filter[ "ID" ] = function( id ) { 13123 var attrId = id.replace( runescape, funescape ); 13124 return function( elem ) { 13125 var node = typeof elem.getAttributeNode !== "undefined" && 13126 elem.getAttributeNode( "id" ); 13127 return node && node.value === attrId; 13128 }; 13129 }; 13130 13131 // Support: IE 6 - 7 only 13132 // getElementById is not reliable as a find shortcut 13133 Expr.find[ "ID" ] = function( id, context ) { 13134 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 13135 var node, i, elems, 13136 elem = context.getElementById( id ); 13137 13138 if ( elem ) { 13139 13140 // Verify the id attribute 13141 node = elem.getAttributeNode( "id" ); 13142 if ( node && node.value === id ) { 13143 return [ elem ]; 13144 } 13145 13146 // Fall back on getElementsByName 13147 elems = context.getElementsByName( id ); 13148 i = 0; 13149 while ( ( elem = elems[ i++ ] ) ) { 13150 node = elem.getAttributeNode( "id" ); 13151 if ( node && node.value === id ) { 13152 return [ elem ]; 13153 } 13154 } 13155 } 13156 13157 return []; 13158 } 13159 }; 13160 } 13161 13162 // Tag 13163 Expr.find[ "TAG" ] = support.getElementsByTagName ? 13164 function( tag, context ) { 13165 if ( typeof context.getElementsByTagName !== "undefined" ) { 13166 return context.getElementsByTagName( tag ); 13167 13168 // DocumentFragment nodes don't have gEBTN 13169 } else if ( support.qsa ) { 13170 return context.querySelectorAll( tag ); 13171 } 13172 } : 13173 13174 function( tag, context ) { 13175 var elem, 13176 tmp = [], 13177 i = 0, 13178 13179 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 13180 results = context.getElementsByTagName( tag ); 13181 13182 // Filter out possible comments 13183 if ( tag === "*" ) { 13184 while ( ( elem = results[ i++ ] ) ) { 13185 if ( elem.nodeType === 1 ) { 13186 tmp.push( elem ); 13187 } 13188 } 13189 13190 return tmp; 13191 } 13192 return results; 13193 }; 13194 13195 // Class 13196 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { 13197 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 13198 return context.getElementsByClassName( className ); 13199 } 13200 }; 13201 13202 /* QSA/matchesSelector 13203 ---------------------------------------------------------------------- */ 13204 13205 // QSA and matchesSelector support 13206 13207 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 13208 rbuggyMatches = []; 13209 13210 // qSa(:focus) reports false when true (Chrome 21) 13211 // We allow this because of a bug in IE8/9 that throws an error 13212 // whenever `document.activeElement` is accessed on an iframe 13213 // So, we allow :focus to pass through QSA all the time to avoid the IE error 13214 // See https://bugs.jquery.com/ticket/13378 13215 rbuggyQSA = []; 13216 13217 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { 13218 13219 // Build QSA regex 13220 // Regex strategy adopted from Diego Perini 13221 assert( function( el ) { 13222 13223 var input; 13224 13225 // Select is set to empty string on purpose 13226 // This is to test IE's treatment of not explicitly 13227 // setting a boolean content attribute, 13228 // since its presence should be enough 13229 // https://bugs.jquery.com/ticket/12359 13230 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 13231 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 13232 "<option selected=''></option></select>"; 13233 13234 // Support: IE8, Opera 11-12.16 13235 // Nothing should be selected when empty strings follow ^= or $= or *= 13236 // The test attribute must be unknown in Opera but "safe" for WinRT 13237 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 13238 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { 13239 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 13240 } 13241 13242 // Support: IE8 13243 // Boolean attributes and "value" are not treated correctly 13244 if ( !el.querySelectorAll( "[selected]" ).length ) { 13245 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 13246 } 13247 13248 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 13249 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 13250 rbuggyQSA.push( "~=" ); 13251 } 13252 13253 // Support: IE 11+, Edge 15 - 18+ 13254 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 13255 // Adding a temporary attribute to the document before the selection works 13256 // around the issue. 13257 // Interestingly, IE 10 & older don't seem to have the issue. 13258 input = document.createElement( "input" ); 13259 input.setAttribute( "name", "" ); 13260 el.appendChild( input ); 13261 if ( !el.querySelectorAll( "[name='']" ).length ) { 13262 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 13263 whitespace + "*(?:''|\"\")" ); 13264 } 13265 13266 // Webkit/Opera - :checked should return selected option elements 13267 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 13268 // IE8 throws error here and will not see later tests 13269 if ( !el.querySelectorAll( ":checked" ).length ) { 13270 rbuggyQSA.push( ":checked" ); 13271 } 13272 13273 // Support: Safari 8+, iOS 8+ 13274 // https://bugs.webkit.org/show_bug.cgi?id=136851 13275 // In-page `selector#id sibling-combinator selector` fails 13276 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 13277 rbuggyQSA.push( ".#.+[+~]" ); 13278 } 13279 13280 // Support: Firefox <=3.6 - 5 only 13281 // Old Firefox doesn't throw on a badly-escaped identifier. 13282 el.querySelectorAll( "\\\f" ); 13283 rbuggyQSA.push( "[\\r\\n\\f]" ); 13284 } ); 13285 13286 assert( function( el ) { 13287 el.innerHTML = "<a href='' disabled='disabled'></a>" + 13288 "<select disabled='disabled'><option/></select>"; 13289 13290 // Support: Windows 8 Native Apps 13291 // The type and name attributes are restricted during .innerHTML assignment 13292 var input = document.createElement( "input" ); 13293 input.setAttribute( "type", "hidden" ); 13294 el.appendChild( input ).setAttribute( "name", "D" ); 13295 13296 // Support: IE8 13297 // Enforce case-sensitivity of name attribute 13298 if ( el.querySelectorAll( "[name=d]" ).length ) { 13299 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 13300 } 13301 13302 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 13303 // IE8 throws error here and will not see later tests 13304 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { 13305 rbuggyQSA.push( ":enabled", ":disabled" ); 13306 } 13307 13308 // Support: IE9-11+ 13309 // IE's :disabled selector does not pick up the children of disabled fieldsets 13310 docElem.appendChild( el ).disabled = true; 13311 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 13312 rbuggyQSA.push( ":enabled", ":disabled" ); 13313 } 13314 13315 // Support: Opera 10 - 11 only 13316 // Opera 10-11 does not throw on post-comma invalid pseudos 13317 el.querySelectorAll( "*,:x" ); 13318 rbuggyQSA.push( ",.*:" ); 13319 } ); 13320 } 13321 13322 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || 13323 docElem.webkitMatchesSelector || 13324 docElem.mozMatchesSelector || 13325 docElem.oMatchesSelector || 13326 docElem.msMatchesSelector ) ) ) ) { 13327 13328 assert( function( el ) { 13329 13330 // Check to see if it's possible to do matchesSelector 13331 // on a disconnected node (IE 9) 13332 support.disconnectedMatch = matches.call( el, "*" ); 13333 13334 // This should fail with an exception 13335 // Gecko does not error, returns false instead 13336 matches.call( el, "[s!='']:x" ); 13337 rbuggyMatches.push( "!=", pseudos ); 13338 } ); 13339 } 13340 13341 if ( !support.cssHas ) { 13342 13343 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 13344 // Our regular `try-catch` mechanism fails to detect natively-unsupported 13345 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 13346 // in browsers that parse the `:has()` argument as a forgiving selector list. 13347 // https://drafts.csswg.org/selectors/#relational now requires the argument 13348 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 13349 rbuggyQSA.push( ":has" ); 13350 } 13351 13352 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 13353 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); 13354 13355 /* Contains 13356 ---------------------------------------------------------------------- */ 13357 hasCompare = rnative.test( docElem.compareDocumentPosition ); 13358 13359 // Element contains another 13360 // Purposefully self-exclusive 13361 // As in, an element does not contain itself 13362 contains = hasCompare || rnative.test( docElem.contains ) ? 13363 function( a, b ) { 13364 13365 // Support: IE <9 only 13366 // IE doesn't have `contains` on `document` so we need to check for 13367 // `documentElement` presence. 13368 // We need to fall back to `a` when `documentElement` is missing 13369 // as `ownerDocument` of elements within `<template/>` may have 13370 // a null one - a default behavior of all modern browsers. 13371 var adown = a.nodeType === 9 && a.documentElement || a, 13372 bup = b && b.parentNode; 13373 return a === bup || !!( bup && bup.nodeType === 1 && ( 13374 adown.contains ? 13375 adown.contains( bup ) : 13376 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 13377 ) ); 13378 } : 13379 function( a, b ) { 13380 if ( b ) { 13381 while ( ( b = b.parentNode ) ) { 13382 if ( b === a ) { 13383 return true; 13384 } 13385 } 13386 } 13387 return false; 13388 }; 13389 13390 /* Sorting 13391 ---------------------------------------------------------------------- */ 13392 13393 // Document order sorting 13394 sortOrder = hasCompare ? 13395 function( a, b ) { 13396 13397 // Flag for duplicate removal 13398 if ( a === b ) { 13399 hasDuplicate = true; 13400 return 0; 13401 } 13402 13403 // Sort on method existence if only one input has compareDocumentPosition 13404 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 13405 if ( compare ) { 13406 return compare; 13407 } 13408 13409 // Calculate position if both inputs belong to the same document 13410 // Support: IE 11+, Edge 17 - 18+ 13411 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13412 // two documents; shallow comparisons work. 13413 // eslint-disable-next-line eqeqeq 13414 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 13415 a.compareDocumentPosition( b ) : 13416 13417 // Otherwise we know they are disconnected 13418 1; 13419 13420 // Disconnected nodes 13421 if ( compare & 1 || 13422 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 13423 13424 // Choose the first element that is related to our preferred document 13425 // Support: IE 11+, Edge 17 - 18+ 13426 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13427 // two documents; shallow comparisons work. 13428 // eslint-disable-next-line eqeqeq 13429 if ( a == document || a.ownerDocument == preferredDoc && 13430 contains( preferredDoc, a ) ) { 13431 return -1; 13432 } 13433 13434 // Support: IE 11+, Edge 17 - 18+ 13435 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13436 // two documents; shallow comparisons work. 13437 // eslint-disable-next-line eqeqeq 13438 if ( b == document || b.ownerDocument == preferredDoc && 13439 contains( preferredDoc, b ) ) { 13440 return 1; 13441 } 13442 13443 // Maintain original order 13444 return sortInput ? 13445 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 13446 0; 13447 } 13448 13449 return compare & 4 ? -1 : 1; 13450 } : 13451 function( a, b ) { 13452 13453 // Exit early if the nodes are identical 13454 if ( a === b ) { 13455 hasDuplicate = true; 13456 return 0; 13457 } 13458 13459 var cur, 13460 i = 0, 13461 aup = a.parentNode, 13462 bup = b.parentNode, 13463 ap = [ a ], 13464 bp = [ b ]; 13465 13466 // Parentless nodes are either documents or disconnected 13467 if ( !aup || !bup ) { 13468 13469 // Support: IE 11+, Edge 17 - 18+ 13470 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13471 // two documents; shallow comparisons work. 13472 /* eslint-disable eqeqeq */ 13473 return a == document ? -1 : 13474 b == document ? 1 : 13475 /* eslint-enable eqeqeq */ 13476 aup ? -1 : 13477 bup ? 1 : 13478 sortInput ? 13479 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 13480 0; 13481 13482 // If the nodes are siblings, we can do a quick check 13483 } else if ( aup === bup ) { 13484 return siblingCheck( a, b ); 13485 } 13486 13487 // Otherwise we need full lists of their ancestors for comparison 13488 cur = a; 13489 while ( ( cur = cur.parentNode ) ) { 13490 ap.unshift( cur ); 13491 } 13492 cur = b; 13493 while ( ( cur = cur.parentNode ) ) { 13494 bp.unshift( cur ); 13495 } 13496 13497 // Walk down the tree looking for a discrepancy 13498 while ( ap[ i ] === bp[ i ] ) { 13499 i++; 13500 } 13501 13502 return i ? 13503 13504 // Do a sibling check if the nodes have a common ancestor 13505 siblingCheck( ap[ i ], bp[ i ] ) : 13506 13507 // Otherwise nodes in our document sort first 13508 // Support: IE 11+, Edge 17 - 18+ 13509 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13510 // two documents; shallow comparisons work. 13511 /* eslint-disable eqeqeq */ 13512 ap[ i ] == preferredDoc ? -1 : 13513 bp[ i ] == preferredDoc ? 1 : 13514 /* eslint-enable eqeqeq */ 13515 0; 13516 }; 13517 13518 return document; 13519}; 13520 13521Sizzle.matches = function( expr, elements ) { 13522 return Sizzle( expr, null, null, elements ); 13523}; 13524 13525Sizzle.matchesSelector = function( elem, expr ) { 13526 setDocument( elem ); 13527 13528 if ( support.matchesSelector && documentIsHTML && 13529 !nonnativeSelectorCache[ expr + " " ] && 13530 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 13531 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 13532 13533 try { 13534 var ret = matches.call( elem, expr ); 13535 13536 // IE 9's matchesSelector returns false on disconnected nodes 13537 if ( ret || support.disconnectedMatch || 13538 13539 // As well, disconnected nodes are said to be in a document 13540 // fragment in IE 9 13541 elem.document && elem.document.nodeType !== 11 ) { 13542 return ret; 13543 } 13544 } catch ( e ) { 13545 nonnativeSelectorCache( expr, true ); 13546 } 13547 } 13548 13549 return Sizzle( expr, document, null, [ elem ] ).length > 0; 13550}; 13551 13552Sizzle.contains = function( context, elem ) { 13553 13554 // Set document vars if needed 13555 // Support: IE 11+, Edge 17 - 18+ 13556 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13557 // two documents; shallow comparisons work. 13558 // eslint-disable-next-line eqeqeq 13559 if ( ( context.ownerDocument || context ) != document ) { 13560 setDocument( context ); 13561 } 13562 return contains( context, elem ); 13563}; 13564 13565Sizzle.attr = function( elem, name ) { 13566 13567 // Set document vars if needed 13568 // Support: IE 11+, Edge 17 - 18+ 13569 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 13570 // two documents; shallow comparisons work. 13571 // eslint-disable-next-line eqeqeq 13572 if ( ( elem.ownerDocument || elem ) != document ) { 13573 setDocument( elem ); 13574 } 13575 13576 var fn = Expr.attrHandle[ name.toLowerCase() ], 13577 13578 // Don't get fooled by Object.prototype properties (jQuery #13807) 13579 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 13580 fn( elem, name, !documentIsHTML ) : 13581 undefined; 13582 13583 return val !== undefined ? 13584 val : 13585 support.attributes || !documentIsHTML ? 13586 elem.getAttribute( name ) : 13587 ( val = elem.getAttributeNode( name ) ) && val.specified ? 13588 val.value : 13589 null; 13590}; 13591 13592Sizzle.escape = function( sel ) { 13593 return ( sel + "" ).replace( rcssescape, fcssescape ); 13594}; 13595 13596Sizzle.error = function( msg ) { 13597 throw new Error( "Syntax error, unrecognized expression: " + msg ); 13598}; 13599 13600/** 13601 * Document sorting and removing duplicates 13602 * @param {ArrayLike} results 13603 */ 13604Sizzle.uniqueSort = function( results ) { 13605 var elem, 13606 duplicates = [], 13607 j = 0, 13608 i = 0; 13609 13610 // Unless we *know* we can detect duplicates, assume their presence 13611 hasDuplicate = !support.detectDuplicates; 13612 sortInput = !support.sortStable && results.slice( 0 ); 13613 results.sort( sortOrder ); 13614 13615 if ( hasDuplicate ) { 13616 while ( ( elem = results[ i++ ] ) ) { 13617 if ( elem === results[ i ] ) { 13618 j = duplicates.push( i ); 13619 } 13620 } 13621 while ( j-- ) { 13622 results.splice( duplicates[ j ], 1 ); 13623 } 13624 } 13625 13626 // Clear input after sorting to release objects 13627 // See https://github.com/jquery/sizzle/pull/225 13628 sortInput = null; 13629 13630 return results; 13631}; 13632 13633/** 13634 * Utility function for retrieving the text value of an array of DOM nodes 13635 * @param {Array|Element} elem 13636 */ 13637getText = Sizzle.getText = function( elem ) { 13638 var node, 13639 ret = "", 13640 i = 0, 13641 nodeType = elem.nodeType; 13642 13643 if ( !nodeType ) { 13644 13645 // If no nodeType, this is expected to be an array 13646 while ( ( node = elem[ i++ ] ) ) { 13647 13648 // Do not traverse comment nodes 13649 ret += getText( node ); 13650 } 13651 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 13652 13653 // Use textContent for elements 13654 // innerText usage removed for consistency of new lines (jQuery #11153) 13655 if ( typeof elem.textContent === "string" ) { 13656 return elem.textContent; 13657 } else { 13658 13659 // Traverse its children 13660 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 13661 ret += getText( elem ); 13662 } 13663 } 13664 } else if ( nodeType === 3 || nodeType === 4 ) { 13665 return elem.nodeValue; 13666 } 13667 13668 // Do not include comment or processing instruction nodes 13669 13670 return ret; 13671}; 13672 13673Expr = Sizzle.selectors = { 13674 13675 // Can be adjusted by the user 13676 cacheLength: 50, 13677 13678 createPseudo: markFunction, 13679 13680 match: matchExpr, 13681 13682 attrHandle: {}, 13683 13684 find: {}, 13685 13686 relative: { 13687 ">": { dir: "parentNode", first: true }, 13688 " ": { dir: "parentNode" }, 13689 "+": { dir: "previousSibling", first: true }, 13690 "~": { dir: "previousSibling" } 13691 }, 13692 13693 preFilter: { 13694 "ATTR": function( match ) { 13695 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 13696 13697 // Move the given value to match[3] whether quoted or unquoted 13698 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || 13699 match[ 5 ] || "" ).replace( runescape, funescape ); 13700 13701 if ( match[ 2 ] === "~=" ) { 13702 match[ 3 ] = " " + match[ 3 ] + " "; 13703 } 13704 13705 return match.slice( 0, 4 ); 13706 }, 13707 13708 "CHILD": function( match ) { 13709 13710 /* matches from matchExpr["CHILD"] 13711 1 type (only|nth|...) 13712 2 what (child|of-type) 13713 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 13714 4 xn-component of xn+y argument ([+-]?\d*n|) 13715 5 sign of xn-component 13716 6 x of xn-component 13717 7 sign of y-component 13718 8 y of y-component 13719 */ 13720 match[ 1 ] = match[ 1 ].toLowerCase(); 13721 13722 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 13723 13724 // nth-* requires argument 13725 if ( !match[ 3 ] ) { 13726 Sizzle.error( match[ 0 ] ); 13727 } 13728 13729 // numeric x and y parameters for Expr.filter.CHILD 13730 // remember that false/true cast respectively to 0/1 13731 match[ 4 ] = +( match[ 4 ] ? 13732 match[ 5 ] + ( match[ 6 ] || 1 ) : 13733 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); 13734 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 13735 13736 // other types prohibit arguments 13737 } else if ( match[ 3 ] ) { 13738 Sizzle.error( match[ 0 ] ); 13739 } 13740 13741 return match; 13742 }, 13743 13744 "PSEUDO": function( match ) { 13745 var excess, 13746 unquoted = !match[ 6 ] && match[ 2 ]; 13747 13748 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { 13749 return null; 13750 } 13751 13752 // Accept quoted arguments as-is 13753 if ( match[ 3 ] ) { 13754 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 13755 13756 // Strip excess characters from unquoted arguments 13757 } else if ( unquoted && rpseudo.test( unquoted ) && 13758 13759 // Get excess from tokenize (recursively) 13760 ( excess = tokenize( unquoted, true ) ) && 13761 13762 // advance to the next closing parenthesis 13763 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 13764 13765 // excess is a negative index 13766 match[ 0 ] = match[ 0 ].slice( 0, excess ); 13767 match[ 2 ] = unquoted.slice( 0, excess ); 13768 } 13769 13770 // Return only captures needed by the pseudo filter method (type and argument) 13771 return match.slice( 0, 3 ); 13772 } 13773 }, 13774 13775 filter: { 13776 13777 "TAG": function( nodeNameSelector ) { 13778 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 13779 return nodeNameSelector === "*" ? 13780 function() { 13781 return true; 13782 } : 13783 function( elem ) { 13784 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 13785 }; 13786 }, 13787 13788 "CLASS": function( className ) { 13789 var pattern = classCache[ className + " " ]; 13790 13791 return pattern || 13792 ( pattern = new RegExp( "(^|" + whitespace + 13793 ")" + className + "(" + whitespace + "|$)" ) ) && classCache( 13794 className, function( elem ) { 13795 return pattern.test( 13796 typeof elem.className === "string" && elem.className || 13797 typeof elem.getAttribute !== "undefined" && 13798 elem.getAttribute( "class" ) || 13799 "" 13800 ); 13801 } ); 13802 }, 13803 13804 "ATTR": function( name, operator, check ) { 13805 return function( elem ) { 13806 var result = Sizzle.attr( elem, name ); 13807 13808 if ( result == null ) { 13809 return operator === "!="; 13810 } 13811 if ( !operator ) { 13812 return true; 13813 } 13814 13815 result += ""; 13816 13817 /* eslint-disable max-len */ 13818 13819 return operator === "=" ? result === check : 13820 operator === "!=" ? result !== check : 13821 operator === "^=" ? check && result.indexOf( check ) === 0 : 13822 operator === "*=" ? check && result.indexOf( check ) > -1 : 13823 operator === "$=" ? check && result.slice( -check.length ) === check : 13824 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 13825 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 13826 false; 13827 /* eslint-enable max-len */ 13828 13829 }; 13830 }, 13831 13832 "CHILD": function( type, what, _argument, first, last ) { 13833 var simple = type.slice( 0, 3 ) !== "nth", 13834 forward = type.slice( -4 ) !== "last", 13835 ofType = what === "of-type"; 13836 13837 return first === 1 && last === 0 ? 13838 13839 // Shortcut for :nth-*(n) 13840 function( elem ) { 13841 return !!elem.parentNode; 13842 } : 13843 13844 function( elem, _context, xml ) { 13845 var cache, uniqueCache, outerCache, node, nodeIndex, start, 13846 dir = simple !== forward ? "nextSibling" : "previousSibling", 13847 parent = elem.parentNode, 13848 name = ofType && elem.nodeName.toLowerCase(), 13849 useCache = !xml && !ofType, 13850 diff = false; 13851 13852 if ( parent ) { 13853 13854 // :(first|last|only)-(child|of-type) 13855 if ( simple ) { 13856 while ( dir ) { 13857 node = elem; 13858 while ( ( node = node[ dir ] ) ) { 13859 if ( ofType ? 13860 node.nodeName.toLowerCase() === name : 13861 node.nodeType === 1 ) { 13862 13863 return false; 13864 } 13865 } 13866 13867 // Reverse direction for :only-* (if we haven't yet done so) 13868 start = dir = type === "only" && !start && "nextSibling"; 13869 } 13870 return true; 13871 } 13872 13873 start = [ forward ? parent.firstChild : parent.lastChild ]; 13874 13875 // non-xml :nth-child(...) stores cache data on `parent` 13876 if ( forward && useCache ) { 13877 13878 // Seek `elem` from a previously-cached index 13879 13880 // ...in a gzip-friendly way 13881 node = parent; 13882 outerCache = node[ expando ] || ( node[ expando ] = {} ); 13883 13884 // Support: IE <9 only 13885 // Defend against cloned attroperties (jQuery gh-1709) 13886 uniqueCache = outerCache[ node.uniqueID ] || 13887 ( outerCache[ node.uniqueID ] = {} ); 13888 13889 cache = uniqueCache[ type ] || []; 13890 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 13891 diff = nodeIndex && cache[ 2 ]; 13892 node = nodeIndex && parent.childNodes[ nodeIndex ]; 13893 13894 while ( ( node = ++nodeIndex && node && node[ dir ] || 13895 13896 // Fallback to seeking `elem` from the start 13897 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 13898 13899 // When found, cache indexes on `parent` and break 13900 if ( node.nodeType === 1 && ++diff && node === elem ) { 13901 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 13902 break; 13903 } 13904 } 13905 13906 } else { 13907 13908 // Use previously-cached element index if available 13909 if ( useCache ) { 13910 13911 // ...in a gzip-friendly way 13912 node = elem; 13913 outerCache = node[ expando ] || ( node[ expando ] = {} ); 13914 13915 // Support: IE <9 only 13916 // Defend against cloned attroperties (jQuery gh-1709) 13917 uniqueCache = outerCache[ node.uniqueID ] || 13918 ( outerCache[ node.uniqueID ] = {} ); 13919 13920 cache = uniqueCache[ type ] || []; 13921 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 13922 diff = nodeIndex; 13923 } 13924 13925 // xml :nth-child(...) 13926 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 13927 if ( diff === false ) { 13928 13929 // Use the same loop as above to seek `elem` from the start 13930 while ( ( node = ++nodeIndex && node && node[ dir ] || 13931 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 13932 13933 if ( ( ofType ? 13934 node.nodeName.toLowerCase() === name : 13935 node.nodeType === 1 ) && 13936 ++diff ) { 13937 13938 // Cache the index of each encountered element 13939 if ( useCache ) { 13940 outerCache = node[ expando ] || 13941 ( node[ expando ] = {} ); 13942 13943 // Support: IE <9 only 13944 // Defend against cloned attroperties (jQuery gh-1709) 13945 uniqueCache = outerCache[ node.uniqueID ] || 13946 ( outerCache[ node.uniqueID ] = {} ); 13947 13948 uniqueCache[ type ] = [ dirruns, diff ]; 13949 } 13950 13951 if ( node === elem ) { 13952 break; 13953 } 13954 } 13955 } 13956 } 13957 } 13958 13959 // Incorporate the offset, then check against cycle size 13960 diff -= last; 13961 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 13962 } 13963 }; 13964 }, 13965 13966 "PSEUDO": function( pseudo, argument ) { 13967 13968 // pseudo-class names are case-insensitive 13969 // http://www.w3.org/TR/selectors/#pseudo-classes 13970 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 13971 // Remember that setFilters inherits from pseudos 13972 var args, 13973 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 13974 Sizzle.error( "unsupported pseudo: " + pseudo ); 13975 13976 // The user may use createPseudo to indicate that 13977 // arguments are needed to create the filter function 13978 // just as Sizzle does 13979 if ( fn[ expando ] ) { 13980 return fn( argument ); 13981 } 13982 13983 // But maintain support for old signatures 13984 if ( fn.length > 1 ) { 13985 args = [ pseudo, pseudo, "", argument ]; 13986 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 13987 markFunction( function( seed, matches ) { 13988 var idx, 13989 matched = fn( seed, argument ), 13990 i = matched.length; 13991 while ( i-- ) { 13992 idx = indexOf( seed, matched[ i ] ); 13993 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 13994 } 13995 } ) : 13996 function( elem ) { 13997 return fn( elem, 0, args ); 13998 }; 13999 } 14000 14001 return fn; 14002 } 14003 }, 14004 14005 pseudos: { 14006 14007 // Potentially complex pseudos 14008 "not": markFunction( function( selector ) { 14009 14010 // Trim the selector passed to compile 14011 // to avoid treating leading and trailing 14012 // spaces as combinators 14013 var input = [], 14014 results = [], 14015 matcher = compile( selector.replace( rtrim, "$1" ) ); 14016 14017 return matcher[ expando ] ? 14018 markFunction( function( seed, matches, _context, xml ) { 14019 var elem, 14020 unmatched = matcher( seed, null, xml, [] ), 14021 i = seed.length; 14022 14023 // Match elements unmatched by `matcher` 14024 while ( i-- ) { 14025 if ( ( elem = unmatched[ i ] ) ) { 14026 seed[ i ] = !( matches[ i ] = elem ); 14027 } 14028 } 14029 } ) : 14030 function( elem, _context, xml ) { 14031 input[ 0 ] = elem; 14032 matcher( input, null, xml, results ); 14033 14034 // Don't keep the element (issue #299) 14035 input[ 0 ] = null; 14036 return !results.pop(); 14037 }; 14038 } ), 14039 14040 "has": markFunction( function( selector ) { 14041 return function( elem ) { 14042 return Sizzle( selector, elem ).length > 0; 14043 }; 14044 } ), 14045 14046 "contains": markFunction( function( text ) { 14047 text = text.replace( runescape, funescape ); 14048 return function( elem ) { 14049 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; 14050 }; 14051 } ), 14052 14053 // "Whether an element is represented by a :lang() selector 14054 // is based solely on the element's language value 14055 // being equal to the identifier C, 14056 // or beginning with the identifier C immediately followed by "-". 14057 // The matching of C against the element's language value is performed case-insensitively. 14058 // The identifier C does not have to be a valid language name." 14059 // http://www.w3.org/TR/selectors/#lang-pseudo 14060 "lang": markFunction( function( lang ) { 14061 14062 // lang value must be a valid identifier 14063 if ( !ridentifier.test( lang || "" ) ) { 14064 Sizzle.error( "unsupported lang: " + lang ); 14065 } 14066 lang = lang.replace( runescape, funescape ).toLowerCase(); 14067 return function( elem ) { 14068 var elemLang; 14069 do { 14070 if ( ( elemLang = documentIsHTML ? 14071 elem.lang : 14072 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 14073 14074 elemLang = elemLang.toLowerCase(); 14075 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 14076 } 14077 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 14078 return false; 14079 }; 14080 } ), 14081 14082 // Miscellaneous 14083 "target": function( elem ) { 14084 var hash = window.location && window.location.hash; 14085 return hash && hash.slice( 1 ) === elem.id; 14086 }, 14087 14088 "root": function( elem ) { 14089 return elem === docElem; 14090 }, 14091 14092 "focus": function( elem ) { 14093 return elem === document.activeElement && 14094 ( !document.hasFocus || document.hasFocus() ) && 14095 !!( elem.type || elem.href || ~elem.tabIndex ); 14096 }, 14097 14098 // Boolean properties 14099 "enabled": createDisabledPseudo( false ), 14100 "disabled": createDisabledPseudo( true ), 14101 14102 "checked": function( elem ) { 14103 14104 // In CSS3, :checked should return both checked and selected elements 14105 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 14106 var nodeName = elem.nodeName.toLowerCase(); 14107 return ( nodeName === "input" && !!elem.checked ) || 14108 ( nodeName === "option" && !!elem.selected ); 14109 }, 14110 14111 "selected": function( elem ) { 14112 14113 // Accessing this property makes selected-by-default 14114 // options in Safari work properly 14115 if ( elem.parentNode ) { 14116 // eslint-disable-next-line no-unused-expressions 14117 elem.parentNode.selectedIndex; 14118 } 14119 14120 return elem.selected === true; 14121 }, 14122 14123 // Contents 14124 "empty": function( elem ) { 14125 14126 // http://www.w3.org/TR/selectors/#empty-pseudo 14127 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 14128 // but not by others (comment: 8; processing instruction: 7; etc.) 14129 // nodeType < 6 works because attributes (2) do not appear as children 14130 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 14131 if ( elem.nodeType < 6 ) { 14132 return false; 14133 } 14134 } 14135 return true; 14136 }, 14137 14138 "parent": function( elem ) { 14139 return !Expr.pseudos[ "empty" ]( elem ); 14140 }, 14141 14142 // Element/input types 14143 "header": function( elem ) { 14144 return rheader.test( elem.nodeName ); 14145 }, 14146 14147 "input": function( elem ) { 14148 return rinputs.test( elem.nodeName ); 14149 }, 14150 14151 "button": function( elem ) { 14152 var name = elem.nodeName.toLowerCase(); 14153 return name === "input" && elem.type === "button" || name === "button"; 14154 }, 14155 14156 "text": function( elem ) { 14157 var attr; 14158 return elem.nodeName.toLowerCase() === "input" && 14159 elem.type === "text" && 14160 14161 // Support: IE <10 only 14162 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 14163 ( ( attr = elem.getAttribute( "type" ) ) == null || 14164 attr.toLowerCase() === "text" ); 14165 }, 14166 14167 // Position-in-collection 14168 "first": createPositionalPseudo( function() { 14169 return [ 0 ]; 14170 } ), 14171 14172 "last": createPositionalPseudo( function( _matchIndexes, length ) { 14173 return [ length - 1 ]; 14174 } ), 14175 14176 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { 14177 return [ argument < 0 ? argument + length : argument ]; 14178 } ), 14179 14180 "even": createPositionalPseudo( function( matchIndexes, length ) { 14181 var i = 0; 14182 for ( ; i < length; i += 2 ) { 14183 matchIndexes.push( i ); 14184 } 14185 return matchIndexes; 14186 } ), 14187 14188 "odd": createPositionalPseudo( function( matchIndexes, length ) { 14189 var i = 1; 14190 for ( ; i < length; i += 2 ) { 14191 matchIndexes.push( i ); 14192 } 14193 return matchIndexes; 14194 } ), 14195 14196 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { 14197 var i = argument < 0 ? 14198 argument + length : 14199 argument > length ? 14200 length : 14201 argument; 14202 for ( ; --i >= 0; ) { 14203 matchIndexes.push( i ); 14204 } 14205 return matchIndexes; 14206 } ), 14207 14208 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { 14209 var i = argument < 0 ? argument + length : argument; 14210 for ( ; ++i < length; ) { 14211 matchIndexes.push( i ); 14212 } 14213 return matchIndexes; 14214 } ) 14215 } 14216}; 14217 14218Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; 14219 14220// Add button/input type pseudos 14221for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 14222 Expr.pseudos[ i ] = createInputPseudo( i ); 14223} 14224for ( i in { submit: true, reset: true } ) { 14225 Expr.pseudos[ i ] = createButtonPseudo( i ); 14226} 14227 14228// Easy API for creating new setFilters 14229function setFilters() {} 14230setFilters.prototype = Expr.filters = Expr.pseudos; 14231Expr.setFilters = new setFilters(); 14232 14233tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 14234 var matched, match, tokens, type, 14235 soFar, groups, preFilters, 14236 cached = tokenCache[ selector + " " ]; 14237 14238 if ( cached ) { 14239 return parseOnly ? 0 : cached.slice( 0 ); 14240 } 14241 14242 soFar = selector; 14243 groups = []; 14244 preFilters = Expr.preFilter; 14245 14246 while ( soFar ) { 14247 14248 // Comma and first run 14249 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 14250 if ( match ) { 14251 14252 // Don't consume trailing commas as valid 14253 soFar = soFar.slice( match[ 0 ].length ) || soFar; 14254 } 14255 groups.push( ( tokens = [] ) ); 14256 } 14257 14258 matched = false; 14259 14260 // Combinators 14261 if ( ( match = rleadingCombinator.exec( soFar ) ) ) { 14262 matched = match.shift(); 14263 tokens.push( { 14264 value: matched, 14265 14266 // Cast descendant combinators to space 14267 type: match[ 0 ].replace( rtrim, " " ) 14268 } ); 14269 soFar = soFar.slice( matched.length ); 14270 } 14271 14272 // Filters 14273 for ( type in Expr.filter ) { 14274 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 14275 ( match = preFilters[ type ]( match ) ) ) ) { 14276 matched = match.shift(); 14277 tokens.push( { 14278 value: matched, 14279 type: type, 14280 matches: match 14281 } ); 14282 soFar = soFar.slice( matched.length ); 14283 } 14284 } 14285 14286 if ( !matched ) { 14287 break; 14288 } 14289 } 14290 14291 // Return the length of the invalid excess 14292 // if we're just parsing 14293 // Otherwise, throw an error or return tokens 14294 return parseOnly ? 14295 soFar.length : 14296 soFar ? 14297 Sizzle.error( selector ) : 14298 14299 // Cache the tokens 14300 tokenCache( selector, groups ).slice( 0 ); 14301}; 14302 14303function toSelector( tokens ) { 14304 var i = 0, 14305 len = tokens.length, 14306 selector = ""; 14307 for ( ; i < len; i++ ) { 14308 selector += tokens[ i ].value; 14309 } 14310 return selector; 14311} 14312 14313function addCombinator( matcher, combinator, base ) { 14314 var dir = combinator.dir, 14315 skip = combinator.next, 14316 key = skip || dir, 14317 checkNonElements = base && key === "parentNode", 14318 doneName = done++; 14319 14320 return combinator.first ? 14321 14322 // Check against closest ancestor/preceding element 14323 function( elem, context, xml ) { 14324 while ( ( elem = elem[ dir ] ) ) { 14325 if ( elem.nodeType === 1 || checkNonElements ) { 14326 return matcher( elem, context, xml ); 14327 } 14328 } 14329 return false; 14330 } : 14331 14332 // Check against all ancestor/preceding elements 14333 function( elem, context, xml ) { 14334 var oldCache, uniqueCache, outerCache, 14335 newCache = [ dirruns, doneName ]; 14336 14337 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 14338 if ( xml ) { 14339 while ( ( elem = elem[ dir ] ) ) { 14340 if ( elem.nodeType === 1 || checkNonElements ) { 14341 if ( matcher( elem, context, xml ) ) { 14342 return true; 14343 } 14344 } 14345 } 14346 } else { 14347 while ( ( elem = elem[ dir ] ) ) { 14348 if ( elem.nodeType === 1 || checkNonElements ) { 14349 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 14350 14351 // Support: IE <9 only 14352 // Defend against cloned attroperties (jQuery gh-1709) 14353 uniqueCache = outerCache[ elem.uniqueID ] || 14354 ( outerCache[ elem.uniqueID ] = {} ); 14355 14356 if ( skip && skip === elem.nodeName.toLowerCase() ) { 14357 elem = elem[ dir ] || elem; 14358 } else if ( ( oldCache = uniqueCache[ key ] ) && 14359 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 14360 14361 // Assign to newCache so results back-propagate to previous elements 14362 return ( newCache[ 2 ] = oldCache[ 2 ] ); 14363 } else { 14364 14365 // Reuse newcache so results back-propagate to previous elements 14366 uniqueCache[ key ] = newCache; 14367 14368 // A match means we're done; a fail means we have to keep checking 14369 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 14370 return true; 14371 } 14372 } 14373 } 14374 } 14375 } 14376 return false; 14377 }; 14378} 14379 14380function elementMatcher( matchers ) { 14381 return matchers.length > 1 ? 14382 function( elem, context, xml ) { 14383 var i = matchers.length; 14384 while ( i-- ) { 14385 if ( !matchers[ i ]( elem, context, xml ) ) { 14386 return false; 14387 } 14388 } 14389 return true; 14390 } : 14391 matchers[ 0 ]; 14392} 14393 14394function multipleContexts( selector, contexts, results ) { 14395 var i = 0, 14396 len = contexts.length; 14397 for ( ; i < len; i++ ) { 14398 Sizzle( selector, contexts[ i ], results ); 14399 } 14400 return results; 14401} 14402 14403function condense( unmatched, map, filter, context, xml ) { 14404 var elem, 14405 newUnmatched = [], 14406 i = 0, 14407 len = unmatched.length, 14408 mapped = map != null; 14409 14410 for ( ; i < len; i++ ) { 14411 if ( ( elem = unmatched[ i ] ) ) { 14412 if ( !filter || filter( elem, context, xml ) ) { 14413 newUnmatched.push( elem ); 14414 if ( mapped ) { 14415 map.push( i ); 14416 } 14417 } 14418 } 14419 } 14420 14421 return newUnmatched; 14422} 14423 14424function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 14425 if ( postFilter && !postFilter[ expando ] ) { 14426 postFilter = setMatcher( postFilter ); 14427 } 14428 if ( postFinder && !postFinder[ expando ] ) { 14429 postFinder = setMatcher( postFinder, postSelector ); 14430 } 14431 return markFunction( function( seed, results, context, xml ) { 14432 var temp, i, elem, 14433 preMap = [], 14434 postMap = [], 14435 preexisting = results.length, 14436 14437 // Get initial elements from seed or context 14438 elems = seed || multipleContexts( 14439 selector || "*", 14440 context.nodeType ? [ context ] : context, 14441 [] 14442 ), 14443 14444 // Prefilter to get matcher input, preserving a map for seed-results synchronization 14445 matcherIn = preFilter && ( seed || !selector ) ? 14446 condense( elems, preMap, preFilter, context, xml ) : 14447 elems, 14448 14449 matcherOut = matcher ? 14450 14451 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 14452 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 14453 14454 // ...intermediate processing is necessary 14455 [] : 14456 14457 // ...otherwise use results directly 14458 results : 14459 matcherIn; 14460 14461 // Find primary matches 14462 if ( matcher ) { 14463 matcher( matcherIn, matcherOut, context, xml ); 14464 } 14465 14466 // Apply postFilter 14467 if ( postFilter ) { 14468 temp = condense( matcherOut, postMap ); 14469 postFilter( temp, [], context, xml ); 14470 14471 // Un-match failing elements by moving them back to matcherIn 14472 i = temp.length; 14473 while ( i-- ) { 14474 if ( ( elem = temp[ i ] ) ) { 14475 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 14476 } 14477 } 14478 } 14479 14480 if ( seed ) { 14481 if ( postFinder || preFilter ) { 14482 if ( postFinder ) { 14483 14484 // Get the final matcherOut by condensing this intermediate into postFinder contexts 14485 temp = []; 14486 i = matcherOut.length; 14487 while ( i-- ) { 14488 if ( ( elem = matcherOut[ i ] ) ) { 14489 14490 // Restore matcherIn since elem is not yet a final match 14491 temp.push( ( matcherIn[ i ] = elem ) ); 14492 } 14493 } 14494 postFinder( null, ( matcherOut = [] ), temp, xml ); 14495 } 14496 14497 // Move matched elements from seed to results to keep them synchronized 14498 i = matcherOut.length; 14499 while ( i-- ) { 14500 if ( ( elem = matcherOut[ i ] ) && 14501 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { 14502 14503 seed[ temp ] = !( results[ temp ] = elem ); 14504 } 14505 } 14506 } 14507 14508 // Add elements to results, through postFinder if defined 14509 } else { 14510 matcherOut = condense( 14511 matcherOut === results ? 14512 matcherOut.splice( preexisting, matcherOut.length ) : 14513 matcherOut 14514 ); 14515 if ( postFinder ) { 14516 postFinder( null, results, matcherOut, xml ); 14517 } else { 14518 push.apply( results, matcherOut ); 14519 } 14520 } 14521 } ); 14522} 14523 14524function matcherFromTokens( tokens ) { 14525 var checkContext, matcher, j, 14526 len = tokens.length, 14527 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 14528 implicitRelative = leadingRelative || Expr.relative[ " " ], 14529 i = leadingRelative ? 1 : 0, 14530 14531 // The foundational matcher ensures that elements are reachable from top-level context(s) 14532 matchContext = addCombinator( function( elem ) { 14533 return elem === checkContext; 14534 }, implicitRelative, true ), 14535 matchAnyContext = addCombinator( function( elem ) { 14536 return indexOf( checkContext, elem ) > -1; 14537 }, implicitRelative, true ), 14538 matchers = [ function( elem, context, xml ) { 14539 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 14540 ( checkContext = context ).nodeType ? 14541 matchContext( elem, context, xml ) : 14542 matchAnyContext( elem, context, xml ) ); 14543 14544 // Avoid hanging onto element (issue #299) 14545 checkContext = null; 14546 return ret; 14547 } ]; 14548 14549 for ( ; i < len; i++ ) { 14550 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 14551 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 14552 } else { 14553 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 14554 14555 // Return special upon seeing a positional matcher 14556 if ( matcher[ expando ] ) { 14557 14558 // Find the next relative operator (if any) for proper handling 14559 j = ++i; 14560 for ( ; j < len; j++ ) { 14561 if ( Expr.relative[ tokens[ j ].type ] ) { 14562 break; 14563 } 14564 } 14565 return setMatcher( 14566 i > 1 && elementMatcher( matchers ), 14567 i > 1 && toSelector( 14568 14569 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 14570 tokens 14571 .slice( 0, i - 1 ) 14572 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 14573 ).replace( rtrim, "$1" ), 14574 matcher, 14575 i < j && matcherFromTokens( tokens.slice( i, j ) ), 14576 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 14577 j < len && toSelector( tokens ) 14578 ); 14579 } 14580 matchers.push( matcher ); 14581 } 14582 } 14583 14584 return elementMatcher( matchers ); 14585} 14586 14587function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 14588 var bySet = setMatchers.length > 0, 14589 byElement = elementMatchers.length > 0, 14590 superMatcher = function( seed, context, xml, results, outermost ) { 14591 var elem, j, matcher, 14592 matchedCount = 0, 14593 i = "0", 14594 unmatched = seed && [], 14595 setMatched = [], 14596 contextBackup = outermostContext, 14597 14598 // We must always have either seed elements or outermost context 14599 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), 14600 14601 // Use integer dirruns iff this is the outermost matcher 14602 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 14603 len = elems.length; 14604 14605 if ( outermost ) { 14606 14607 // Support: IE 11+, Edge 17 - 18+ 14608 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 14609 // two documents; shallow comparisons work. 14610 // eslint-disable-next-line eqeqeq 14611 outermostContext = context == document || context || outermost; 14612 } 14613 14614 // Add elements passing elementMatchers directly to results 14615 // Support: IE<9, Safari 14616 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 14617 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 14618 if ( byElement && elem ) { 14619 j = 0; 14620 14621 // Support: IE 11+, Edge 17 - 18+ 14622 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 14623 // two documents; shallow comparisons work. 14624 // eslint-disable-next-line eqeqeq 14625 if ( !context && elem.ownerDocument != document ) { 14626 setDocument( elem ); 14627 xml = !documentIsHTML; 14628 } 14629 while ( ( matcher = elementMatchers[ j++ ] ) ) { 14630 if ( matcher( elem, context || document, xml ) ) { 14631 results.push( elem ); 14632 break; 14633 } 14634 } 14635 if ( outermost ) { 14636 dirruns = dirrunsUnique; 14637 } 14638 } 14639 14640 // Track unmatched elements for set filters 14641 if ( bySet ) { 14642 14643 // They will have gone through all possible matchers 14644 if ( ( elem = !matcher && elem ) ) { 14645 matchedCount--; 14646 } 14647 14648 // Lengthen the array for every element, matched or not 14649 if ( seed ) { 14650 unmatched.push( elem ); 14651 } 14652 } 14653 } 14654 14655 // `i` is now the count of elements visited above, and adding it to `matchedCount` 14656 // makes the latter nonnegative. 14657 matchedCount += i; 14658 14659 // Apply set filters to unmatched elements 14660 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 14661 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 14662 // no element matchers and no seed. 14663 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 14664 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 14665 // numerically zero. 14666 if ( bySet && i !== matchedCount ) { 14667 j = 0; 14668 while ( ( matcher = setMatchers[ j++ ] ) ) { 14669 matcher( unmatched, setMatched, context, xml ); 14670 } 14671 14672 if ( seed ) { 14673 14674 // Reintegrate element matches to eliminate the need for sorting 14675 if ( matchedCount > 0 ) { 14676 while ( i-- ) { 14677 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 14678 setMatched[ i ] = pop.call( results ); 14679 } 14680 } 14681 } 14682 14683 // Discard index placeholder values to get only actual matches 14684 setMatched = condense( setMatched ); 14685 } 14686 14687 // Add matches to results 14688 push.apply( results, setMatched ); 14689 14690 // Seedless set matches succeeding multiple successful matchers stipulate sorting 14691 if ( outermost && !seed && setMatched.length > 0 && 14692 ( matchedCount + setMatchers.length ) > 1 ) { 14693 14694 Sizzle.uniqueSort( results ); 14695 } 14696 } 14697 14698 // Override manipulation of globals by nested matchers 14699 if ( outermost ) { 14700 dirruns = dirrunsUnique; 14701 outermostContext = contextBackup; 14702 } 14703 14704 return unmatched; 14705 }; 14706 14707 return bySet ? 14708 markFunction( superMatcher ) : 14709 superMatcher; 14710} 14711 14712compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 14713 var i, 14714 setMatchers = [], 14715 elementMatchers = [], 14716 cached = compilerCache[ selector + " " ]; 14717 14718 if ( !cached ) { 14719 14720 // Generate a function of recursive functions that can be used to check each element 14721 if ( !match ) { 14722 match = tokenize( selector ); 14723 } 14724 i = match.length; 14725 while ( i-- ) { 14726 cached = matcherFromTokens( match[ i ] ); 14727 if ( cached[ expando ] ) { 14728 setMatchers.push( cached ); 14729 } else { 14730 elementMatchers.push( cached ); 14731 } 14732 } 14733 14734 // Cache the compiled function 14735 cached = compilerCache( 14736 selector, 14737 matcherFromGroupMatchers( elementMatchers, setMatchers ) 14738 ); 14739 14740 // Save selector and tokenization 14741 cached.selector = selector; 14742 } 14743 return cached; 14744}; 14745 14746/** 14747 * A low-level selection function that works with Sizzle's compiled 14748 * selector functions 14749 * @param {String|Function} selector A selector or a pre-compiled 14750 * selector function built with Sizzle.compile 14751 * @param {Element} context 14752 * @param {Array} [results] 14753 * @param {Array} [seed] A set of elements to match against 14754 */ 14755select = Sizzle.select = function( selector, context, results, seed ) { 14756 var i, tokens, token, type, find, 14757 compiled = typeof selector === "function" && selector, 14758 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 14759 14760 results = results || []; 14761 14762 // Try to minimize operations if there is only one selector in the list and no seed 14763 // (the latter of which guarantees us context) 14764 if ( match.length === 1 ) { 14765 14766 // Reduce context if the leading compound selector is an ID 14767 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 14768 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 14769 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 14770 14771 context = ( Expr.find[ "ID" ]( token.matches[ 0 ] 14772 .replace( runescape, funescape ), context ) || [] )[ 0 ]; 14773 if ( !context ) { 14774 return results; 14775 14776 // Precompiled matchers will still verify ancestry, so step up a level 14777 } else if ( compiled ) { 14778 context = context.parentNode; 14779 } 14780 14781 selector = selector.slice( tokens.shift().value.length ); 14782 } 14783 14784 // Fetch a seed set for right-to-left matching 14785 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; 14786 while ( i-- ) { 14787 token = tokens[ i ]; 14788 14789 // Abort if we hit a combinator 14790 if ( Expr.relative[ ( type = token.type ) ] ) { 14791 break; 14792 } 14793 if ( ( find = Expr.find[ type ] ) ) { 14794 14795 // Search, expanding context for leading sibling combinators 14796 if ( ( seed = find( 14797 token.matches[ 0 ].replace( runescape, funescape ), 14798 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || 14799 context 14800 ) ) ) { 14801 14802 // If seed is empty or no tokens remain, we can return early 14803 tokens.splice( i, 1 ); 14804 selector = seed.length && toSelector( tokens ); 14805 if ( !selector ) { 14806 push.apply( results, seed ); 14807 return results; 14808 } 14809 14810 break; 14811 } 14812 } 14813 } 14814 } 14815 14816 // Compile and execute a filtering function if one is not provided 14817 // Provide `match` to avoid retokenization if we modified the selector above 14818 ( compiled || compile( selector, match ) )( 14819 seed, 14820 context, 14821 !documentIsHTML, 14822 results, 14823 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 14824 ); 14825 return results; 14826}; 14827 14828// One-time assignments 14829 14830// Sort stability 14831support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 14832 14833// Support: Chrome 14-35+ 14834// Always assume duplicates if they aren't passed to the comparison function 14835support.detectDuplicates = !!hasDuplicate; 14836 14837// Initialize against the default document 14838setDocument(); 14839 14840// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 14841// Detached nodes confoundingly follow *each other* 14842support.sortDetached = assert( function( el ) { 14843 14844 // Should return 1, but returns 4 (following) 14845 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 14846} ); 14847 14848// Support: IE<8 14849// Prevent attribute/property "interpolation" 14850// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 14851if ( !assert( function( el ) { 14852 el.innerHTML = "<a href='#'></a>"; 14853 return el.firstChild.getAttribute( "href" ) === "#"; 14854} ) ) { 14855 addHandle( "type|href|height|width", function( elem, name, isXML ) { 14856 if ( !isXML ) { 14857 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 14858 } 14859 } ); 14860} 14861 14862// Support: IE<9 14863// Use defaultValue in place of getAttribute("value") 14864if ( !support.attributes || !assert( function( el ) { 14865 el.innerHTML = "<input/>"; 14866 el.firstChild.setAttribute( "value", "" ); 14867 return el.firstChild.getAttribute( "value" ) === ""; 14868} ) ) { 14869 addHandle( "value", function( elem, _name, isXML ) { 14870 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 14871 return elem.defaultValue; 14872 } 14873 } ); 14874} 14875 14876// Support: IE<9 14877// Use getAttributeNode to fetch booleans when getAttribute lies 14878if ( !assert( function( el ) { 14879 return el.getAttribute( "disabled" ) == null; 14880} ) ) { 14881 addHandle( booleans, function( elem, name, isXML ) { 14882 var val; 14883 if ( !isXML ) { 14884 return elem[ name ] === true ? name.toLowerCase() : 14885 ( val = elem.getAttributeNode( name ) ) && val.specified ? 14886 val.value : 14887 null; 14888 } 14889 } ); 14890} 14891 14892return Sizzle; 14893 14894} )( window ); 14895 14896 14897 14898jQuery.find = Sizzle; 14899jQuery.expr = Sizzle.selectors; 14900 14901// Deprecated 14902jQuery.expr[ ":" ] = jQuery.expr.pseudos; 14903jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 14904jQuery.text = Sizzle.getText; 14905jQuery.isXMLDoc = Sizzle.isXML; 14906jQuery.contains = Sizzle.contains; 14907jQuery.escapeSelector = Sizzle.escape; 14908 14909 14910 14911 14912var dir = function( elem, dir, until ) { 14913 var matched = [], 14914 truncate = until !== undefined; 14915 14916 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 14917 if ( elem.nodeType === 1 ) { 14918 if ( truncate && jQuery( elem ).is( until ) ) { 14919 break; 14920 } 14921 matched.push( elem ); 14922 } 14923 } 14924 return matched; 14925}; 14926 14927 14928var siblings = function( n, elem ) { 14929 var matched = []; 14930 14931 for ( ; n; n = n.nextSibling ) { 14932 if ( n.nodeType === 1 && n !== elem ) { 14933 matched.push( n ); 14934 } 14935 } 14936 14937 return matched; 14938}; 14939 14940 14941var rneedsContext = jQuery.expr.match.needsContext; 14942 14943 14944 14945function nodeName( elem, name ) { 14946 14947 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 14948 14949} 14950var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 14951 14952 14953 14954// Implement the identical functionality for filter and not 14955function winnow( elements, qualifier, not ) { 14956 if ( isFunction( qualifier ) ) { 14957 return jQuery.grep( elements, function( elem, i ) { 14958 return !!qualifier.call( elem, i, elem ) !== not; 14959 } ); 14960 } 14961 14962 // Single element 14963 if ( qualifier.nodeType ) { 14964 return jQuery.grep( elements, function( elem ) { 14965 return ( elem === qualifier ) !== not; 14966 } ); 14967 } 14968 14969 // Arraylike of elements (jQuery, arguments, Array) 14970 if ( typeof qualifier !== "string" ) { 14971 return jQuery.grep( elements, function( elem ) { 14972 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 14973 } ); 14974 } 14975 14976 // Filtered directly for both simple and complex selectors 14977 return jQuery.filter( qualifier, elements, not ); 14978} 14979 14980jQuery.filter = function( expr, elems, not ) { 14981 var elem = elems[ 0 ]; 14982 14983 if ( not ) { 14984 expr = ":not(" + expr + ")"; 14985 } 14986 14987 if ( elems.length === 1 && elem.nodeType === 1 ) { 14988 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 14989 } 14990 14991 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 14992 return elem.nodeType === 1; 14993 } ) ); 14994}; 14995 14996jQuery.fn.extend( { 14997 find: function( selector ) { 14998 var i, ret, 14999 len = this.length, 15000 self = this; 15001 15002 if ( typeof selector !== "string" ) { 15003 return this.pushStack( jQuery( selector ).filter( function() { 15004 for ( i = 0; i < len; i++ ) { 15005 if ( jQuery.contains( self[ i ], this ) ) { 15006 return true; 15007 } 15008 } 15009 } ) ); 15010 } 15011 15012 ret = this.pushStack( [] ); 15013 15014 for ( i = 0; i < len; i++ ) { 15015 jQuery.find( selector, self[ i ], ret ); 15016 } 15017 15018 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 15019 }, 15020 filter: function( selector ) { 15021 return this.pushStack( winnow( this, selector || [], false ) ); 15022 }, 15023 not: function( selector ) { 15024 return this.pushStack( winnow( this, selector || [], true ) ); 15025 }, 15026 is: function( selector ) { 15027 return !!winnow( 15028 this, 15029 15030 // If this is a positional/relative selector, check membership in the returned set 15031 // so $("p:first").is("p:last") won't return true for a doc with two "p". 15032 typeof selector === "string" && rneedsContext.test( selector ) ? 15033 jQuery( selector ) : 15034 selector || [], 15035 false 15036 ).length; 15037 } 15038} ); 15039 15040 15041// Initialize a jQuery object 15042 15043 15044// A central reference to the root jQuery(document) 15045var rootjQuery, 15046 15047 // A simple way to check for HTML strings 15048 // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521) 15049 // Strict HTML recognition (trac-11290: must start with <) 15050 // Shortcut simple #id case for speed 15051 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 15052 15053 init = jQuery.fn.init = function( selector, context, root ) { 15054 var match, elem; 15055 15056 // HANDLE: $(""), $(null), $(undefined), $(false) 15057 if ( !selector ) { 15058 return this; 15059 } 15060 15061 // Method init() accepts an alternate rootjQuery 15062 // so migrate can support jQuery.sub (gh-2101) 15063 root = root || rootjQuery; 15064 15065 // Handle HTML strings 15066 if ( typeof selector === "string" ) { 15067 if ( selector[ 0 ] === "<" && 15068 selector[ selector.length - 1 ] === ">" && 15069 selector.length >= 3 ) { 15070 15071 // Assume that strings that start and end with <> are HTML and skip the regex check 15072 match = [ null, selector, null ]; 15073 15074 } else { 15075 match = rquickExpr.exec( selector ); 15076 } 15077 15078 // Match html or make sure no context is specified for #id 15079 if ( match && ( match[ 1 ] || !context ) ) { 15080 15081 // HANDLE: $(html) -> $(array) 15082 if ( match[ 1 ] ) { 15083 context = context instanceof jQuery ? context[ 0 ] : context; 15084 15085 // Option to run scripts is true for back-compat 15086 // Intentionally let the error be thrown if parseHTML is not present 15087 jQuery.merge( this, jQuery.parseHTML( 15088 match[ 1 ], 15089 context && context.nodeType ? context.ownerDocument || context : document, 15090 true 15091 ) ); 15092 15093 // HANDLE: $(html, props) 15094 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 15095 for ( match in context ) { 15096 15097 // Properties of context are called as methods if possible 15098 if ( isFunction( this[ match ] ) ) { 15099 this[ match ]( context[ match ] ); 15100 15101 // ...and otherwise set as attributes 15102 } else { 15103 this.attr( match, context[ match ] ); 15104 } 15105 } 15106 } 15107 15108 return this; 15109 15110 // HANDLE: $(#id) 15111 } else { 15112 elem = document.getElementById( match[ 2 ] ); 15113 15114 if ( elem ) { 15115 15116 // Inject the element directly into the jQuery object 15117 this[ 0 ] = elem; 15118 this.length = 1; 15119 } 15120 return this; 15121 } 15122 15123 // HANDLE: $(expr, $(...)) 15124 } else if ( !context || context.jquery ) { 15125 return ( context || root ).find( selector ); 15126 15127 // HANDLE: $(expr, context) 15128 // (which is just equivalent to: $(context).find(expr) 15129 } else { 15130 return this.constructor( context ).find( selector ); 15131 } 15132 15133 // HANDLE: $(DOMElement) 15134 } else if ( selector.nodeType ) { 15135 this[ 0 ] = selector; 15136 this.length = 1; 15137 return this; 15138 15139 // HANDLE: $(function) 15140 // Shortcut for document ready 15141 } else if ( isFunction( selector ) ) { 15142 return root.ready !== undefined ? 15143 root.ready( selector ) : 15144 15145 // Execute immediately if ready is not present 15146 selector( jQuery ); 15147 } 15148 15149 return jQuery.makeArray( selector, this ); 15150 }; 15151 15152// Give the init function the jQuery prototype for later instantiation 15153init.prototype = jQuery.fn; 15154 15155// Initialize central reference 15156rootjQuery = jQuery( document ); 15157 15158 15159var rparentsprev = /^(?:parents|prev(?:Until|All))/, 15160 15161 // Methods guaranteed to produce a unique set when starting from a unique set 15162 guaranteedUnique = { 15163 children: true, 15164 contents: true, 15165 next: true, 15166 prev: true 15167 }; 15168 15169jQuery.fn.extend( { 15170 has: function( target ) { 15171 var targets = jQuery( target, this ), 15172 l = targets.length; 15173 15174 return this.filter( function() { 15175 var i = 0; 15176 for ( ; i < l; i++ ) { 15177 if ( jQuery.contains( this, targets[ i ] ) ) { 15178 return true; 15179 } 15180 } 15181 } ); 15182 }, 15183 15184 closest: function( selectors, context ) { 15185 var cur, 15186 i = 0, 15187 l = this.length, 15188 matched = [], 15189 targets = typeof selectors !== "string" && jQuery( selectors ); 15190 15191 // Positional selectors never match, since there's no _selection_ context 15192 if ( !rneedsContext.test( selectors ) ) { 15193 for ( ; i < l; i++ ) { 15194 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 15195 15196 // Always skip document fragments 15197 if ( cur.nodeType < 11 && ( targets ? 15198 targets.index( cur ) > -1 : 15199 15200 // Don't pass non-elements to Sizzle 15201 cur.nodeType === 1 && 15202 jQuery.find.matchesSelector( cur, selectors ) ) ) { 15203 15204 matched.push( cur ); 15205 break; 15206 } 15207 } 15208 } 15209 } 15210 15211 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 15212 }, 15213 15214 // Determine the position of an element within the set 15215 index: function( elem ) { 15216 15217 // No argument, return index in parent 15218 if ( !elem ) { 15219 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 15220 } 15221 15222 // Index in selector 15223 if ( typeof elem === "string" ) { 15224 return indexOf.call( jQuery( elem ), this[ 0 ] ); 15225 } 15226 15227 // Locate the position of the desired element 15228 return indexOf.call( this, 15229 15230 // If it receives a jQuery object, the first element is used 15231 elem.jquery ? elem[ 0 ] : elem 15232 ); 15233 }, 15234 15235 add: function( selector, context ) { 15236 return this.pushStack( 15237 jQuery.uniqueSort( 15238 jQuery.merge( this.get(), jQuery( selector, context ) ) 15239 ) 15240 ); 15241 }, 15242 15243 addBack: function( selector ) { 15244 return this.add( selector == null ? 15245 this.prevObject : this.prevObject.filter( selector ) 15246 ); 15247 } 15248} ); 15249 15250function sibling( cur, dir ) { 15251 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 15252 return cur; 15253} 15254 15255jQuery.each( { 15256 parent: function( elem ) { 15257 var parent = elem.parentNode; 15258 return parent && parent.nodeType !== 11 ? parent : null; 15259 }, 15260 parents: function( elem ) { 15261 return dir( elem, "parentNode" ); 15262 }, 15263 parentsUntil: function( elem, _i, until ) { 15264 return dir( elem, "parentNode", until ); 15265 }, 15266 next: function( elem ) { 15267 return sibling( elem, "nextSibling" ); 15268 }, 15269 prev: function( elem ) { 15270 return sibling( elem, "previousSibling" ); 15271 }, 15272 nextAll: function( elem ) { 15273 return dir( elem, "nextSibling" ); 15274 }, 15275 prevAll: function( elem ) { 15276 return dir( elem, "previousSibling" ); 15277 }, 15278 nextUntil: function( elem, _i, until ) { 15279 return dir( elem, "nextSibling", until ); 15280 }, 15281 prevUntil: function( elem, _i, until ) { 15282 return dir( elem, "previousSibling", until ); 15283 }, 15284 siblings: function( elem ) { 15285 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 15286 }, 15287 children: function( elem ) { 15288 return siblings( elem.firstChild ); 15289 }, 15290 contents: function( elem ) { 15291 if ( elem.contentDocument != null && 15292 15293 // Support: IE 11+ 15294 // <object> elements with no `data` attribute has an object 15295 // `contentDocument` with a `null` prototype. 15296 getProto( elem.contentDocument ) ) { 15297 15298 return elem.contentDocument; 15299 } 15300 15301 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 15302 // Treat the template element as a regular one in browsers that 15303 // don't support it. 15304 if ( nodeName( elem, "template" ) ) { 15305 elem = elem.content || elem; 15306 } 15307 15308 return jQuery.merge( [], elem.childNodes ); 15309 } 15310}, function( name, fn ) { 15311 jQuery.fn[ name ] = function( until, selector ) { 15312 var matched = jQuery.map( this, fn, until ); 15313 15314 if ( name.slice( -5 ) !== "Until" ) { 15315 selector = until; 15316 } 15317 15318 if ( selector && typeof selector === "string" ) { 15319 matched = jQuery.filter( selector, matched ); 15320 } 15321 15322 if ( this.length > 1 ) { 15323 15324 // Remove duplicates 15325 if ( !guaranteedUnique[ name ] ) { 15326 jQuery.uniqueSort( matched ); 15327 } 15328 15329 // Reverse order for parents* and prev-derivatives 15330 if ( rparentsprev.test( name ) ) { 15331 matched.reverse(); 15332 } 15333 } 15334 15335 return this.pushStack( matched ); 15336 }; 15337} ); 15338var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 15339 15340 15341 15342// Convert String-formatted options into Object-formatted ones 15343function createOptions( options ) { 15344 var object = {}; 15345 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 15346 object[ flag ] = true; 15347 } ); 15348 return object; 15349} 15350 15351/* 15352 * Create a callback list using the following parameters: 15353 * 15354 * options: an optional list of space-separated options that will change how 15355 * the callback list behaves or a more traditional option object 15356 * 15357 * By default a callback list will act like an event callback list and can be 15358 * "fired" multiple times. 15359 * 15360 * Possible options: 15361 * 15362 * once: will ensure the callback list can only be fired once (like a Deferred) 15363 * 15364 * memory: will keep track of previous values and will call any callback added 15365 * after the list has been fired right away with the latest "memorized" 15366 * values (like a Deferred) 15367 * 15368 * unique: will ensure a callback can only be added once (no duplicate in the list) 15369 * 15370 * stopOnFalse: interrupt callings when a callback returns false 15371 * 15372 */ 15373jQuery.Callbacks = function( options ) { 15374 15375 // Convert options from String-formatted to Object-formatted if needed 15376 // (we check in cache first) 15377 options = typeof options === "string" ? 15378 createOptions( options ) : 15379 jQuery.extend( {}, options ); 15380 15381 var // Flag to know if list is currently firing 15382 firing, 15383 15384 // Last fire value for non-forgettable lists 15385 memory, 15386 15387 // Flag to know if list was already fired 15388 fired, 15389 15390 // Flag to prevent firing 15391 locked, 15392 15393 // Actual callback list 15394 list = [], 15395 15396 // Queue of execution data for repeatable lists 15397 queue = [], 15398 15399 // Index of currently firing callback (modified by add/remove as needed) 15400 firingIndex = -1, 15401 15402 // Fire callbacks 15403 fire = function() { 15404 15405 // Enforce single-firing 15406 locked = locked || options.once; 15407 15408 // Execute callbacks for all pending executions, 15409 // respecting firingIndex overrides and runtime changes 15410 fired = firing = true; 15411 for ( ; queue.length; firingIndex = -1 ) { 15412 memory = queue.shift(); 15413 while ( ++firingIndex < list.length ) { 15414 15415 // Run callback and check for early termination 15416 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 15417 options.stopOnFalse ) { 15418 15419 // Jump to end and forget the data so .add doesn't re-fire 15420 firingIndex = list.length; 15421 memory = false; 15422 } 15423 } 15424 } 15425 15426 // Forget the data if we're done with it 15427 if ( !options.memory ) { 15428 memory = false; 15429 } 15430 15431 firing = false; 15432 15433 // Clean up if we're done firing for good 15434 if ( locked ) { 15435 15436 // Keep an empty list if we have data for future add calls 15437 if ( memory ) { 15438 list = []; 15439 15440 // Otherwise, this object is spent 15441 } else { 15442 list = ""; 15443 } 15444 } 15445 }, 15446 15447 // Actual Callbacks object 15448 self = { 15449 15450 // Add a callback or a collection of callbacks to the list 15451 add: function() { 15452 if ( list ) { 15453 15454 // If we have memory from a past run, we should fire after adding 15455 if ( memory && !firing ) { 15456 firingIndex = list.length - 1; 15457 queue.push( memory ); 15458 } 15459 15460 ( function add( args ) { 15461 jQuery.each( args, function( _, arg ) { 15462 if ( isFunction( arg ) ) { 15463 if ( !options.unique || !self.has( arg ) ) { 15464 list.push( arg ); 15465 } 15466 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 15467 15468 // Inspect recursively 15469 add( arg ); 15470 } 15471 } ); 15472 } )( arguments ); 15473 15474 if ( memory && !firing ) { 15475 fire(); 15476 } 15477 } 15478 return this; 15479 }, 15480 15481 // Remove a callback from the list 15482 remove: function() { 15483 jQuery.each( arguments, function( _, arg ) { 15484 var index; 15485 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 15486 list.splice( index, 1 ); 15487 15488 // Handle firing indexes 15489 if ( index <= firingIndex ) { 15490 firingIndex--; 15491 } 15492 } 15493 } ); 15494 return this; 15495 }, 15496 15497 // Check if a given callback is in the list. 15498 // If no argument is given, return whether or not list has callbacks attached. 15499 has: function( fn ) { 15500 return fn ? 15501 jQuery.inArray( fn, list ) > -1 : 15502 list.length > 0; 15503 }, 15504 15505 // Remove all callbacks from the list 15506 empty: function() { 15507 if ( list ) { 15508 list = []; 15509 } 15510 return this; 15511 }, 15512 15513 // Disable .fire and .add 15514 // Abort any current/pending executions 15515 // Clear all callbacks and values 15516 disable: function() { 15517 locked = queue = []; 15518 list = memory = ""; 15519 return this; 15520 }, 15521 disabled: function() { 15522 return !list; 15523 }, 15524 15525 // Disable .fire 15526 // Also disable .add unless we have memory (since it would have no effect) 15527 // Abort any pending executions 15528 lock: function() { 15529 locked = queue = []; 15530 if ( !memory && !firing ) { 15531 list = memory = ""; 15532 } 15533 return this; 15534 }, 15535 locked: function() { 15536 return !!locked; 15537 }, 15538 15539 // Call all callbacks with the given context and arguments 15540 fireWith: function( context, args ) { 15541 if ( !locked ) { 15542 args = args || []; 15543 args = [ context, args.slice ? args.slice() : args ]; 15544 queue.push( args ); 15545 if ( !firing ) { 15546 fire(); 15547 } 15548 } 15549 return this; 15550 }, 15551 15552 // Call all the callbacks with the given arguments 15553 fire: function() { 15554 self.fireWith( this, arguments ); 15555 return this; 15556 }, 15557 15558 // To know if the callbacks have already been called at least once 15559 fired: function() { 15560 return !!fired; 15561 } 15562 }; 15563 15564 return self; 15565}; 15566 15567 15568function Identity( v ) { 15569 return v; 15570} 15571function Thrower( ex ) { 15572 throw ex; 15573} 15574 15575function adoptValue( value, resolve, reject, noValue ) { 15576 var method; 15577 15578 try { 15579 15580 // Check for promise aspect first to privilege synchronous behavior 15581 if ( value && isFunction( ( method = value.promise ) ) ) { 15582 method.call( value ).done( resolve ).fail( reject ); 15583 15584 // Other thenables 15585 } else if ( value && isFunction( ( method = value.then ) ) ) { 15586 method.call( value, resolve, reject ); 15587 15588 // Other non-thenables 15589 } else { 15590 15591 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 15592 // * false: [ value ].slice( 0 ) => resolve( value ) 15593 // * true: [ value ].slice( 1 ) => resolve() 15594 resolve.apply( undefined, [ value ].slice( noValue ) ); 15595 } 15596 15597 // For Promises/A+, convert exceptions into rejections 15598 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 15599 // Deferred#then to conditionally suppress rejection. 15600 } catch ( value ) { 15601 15602 // Support: Android 4.0 only 15603 // Strict mode functions invoked without .call/.apply get global-object context 15604 reject.apply( undefined, [ value ] ); 15605 } 15606} 15607 15608jQuery.extend( { 15609 15610 Deferred: function( func ) { 15611 var tuples = [ 15612 15613 // action, add listener, callbacks, 15614 // ... .then handlers, argument index, [final state] 15615 [ "notify", "progress", jQuery.Callbacks( "memory" ), 15616 jQuery.Callbacks( "memory" ), 2 ], 15617 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 15618 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 15619 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 15620 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 15621 ], 15622 state = "pending", 15623 promise = { 15624 state: function() { 15625 return state; 15626 }, 15627 always: function() { 15628 deferred.done( arguments ).fail( arguments ); 15629 return this; 15630 }, 15631 "catch": function( fn ) { 15632 return promise.then( null, fn ); 15633 }, 15634 15635 // Keep pipe for back-compat 15636 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 15637 var fns = arguments; 15638 15639 return jQuery.Deferred( function( newDefer ) { 15640 jQuery.each( tuples, function( _i, tuple ) { 15641 15642 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 15643 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 15644 15645 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 15646 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 15647 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 15648 deferred[ tuple[ 1 ] ]( function() { 15649 var returned = fn && fn.apply( this, arguments ); 15650 if ( returned && isFunction( returned.promise ) ) { 15651 returned.promise() 15652 .progress( newDefer.notify ) 15653 .done( newDefer.resolve ) 15654 .fail( newDefer.reject ); 15655 } else { 15656 newDefer[ tuple[ 0 ] + "With" ]( 15657 this, 15658 fn ? [ returned ] : arguments 15659 ); 15660 } 15661 } ); 15662 } ); 15663 fns = null; 15664 } ).promise(); 15665 }, 15666 then: function( onFulfilled, onRejected, onProgress ) { 15667 var maxDepth = 0; 15668 function resolve( depth, deferred, handler, special ) { 15669 return function() { 15670 var that = this, 15671 args = arguments, 15672 mightThrow = function() { 15673 var returned, then; 15674 15675 // Support: Promises/A+ section 2.3.3.3.3 15676 // https://promisesaplus.com/#point-59 15677 // Ignore double-resolution attempts 15678 if ( depth < maxDepth ) { 15679 return; 15680 } 15681 15682 returned = handler.apply( that, args ); 15683 15684 // Support: Promises/A+ section 2.3.1 15685 // https://promisesaplus.com/#point-48 15686 if ( returned === deferred.promise() ) { 15687 throw new TypeError( "Thenable self-resolution" ); 15688 } 15689 15690 // Support: Promises/A+ sections 2.3.3.1, 3.5 15691 // https://promisesaplus.com/#point-54 15692 // https://promisesaplus.com/#point-75 15693 // Retrieve `then` only once 15694 then = returned && 15695 15696 // Support: Promises/A+ section 2.3.4 15697 // https://promisesaplus.com/#point-64 15698 // Only check objects and functions for thenability 15699 ( typeof returned === "object" || 15700 typeof returned === "function" ) && 15701 returned.then; 15702 15703 // Handle a returned thenable 15704 if ( isFunction( then ) ) { 15705 15706 // Special processors (notify) just wait for resolution 15707 if ( special ) { 15708 then.call( 15709 returned, 15710 resolve( maxDepth, deferred, Identity, special ), 15711 resolve( maxDepth, deferred, Thrower, special ) 15712 ); 15713 15714 // Normal processors (resolve) also hook into progress 15715 } else { 15716 15717 // ...and disregard older resolution values 15718 maxDepth++; 15719 15720 then.call( 15721 returned, 15722 resolve( maxDepth, deferred, Identity, special ), 15723 resolve( maxDepth, deferred, Thrower, special ), 15724 resolve( maxDepth, deferred, Identity, 15725 deferred.notifyWith ) 15726 ); 15727 } 15728 15729 // Handle all other returned values 15730 } else { 15731 15732 // Only substitute handlers pass on context 15733 // and multiple values (non-spec behavior) 15734 if ( handler !== Identity ) { 15735 that = undefined; 15736 args = [ returned ]; 15737 } 15738 15739 // Process the value(s) 15740 // Default process is resolve 15741 ( special || deferred.resolveWith )( that, args ); 15742 } 15743 }, 15744 15745 // Only normal processors (resolve) catch and reject exceptions 15746 process = special ? 15747 mightThrow : 15748 function() { 15749 try { 15750 mightThrow(); 15751 } catch ( e ) { 15752 15753 if ( jQuery.Deferred.exceptionHook ) { 15754 jQuery.Deferred.exceptionHook( e, 15755 process.stackTrace ); 15756 } 15757 15758 // Support: Promises/A+ section 2.3.3.3.4.1 15759 // https://promisesaplus.com/#point-61 15760 // Ignore post-resolution exceptions 15761 if ( depth + 1 >= maxDepth ) { 15762 15763 // Only substitute handlers pass on context 15764 // and multiple values (non-spec behavior) 15765 if ( handler !== Thrower ) { 15766 that = undefined; 15767 args = [ e ]; 15768 } 15769 15770 deferred.rejectWith( that, args ); 15771 } 15772 } 15773 }; 15774 15775 // Support: Promises/A+ section 2.3.3.3.1 15776 // https://promisesaplus.com/#point-57 15777 // Re-resolve promises immediately to dodge false rejection from 15778 // subsequent errors 15779 if ( depth ) { 15780 process(); 15781 } else { 15782 15783 // Call an optional hook to record the stack, in case of exception 15784 // since it's otherwise lost when execution goes async 15785 if ( jQuery.Deferred.getStackHook ) { 15786 process.stackTrace = jQuery.Deferred.getStackHook(); 15787 } 15788 window.setTimeout( process ); 15789 } 15790 }; 15791 } 15792 15793 return jQuery.Deferred( function( newDefer ) { 15794 15795 // progress_handlers.add( ... ) 15796 tuples[ 0 ][ 3 ].add( 15797 resolve( 15798 0, 15799 newDefer, 15800 isFunction( onProgress ) ? 15801 onProgress : 15802 Identity, 15803 newDefer.notifyWith 15804 ) 15805 ); 15806 15807 // fulfilled_handlers.add( ... ) 15808 tuples[ 1 ][ 3 ].add( 15809 resolve( 15810 0, 15811 newDefer, 15812 isFunction( onFulfilled ) ? 15813 onFulfilled : 15814 Identity 15815 ) 15816 ); 15817 15818 // rejected_handlers.add( ... ) 15819 tuples[ 2 ][ 3 ].add( 15820 resolve( 15821 0, 15822 newDefer, 15823 isFunction( onRejected ) ? 15824 onRejected : 15825 Thrower 15826 ) 15827 ); 15828 } ).promise(); 15829 }, 15830 15831 // Get a promise for this deferred 15832 // If obj is provided, the promise aspect is added to the object 15833 promise: function( obj ) { 15834 return obj != null ? jQuery.extend( obj, promise ) : promise; 15835 } 15836 }, 15837 deferred = {}; 15838 15839 // Add list-specific methods 15840 jQuery.each( tuples, function( i, tuple ) { 15841 var list = tuple[ 2 ], 15842 stateString = tuple[ 5 ]; 15843 15844 // promise.progress = list.add 15845 // promise.done = list.add 15846 // promise.fail = list.add 15847 promise[ tuple[ 1 ] ] = list.add; 15848 15849 // Handle state 15850 if ( stateString ) { 15851 list.add( 15852 function() { 15853 15854 // state = "resolved" (i.e., fulfilled) 15855 // state = "rejected" 15856 state = stateString; 15857 }, 15858 15859 // rejected_callbacks.disable 15860 // fulfilled_callbacks.disable 15861 tuples[ 3 - i ][ 2 ].disable, 15862 15863 // rejected_handlers.disable 15864 // fulfilled_handlers.disable 15865 tuples[ 3 - i ][ 3 ].disable, 15866 15867 // progress_callbacks.lock 15868 tuples[ 0 ][ 2 ].lock, 15869 15870 // progress_handlers.lock 15871 tuples[ 0 ][ 3 ].lock 15872 ); 15873 } 15874 15875 // progress_handlers.fire 15876 // fulfilled_handlers.fire 15877 // rejected_handlers.fire 15878 list.add( tuple[ 3 ].fire ); 15879 15880 // deferred.notify = function() { deferred.notifyWith(...) } 15881 // deferred.resolve = function() { deferred.resolveWith(...) } 15882 // deferred.reject = function() { deferred.rejectWith(...) } 15883 deferred[ tuple[ 0 ] ] = function() { 15884 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 15885 return this; 15886 }; 15887 15888 // deferred.notifyWith = list.fireWith 15889 // deferred.resolveWith = list.fireWith 15890 // deferred.rejectWith = list.fireWith 15891 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 15892 } ); 15893 15894 // Make the deferred a promise 15895 promise.promise( deferred ); 15896 15897 // Call given func if any 15898 if ( func ) { 15899 func.call( deferred, deferred ); 15900 } 15901 15902 // All done! 15903 return deferred; 15904 }, 15905 15906 // Deferred helper 15907 when: function( singleValue ) { 15908 var 15909 15910 // count of uncompleted subordinates 15911 remaining = arguments.length, 15912 15913 // count of unprocessed arguments 15914 i = remaining, 15915 15916 // subordinate fulfillment data 15917 resolveContexts = Array( i ), 15918 resolveValues = slice.call( arguments ), 15919 15920 // the primary Deferred 15921 primary = jQuery.Deferred(), 15922 15923 // subordinate callback factory 15924 updateFunc = function( i ) { 15925 return function( value ) { 15926 resolveContexts[ i ] = this; 15927 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 15928 if ( !( --remaining ) ) { 15929 primary.resolveWith( resolveContexts, resolveValues ); 15930 } 15931 }; 15932 }; 15933 15934 // Single- and empty arguments are adopted like Promise.resolve 15935 if ( remaining <= 1 ) { 15936 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 15937 !remaining ); 15938 15939 // Use .then() to unwrap secondary thenables (cf. gh-3000) 15940 if ( primary.state() === "pending" || 15941 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 15942 15943 return primary.then(); 15944 } 15945 } 15946 15947 // Multiple arguments are aggregated like Promise.all array elements 15948 while ( i-- ) { 15949 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 15950 } 15951 15952 return primary.promise(); 15953 } 15954} ); 15955 15956 15957// These usually indicate a programmer mistake during development, 15958// warn about them ASAP rather than swallowing them by default. 15959var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 15960 15961jQuery.Deferred.exceptionHook = function( error, stack ) { 15962 15963 // Support: IE 8 - 9 only 15964 // Console exists when dev tools are open, which can happen at any time 15965 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 15966 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 15967 } 15968}; 15969 15970 15971 15972 15973jQuery.readyException = function( error ) { 15974 window.setTimeout( function() { 15975 throw error; 15976 } ); 15977}; 15978 15979 15980 15981 15982// The deferred used on DOM ready 15983var readyList = jQuery.Deferred(); 15984 15985jQuery.fn.ready = function( fn ) { 15986 15987 readyList 15988 .then( fn ) 15989 15990 // Wrap jQuery.readyException in a function so that the lookup 15991 // happens at the time of error handling instead of callback 15992 // registration. 15993 .catch( function( error ) { 15994 jQuery.readyException( error ); 15995 } ); 15996 15997 return this; 15998}; 15999 16000jQuery.extend( { 16001 16002 // Is the DOM ready to be used? Set to true once it occurs. 16003 isReady: false, 16004 16005 // A counter to track how many items to wait for before 16006 // the ready event fires. See trac-6781 16007 readyWait: 1, 16008 16009 // Handle when the DOM is ready 16010 ready: function( wait ) { 16011 16012 // Abort if there are pending holds or we're already ready 16013 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 16014 return; 16015 } 16016 16017 // Remember that the DOM is ready 16018 jQuery.isReady = true; 16019 16020 // If a normal DOM Ready event fired, decrement, and wait if need be 16021 if ( wait !== true && --jQuery.readyWait > 0 ) { 16022 return; 16023 } 16024 16025 // If there are functions bound, to execute 16026 readyList.resolveWith( document, [ jQuery ] ); 16027 } 16028} ); 16029 16030jQuery.ready.then = readyList.then; 16031 16032// The ready event handler and self cleanup method 16033function completed() { 16034 document.removeEventListener( "DOMContentLoaded", completed ); 16035 window.removeEventListener( "load", completed ); 16036 jQuery.ready(); 16037} 16038 16039// Catch cases where $(document).ready() is called 16040// after the browser event has already occurred. 16041// Support: IE <=9 - 10 only 16042// Older IE sometimes signals "interactive" too soon 16043if ( document.readyState === "complete" || 16044 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 16045 16046 // Handle it asynchronously to allow scripts the opportunity to delay ready 16047 window.setTimeout( jQuery.ready ); 16048 16049} else { 16050 16051 // Use the handy event callback 16052 document.addEventListener( "DOMContentLoaded", completed ); 16053 16054 // A fallback to window.onload, that will always work 16055 window.addEventListener( "load", completed ); 16056} 16057 16058 16059 16060 16061// Multifunctional method to get and set values of a collection 16062// The value/s can optionally be executed if it's a function 16063var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 16064 var i = 0, 16065 len = elems.length, 16066 bulk = key == null; 16067 16068 // Sets many values 16069 if ( toType( key ) === "object" ) { 16070 chainable = true; 16071 for ( i in key ) { 16072 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 16073 } 16074 16075 // Sets one value 16076 } else if ( value !== undefined ) { 16077 chainable = true; 16078 16079 if ( !isFunction( value ) ) { 16080 raw = true; 16081 } 16082 16083 if ( bulk ) { 16084 16085 // Bulk operations run against the entire set 16086 if ( raw ) { 16087 fn.call( elems, value ); 16088 fn = null; 16089 16090 // ...except when executing function values 16091 } else { 16092 bulk = fn; 16093 fn = function( elem, _key, value ) { 16094 return bulk.call( jQuery( elem ), value ); 16095 }; 16096 } 16097 } 16098 16099 if ( fn ) { 16100 for ( ; i < len; i++ ) { 16101 fn( 16102 elems[ i ], key, raw ? 16103 value : 16104 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 16105 ); 16106 } 16107 } 16108 } 16109 16110 if ( chainable ) { 16111 return elems; 16112 } 16113 16114 // Gets 16115 if ( bulk ) { 16116 return fn.call( elems ); 16117 } 16118 16119 return len ? fn( elems[ 0 ], key ) : emptyGet; 16120}; 16121 16122 16123// Matches dashed string for camelizing 16124var rmsPrefix = /^-ms-/, 16125 rdashAlpha = /-([a-z])/g; 16126 16127// Used by camelCase as callback to replace() 16128function fcamelCase( _all, letter ) { 16129 return letter.toUpperCase(); 16130} 16131 16132// Convert dashed to camelCase; used by the css and data modules 16133// Support: IE <=9 - 11, Edge 12 - 15 16134// Microsoft forgot to hump their vendor prefix (trac-9572) 16135function camelCase( string ) { 16136 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 16137} 16138var acceptData = function( owner ) { 16139 16140 // Accepts only: 16141 // - Node 16142 // - Node.ELEMENT_NODE 16143 // - Node.DOCUMENT_NODE 16144 // - Object 16145 // - Any 16146 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 16147}; 16148 16149 16150 16151 16152function Data() { 16153 this.expando = jQuery.expando + Data.uid++; 16154} 16155 16156Data.uid = 1; 16157 16158Data.prototype = { 16159 16160 cache: function( owner ) { 16161 16162 // Check if the owner object already has a cache 16163 var value = owner[ this.expando ]; 16164 16165 // If not, create one 16166 if ( !value ) { 16167 value = {}; 16168 16169 // We can accept data for non-element nodes in modern browsers, 16170 // but we should not, see trac-8335. 16171 // Always return an empty object. 16172 if ( acceptData( owner ) ) { 16173 16174 // If it is a node unlikely to be stringify-ed or looped over 16175 // use plain assignment 16176 if ( owner.nodeType ) { 16177 owner[ this.expando ] = value; 16178 16179 // Otherwise secure it in a non-enumerable property 16180 // configurable must be true to allow the property to be 16181 // deleted when data is removed 16182 } else { 16183 Object.defineProperty( owner, this.expando, { 16184 value: value, 16185 configurable: true 16186 } ); 16187 } 16188 } 16189 } 16190 16191 return value; 16192 }, 16193 set: function( owner, data, value ) { 16194 var prop, 16195 cache = this.cache( owner ); 16196 16197 // Handle: [ owner, key, value ] args 16198 // Always use camelCase key (gh-2257) 16199 if ( typeof data === "string" ) { 16200 cache[ camelCase( data ) ] = value; 16201 16202 // Handle: [ owner, { properties } ] args 16203 } else { 16204 16205 // Copy the properties one-by-one to the cache object 16206 for ( prop in data ) { 16207 cache[ camelCase( prop ) ] = data[ prop ]; 16208 } 16209 } 16210 return cache; 16211 }, 16212 get: function( owner, key ) { 16213 return key === undefined ? 16214 this.cache( owner ) : 16215 16216 // Always use camelCase key (gh-2257) 16217 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 16218 }, 16219 access: function( owner, key, value ) { 16220 16221 // In cases where either: 16222 // 16223 // 1. No key was specified 16224 // 2. A string key was specified, but no value provided 16225 // 16226 // Take the "read" path and allow the get method to determine 16227 // which value to return, respectively either: 16228 // 16229 // 1. The entire cache object 16230 // 2. The data stored at the key 16231 // 16232 if ( key === undefined || 16233 ( ( key && typeof key === "string" ) && value === undefined ) ) { 16234 16235 return this.get( owner, key ); 16236 } 16237 16238 // When the key is not a string, or both a key and value 16239 // are specified, set or extend (existing objects) with either: 16240 // 16241 // 1. An object of properties 16242 // 2. A key and value 16243 // 16244 this.set( owner, key, value ); 16245 16246 // Since the "set" path can have two possible entry points 16247 // return the expected data based on which path was taken[*] 16248 return value !== undefined ? value : key; 16249 }, 16250 remove: function( owner, key ) { 16251 var i, 16252 cache = owner[ this.expando ]; 16253 16254 if ( cache === undefined ) { 16255 return; 16256 } 16257 16258 if ( key !== undefined ) { 16259 16260 // Support array or space separated string of keys 16261 if ( Array.isArray( key ) ) { 16262 16263 // If key is an array of keys... 16264 // We always set camelCase keys, so remove that. 16265 key = key.map( camelCase ); 16266 } else { 16267 key = camelCase( key ); 16268 16269 // If a key with the spaces exists, use it. 16270 // Otherwise, create an array by matching non-whitespace 16271 key = key in cache ? 16272 [ key ] : 16273 ( key.match( rnothtmlwhite ) || [] ); 16274 } 16275 16276 i = key.length; 16277 16278 while ( i-- ) { 16279 delete cache[ key[ i ] ]; 16280 } 16281 } 16282 16283 // Remove the expando if there's no more data 16284 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 16285 16286 // Support: Chrome <=35 - 45 16287 // Webkit & Blink performance suffers when deleting properties 16288 // from DOM nodes, so set to undefined instead 16289 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 16290 if ( owner.nodeType ) { 16291 owner[ this.expando ] = undefined; 16292 } else { 16293 delete owner[ this.expando ]; 16294 } 16295 } 16296 }, 16297 hasData: function( owner ) { 16298 var cache = owner[ this.expando ]; 16299 return cache !== undefined && !jQuery.isEmptyObject( cache ); 16300 } 16301}; 16302var dataPriv = new Data(); 16303 16304var dataUser = new Data(); 16305 16306 16307 16308// Implementation Summary 16309// 16310// 1. Enforce API surface and semantic compatibility with 1.9.x branch 16311// 2. Improve the module's maintainability by reducing the storage 16312// paths to a single mechanism. 16313// 3. Use the same single mechanism to support "private" and "user" data. 16314// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 16315// 5. Avoid exposing implementation details on user objects (eg. expando properties) 16316// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 16317 16318var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 16319 rmultiDash = /[A-Z]/g; 16320 16321function getData( data ) { 16322 if ( data === "true" ) { 16323 return true; 16324 } 16325 16326 if ( data === "false" ) { 16327 return false; 16328 } 16329 16330 if ( data === "null" ) { 16331 return null; 16332 } 16333 16334 // Only convert to a number if it doesn't change the string 16335 if ( data === +data + "" ) { 16336 return +data; 16337 } 16338 16339 if ( rbrace.test( data ) ) { 16340 return JSON.parse( data ); 16341 } 16342 16343 return data; 16344} 16345 16346function dataAttr( elem, key, data ) { 16347 var name; 16348 16349 // If nothing was found internally, try to fetch any 16350 // data from the HTML5 data-* attribute 16351 if ( data === undefined && elem.nodeType === 1 ) { 16352 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 16353 data = elem.getAttribute( name ); 16354 16355 if ( typeof data === "string" ) { 16356 try { 16357 data = getData( data ); 16358 } catch ( e ) {} 16359 16360 // Make sure we set the data so it isn't changed later 16361 dataUser.set( elem, key, data ); 16362 } else { 16363 data = undefined; 16364 } 16365 } 16366 return data; 16367} 16368 16369jQuery.extend( { 16370 hasData: function( elem ) { 16371 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 16372 }, 16373 16374 data: function( elem, name, data ) { 16375 return dataUser.access( elem, name, data ); 16376 }, 16377 16378 removeData: function( elem, name ) { 16379 dataUser.remove( elem, name ); 16380 }, 16381 16382 // TODO: Now that all calls to _data and _removeData have been replaced 16383 // with direct calls to dataPriv methods, these can be deprecated. 16384 _data: function( elem, name, data ) { 16385 return dataPriv.access( elem, name, data ); 16386 }, 16387 16388 _removeData: function( elem, name ) { 16389 dataPriv.remove( elem, name ); 16390 } 16391} ); 16392 16393jQuery.fn.extend( { 16394 data: function( key, value ) { 16395 var i, name, data, 16396 elem = this[ 0 ], 16397 attrs = elem && elem.attributes; 16398 16399 // Gets all values 16400 if ( key === undefined ) { 16401 if ( this.length ) { 16402 data = dataUser.get( elem ); 16403 16404 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 16405 i = attrs.length; 16406 while ( i-- ) { 16407 16408 // Support: IE 11 only 16409 // The attrs elements can be null (trac-14894) 16410 if ( attrs[ i ] ) { 16411 name = attrs[ i ].name; 16412 if ( name.indexOf( "data-" ) === 0 ) { 16413 name = camelCase( name.slice( 5 ) ); 16414 dataAttr( elem, name, data[ name ] ); 16415 } 16416 } 16417 } 16418 dataPriv.set( elem, "hasDataAttrs", true ); 16419 } 16420 } 16421 16422 return data; 16423 } 16424 16425 // Sets multiple values 16426 if ( typeof key === "object" ) { 16427 return this.each( function() { 16428 dataUser.set( this, key ); 16429 } ); 16430 } 16431 16432 return access( this, function( value ) { 16433 var data; 16434 16435 // The calling jQuery object (element matches) is not empty 16436 // (and therefore has an element appears at this[ 0 ]) and the 16437 // `value` parameter was not undefined. An empty jQuery object 16438 // will result in `undefined` for elem = this[ 0 ] which will 16439 // throw an exception if an attempt to read a data cache is made. 16440 if ( elem && value === undefined ) { 16441 16442 // Attempt to get data from the cache 16443 // The key will always be camelCased in Data 16444 data = dataUser.get( elem, key ); 16445 if ( data !== undefined ) { 16446 return data; 16447 } 16448 16449 // Attempt to "discover" the data in 16450 // HTML5 custom data-* attrs 16451 data = dataAttr( elem, key ); 16452 if ( data !== undefined ) { 16453 return data; 16454 } 16455 16456 // We tried really hard, but the data doesn't exist. 16457 return; 16458 } 16459 16460 // Set the data... 16461 this.each( function() { 16462 16463 // We always store the camelCased key 16464 dataUser.set( this, key, value ); 16465 } ); 16466 }, null, value, arguments.length > 1, null, true ); 16467 }, 16468 16469 removeData: function( key ) { 16470 return this.each( function() { 16471 dataUser.remove( this, key ); 16472 } ); 16473 } 16474} ); 16475 16476 16477jQuery.extend( { 16478 queue: function( elem, type, data ) { 16479 var queue; 16480 16481 if ( elem ) { 16482 type = ( type || "fx" ) + "queue"; 16483 queue = dataPriv.get( elem, type ); 16484 16485 // Speed up dequeue by getting out quickly if this is just a lookup 16486 if ( data ) { 16487 if ( !queue || Array.isArray( data ) ) { 16488 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 16489 } else { 16490 queue.push( data ); 16491 } 16492 } 16493 return queue || []; 16494 } 16495 }, 16496 16497 dequeue: function( elem, type ) { 16498 type = type || "fx"; 16499 16500 var queue = jQuery.queue( elem, type ), 16501 startLength = queue.length, 16502 fn = queue.shift(), 16503 hooks = jQuery._queueHooks( elem, type ), 16504 next = function() { 16505 jQuery.dequeue( elem, type ); 16506 }; 16507 16508 // If the fx queue is dequeued, always remove the progress sentinel 16509 if ( fn === "inprogress" ) { 16510 fn = queue.shift(); 16511 startLength--; 16512 } 16513 16514 if ( fn ) { 16515 16516 // Add a progress sentinel to prevent the fx queue from being 16517 // automatically dequeued 16518 if ( type === "fx" ) { 16519 queue.unshift( "inprogress" ); 16520 } 16521 16522 // Clear up the last queue stop function 16523 delete hooks.stop; 16524 fn.call( elem, next, hooks ); 16525 } 16526 16527 if ( !startLength && hooks ) { 16528 hooks.empty.fire(); 16529 } 16530 }, 16531 16532 // Not public - generate a queueHooks object, or return the current one 16533 _queueHooks: function( elem, type ) { 16534 var key = type + "queueHooks"; 16535 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 16536 empty: jQuery.Callbacks( "once memory" ).add( function() { 16537 dataPriv.remove( elem, [ type + "queue", key ] ); 16538 } ) 16539 } ); 16540 } 16541} ); 16542 16543jQuery.fn.extend( { 16544 queue: function( type, data ) { 16545 var setter = 2; 16546 16547 if ( typeof type !== "string" ) { 16548 data = type; 16549 type = "fx"; 16550 setter--; 16551 } 16552 16553 if ( arguments.length < setter ) { 16554 return jQuery.queue( this[ 0 ], type ); 16555 } 16556 16557 return data === undefined ? 16558 this : 16559 this.each( function() { 16560 var queue = jQuery.queue( this, type, data ); 16561 16562 // Ensure a hooks for this queue 16563 jQuery._queueHooks( this, type ); 16564 16565 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 16566 jQuery.dequeue( this, type ); 16567 } 16568 } ); 16569 }, 16570 dequeue: function( type ) { 16571 return this.each( function() { 16572 jQuery.dequeue( this, type ); 16573 } ); 16574 }, 16575 clearQueue: function( type ) { 16576 return this.queue( type || "fx", [] ); 16577 }, 16578 16579 // Get a promise resolved when queues of a certain type 16580 // are emptied (fx is the type by default) 16581 promise: function( type, obj ) { 16582 var tmp, 16583 count = 1, 16584 defer = jQuery.Deferred(), 16585 elements = this, 16586 i = this.length, 16587 resolve = function() { 16588 if ( !( --count ) ) { 16589 defer.resolveWith( elements, [ elements ] ); 16590 } 16591 }; 16592 16593 if ( typeof type !== "string" ) { 16594 obj = type; 16595 type = undefined; 16596 } 16597 type = type || "fx"; 16598 16599 while ( i-- ) { 16600 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 16601 if ( tmp && tmp.empty ) { 16602 count++; 16603 tmp.empty.add( resolve ); 16604 } 16605 } 16606 resolve(); 16607 return defer.promise( obj ); 16608 } 16609} ); 16610var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 16611 16612var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 16613 16614 16615var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 16616 16617var documentElement = document.documentElement; 16618 16619 16620 16621 var isAttached = function( elem ) { 16622 return jQuery.contains( elem.ownerDocument, elem ); 16623 }, 16624 composed = { composed: true }; 16625 16626 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 16627 // Check attachment across shadow DOM boundaries when possible (gh-3504) 16628 // Support: iOS 10.0-10.2 only 16629 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 16630 // leading to errors. We need to check for `getRootNode`. 16631 if ( documentElement.getRootNode ) { 16632 isAttached = function( elem ) { 16633 return jQuery.contains( elem.ownerDocument, elem ) || 16634 elem.getRootNode( composed ) === elem.ownerDocument; 16635 }; 16636 } 16637var isHiddenWithinTree = function( elem, el ) { 16638 16639 // isHiddenWithinTree might be called from jQuery#filter function; 16640 // in that case, element will be second argument 16641 elem = el || elem; 16642 16643 // Inline style trumps all 16644 return elem.style.display === "none" || 16645 elem.style.display === "" && 16646 16647 // Otherwise, check computed style 16648 // Support: Firefox <=43 - 45 16649 // Disconnected elements can have computed display: none, so first confirm that elem is 16650 // in the document. 16651 isAttached( elem ) && 16652 16653 jQuery.css( elem, "display" ) === "none"; 16654 }; 16655 16656 16657 16658function adjustCSS( elem, prop, valueParts, tween ) { 16659 var adjusted, scale, 16660 maxIterations = 20, 16661 currentValue = tween ? 16662 function() { 16663 return tween.cur(); 16664 } : 16665 function() { 16666 return jQuery.css( elem, prop, "" ); 16667 }, 16668 initial = currentValue(), 16669 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 16670 16671 // Starting value computation is required for potential unit mismatches 16672 initialInUnit = elem.nodeType && 16673 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 16674 rcssNum.exec( jQuery.css( elem, prop ) ); 16675 16676 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 16677 16678 // Support: Firefox <=54 16679 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 16680 initial = initial / 2; 16681 16682 // Trust units reported by jQuery.css 16683 unit = unit || initialInUnit[ 3 ]; 16684 16685 // Iteratively approximate from a nonzero starting point 16686 initialInUnit = +initial || 1; 16687 16688 while ( maxIterations-- ) { 16689 16690 // Evaluate and update our best guess (doubling guesses that zero out). 16691 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 16692 jQuery.style( elem, prop, initialInUnit + unit ); 16693 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 16694 maxIterations = 0; 16695 } 16696 initialInUnit = initialInUnit / scale; 16697 16698 } 16699 16700 initialInUnit = initialInUnit * 2; 16701 jQuery.style( elem, prop, initialInUnit + unit ); 16702 16703 // Make sure we update the tween properties later on 16704 valueParts = valueParts || []; 16705 } 16706 16707 if ( valueParts ) { 16708 initialInUnit = +initialInUnit || +initial || 0; 16709 16710 // Apply relative offset (+=/-=) if specified 16711 adjusted = valueParts[ 1 ] ? 16712 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 16713 +valueParts[ 2 ]; 16714 if ( tween ) { 16715 tween.unit = unit; 16716 tween.start = initialInUnit; 16717 tween.end = adjusted; 16718 } 16719 } 16720 return adjusted; 16721} 16722 16723 16724var defaultDisplayMap = {}; 16725 16726function getDefaultDisplay( elem ) { 16727 var temp, 16728 doc = elem.ownerDocument, 16729 nodeName = elem.nodeName, 16730 display = defaultDisplayMap[ nodeName ]; 16731 16732 if ( display ) { 16733 return display; 16734 } 16735 16736 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 16737 display = jQuery.css( temp, "display" ); 16738 16739 temp.parentNode.removeChild( temp ); 16740 16741 if ( display === "none" ) { 16742 display = "block"; 16743 } 16744 defaultDisplayMap[ nodeName ] = display; 16745 16746 return display; 16747} 16748 16749function showHide( elements, show ) { 16750 var display, elem, 16751 values = [], 16752 index = 0, 16753 length = elements.length; 16754 16755 // Determine new display value for elements that need to change 16756 for ( ; index < length; index++ ) { 16757 elem = elements[ index ]; 16758 if ( !elem.style ) { 16759 continue; 16760 } 16761 16762 display = elem.style.display; 16763 if ( show ) { 16764 16765 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 16766 // check is required in this first loop unless we have a nonempty display value (either 16767 // inline or about-to-be-restored) 16768 if ( display === "none" ) { 16769 values[ index ] = dataPriv.get( elem, "display" ) || null; 16770 if ( !values[ index ] ) { 16771 elem.style.display = ""; 16772 } 16773 } 16774 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 16775 values[ index ] = getDefaultDisplay( elem ); 16776 } 16777 } else { 16778 if ( display !== "none" ) { 16779 values[ index ] = "none"; 16780 16781 // Remember what we're overwriting 16782 dataPriv.set( elem, "display", display ); 16783 } 16784 } 16785 } 16786 16787 // Set the display of the elements in a second loop to avoid constant reflow 16788 for ( index = 0; index < length; index++ ) { 16789 if ( values[ index ] != null ) { 16790 elements[ index ].style.display = values[ index ]; 16791 } 16792 } 16793 16794 return elements; 16795} 16796 16797jQuery.fn.extend( { 16798 show: function() { 16799 return showHide( this, true ); 16800 }, 16801 hide: function() { 16802 return showHide( this ); 16803 }, 16804 toggle: function( state ) { 16805 if ( typeof state === "boolean" ) { 16806 return state ? this.show() : this.hide(); 16807 } 16808 16809 return this.each( function() { 16810 if ( isHiddenWithinTree( this ) ) { 16811 jQuery( this ).show(); 16812 } else { 16813 jQuery( this ).hide(); 16814 } 16815 } ); 16816 } 16817} ); 16818var rcheckableType = ( /^(?:checkbox|radio)$/i ); 16819 16820var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 16821 16822var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 16823 16824 16825 16826( function() { 16827 var fragment = document.createDocumentFragment(), 16828 div = fragment.appendChild( document.createElement( "div" ) ), 16829 input = document.createElement( "input" ); 16830 16831 // Support: Android 4.0 - 4.3 only 16832 // Check state lost if the name is set (trac-11217) 16833 // Support: Windows Web Apps (WWA) 16834 // `name` and `type` must use .setAttribute for WWA (trac-14901) 16835 input.setAttribute( "type", "radio" ); 16836 input.setAttribute( "checked", "checked" ); 16837 input.setAttribute( "name", "t" ); 16838 16839 div.appendChild( input ); 16840 16841 // Support: Android <=4.1 only 16842 // Older WebKit doesn't clone checked state correctly in fragments 16843 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 16844 16845 // Support: IE <=11 only 16846 // Make sure textarea (and checkbox) defaultValue is properly cloned 16847 div.innerHTML = "<textarea>x</textarea>"; 16848 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 16849 16850 // Support: IE <=9 only 16851 // IE <=9 replaces <option> tags with their contents when inserted outside of 16852 // the select element. 16853 div.innerHTML = "<option></option>"; 16854 support.option = !!div.lastChild; 16855} )(); 16856 16857 16858// We have to close these tags to support XHTML (trac-13200) 16859var wrapMap = { 16860 16861 // XHTML parsers do not magically insert elements in the 16862 // same way that tag soup parsers do. So we cannot shorten 16863 // this by omitting <tbody> or other required elements. 16864 thead: [ 1, "<table>", "</table>" ], 16865 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 16866 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 16867 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 16868 16869 _default: [ 0, "", "" ] 16870}; 16871 16872wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 16873wrapMap.th = wrapMap.td; 16874 16875// Support: IE <=9 only 16876if ( !support.option ) { 16877 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 16878} 16879 16880 16881function getAll( context, tag ) { 16882 16883 // Support: IE <=9 - 11 only 16884 // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) 16885 var ret; 16886 16887 if ( typeof context.getElementsByTagName !== "undefined" ) { 16888 ret = context.getElementsByTagName( tag || "*" ); 16889 16890 } else if ( typeof context.querySelectorAll !== "undefined" ) { 16891 ret = context.querySelectorAll( tag || "*" ); 16892 16893 } else { 16894 ret = []; 16895 } 16896 16897 if ( tag === undefined || tag && nodeName( context, tag ) ) { 16898 return jQuery.merge( [ context ], ret ); 16899 } 16900 16901 return ret; 16902} 16903 16904 16905// Mark scripts as having already been evaluated 16906function setGlobalEval( elems, refElements ) { 16907 var i = 0, 16908 l = elems.length; 16909 16910 for ( ; i < l; i++ ) { 16911 dataPriv.set( 16912 elems[ i ], 16913 "globalEval", 16914 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 16915 ); 16916 } 16917} 16918 16919 16920var rhtml = /<|&#?\w+;/; 16921 16922function buildFragment( elems, context, scripts, selection, ignored ) { 16923 var elem, tmp, tag, wrap, attached, j, 16924 fragment = context.createDocumentFragment(), 16925 nodes = [], 16926 i = 0, 16927 l = elems.length; 16928 16929 for ( ; i < l; i++ ) { 16930 elem = elems[ i ]; 16931 16932 if ( elem || elem === 0 ) { 16933 16934 // Add nodes directly 16935 if ( toType( elem ) === "object" ) { 16936 16937 // Support: Android <=4.0 only, PhantomJS 1 only 16938 // push.apply(_, arraylike) throws on ancient WebKit 16939 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 16940 16941 // Convert non-html into a text node 16942 } else if ( !rhtml.test( elem ) ) { 16943 nodes.push( context.createTextNode( elem ) ); 16944 16945 // Convert html into DOM nodes 16946 } else { 16947 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 16948 16949 // Deserialize a standard representation 16950 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 16951 wrap = wrapMap[ tag ] || wrapMap._default; 16952 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 16953 16954 // Descend through wrappers to the right content 16955 j = wrap[ 0 ]; 16956 while ( j-- ) { 16957 tmp = tmp.lastChild; 16958 } 16959 16960 // Support: Android <=4.0 only, PhantomJS 1 only 16961 // push.apply(_, arraylike) throws on ancient WebKit 16962 jQuery.merge( nodes, tmp.childNodes ); 16963 16964 // Remember the top-level container 16965 tmp = fragment.firstChild; 16966 16967 // Ensure the created nodes are orphaned (trac-12392) 16968 tmp.textContent = ""; 16969 } 16970 } 16971 } 16972 16973 // Remove wrapper from fragment 16974 fragment.textContent = ""; 16975 16976 i = 0; 16977 while ( ( elem = nodes[ i++ ] ) ) { 16978 16979 // Skip elements already in the context collection (trac-4087) 16980 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 16981 if ( ignored ) { 16982 ignored.push( elem ); 16983 } 16984 continue; 16985 } 16986 16987 attached = isAttached( elem ); 16988 16989 // Append to fragment 16990 tmp = getAll( fragment.appendChild( elem ), "script" ); 16991 16992 // Preserve script evaluation history 16993 if ( attached ) { 16994 setGlobalEval( tmp ); 16995 } 16996 16997 // Capture executables 16998 if ( scripts ) { 16999 j = 0; 17000 while ( ( elem = tmp[ j++ ] ) ) { 17001 if ( rscriptType.test( elem.type || "" ) ) { 17002 scripts.push( elem ); 17003 } 17004 } 17005 } 17006 } 17007 17008 return fragment; 17009} 17010 17011 17012var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 17013 17014function returnTrue() { 17015 return true; 17016} 17017 17018function returnFalse() { 17019 return false; 17020} 17021 17022// Support: IE <=9 - 11+ 17023// focus() and blur() are asynchronous, except when they are no-op. 17024// So expect focus to be synchronous when the element is already active, 17025// and blur to be synchronous when the element is not already active. 17026// (focus and blur are always synchronous in other supported browsers, 17027// this just defines when we can count on it). 17028function expectSync( elem, type ) { 17029 return ( elem === safeActiveElement() ) === ( type === "focus" ); 17030} 17031 17032// Support: IE <=9 only 17033// Accessing document.activeElement can throw unexpectedly 17034// https://bugs.jquery.com/ticket/13393 17035function safeActiveElement() { 17036 try { 17037 return document.activeElement; 17038 } catch ( err ) { } 17039} 17040 17041function on( elem, types, selector, data, fn, one ) { 17042 var origFn, type; 17043 17044 // Types can be a map of types/handlers 17045 if ( typeof types === "object" ) { 17046 17047 // ( types-Object, selector, data ) 17048 if ( typeof selector !== "string" ) { 17049 17050 // ( types-Object, data ) 17051 data = data || selector; 17052 selector = undefined; 17053 } 17054 for ( type in types ) { 17055 on( elem, type, selector, data, types[ type ], one ); 17056 } 17057 return elem; 17058 } 17059 17060 if ( data == null && fn == null ) { 17061 17062 // ( types, fn ) 17063 fn = selector; 17064 data = selector = undefined; 17065 } else if ( fn == null ) { 17066 if ( typeof selector === "string" ) { 17067 17068 // ( types, selector, fn ) 17069 fn = data; 17070 data = undefined; 17071 } else { 17072 17073 // ( types, data, fn ) 17074 fn = data; 17075 data = selector; 17076 selector = undefined; 17077 } 17078 } 17079 if ( fn === false ) { 17080 fn = returnFalse; 17081 } else if ( !fn ) { 17082 return elem; 17083 } 17084 17085 if ( one === 1 ) { 17086 origFn = fn; 17087 fn = function( event ) { 17088 17089 // Can use an empty set, since event contains the info 17090 jQuery().off( event ); 17091 return origFn.apply( this, arguments ); 17092 }; 17093 17094 // Use same guid so caller can remove using origFn 17095 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 17096 } 17097 return elem.each( function() { 17098 jQuery.event.add( this, types, fn, data, selector ); 17099 } ); 17100} 17101 17102/* 17103 * Helper functions for managing events -- not part of the public interface. 17104 * Props to Dean Edwards' addEvent library for many of the ideas. 17105 */ 17106jQuery.event = { 17107 17108 global: {}, 17109 17110 add: function( elem, types, handler, data, selector ) { 17111 17112 var handleObjIn, eventHandle, tmp, 17113 events, t, handleObj, 17114 special, handlers, type, namespaces, origType, 17115 elemData = dataPriv.get( elem ); 17116 17117 // Only attach events to objects that accept data 17118 if ( !acceptData( elem ) ) { 17119 return; 17120 } 17121 17122 // Caller can pass in an object of custom data in lieu of the handler 17123 if ( handler.handler ) { 17124 handleObjIn = handler; 17125 handler = handleObjIn.handler; 17126 selector = handleObjIn.selector; 17127 } 17128 17129 // Ensure that invalid selectors throw exceptions at attach time 17130 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 17131 if ( selector ) { 17132 jQuery.find.matchesSelector( documentElement, selector ); 17133 } 17134 17135 // Make sure that the handler has a unique ID, used to find/remove it later 17136 if ( !handler.guid ) { 17137 handler.guid = jQuery.guid++; 17138 } 17139 17140 // Init the element's event structure and main handler, if this is the first 17141 if ( !( events = elemData.events ) ) { 17142 events = elemData.events = Object.create( null ); 17143 } 17144 if ( !( eventHandle = elemData.handle ) ) { 17145 eventHandle = elemData.handle = function( e ) { 17146 17147 // Discard the second event of a jQuery.event.trigger() and 17148 // when an event is called after a page has unloaded 17149 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 17150 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 17151 }; 17152 } 17153 17154 // Handle multiple events separated by a space 17155 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 17156 t = types.length; 17157 while ( t-- ) { 17158 tmp = rtypenamespace.exec( types[ t ] ) || []; 17159 type = origType = tmp[ 1 ]; 17160 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 17161 17162 // There *must* be a type, no attaching namespace-only handlers 17163 if ( !type ) { 17164 continue; 17165 } 17166 17167 // If event changes its type, use the special event handlers for the changed type 17168 special = jQuery.event.special[ type ] || {}; 17169 17170 // If selector defined, determine special event api type, otherwise given type 17171 type = ( selector ? special.delegateType : special.bindType ) || type; 17172 17173 // Update special based on newly reset type 17174 special = jQuery.event.special[ type ] || {}; 17175 17176 // handleObj is passed to all event handlers 17177 handleObj = jQuery.extend( { 17178 type: type, 17179 origType: origType, 17180 data: data, 17181 handler: handler, 17182 guid: handler.guid, 17183 selector: selector, 17184 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 17185 namespace: namespaces.join( "." ) 17186 }, handleObjIn ); 17187 17188 // Init the event handler queue if we're the first 17189 if ( !( handlers = events[ type ] ) ) { 17190 handlers = events[ type ] = []; 17191 handlers.delegateCount = 0; 17192 17193 // Only use addEventListener if the special events handler returns false 17194 if ( !special.setup || 17195 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 17196 17197 if ( elem.addEventListener ) { 17198 elem.addEventListener( type, eventHandle ); 17199 } 17200 } 17201 } 17202 17203 if ( special.add ) { 17204 special.add.call( elem, handleObj ); 17205 17206 if ( !handleObj.handler.guid ) { 17207 handleObj.handler.guid = handler.guid; 17208 } 17209 } 17210 17211 // Add to the element's handler list, delegates in front 17212 if ( selector ) { 17213 handlers.splice( handlers.delegateCount++, 0, handleObj ); 17214 } else { 17215 handlers.push( handleObj ); 17216 } 17217 17218 // Keep track of which events have ever been used, for event optimization 17219 jQuery.event.global[ type ] = true; 17220 } 17221 17222 }, 17223 17224 // Detach an event or set of events from an element 17225 remove: function( elem, types, handler, selector, mappedTypes ) { 17226 17227 var j, origCount, tmp, 17228 events, t, handleObj, 17229 special, handlers, type, namespaces, origType, 17230 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 17231 17232 if ( !elemData || !( events = elemData.events ) ) { 17233 return; 17234 } 17235 17236 // Once for each type.namespace in types; type may be omitted 17237 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 17238 t = types.length; 17239 while ( t-- ) { 17240 tmp = rtypenamespace.exec( types[ t ] ) || []; 17241 type = origType = tmp[ 1 ]; 17242 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 17243 17244 // Unbind all events (on this namespace, if provided) for the element 17245 if ( !type ) { 17246 for ( type in events ) { 17247 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 17248 } 17249 continue; 17250 } 17251 17252 special = jQuery.event.special[ type ] || {}; 17253 type = ( selector ? special.delegateType : special.bindType ) || type; 17254 handlers = events[ type ] || []; 17255 tmp = tmp[ 2 ] && 17256 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 17257 17258 // Remove matching events 17259 origCount = j = handlers.length; 17260 while ( j-- ) { 17261 handleObj = handlers[ j ]; 17262 17263 if ( ( mappedTypes || origType === handleObj.origType ) && 17264 ( !handler || handler.guid === handleObj.guid ) && 17265 ( !tmp || tmp.test( handleObj.namespace ) ) && 17266 ( !selector || selector === handleObj.selector || 17267 selector === "**" && handleObj.selector ) ) { 17268 handlers.splice( j, 1 ); 17269 17270 if ( handleObj.selector ) { 17271 handlers.delegateCount--; 17272 } 17273 if ( special.remove ) { 17274 special.remove.call( elem, handleObj ); 17275 } 17276 } 17277 } 17278 17279 // Remove generic event handler if we removed something and no more handlers exist 17280 // (avoids potential for endless recursion during removal of special event handlers) 17281 if ( origCount && !handlers.length ) { 17282 if ( !special.teardown || 17283 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 17284 17285 jQuery.removeEvent( elem, type, elemData.handle ); 17286 } 17287 17288 delete events[ type ]; 17289 } 17290 } 17291 17292 // Remove data and the expando if it's no longer used 17293 if ( jQuery.isEmptyObject( events ) ) { 17294 dataPriv.remove( elem, "handle events" ); 17295 } 17296 }, 17297 17298 dispatch: function( nativeEvent ) { 17299 17300 var i, j, ret, matched, handleObj, handlerQueue, 17301 args = new Array( arguments.length ), 17302 17303 // Make a writable jQuery.Event from the native event object 17304 event = jQuery.event.fix( nativeEvent ), 17305 17306 handlers = ( 17307 dataPriv.get( this, "events" ) || Object.create( null ) 17308 )[ event.type ] || [], 17309 special = jQuery.event.special[ event.type ] || {}; 17310 17311 // Use the fix-ed jQuery.Event rather than the (read-only) native event 17312 args[ 0 ] = event; 17313 17314 for ( i = 1; i < arguments.length; i++ ) { 17315 args[ i ] = arguments[ i ]; 17316 } 17317 17318 event.delegateTarget = this; 17319 17320 // Call the preDispatch hook for the mapped type, and let it bail if desired 17321 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 17322 return; 17323 } 17324 17325 // Determine handlers 17326 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 17327 17328 // Run delegates first; they may want to stop propagation beneath us 17329 i = 0; 17330 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 17331 event.currentTarget = matched.elem; 17332 17333 j = 0; 17334 while ( ( handleObj = matched.handlers[ j++ ] ) && 17335 !event.isImmediatePropagationStopped() ) { 17336 17337 // If the event is namespaced, then each handler is only invoked if it is 17338 // specially universal or its namespaces are a superset of the event's. 17339 if ( !event.rnamespace || handleObj.namespace === false || 17340 event.rnamespace.test( handleObj.namespace ) ) { 17341 17342 event.handleObj = handleObj; 17343 event.data = handleObj.data; 17344 17345 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 17346 handleObj.handler ).apply( matched.elem, args ); 17347 17348 if ( ret !== undefined ) { 17349 if ( ( event.result = ret ) === false ) { 17350 event.preventDefault(); 17351 event.stopPropagation(); 17352 } 17353 } 17354 } 17355 } 17356 } 17357 17358 // Call the postDispatch hook for the mapped type 17359 if ( special.postDispatch ) { 17360 special.postDispatch.call( this, event ); 17361 } 17362 17363 return event.result; 17364 }, 17365 17366 handlers: function( event, handlers ) { 17367 var i, handleObj, sel, matchedHandlers, matchedSelectors, 17368 handlerQueue = [], 17369 delegateCount = handlers.delegateCount, 17370 cur = event.target; 17371 17372 // Find delegate handlers 17373 if ( delegateCount && 17374 17375 // Support: IE <=9 17376 // Black-hole SVG <use> instance trees (trac-13180) 17377 cur.nodeType && 17378 17379 // Support: Firefox <=42 17380 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 17381 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 17382 // Support: IE 11 only 17383 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 17384 !( event.type === "click" && event.button >= 1 ) ) { 17385 17386 for ( ; cur !== this; cur = cur.parentNode || this ) { 17387 17388 // Don't check non-elements (trac-13208) 17389 // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) 17390 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 17391 matchedHandlers = []; 17392 matchedSelectors = {}; 17393 for ( i = 0; i < delegateCount; i++ ) { 17394 handleObj = handlers[ i ]; 17395 17396 // Don't conflict with Object.prototype properties (trac-13203) 17397 sel = handleObj.selector + " "; 17398 17399 if ( matchedSelectors[ sel ] === undefined ) { 17400 matchedSelectors[ sel ] = handleObj.needsContext ? 17401 jQuery( sel, this ).index( cur ) > -1 : 17402 jQuery.find( sel, this, null, [ cur ] ).length; 17403 } 17404 if ( matchedSelectors[ sel ] ) { 17405 matchedHandlers.push( handleObj ); 17406 } 17407 } 17408 if ( matchedHandlers.length ) { 17409 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 17410 } 17411 } 17412 } 17413 } 17414 17415 // Add the remaining (directly-bound) handlers 17416 cur = this; 17417 if ( delegateCount < handlers.length ) { 17418 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 17419 } 17420 17421 return handlerQueue; 17422 }, 17423 17424 addProp: function( name, hook ) { 17425 Object.defineProperty( jQuery.Event.prototype, name, { 17426 enumerable: true, 17427 configurable: true, 17428 17429 get: isFunction( hook ) ? 17430 function() { 17431 if ( this.originalEvent ) { 17432 return hook( this.originalEvent ); 17433 } 17434 } : 17435 function() { 17436 if ( this.originalEvent ) { 17437 return this.originalEvent[ name ]; 17438 } 17439 }, 17440 17441 set: function( value ) { 17442 Object.defineProperty( this, name, { 17443 enumerable: true, 17444 configurable: true, 17445 writable: true, 17446 value: value 17447 } ); 17448 } 17449 } ); 17450 }, 17451 17452 fix: function( originalEvent ) { 17453 return originalEvent[ jQuery.expando ] ? 17454 originalEvent : 17455 new jQuery.Event( originalEvent ); 17456 }, 17457 17458 special: { 17459 load: { 17460 17461 // Prevent triggered image.load events from bubbling to window.load 17462 noBubble: true 17463 }, 17464 click: { 17465 17466 // Utilize native event to ensure correct state for checkable inputs 17467 setup: function( data ) { 17468 17469 // For mutual compressibility with _default, replace `this` access with a local var. 17470 // `|| data` is dead code meant only to preserve the variable through minification. 17471 var el = this || data; 17472 17473 // Claim the first handler 17474 if ( rcheckableType.test( el.type ) && 17475 el.click && nodeName( el, "input" ) ) { 17476 17477 // dataPriv.set( el, "click", ... ) 17478 leverageNative( el, "click", returnTrue ); 17479 } 17480 17481 // Return false to allow normal processing in the caller 17482 return false; 17483 }, 17484 trigger: function( data ) { 17485 17486 // For mutual compressibility with _default, replace `this` access with a local var. 17487 // `|| data` is dead code meant only to preserve the variable through minification. 17488 var el = this || data; 17489 17490 // Force setup before triggering a click 17491 if ( rcheckableType.test( el.type ) && 17492 el.click && nodeName( el, "input" ) ) { 17493 17494 leverageNative( el, "click" ); 17495 } 17496 17497 // Return non-false to allow normal event-path propagation 17498 return true; 17499 }, 17500 17501 // For cross-browser consistency, suppress native .click() on links 17502 // Also prevent it if we're currently inside a leveraged native-event stack 17503 _default: function( event ) { 17504 var target = event.target; 17505 return rcheckableType.test( target.type ) && 17506 target.click && nodeName( target, "input" ) && 17507 dataPriv.get( target, "click" ) || 17508 nodeName( target, "a" ); 17509 } 17510 }, 17511 17512 beforeunload: { 17513 postDispatch: function( event ) { 17514 17515 // Support: Firefox 20+ 17516 // Firefox doesn't alert if the returnValue field is not set. 17517 if ( event.result !== undefined && event.originalEvent ) { 17518 event.originalEvent.returnValue = event.result; 17519 } 17520 } 17521 } 17522 } 17523}; 17524 17525// Ensure the presence of an event listener that handles manually-triggered 17526// synthetic events by interrupting progress until reinvoked in response to 17527// *native* events that it fires directly, ensuring that state changes have 17528// already occurred before other listeners are invoked. 17529function leverageNative( el, type, expectSync ) { 17530 17531 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 17532 if ( !expectSync ) { 17533 if ( dataPriv.get( el, type ) === undefined ) { 17534 jQuery.event.add( el, type, returnTrue ); 17535 } 17536 return; 17537 } 17538 17539 // Register the controller as a special universal handler for all event namespaces 17540 dataPriv.set( el, type, false ); 17541 jQuery.event.add( el, type, { 17542 namespace: false, 17543 handler: function( event ) { 17544 var notAsync, result, 17545 saved = dataPriv.get( this, type ); 17546 17547 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 17548 17549 // Interrupt processing of the outer synthetic .trigger()ed event 17550 // Saved data should be false in such cases, but might be a leftover capture object 17551 // from an async native handler (gh-4350) 17552 if ( !saved.length ) { 17553 17554 // Store arguments for use when handling the inner native event 17555 // There will always be at least one argument (an event object), so this array 17556 // will not be confused with a leftover capture object. 17557 saved = slice.call( arguments ); 17558 dataPriv.set( this, type, saved ); 17559 17560 // Trigger the native event and capture its result 17561 // Support: IE <=9 - 11+ 17562 // focus() and blur() are asynchronous 17563 notAsync = expectSync( this, type ); 17564 this[ type ](); 17565 result = dataPriv.get( this, type ); 17566 if ( saved !== result || notAsync ) { 17567 dataPriv.set( this, type, false ); 17568 } else { 17569 result = {}; 17570 } 17571 if ( saved !== result ) { 17572 17573 // Cancel the outer synthetic event 17574 event.stopImmediatePropagation(); 17575 event.preventDefault(); 17576 17577 // Support: Chrome 86+ 17578 // In Chrome, if an element having a focusout handler is blurred by 17579 // clicking outside of it, it invokes the handler synchronously. If 17580 // that handler calls `.remove()` on the element, the data is cleared, 17581 // leaving `result` undefined. We need to guard against this. 17582 return result && result.value; 17583 } 17584 17585 // If this is an inner synthetic event for an event with a bubbling surrogate 17586 // (focus or blur), assume that the surrogate already propagated from triggering the 17587 // native event and prevent that from happening again here. 17588 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 17589 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 17590 // less bad than duplication. 17591 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 17592 event.stopPropagation(); 17593 } 17594 17595 // If this is a native event triggered above, everything is now in order 17596 // Fire an inner synthetic event with the original arguments 17597 } else if ( saved.length ) { 17598 17599 // ...and capture the result 17600 dataPriv.set( this, type, { 17601 value: jQuery.event.trigger( 17602 17603 // Support: IE <=9 - 11+ 17604 // Extend with the prototype to reset the above stopImmediatePropagation() 17605 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 17606 saved.slice( 1 ), 17607 this 17608 ) 17609 } ); 17610 17611 // Abort handling of the native event 17612 event.stopImmediatePropagation(); 17613 } 17614 } 17615 } ); 17616} 17617 17618jQuery.removeEvent = function( elem, type, handle ) { 17619 17620 // This "if" is needed for plain objects 17621 if ( elem.removeEventListener ) { 17622 elem.removeEventListener( type, handle ); 17623 } 17624}; 17625 17626jQuery.Event = function( src, props ) { 17627 17628 // Allow instantiation without the 'new' keyword 17629 if ( !( this instanceof jQuery.Event ) ) { 17630 return new jQuery.Event( src, props ); 17631 } 17632 17633 // Event object 17634 if ( src && src.type ) { 17635 this.originalEvent = src; 17636 this.type = src.type; 17637 17638 // Events bubbling up the document may have been marked as prevented 17639 // by a handler lower down the tree; reflect the correct value. 17640 this.isDefaultPrevented = src.defaultPrevented || 17641 src.defaultPrevented === undefined && 17642 17643 // Support: Android <=2.3 only 17644 src.returnValue === false ? 17645 returnTrue : 17646 returnFalse; 17647 17648 // Create target properties 17649 // Support: Safari <=6 - 7 only 17650 // Target should not be a text node (trac-504, trac-13143) 17651 this.target = ( src.target && src.target.nodeType === 3 ) ? 17652 src.target.parentNode : 17653 src.target; 17654 17655 this.currentTarget = src.currentTarget; 17656 this.relatedTarget = src.relatedTarget; 17657 17658 // Event type 17659 } else { 17660 this.type = src; 17661 } 17662 17663 // Put explicitly provided properties onto the event object 17664 if ( props ) { 17665 jQuery.extend( this, props ); 17666 } 17667 17668 // Create a timestamp if incoming event doesn't have one 17669 this.timeStamp = src && src.timeStamp || Date.now(); 17670 17671 // Mark it as fixed 17672 this[ jQuery.expando ] = true; 17673}; 17674 17675// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 17676// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 17677jQuery.Event.prototype = { 17678 constructor: jQuery.Event, 17679 isDefaultPrevented: returnFalse, 17680 isPropagationStopped: returnFalse, 17681 isImmediatePropagationStopped: returnFalse, 17682 isSimulated: false, 17683 17684 preventDefault: function() { 17685 var e = this.originalEvent; 17686 17687 this.isDefaultPrevented = returnTrue; 17688 17689 if ( e && !this.isSimulated ) { 17690 e.preventDefault(); 17691 } 17692 }, 17693 stopPropagation: function() { 17694 var e = this.originalEvent; 17695 17696 this.isPropagationStopped = returnTrue; 17697 17698 if ( e && !this.isSimulated ) { 17699 e.stopPropagation(); 17700 } 17701 }, 17702 stopImmediatePropagation: function() { 17703 var e = this.originalEvent; 17704 17705 this.isImmediatePropagationStopped = returnTrue; 17706 17707 if ( e && !this.isSimulated ) { 17708 e.stopImmediatePropagation(); 17709 } 17710 17711 this.stopPropagation(); 17712 } 17713}; 17714 17715// Includes all common event props including KeyEvent and MouseEvent specific props 17716jQuery.each( { 17717 altKey: true, 17718 bubbles: true, 17719 cancelable: true, 17720 changedTouches: true, 17721 ctrlKey: true, 17722 detail: true, 17723 eventPhase: true, 17724 metaKey: true, 17725 pageX: true, 17726 pageY: true, 17727 shiftKey: true, 17728 view: true, 17729 "char": true, 17730 code: true, 17731 charCode: true, 17732 key: true, 17733 keyCode: true, 17734 button: true, 17735 buttons: true, 17736 clientX: true, 17737 clientY: true, 17738 offsetX: true, 17739 offsetY: true, 17740 pointerId: true, 17741 pointerType: true, 17742 screenX: true, 17743 screenY: true, 17744 targetTouches: true, 17745 toElement: true, 17746 touches: true, 17747 which: true 17748}, jQuery.event.addProp ); 17749 17750jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 17751 jQuery.event.special[ type ] = { 17752 17753 // Utilize native event if possible so blur/focus sequence is correct 17754 setup: function() { 17755 17756 // Claim the first handler 17757 // dataPriv.set( this, "focus", ... ) 17758 // dataPriv.set( this, "blur", ... ) 17759 leverageNative( this, type, expectSync ); 17760 17761 // Return false to allow normal processing in the caller 17762 return false; 17763 }, 17764 trigger: function() { 17765 17766 // Force setup before trigger 17767 leverageNative( this, type ); 17768 17769 // Return non-false to allow normal event-path propagation 17770 return true; 17771 }, 17772 17773 // Suppress native focus or blur if we're currently inside 17774 // a leveraged native-event stack 17775 _default: function( event ) { 17776 return dataPriv.get( event.target, type ); 17777 }, 17778 17779 delegateType: delegateType 17780 }; 17781} ); 17782 17783// Create mouseenter/leave events using mouseover/out and event-time checks 17784// so that event delegation works in jQuery. 17785// Do the same for pointerenter/pointerleave and pointerover/pointerout 17786// 17787// Support: Safari 7 only 17788// Safari sends mouseenter too often; see: 17789// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 17790// for the description of the bug (it existed in older Chrome versions as well). 17791jQuery.each( { 17792 mouseenter: "mouseover", 17793 mouseleave: "mouseout", 17794 pointerenter: "pointerover", 17795 pointerleave: "pointerout" 17796}, function( orig, fix ) { 17797 jQuery.event.special[ orig ] = { 17798 delegateType: fix, 17799 bindType: fix, 17800 17801 handle: function( event ) { 17802 var ret, 17803 target = this, 17804 related = event.relatedTarget, 17805 handleObj = event.handleObj; 17806 17807 // For mouseenter/leave call the handler if related is outside the target. 17808 // NB: No relatedTarget if the mouse left/entered the browser window 17809 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 17810 event.type = handleObj.origType; 17811 ret = handleObj.handler.apply( this, arguments ); 17812 event.type = fix; 17813 } 17814 return ret; 17815 } 17816 }; 17817} ); 17818 17819jQuery.fn.extend( { 17820 17821 on: function( types, selector, data, fn ) { 17822 return on( this, types, selector, data, fn ); 17823 }, 17824 one: function( types, selector, data, fn ) { 17825 return on( this, types, selector, data, fn, 1 ); 17826 }, 17827 off: function( types, selector, fn ) { 17828 var handleObj, type; 17829 if ( types && types.preventDefault && types.handleObj ) { 17830 17831 // ( event ) dispatched jQuery.Event 17832 handleObj = types.handleObj; 17833 jQuery( types.delegateTarget ).off( 17834 handleObj.namespace ? 17835 handleObj.origType + "." + handleObj.namespace : 17836 handleObj.origType, 17837 handleObj.selector, 17838 handleObj.handler 17839 ); 17840 return this; 17841 } 17842 if ( typeof types === "object" ) { 17843 17844 // ( types-object [, selector] ) 17845 for ( type in types ) { 17846 this.off( type, selector, types[ type ] ); 17847 } 17848 return this; 17849 } 17850 if ( selector === false || typeof selector === "function" ) { 17851 17852 // ( types [, fn] ) 17853 fn = selector; 17854 selector = undefined; 17855 } 17856 if ( fn === false ) { 17857 fn = returnFalse; 17858 } 17859 return this.each( function() { 17860 jQuery.event.remove( this, types, fn, selector ); 17861 } ); 17862 } 17863} ); 17864 17865 17866var 17867 17868 // Support: IE <=10 - 11, Edge 12 - 13 only 17869 // In IE/Edge using regex groups here causes severe slowdowns. 17870 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 17871 rnoInnerhtml = /<script|<style|<link/i, 17872 17873 // checked="checked" or checked 17874 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 17875 17876 rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g; 17877 17878// Prefer a tbody over its parent table for containing new rows 17879function manipulationTarget( elem, content ) { 17880 if ( nodeName( elem, "table" ) && 17881 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 17882 17883 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 17884 } 17885 17886 return elem; 17887} 17888 17889// Replace/restore the type attribute of script elements for safe DOM manipulation 17890function disableScript( elem ) { 17891 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 17892 return elem; 17893} 17894function restoreScript( elem ) { 17895 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 17896 elem.type = elem.type.slice( 5 ); 17897 } else { 17898 elem.removeAttribute( "type" ); 17899 } 17900 17901 return elem; 17902} 17903 17904function cloneCopyEvent( src, dest ) { 17905 var i, l, type, pdataOld, udataOld, udataCur, events; 17906 17907 if ( dest.nodeType !== 1 ) { 17908 return; 17909 } 17910 17911 // 1. Copy private data: events, handlers, etc. 17912 if ( dataPriv.hasData( src ) ) { 17913 pdataOld = dataPriv.get( src ); 17914 events = pdataOld.events; 17915 17916 if ( events ) { 17917 dataPriv.remove( dest, "handle events" ); 17918 17919 for ( type in events ) { 17920 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 17921 jQuery.event.add( dest, type, events[ type ][ i ] ); 17922 } 17923 } 17924 } 17925 } 17926 17927 // 2. Copy user data 17928 if ( dataUser.hasData( src ) ) { 17929 udataOld = dataUser.access( src ); 17930 udataCur = jQuery.extend( {}, udataOld ); 17931 17932 dataUser.set( dest, udataCur ); 17933 } 17934} 17935 17936// Fix IE bugs, see support tests 17937function fixInput( src, dest ) { 17938 var nodeName = dest.nodeName.toLowerCase(); 17939 17940 // Fails to persist the checked state of a cloned checkbox or radio button. 17941 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 17942 dest.checked = src.checked; 17943 17944 // Fails to return the selected option to the default selected state when cloning options 17945 } else if ( nodeName === "input" || nodeName === "textarea" ) { 17946 dest.defaultValue = src.defaultValue; 17947 } 17948} 17949 17950function domManip( collection, args, callback, ignored ) { 17951 17952 // Flatten any nested arrays 17953 args = flat( args ); 17954 17955 var fragment, first, scripts, hasScripts, node, doc, 17956 i = 0, 17957 l = collection.length, 17958 iNoClone = l - 1, 17959 value = args[ 0 ], 17960 valueIsFunction = isFunction( value ); 17961 17962 // We can't cloneNode fragments that contain checked, in WebKit 17963 if ( valueIsFunction || 17964 ( l > 1 && typeof value === "string" && 17965 !support.checkClone && rchecked.test( value ) ) ) { 17966 return collection.each( function( index ) { 17967 var self = collection.eq( index ); 17968 if ( valueIsFunction ) { 17969 args[ 0 ] = value.call( this, index, self.html() ); 17970 } 17971 domManip( self, args, callback, ignored ); 17972 } ); 17973 } 17974 17975 if ( l ) { 17976 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 17977 first = fragment.firstChild; 17978 17979 if ( fragment.childNodes.length === 1 ) { 17980 fragment = first; 17981 } 17982 17983 // Require either new content or an interest in ignored elements to invoke the callback 17984 if ( first || ignored ) { 17985 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 17986 hasScripts = scripts.length; 17987 17988 // Use the original fragment for the last item 17989 // instead of the first because it can end up 17990 // being emptied incorrectly in certain situations (trac-8070). 17991 for ( ; i < l; i++ ) { 17992 node = fragment; 17993 17994 if ( i !== iNoClone ) { 17995 node = jQuery.clone( node, true, true ); 17996 17997 // Keep references to cloned scripts for later restoration 17998 if ( hasScripts ) { 17999 18000 // Support: Android <=4.0 only, PhantomJS 1 only 18001 // push.apply(_, arraylike) throws on ancient WebKit 18002 jQuery.merge( scripts, getAll( node, "script" ) ); 18003 } 18004 } 18005 18006 callback.call( collection[ i ], node, i ); 18007 } 18008 18009 if ( hasScripts ) { 18010 doc = scripts[ scripts.length - 1 ].ownerDocument; 18011 18012 // Reenable scripts 18013 jQuery.map( scripts, restoreScript ); 18014 18015 // Evaluate executable scripts on first document insertion 18016 for ( i = 0; i < hasScripts; i++ ) { 18017 node = scripts[ i ]; 18018 if ( rscriptType.test( node.type || "" ) && 18019 !dataPriv.access( node, "globalEval" ) && 18020 jQuery.contains( doc, node ) ) { 18021 18022 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 18023 18024 // Optional AJAX dependency, but won't run scripts if not present 18025 if ( jQuery._evalUrl && !node.noModule ) { 18026 jQuery._evalUrl( node.src, { 18027 nonce: node.nonce || node.getAttribute( "nonce" ) 18028 }, doc ); 18029 } 18030 } else { 18031 18032 // Unwrap a CDATA section containing script contents. This shouldn't be 18033 // needed as in XML documents they're already not visible when 18034 // inspecting element contents and in HTML documents they have no 18035 // meaning but we're preserving that logic for backwards compatibility. 18036 // This will be removed completely in 4.0. See gh-4904. 18037 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 18038 } 18039 } 18040 } 18041 } 18042 } 18043 } 18044 18045 return collection; 18046} 18047 18048function remove( elem, selector, keepData ) { 18049 var node, 18050 nodes = selector ? jQuery.filter( selector, elem ) : elem, 18051 i = 0; 18052 18053 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 18054 if ( !keepData && node.nodeType === 1 ) { 18055 jQuery.cleanData( getAll( node ) ); 18056 } 18057 18058 if ( node.parentNode ) { 18059 if ( keepData && isAttached( node ) ) { 18060 setGlobalEval( getAll( node, "script" ) ); 18061 } 18062 node.parentNode.removeChild( node ); 18063 } 18064 } 18065 18066 return elem; 18067} 18068 18069jQuery.extend( { 18070 htmlPrefilter: function( html ) { 18071 return html; 18072 }, 18073 18074 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 18075 var i, l, srcElements, destElements, 18076 clone = elem.cloneNode( true ), 18077 inPage = isAttached( elem ); 18078 18079 // Fix IE cloning issues 18080 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 18081 !jQuery.isXMLDoc( elem ) ) { 18082 18083 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 18084 destElements = getAll( clone ); 18085 srcElements = getAll( elem ); 18086 18087 for ( i = 0, l = srcElements.length; i < l; i++ ) { 18088 fixInput( srcElements[ i ], destElements[ i ] ); 18089 } 18090 } 18091 18092 // Copy the events from the original to the clone 18093 if ( dataAndEvents ) { 18094 if ( deepDataAndEvents ) { 18095 srcElements = srcElements || getAll( elem ); 18096 destElements = destElements || getAll( clone ); 18097 18098 for ( i = 0, l = srcElements.length; i < l; i++ ) { 18099 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 18100 } 18101 } else { 18102 cloneCopyEvent( elem, clone ); 18103 } 18104 } 18105 18106 // Preserve script evaluation history 18107 destElements = getAll( clone, "script" ); 18108 if ( destElements.length > 0 ) { 18109 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 18110 } 18111 18112 // Return the cloned set 18113 return clone; 18114 }, 18115 18116 cleanData: function( elems ) { 18117 var data, elem, type, 18118 special = jQuery.event.special, 18119 i = 0; 18120 18121 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 18122 if ( acceptData( elem ) ) { 18123 if ( ( data = elem[ dataPriv.expando ] ) ) { 18124 if ( data.events ) { 18125 for ( type in data.events ) { 18126 if ( special[ type ] ) { 18127 jQuery.event.remove( elem, type ); 18128 18129 // This is a shortcut to avoid jQuery.event.remove's overhead 18130 } else { 18131 jQuery.removeEvent( elem, type, data.handle ); 18132 } 18133 } 18134 } 18135 18136 // Support: Chrome <=35 - 45+ 18137 // Assign undefined instead of using delete, see Data#remove 18138 elem[ dataPriv.expando ] = undefined; 18139 } 18140 if ( elem[ dataUser.expando ] ) { 18141 18142 // Support: Chrome <=35 - 45+ 18143 // Assign undefined instead of using delete, see Data#remove 18144 elem[ dataUser.expando ] = undefined; 18145 } 18146 } 18147 } 18148 } 18149} ); 18150 18151jQuery.fn.extend( { 18152 detach: function( selector ) { 18153 return remove( this, selector, true ); 18154 }, 18155 18156 remove: function( selector ) { 18157 return remove( this, selector ); 18158 }, 18159 18160 text: function( value ) { 18161 return access( this, function( value ) { 18162 return value === undefined ? 18163 jQuery.text( this ) : 18164 this.empty().each( function() { 18165 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 18166 this.textContent = value; 18167 } 18168 } ); 18169 }, null, value, arguments.length ); 18170 }, 18171 18172 append: function() { 18173 return domManip( this, arguments, function( elem ) { 18174 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 18175 var target = manipulationTarget( this, elem ); 18176 target.appendChild( elem ); 18177 } 18178 } ); 18179 }, 18180 18181 prepend: function() { 18182 return domManip( this, arguments, function( elem ) { 18183 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 18184 var target = manipulationTarget( this, elem ); 18185 target.insertBefore( elem, target.firstChild ); 18186 } 18187 } ); 18188 }, 18189 18190 before: function() { 18191 return domManip( this, arguments, function( elem ) { 18192 if ( this.parentNode ) { 18193 this.parentNode.insertBefore( elem, this ); 18194 } 18195 } ); 18196 }, 18197 18198 after: function() { 18199 return domManip( this, arguments, function( elem ) { 18200 if ( this.parentNode ) { 18201 this.parentNode.insertBefore( elem, this.nextSibling ); 18202 } 18203 } ); 18204 }, 18205 18206 empty: function() { 18207 var elem, 18208 i = 0; 18209 18210 for ( ; ( elem = this[ i ] ) != null; i++ ) { 18211 if ( elem.nodeType === 1 ) { 18212 18213 // Prevent memory leaks 18214 jQuery.cleanData( getAll( elem, false ) ); 18215 18216 // Remove any remaining nodes 18217 elem.textContent = ""; 18218 } 18219 } 18220 18221 return this; 18222 }, 18223 18224 clone: function( dataAndEvents, deepDataAndEvents ) { 18225 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 18226 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 18227 18228 return this.map( function() { 18229 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 18230 } ); 18231 }, 18232 18233 html: function( value ) { 18234 return access( this, function( value ) { 18235 var elem = this[ 0 ] || {}, 18236 i = 0, 18237 l = this.length; 18238 18239 if ( value === undefined && elem.nodeType === 1 ) { 18240 return elem.innerHTML; 18241 } 18242 18243 // See if we can take a shortcut and just use innerHTML 18244 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 18245 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 18246 18247 value = jQuery.htmlPrefilter( value ); 18248 18249 try { 18250 for ( ; i < l; i++ ) { 18251 elem = this[ i ] || {}; 18252 18253 // Remove element nodes and prevent memory leaks 18254 if ( elem.nodeType === 1 ) { 18255 jQuery.cleanData( getAll( elem, false ) ); 18256 elem.innerHTML = value; 18257 } 18258 } 18259 18260 elem = 0; 18261 18262 // If using innerHTML throws an exception, use the fallback method 18263 } catch ( e ) {} 18264 } 18265 18266 if ( elem ) { 18267 this.empty().append( value ); 18268 } 18269 }, null, value, arguments.length ); 18270 }, 18271 18272 replaceWith: function() { 18273 var ignored = []; 18274 18275 // Make the changes, replacing each non-ignored context element with the new content 18276 return domManip( this, arguments, function( elem ) { 18277 var parent = this.parentNode; 18278 18279 if ( jQuery.inArray( this, ignored ) < 0 ) { 18280 jQuery.cleanData( getAll( this ) ); 18281 if ( parent ) { 18282 parent.replaceChild( elem, this ); 18283 } 18284 } 18285 18286 // Force callback invocation 18287 }, ignored ); 18288 } 18289} ); 18290 18291jQuery.each( { 18292 appendTo: "append", 18293 prependTo: "prepend", 18294 insertBefore: "before", 18295 insertAfter: "after", 18296 replaceAll: "replaceWith" 18297}, function( name, original ) { 18298 jQuery.fn[ name ] = function( selector ) { 18299 var elems, 18300 ret = [], 18301 insert = jQuery( selector ), 18302 last = insert.length - 1, 18303 i = 0; 18304 18305 for ( ; i <= last; i++ ) { 18306 elems = i === last ? this : this.clone( true ); 18307 jQuery( insert[ i ] )[ original ]( elems ); 18308 18309 // Support: Android <=4.0 only, PhantomJS 1 only 18310 // .get() because push.apply(_, arraylike) throws on ancient WebKit 18311 push.apply( ret, elems.get() ); 18312 } 18313 18314 return this.pushStack( ret ); 18315 }; 18316} ); 18317var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 18318 18319var rcustomProp = /^--/; 18320 18321 18322var getStyles = function( elem ) { 18323 18324 // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) 18325 // IE throws on elements created in popups 18326 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 18327 var view = elem.ownerDocument.defaultView; 18328 18329 if ( !view || !view.opener ) { 18330 view = window; 18331 } 18332 18333 return view.getComputedStyle( elem ); 18334 }; 18335 18336var swap = function( elem, options, callback ) { 18337 var ret, name, 18338 old = {}; 18339 18340 // Remember the old values, and insert the new ones 18341 for ( name in options ) { 18342 old[ name ] = elem.style[ name ]; 18343 elem.style[ name ] = options[ name ]; 18344 } 18345 18346 ret = callback.call( elem ); 18347 18348 // Revert the old values 18349 for ( name in options ) { 18350 elem.style[ name ] = old[ name ]; 18351 } 18352 18353 return ret; 18354}; 18355 18356 18357var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 18358 18359var whitespace = "[\\x20\\t\\r\\n\\f]"; 18360 18361 18362var rtrimCSS = new RegExp( 18363 "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", 18364 "g" 18365); 18366 18367 18368 18369 18370( function() { 18371 18372 // Executing both pixelPosition & boxSizingReliable tests require only one layout 18373 // so they're executed at the same time to save the second computation. 18374 function computeStyleTests() { 18375 18376 // This is a singleton, we need to execute it only once 18377 if ( !div ) { 18378 return; 18379 } 18380 18381 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 18382 "margin-top:1px;padding:0;border:0"; 18383 div.style.cssText = 18384 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 18385 "margin:auto;border:1px;padding:1px;" + 18386 "width:60%;top:1%"; 18387 documentElement.appendChild( container ).appendChild( div ); 18388 18389 var divStyle = window.getComputedStyle( div ); 18390 pixelPositionVal = divStyle.top !== "1%"; 18391 18392 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 18393 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 18394 18395 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 18396 // Some styles come back with percentage values, even though they shouldn't 18397 div.style.right = "60%"; 18398 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 18399 18400 // Support: IE 9 - 11 only 18401 // Detect misreporting of content dimensions for box-sizing:border-box elements 18402 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 18403 18404 // Support: IE 9 only 18405 // Detect overflow:scroll screwiness (gh-3699) 18406 // Support: Chrome <=64 18407 // Don't get tricked when zoom affects offsetWidth (gh-4029) 18408 div.style.position = "absolute"; 18409 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 18410 18411 documentElement.removeChild( container ); 18412 18413 // Nullify the div so it wouldn't be stored in the memory and 18414 // it will also be a sign that checks already performed 18415 div = null; 18416 } 18417 18418 function roundPixelMeasures( measure ) { 18419 return Math.round( parseFloat( measure ) ); 18420 } 18421 18422 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 18423 reliableTrDimensionsVal, reliableMarginLeftVal, 18424 container = document.createElement( "div" ), 18425 div = document.createElement( "div" ); 18426 18427 // Finish early in limited (non-browser) environments 18428 if ( !div.style ) { 18429 return; 18430 } 18431 18432 // Support: IE <=9 - 11 only 18433 // Style of cloned element affects source element cloned (trac-8908) 18434 div.style.backgroundClip = "content-box"; 18435 div.cloneNode( true ).style.backgroundClip = ""; 18436 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 18437 18438 jQuery.extend( support, { 18439 boxSizingReliable: function() { 18440 computeStyleTests(); 18441 return boxSizingReliableVal; 18442 }, 18443 pixelBoxStyles: function() { 18444 computeStyleTests(); 18445 return pixelBoxStylesVal; 18446 }, 18447 pixelPosition: function() { 18448 computeStyleTests(); 18449 return pixelPositionVal; 18450 }, 18451 reliableMarginLeft: function() { 18452 computeStyleTests(); 18453 return reliableMarginLeftVal; 18454 }, 18455 scrollboxSize: function() { 18456 computeStyleTests(); 18457 return scrollboxSizeVal; 18458 }, 18459 18460 // Support: IE 9 - 11+, Edge 15 - 18+ 18461 // IE/Edge misreport `getComputedStyle` of table rows with width/height 18462 // set in CSS while `offset*` properties report correct values. 18463 // Behavior in IE 9 is more subtle than in newer versions & it passes 18464 // some versions of this test; make sure not to make it pass there! 18465 // 18466 // Support: Firefox 70+ 18467 // Only Firefox includes border widths 18468 // in computed dimensions. (gh-4529) 18469 reliableTrDimensions: function() { 18470 var table, tr, trChild, trStyle; 18471 if ( reliableTrDimensionsVal == null ) { 18472 table = document.createElement( "table" ); 18473 tr = document.createElement( "tr" ); 18474 trChild = document.createElement( "div" ); 18475 18476 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 18477 tr.style.cssText = "border:1px solid"; 18478 18479 // Support: Chrome 86+ 18480 // Height set through cssText does not get applied. 18481 // Computed height then comes back as 0. 18482 tr.style.height = "1px"; 18483 trChild.style.height = "9px"; 18484 18485 // Support: Android 8 Chrome 86+ 18486 // In our bodyBackground.html iframe, 18487 // display for all div elements is set to "inline", 18488 // which causes a problem only in Android 8 Chrome 86. 18489 // Ensuring the div is display: block 18490 // gets around this issue. 18491 trChild.style.display = "block"; 18492 18493 documentElement 18494 .appendChild( table ) 18495 .appendChild( tr ) 18496 .appendChild( trChild ); 18497 18498 trStyle = window.getComputedStyle( tr ); 18499 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 18500 parseInt( trStyle.borderTopWidth, 10 ) + 18501 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 18502 18503 documentElement.removeChild( table ); 18504 } 18505 return reliableTrDimensionsVal; 18506 } 18507 } ); 18508} )(); 18509 18510 18511function curCSS( elem, name, computed ) { 18512 var width, minWidth, maxWidth, ret, 18513 isCustomProp = rcustomProp.test( name ), 18514 18515 // Support: Firefox 51+ 18516 // Retrieving style before computed somehow 18517 // fixes an issue with getting wrong values 18518 // on detached elements 18519 style = elem.style; 18520 18521 computed = computed || getStyles( elem ); 18522 18523 // getPropertyValue is needed for: 18524 // .css('filter') (IE 9 only, trac-12537) 18525 // .css('--customProperty) (gh-3144) 18526 if ( computed ) { 18527 18528 // Support: IE <=9 - 11+ 18529 // IE only supports `"float"` in `getPropertyValue`; in computed styles 18530 // it's only available as `"cssFloat"`. We no longer modify properties 18531 // sent to `.css()` apart from camelCasing, so we need to check both. 18532 // Normally, this would create difference in behavior: if 18533 // `getPropertyValue` returns an empty string, the value returned 18534 // by `.css()` would be `undefined`. This is usually the case for 18535 // disconnected elements. However, in IE even disconnected elements 18536 // with no styles return `"none"` for `getPropertyValue( "float" )` 18537 ret = computed.getPropertyValue( name ) || computed[ name ]; 18538 18539 if ( isCustomProp && ret ) { 18540 18541 // Support: Firefox 105+, Chrome <=105+ 18542 // Spec requires trimming whitespace for custom properties (gh-4926). 18543 // Firefox only trims leading whitespace. Chrome just collapses 18544 // both leading & trailing whitespace to a single space. 18545 // 18546 // Fall back to `undefined` if empty string returned. 18547 // This collapses a missing definition with property defined 18548 // and set to an empty string but there's no standard API 18549 // allowing us to differentiate them without a performance penalty 18550 // and returning `undefined` aligns with older jQuery. 18551 // 18552 // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED 18553 // as whitespace while CSS does not, but this is not a problem 18554 // because CSS preprocessing replaces them with U+000A LINE FEED 18555 // (which *is* CSS whitespace) 18556 // https://www.w3.org/TR/css-syntax-3/#input-preprocessing 18557 ret = ret.replace( rtrimCSS, "$1" ) || undefined; 18558 } 18559 18560 if ( ret === "" && !isAttached( elem ) ) { 18561 ret = jQuery.style( elem, name ); 18562 } 18563 18564 // A tribute to the "awesome hack by Dean Edwards" 18565 // Android Browser returns percentage for some values, 18566 // but width seems to be reliably pixels. 18567 // This is against the CSSOM draft spec: 18568 // https://drafts.csswg.org/cssom/#resolved-values 18569 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 18570 18571 // Remember the original values 18572 width = style.width; 18573 minWidth = style.minWidth; 18574 maxWidth = style.maxWidth; 18575 18576 // Put in the new values to get a computed value out 18577 style.minWidth = style.maxWidth = style.width = ret; 18578 ret = computed.width; 18579 18580 // Revert the changed values 18581 style.width = width; 18582 style.minWidth = minWidth; 18583 style.maxWidth = maxWidth; 18584 } 18585 } 18586 18587 return ret !== undefined ? 18588 18589 // Support: IE <=9 - 11 only 18590 // IE returns zIndex value as an integer. 18591 ret + "" : 18592 ret; 18593} 18594 18595 18596function addGetHookIf( conditionFn, hookFn ) { 18597 18598 // Define the hook, we'll check on the first run if it's really needed. 18599 return { 18600 get: function() { 18601 if ( conditionFn() ) { 18602 18603 // Hook not needed (or it's not possible to use it due 18604 // to missing dependency), remove it. 18605 delete this.get; 18606 return; 18607 } 18608 18609 // Hook needed; redefine it so that the support test is not executed again. 18610 return ( this.get = hookFn ).apply( this, arguments ); 18611 } 18612 }; 18613} 18614 18615 18616var cssPrefixes = [ "Webkit", "Moz", "ms" ], 18617 emptyStyle = document.createElement( "div" ).style, 18618 vendorProps = {}; 18619 18620// Return a vendor-prefixed property or undefined 18621function vendorPropName( name ) { 18622 18623 // Check for vendor prefixed names 18624 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 18625 i = cssPrefixes.length; 18626 18627 while ( i-- ) { 18628 name = cssPrefixes[ i ] + capName; 18629 if ( name in emptyStyle ) { 18630 return name; 18631 } 18632 } 18633} 18634 18635// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 18636function finalPropName( name ) { 18637 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 18638 18639 if ( final ) { 18640 return final; 18641 } 18642 if ( name in emptyStyle ) { 18643 return name; 18644 } 18645 return vendorProps[ name ] = vendorPropName( name ) || name; 18646} 18647 18648 18649var 18650 18651 // Swappable if display is none or starts with table 18652 // except "table", "table-cell", or "table-caption" 18653 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 18654 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 18655 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 18656 cssNormalTransform = { 18657 letterSpacing: "0", 18658 fontWeight: "400" 18659 }; 18660 18661function setPositiveNumber( _elem, value, subtract ) { 18662 18663 // Any relative (+/-) values have already been 18664 // normalized at this point 18665 var matches = rcssNum.exec( value ); 18666 return matches ? 18667 18668 // Guard against undefined "subtract", e.g., when used as in cssHooks 18669 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 18670 value; 18671} 18672 18673function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 18674 var i = dimension === "width" ? 1 : 0, 18675 extra = 0, 18676 delta = 0; 18677 18678 // Adjustment may not be necessary 18679 if ( box === ( isBorderBox ? "border" : "content" ) ) { 18680 return 0; 18681 } 18682 18683 for ( ; i < 4; i += 2 ) { 18684 18685 // Both box models exclude margin 18686 if ( box === "margin" ) { 18687 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 18688 } 18689 18690 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 18691 if ( !isBorderBox ) { 18692 18693 // Add padding 18694 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 18695 18696 // For "border" or "margin", add border 18697 if ( box !== "padding" ) { 18698 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 18699 18700 // But still keep track of it otherwise 18701 } else { 18702 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 18703 } 18704 18705 // If we get here with a border-box (content + padding + border), we're seeking "content" or 18706 // "padding" or "margin" 18707 } else { 18708 18709 // For "content", subtract padding 18710 if ( box === "content" ) { 18711 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 18712 } 18713 18714 // For "content" or "padding", subtract border 18715 if ( box !== "margin" ) { 18716 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 18717 } 18718 } 18719 } 18720 18721 // Account for positive content-box scroll gutter when requested by providing computedVal 18722 if ( !isBorderBox && computedVal >= 0 ) { 18723 18724 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 18725 // Assuming integer scroll gutter, subtract the rest and round down 18726 delta += Math.max( 0, Math.ceil( 18727 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 18728 computedVal - 18729 delta - 18730 extra - 18731 0.5 18732 18733 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 18734 // Use an explicit zero to avoid NaN (gh-3964) 18735 ) ) || 0; 18736 } 18737 18738 return delta; 18739} 18740 18741function getWidthOrHeight( elem, dimension, extra ) { 18742 18743 // Start with computed style 18744 var styles = getStyles( elem ), 18745 18746 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 18747 // Fake content-box until we know it's needed to know the true value. 18748 boxSizingNeeded = !support.boxSizingReliable() || extra, 18749 isBorderBox = boxSizingNeeded && 18750 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 18751 valueIsBorderBox = isBorderBox, 18752 18753 val = curCSS( elem, dimension, styles ), 18754 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 18755 18756 // Support: Firefox <=54 18757 // Return a confounding non-pixel value or feign ignorance, as appropriate. 18758 if ( rnumnonpx.test( val ) ) { 18759 if ( !extra ) { 18760 return val; 18761 } 18762 val = "auto"; 18763 } 18764 18765 18766 // Support: IE 9 - 11 only 18767 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 18768 // In those cases, the computed value can be trusted to be border-box. 18769 if ( ( !support.boxSizingReliable() && isBorderBox || 18770 18771 // Support: IE 10 - 11+, Edge 15 - 18+ 18772 // IE/Edge misreport `getComputedStyle` of table rows with width/height 18773 // set in CSS while `offset*` properties report correct values. 18774 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 18775 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 18776 18777 // Fall back to offsetWidth/offsetHeight when value is "auto" 18778 // This happens for inline elements with no explicit setting (gh-3571) 18779 val === "auto" || 18780 18781 // Support: Android <=4.1 - 4.3 only 18782 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 18783 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 18784 18785 // Make sure the element is visible & connected 18786 elem.getClientRects().length ) { 18787 18788 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 18789 18790 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 18791 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 18792 // retrieved value as a content box dimension. 18793 valueIsBorderBox = offsetProp in elem; 18794 if ( valueIsBorderBox ) { 18795 val = elem[ offsetProp ]; 18796 } 18797 } 18798 18799 // Normalize "" and auto 18800 val = parseFloat( val ) || 0; 18801 18802 // Adjust for the element's box model 18803 return ( val + 18804 boxModelAdjustment( 18805 elem, 18806 dimension, 18807 extra || ( isBorderBox ? "border" : "content" ), 18808 valueIsBorderBox, 18809 styles, 18810 18811 // Provide the current computed size to request scroll gutter calculation (gh-3589) 18812 val 18813 ) 18814 ) + "px"; 18815} 18816 18817jQuery.extend( { 18818 18819 // Add in style property hooks for overriding the default 18820 // behavior of getting and setting a style property 18821 cssHooks: { 18822 opacity: { 18823 get: function( elem, computed ) { 18824 if ( computed ) { 18825 18826 // We should always get a number back from opacity 18827 var ret = curCSS( elem, "opacity" ); 18828 return ret === "" ? "1" : ret; 18829 } 18830 } 18831 } 18832 }, 18833 18834 // Don't automatically add "px" to these possibly-unitless properties 18835 cssNumber: { 18836 "animationIterationCount": true, 18837 "columnCount": true, 18838 "fillOpacity": true, 18839 "flexGrow": true, 18840 "flexShrink": true, 18841 "fontWeight": true, 18842 "gridArea": true, 18843 "gridColumn": true, 18844 "gridColumnEnd": true, 18845 "gridColumnStart": true, 18846 "gridRow": true, 18847 "gridRowEnd": true, 18848 "gridRowStart": true, 18849 "lineHeight": true, 18850 "opacity": true, 18851 "order": true, 18852 "orphans": true, 18853 "widows": true, 18854 "zIndex": true, 18855 "zoom": true 18856 }, 18857 18858 // Add in properties whose names you wish to fix before 18859 // setting or getting the value 18860 cssProps: {}, 18861 18862 // Get and set the style property on a DOM Node 18863 style: function( elem, name, value, extra ) { 18864 18865 // Don't set styles on text and comment nodes 18866 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 18867 return; 18868 } 18869 18870 // Make sure that we're working with the right name 18871 var ret, type, hooks, 18872 origName = camelCase( name ), 18873 isCustomProp = rcustomProp.test( name ), 18874 style = elem.style; 18875 18876 // Make sure that we're working with the right name. We don't 18877 // want to query the value if it is a CSS custom property 18878 // since they are user-defined. 18879 if ( !isCustomProp ) { 18880 name = finalPropName( origName ); 18881 } 18882 18883 // Gets hook for the prefixed version, then unprefixed version 18884 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 18885 18886 // Check if we're setting a value 18887 if ( value !== undefined ) { 18888 type = typeof value; 18889 18890 // Convert "+=" or "-=" to relative numbers (trac-7345) 18891 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 18892 value = adjustCSS( elem, name, ret ); 18893 18894 // Fixes bug trac-9237 18895 type = "number"; 18896 } 18897 18898 // Make sure that null and NaN values aren't set (trac-7116) 18899 if ( value == null || value !== value ) { 18900 return; 18901 } 18902 18903 // If a number was passed in, add the unit (except for certain CSS properties) 18904 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 18905 // "px" to a few hardcoded values. 18906 if ( type === "number" && !isCustomProp ) { 18907 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 18908 } 18909 18910 // background-* props affect original clone's values 18911 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 18912 style[ name ] = "inherit"; 18913 } 18914 18915 // If a hook was provided, use that value, otherwise just set the specified value 18916 if ( !hooks || !( "set" in hooks ) || 18917 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 18918 18919 if ( isCustomProp ) { 18920 style.setProperty( name, value ); 18921 } else { 18922 style[ name ] = value; 18923 } 18924 } 18925 18926 } else { 18927 18928 // If a hook was provided get the non-computed value from there 18929 if ( hooks && "get" in hooks && 18930 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 18931 18932 return ret; 18933 } 18934 18935 // Otherwise just get the value from the style object 18936 return style[ name ]; 18937 } 18938 }, 18939 18940 css: function( elem, name, extra, styles ) { 18941 var val, num, hooks, 18942 origName = camelCase( name ), 18943 isCustomProp = rcustomProp.test( name ); 18944 18945 // Make sure that we're working with the right name. We don't 18946 // want to modify the value if it is a CSS custom property 18947 // since they are user-defined. 18948 if ( !isCustomProp ) { 18949 name = finalPropName( origName ); 18950 } 18951 18952 // Try prefixed name followed by the unprefixed name 18953 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 18954 18955 // If a hook was provided get the computed value from there 18956 if ( hooks && "get" in hooks ) { 18957 val = hooks.get( elem, true, extra ); 18958 } 18959 18960 // Otherwise, if a way to get the computed value exists, use that 18961 if ( val === undefined ) { 18962 val = curCSS( elem, name, styles ); 18963 } 18964 18965 // Convert "normal" to computed value 18966 if ( val === "normal" && name in cssNormalTransform ) { 18967 val = cssNormalTransform[ name ]; 18968 } 18969 18970 // Make numeric if forced or a qualifier was provided and val looks numeric 18971 if ( extra === "" || extra ) { 18972 num = parseFloat( val ); 18973 return extra === true || isFinite( num ) ? num || 0 : val; 18974 } 18975 18976 return val; 18977 } 18978} ); 18979 18980jQuery.each( [ "height", "width" ], function( _i, dimension ) { 18981 jQuery.cssHooks[ dimension ] = { 18982 get: function( elem, computed, extra ) { 18983 if ( computed ) { 18984 18985 // Certain elements can have dimension info if we invisibly show them 18986 // but it must have a current display style that would benefit 18987 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 18988 18989 // Support: Safari 8+ 18990 // Table columns in Safari have non-zero offsetWidth & zero 18991 // getBoundingClientRect().width unless display is changed. 18992 // Support: IE <=11 only 18993 // Running getBoundingClientRect on a disconnected node 18994 // in IE throws an error. 18995 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 18996 swap( elem, cssShow, function() { 18997 return getWidthOrHeight( elem, dimension, extra ); 18998 } ) : 18999 getWidthOrHeight( elem, dimension, extra ); 19000 } 19001 }, 19002 19003 set: function( elem, value, extra ) { 19004 var matches, 19005 styles = getStyles( elem ), 19006 19007 // Only read styles.position if the test has a chance to fail 19008 // to avoid forcing a reflow. 19009 scrollboxSizeBuggy = !support.scrollboxSize() && 19010 styles.position === "absolute", 19011 19012 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 19013 boxSizingNeeded = scrollboxSizeBuggy || extra, 19014 isBorderBox = boxSizingNeeded && 19015 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 19016 subtract = extra ? 19017 boxModelAdjustment( 19018 elem, 19019 dimension, 19020 extra, 19021 isBorderBox, 19022 styles 19023 ) : 19024 0; 19025 19026 // Account for unreliable border-box dimensions by comparing offset* to computed and 19027 // faking a content-box to get border and padding (gh-3699) 19028 if ( isBorderBox && scrollboxSizeBuggy ) { 19029 subtract -= Math.ceil( 19030 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 19031 parseFloat( styles[ dimension ] ) - 19032 boxModelAdjustment( elem, dimension, "border", false, styles ) - 19033 0.5 19034 ); 19035 } 19036 19037 // Convert to pixels if value adjustment is needed 19038 if ( subtract && ( matches = rcssNum.exec( value ) ) && 19039 ( matches[ 3 ] || "px" ) !== "px" ) { 19040 19041 elem.style[ dimension ] = value; 19042 value = jQuery.css( elem, dimension ); 19043 } 19044 19045 return setPositiveNumber( elem, value, subtract ); 19046 } 19047 }; 19048} ); 19049 19050jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 19051 function( elem, computed ) { 19052 if ( computed ) { 19053 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 19054 elem.getBoundingClientRect().left - 19055 swap( elem, { marginLeft: 0 }, function() { 19056 return elem.getBoundingClientRect().left; 19057 } ) 19058 ) + "px"; 19059 } 19060 } 19061); 19062 19063// These hooks are used by animate to expand properties 19064jQuery.each( { 19065 margin: "", 19066 padding: "", 19067 border: "Width" 19068}, function( prefix, suffix ) { 19069 jQuery.cssHooks[ prefix + suffix ] = { 19070 expand: function( value ) { 19071 var i = 0, 19072 expanded = {}, 19073 19074 // Assumes a single number if not a string 19075 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 19076 19077 for ( ; i < 4; i++ ) { 19078 expanded[ prefix + cssExpand[ i ] + suffix ] = 19079 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 19080 } 19081 19082 return expanded; 19083 } 19084 }; 19085 19086 if ( prefix !== "margin" ) { 19087 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 19088 } 19089} ); 19090 19091jQuery.fn.extend( { 19092 css: function( name, value ) { 19093 return access( this, function( elem, name, value ) { 19094 var styles, len, 19095 map = {}, 19096 i = 0; 19097 19098 if ( Array.isArray( name ) ) { 19099 styles = getStyles( elem ); 19100 len = name.length; 19101 19102 for ( ; i < len; i++ ) { 19103 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 19104 } 19105 19106 return map; 19107 } 19108 19109 return value !== undefined ? 19110 jQuery.style( elem, name, value ) : 19111 jQuery.css( elem, name ); 19112 }, name, value, arguments.length > 1 ); 19113 } 19114} ); 19115 19116 19117function Tween( elem, options, prop, end, easing ) { 19118 return new Tween.prototype.init( elem, options, prop, end, easing ); 19119} 19120jQuery.Tween = Tween; 19121 19122Tween.prototype = { 19123 constructor: Tween, 19124 init: function( elem, options, prop, end, easing, unit ) { 19125 this.elem = elem; 19126 this.prop = prop; 19127 this.easing = easing || jQuery.easing._default; 19128 this.options = options; 19129 this.start = this.now = this.cur(); 19130 this.end = end; 19131 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 19132 }, 19133 cur: function() { 19134 var hooks = Tween.propHooks[ this.prop ]; 19135 19136 return hooks && hooks.get ? 19137 hooks.get( this ) : 19138 Tween.propHooks._default.get( this ); 19139 }, 19140 run: function( percent ) { 19141 var eased, 19142 hooks = Tween.propHooks[ this.prop ]; 19143 19144 if ( this.options.duration ) { 19145 this.pos = eased = jQuery.easing[ this.easing ]( 19146 percent, this.options.duration * percent, 0, 1, this.options.duration 19147 ); 19148 } else { 19149 this.pos = eased = percent; 19150 } 19151 this.now = ( this.end - this.start ) * eased + this.start; 19152 19153 if ( this.options.step ) { 19154 this.options.step.call( this.elem, this.now, this ); 19155 } 19156 19157 if ( hooks && hooks.set ) { 19158 hooks.set( this ); 19159 } else { 19160 Tween.propHooks._default.set( this ); 19161 } 19162 return this; 19163 } 19164}; 19165 19166Tween.prototype.init.prototype = Tween.prototype; 19167 19168Tween.propHooks = { 19169 _default: { 19170 get: function( tween ) { 19171 var result; 19172 19173 // Use a property on the element directly when it is not a DOM element, 19174 // or when there is no matching style property that exists. 19175 if ( tween.elem.nodeType !== 1 || 19176 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 19177 return tween.elem[ tween.prop ]; 19178 } 19179 19180 // Passing an empty string as a 3rd parameter to .css will automatically 19181 // attempt a parseFloat and fallback to a string if the parse fails. 19182 // Simple values such as "10px" are parsed to Float; 19183 // complex values such as "rotate(1rad)" are returned as-is. 19184 result = jQuery.css( tween.elem, tween.prop, "" ); 19185 19186 // Empty strings, null, undefined and "auto" are converted to 0. 19187 return !result || result === "auto" ? 0 : result; 19188 }, 19189 set: function( tween ) { 19190 19191 // Use step hook for back compat. 19192 // Use cssHook if its there. 19193 // Use .style if available and use plain properties where available. 19194 if ( jQuery.fx.step[ tween.prop ] ) { 19195 jQuery.fx.step[ tween.prop ]( tween ); 19196 } else if ( tween.elem.nodeType === 1 && ( 19197 jQuery.cssHooks[ tween.prop ] || 19198 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 19199 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 19200 } else { 19201 tween.elem[ tween.prop ] = tween.now; 19202 } 19203 } 19204 } 19205}; 19206 19207// Support: IE <=9 only 19208// Panic based approach to setting things on disconnected nodes 19209Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 19210 set: function( tween ) { 19211 if ( tween.elem.nodeType && tween.elem.parentNode ) { 19212 tween.elem[ tween.prop ] = tween.now; 19213 } 19214 } 19215}; 19216 19217jQuery.easing = { 19218 linear: function( p ) { 19219 return p; 19220 }, 19221 swing: function( p ) { 19222 return 0.5 - Math.cos( p * Math.PI ) / 2; 19223 }, 19224 _default: "swing" 19225}; 19226 19227jQuery.fx = Tween.prototype.init; 19228 19229// Back compat <1.8 extension point 19230jQuery.fx.step = {}; 19231 19232 19233 19234 19235var 19236 fxNow, inProgress, 19237 rfxtypes = /^(?:toggle|show|hide)$/, 19238 rrun = /queueHooks$/; 19239 19240function schedule() { 19241 if ( inProgress ) { 19242 if ( document.hidden === false && window.requestAnimationFrame ) { 19243 window.requestAnimationFrame( schedule ); 19244 } else { 19245 window.setTimeout( schedule, jQuery.fx.interval ); 19246 } 19247 19248 jQuery.fx.tick(); 19249 } 19250} 19251 19252// Animations created synchronously will run synchronously 19253function createFxNow() { 19254 window.setTimeout( function() { 19255 fxNow = undefined; 19256 } ); 19257 return ( fxNow = Date.now() ); 19258} 19259 19260// Generate parameters to create a standard animation 19261function genFx( type, includeWidth ) { 19262 var which, 19263 i = 0, 19264 attrs = { height: type }; 19265 19266 // If we include width, step value is 1 to do all cssExpand values, 19267 // otherwise step value is 2 to skip over Left and Right 19268 includeWidth = includeWidth ? 1 : 0; 19269 for ( ; i < 4; i += 2 - includeWidth ) { 19270 which = cssExpand[ i ]; 19271 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 19272 } 19273 19274 if ( includeWidth ) { 19275 attrs.opacity = attrs.width = type; 19276 } 19277 19278 return attrs; 19279} 19280 19281function createTween( value, prop, animation ) { 19282 var tween, 19283 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 19284 index = 0, 19285 length = collection.length; 19286 for ( ; index < length; index++ ) { 19287 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 19288 19289 // We're done with this property 19290 return tween; 19291 } 19292 } 19293} 19294 19295function defaultPrefilter( elem, props, opts ) { 19296 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 19297 isBox = "width" in props || "height" in props, 19298 anim = this, 19299 orig = {}, 19300 style = elem.style, 19301 hidden = elem.nodeType && isHiddenWithinTree( elem ), 19302 dataShow = dataPriv.get( elem, "fxshow" ); 19303 19304 // Queue-skipping animations hijack the fx hooks 19305 if ( !opts.queue ) { 19306 hooks = jQuery._queueHooks( elem, "fx" ); 19307 if ( hooks.unqueued == null ) { 19308 hooks.unqueued = 0; 19309 oldfire = hooks.empty.fire; 19310 hooks.empty.fire = function() { 19311 if ( !hooks.unqueued ) { 19312 oldfire(); 19313 } 19314 }; 19315 } 19316 hooks.unqueued++; 19317 19318 anim.always( function() { 19319 19320 // Ensure the complete handler is called before this completes 19321 anim.always( function() { 19322 hooks.unqueued--; 19323 if ( !jQuery.queue( elem, "fx" ).length ) { 19324 hooks.empty.fire(); 19325 } 19326 } ); 19327 } ); 19328 } 19329 19330 // Detect show/hide animations 19331 for ( prop in props ) { 19332 value = props[ prop ]; 19333 if ( rfxtypes.test( value ) ) { 19334 delete props[ prop ]; 19335 toggle = toggle || value === "toggle"; 19336 if ( value === ( hidden ? "hide" : "show" ) ) { 19337 19338 // Pretend to be hidden if this is a "show" and 19339 // there is still data from a stopped show/hide 19340 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 19341 hidden = true; 19342 19343 // Ignore all other no-op show/hide data 19344 } else { 19345 continue; 19346 } 19347 } 19348 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 19349 } 19350 } 19351 19352 // Bail out if this is a no-op like .hide().hide() 19353 propTween = !jQuery.isEmptyObject( props ); 19354 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 19355 return; 19356 } 19357 19358 // Restrict "overflow" and "display" styles during box animations 19359 if ( isBox && elem.nodeType === 1 ) { 19360 19361 // Support: IE <=9 - 11, Edge 12 - 15 19362 // Record all 3 overflow attributes because IE does not infer the shorthand 19363 // from identically-valued overflowX and overflowY and Edge just mirrors 19364 // the overflowX value there. 19365 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 19366 19367 // Identify a display type, preferring old show/hide data over the CSS cascade 19368 restoreDisplay = dataShow && dataShow.display; 19369 if ( restoreDisplay == null ) { 19370 restoreDisplay = dataPriv.get( elem, "display" ); 19371 } 19372 display = jQuery.css( elem, "display" ); 19373 if ( display === "none" ) { 19374 if ( restoreDisplay ) { 19375 display = restoreDisplay; 19376 } else { 19377 19378 // Get nonempty value(s) by temporarily forcing visibility 19379 showHide( [ elem ], true ); 19380 restoreDisplay = elem.style.display || restoreDisplay; 19381 display = jQuery.css( elem, "display" ); 19382 showHide( [ elem ] ); 19383 } 19384 } 19385 19386 // Animate inline elements as inline-block 19387 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 19388 if ( jQuery.css( elem, "float" ) === "none" ) { 19389 19390 // Restore the original display value at the end of pure show/hide animations 19391 if ( !propTween ) { 19392 anim.done( function() { 19393 style.display = restoreDisplay; 19394 } ); 19395 if ( restoreDisplay == null ) { 19396 display = style.display; 19397 restoreDisplay = display === "none" ? "" : display; 19398 } 19399 } 19400 style.display = "inline-block"; 19401 } 19402 } 19403 } 19404 19405 if ( opts.overflow ) { 19406 style.overflow = "hidden"; 19407 anim.always( function() { 19408 style.overflow = opts.overflow[ 0 ]; 19409 style.overflowX = opts.overflow[ 1 ]; 19410 style.overflowY = opts.overflow[ 2 ]; 19411 } ); 19412 } 19413 19414 // Implement show/hide animations 19415 propTween = false; 19416 for ( prop in orig ) { 19417 19418 // General show/hide setup for this element animation 19419 if ( !propTween ) { 19420 if ( dataShow ) { 19421 if ( "hidden" in dataShow ) { 19422 hidden = dataShow.hidden; 19423 } 19424 } else { 19425 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 19426 } 19427 19428 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 19429 if ( toggle ) { 19430 dataShow.hidden = !hidden; 19431 } 19432 19433 // Show elements before animating them 19434 if ( hidden ) { 19435 showHide( [ elem ], true ); 19436 } 19437 19438 /* eslint-disable no-loop-func */ 19439 19440 anim.done( function() { 19441 19442 /* eslint-enable no-loop-func */ 19443 19444 // The final step of a "hide" animation is actually hiding the element 19445 if ( !hidden ) { 19446 showHide( [ elem ] ); 19447 } 19448 dataPriv.remove( elem, "fxshow" ); 19449 for ( prop in orig ) { 19450 jQuery.style( elem, prop, orig[ prop ] ); 19451 } 19452 } ); 19453 } 19454 19455 // Per-property setup 19456 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 19457 if ( !( prop in dataShow ) ) { 19458 dataShow[ prop ] = propTween.start; 19459 if ( hidden ) { 19460 propTween.end = propTween.start; 19461 propTween.start = 0; 19462 } 19463 } 19464 } 19465} 19466 19467function propFilter( props, specialEasing ) { 19468 var index, name, easing, value, hooks; 19469 19470 // camelCase, specialEasing and expand cssHook pass 19471 for ( index in props ) { 19472 name = camelCase( index ); 19473 easing = specialEasing[ name ]; 19474 value = props[ index ]; 19475 if ( Array.isArray( value ) ) { 19476 easing = value[ 1 ]; 19477 value = props[ index ] = value[ 0 ]; 19478 } 19479 19480 if ( index !== name ) { 19481 props[ name ] = value; 19482 delete props[ index ]; 19483 } 19484 19485 hooks = jQuery.cssHooks[ name ]; 19486 if ( hooks && "expand" in hooks ) { 19487 value = hooks.expand( value ); 19488 delete props[ name ]; 19489 19490 // Not quite $.extend, this won't overwrite existing keys. 19491 // Reusing 'index' because we have the correct "name" 19492 for ( index in value ) { 19493 if ( !( index in props ) ) { 19494 props[ index ] = value[ index ]; 19495 specialEasing[ index ] = easing; 19496 } 19497 } 19498 } else { 19499 specialEasing[ name ] = easing; 19500 } 19501 } 19502} 19503 19504function Animation( elem, properties, options ) { 19505 var result, 19506 stopped, 19507 index = 0, 19508 length = Animation.prefilters.length, 19509 deferred = jQuery.Deferred().always( function() { 19510 19511 // Don't match elem in the :animated selector 19512 delete tick.elem; 19513 } ), 19514 tick = function() { 19515 if ( stopped ) { 19516 return false; 19517 } 19518 var currentTime = fxNow || createFxNow(), 19519 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 19520 19521 // Support: Android 2.3 only 19522 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) 19523 temp = remaining / animation.duration || 0, 19524 percent = 1 - temp, 19525 index = 0, 19526 length = animation.tweens.length; 19527 19528 for ( ; index < length; index++ ) { 19529 animation.tweens[ index ].run( percent ); 19530 } 19531 19532 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 19533 19534 // If there's more to do, yield 19535 if ( percent < 1 && length ) { 19536 return remaining; 19537 } 19538 19539 // If this was an empty animation, synthesize a final progress notification 19540 if ( !length ) { 19541 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 19542 } 19543 19544 // Resolve the animation and report its conclusion 19545 deferred.resolveWith( elem, [ animation ] ); 19546 return false; 19547 }, 19548 animation = deferred.promise( { 19549 elem: elem, 19550 props: jQuery.extend( {}, properties ), 19551 opts: jQuery.extend( true, { 19552 specialEasing: {}, 19553 easing: jQuery.easing._default 19554 }, options ), 19555 originalProperties: properties, 19556 originalOptions: options, 19557 startTime: fxNow || createFxNow(), 19558 duration: options.duration, 19559 tweens: [], 19560 createTween: function( prop, end ) { 19561 var tween = jQuery.Tween( elem, animation.opts, prop, end, 19562 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 19563 animation.tweens.push( tween ); 19564 return tween; 19565 }, 19566 stop: function( gotoEnd ) { 19567 var index = 0, 19568 19569 // If we are going to the end, we want to run all the tweens 19570 // otherwise we skip this part 19571 length = gotoEnd ? animation.tweens.length : 0; 19572 if ( stopped ) { 19573 return this; 19574 } 19575 stopped = true; 19576 for ( ; index < length; index++ ) { 19577 animation.tweens[ index ].run( 1 ); 19578 } 19579 19580 // Resolve when we played the last frame; otherwise, reject 19581 if ( gotoEnd ) { 19582 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 19583 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 19584 } else { 19585 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 19586 } 19587 return this; 19588 } 19589 } ), 19590 props = animation.props; 19591 19592 propFilter( props, animation.opts.specialEasing ); 19593 19594 for ( ; index < length; index++ ) { 19595 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 19596 if ( result ) { 19597 if ( isFunction( result.stop ) ) { 19598 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 19599 result.stop.bind( result ); 19600 } 19601 return result; 19602 } 19603 } 19604 19605 jQuery.map( props, createTween, animation ); 19606 19607 if ( isFunction( animation.opts.start ) ) { 19608 animation.opts.start.call( elem, animation ); 19609 } 19610 19611 // Attach callbacks from options 19612 animation 19613 .progress( animation.opts.progress ) 19614 .done( animation.opts.done, animation.opts.complete ) 19615 .fail( animation.opts.fail ) 19616 .always( animation.opts.always ); 19617 19618 jQuery.fx.timer( 19619 jQuery.extend( tick, { 19620 elem: elem, 19621 anim: animation, 19622 queue: animation.opts.queue 19623 } ) 19624 ); 19625 19626 return animation; 19627} 19628 19629jQuery.Animation = jQuery.extend( Animation, { 19630 19631 tweeners: { 19632 "*": [ function( prop, value ) { 19633 var tween = this.createTween( prop, value ); 19634 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 19635 return tween; 19636 } ] 19637 }, 19638 19639 tweener: function( props, callback ) { 19640 if ( isFunction( props ) ) { 19641 callback = props; 19642 props = [ "*" ]; 19643 } else { 19644 props = props.match( rnothtmlwhite ); 19645 } 19646 19647 var prop, 19648 index = 0, 19649 length = props.length; 19650 19651 for ( ; index < length; index++ ) { 19652 prop = props[ index ]; 19653 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 19654 Animation.tweeners[ prop ].unshift( callback ); 19655 } 19656 }, 19657 19658 prefilters: [ defaultPrefilter ], 19659 19660 prefilter: function( callback, prepend ) { 19661 if ( prepend ) { 19662 Animation.prefilters.unshift( callback ); 19663 } else { 19664 Animation.prefilters.push( callback ); 19665 } 19666 } 19667} ); 19668 19669jQuery.speed = function( speed, easing, fn ) { 19670 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 19671 complete: fn || !fn && easing || 19672 isFunction( speed ) && speed, 19673 duration: speed, 19674 easing: fn && easing || easing && !isFunction( easing ) && easing 19675 }; 19676 19677 // Go to the end state if fx are off 19678 if ( jQuery.fx.off ) { 19679 opt.duration = 0; 19680 19681 } else { 19682 if ( typeof opt.duration !== "number" ) { 19683 if ( opt.duration in jQuery.fx.speeds ) { 19684 opt.duration = jQuery.fx.speeds[ opt.duration ]; 19685 19686 } else { 19687 opt.duration = jQuery.fx.speeds._default; 19688 } 19689 } 19690 } 19691 19692 // Normalize opt.queue - true/undefined/null -> "fx" 19693 if ( opt.queue == null || opt.queue === true ) { 19694 opt.queue = "fx"; 19695 } 19696 19697 // Queueing 19698 opt.old = opt.complete; 19699 19700 opt.complete = function() { 19701 if ( isFunction( opt.old ) ) { 19702 opt.old.call( this ); 19703 } 19704 19705 if ( opt.queue ) { 19706 jQuery.dequeue( this, opt.queue ); 19707 } 19708 }; 19709 19710 return opt; 19711}; 19712 19713jQuery.fn.extend( { 19714 fadeTo: function( speed, to, easing, callback ) { 19715 19716 // Show any hidden elements after setting opacity to 0 19717 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 19718 19719 // Animate to the value specified 19720 .end().animate( { opacity: to }, speed, easing, callback ); 19721 }, 19722 animate: function( prop, speed, easing, callback ) { 19723 var empty = jQuery.isEmptyObject( prop ), 19724 optall = jQuery.speed( speed, easing, callback ), 19725 doAnimation = function() { 19726 19727 // Operate on a copy of prop so per-property easing won't be lost 19728 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 19729 19730 // Empty animations, or finishing resolves immediately 19731 if ( empty || dataPriv.get( this, "finish" ) ) { 19732 anim.stop( true ); 19733 } 19734 }; 19735 19736 doAnimation.finish = doAnimation; 19737 19738 return empty || optall.queue === false ? 19739 this.each( doAnimation ) : 19740 this.queue( optall.queue, doAnimation ); 19741 }, 19742 stop: function( type, clearQueue, gotoEnd ) { 19743 var stopQueue = function( hooks ) { 19744 var stop = hooks.stop; 19745 delete hooks.stop; 19746 stop( gotoEnd ); 19747 }; 19748 19749 if ( typeof type !== "string" ) { 19750 gotoEnd = clearQueue; 19751 clearQueue = type; 19752 type = undefined; 19753 } 19754 if ( clearQueue ) { 19755 this.queue( type || "fx", [] ); 19756 } 19757 19758 return this.each( function() { 19759 var dequeue = true, 19760 index = type != null && type + "queueHooks", 19761 timers = jQuery.timers, 19762 data = dataPriv.get( this ); 19763 19764 if ( index ) { 19765 if ( data[ index ] && data[ index ].stop ) { 19766 stopQueue( data[ index ] ); 19767 } 19768 } else { 19769 for ( index in data ) { 19770 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 19771 stopQueue( data[ index ] ); 19772 } 19773 } 19774 } 19775 19776 for ( index = timers.length; index--; ) { 19777 if ( timers[ index ].elem === this && 19778 ( type == null || timers[ index ].queue === type ) ) { 19779 19780 timers[ index ].anim.stop( gotoEnd ); 19781 dequeue = false; 19782 timers.splice( index, 1 ); 19783 } 19784 } 19785 19786 // Start the next in the queue if the last step wasn't forced. 19787 // Timers currently will call their complete callbacks, which 19788 // will dequeue but only if they were gotoEnd. 19789 if ( dequeue || !gotoEnd ) { 19790 jQuery.dequeue( this, type ); 19791 } 19792 } ); 19793 }, 19794 finish: function( type ) { 19795 if ( type !== false ) { 19796 type = type || "fx"; 19797 } 19798 return this.each( function() { 19799 var index, 19800 data = dataPriv.get( this ), 19801 queue = data[ type + "queue" ], 19802 hooks = data[ type + "queueHooks" ], 19803 timers = jQuery.timers, 19804 length = queue ? queue.length : 0; 19805 19806 // Enable finishing flag on private data 19807 data.finish = true; 19808 19809 // Empty the queue first 19810 jQuery.queue( this, type, [] ); 19811 19812 if ( hooks && hooks.stop ) { 19813 hooks.stop.call( this, true ); 19814 } 19815 19816 // Look for any active animations, and finish them 19817 for ( index = timers.length; index--; ) { 19818 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 19819 timers[ index ].anim.stop( true ); 19820 timers.splice( index, 1 ); 19821 } 19822 } 19823 19824 // Look for any animations in the old queue and finish them 19825 for ( index = 0; index < length; index++ ) { 19826 if ( queue[ index ] && queue[ index ].finish ) { 19827 queue[ index ].finish.call( this ); 19828 } 19829 } 19830 19831 // Turn off finishing flag 19832 delete data.finish; 19833 } ); 19834 } 19835} ); 19836 19837jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 19838 var cssFn = jQuery.fn[ name ]; 19839 jQuery.fn[ name ] = function( speed, easing, callback ) { 19840 return speed == null || typeof speed === "boolean" ? 19841 cssFn.apply( this, arguments ) : 19842 this.animate( genFx( name, true ), speed, easing, callback ); 19843 }; 19844} ); 19845 19846// Generate shortcuts for custom animations 19847jQuery.each( { 19848 slideDown: genFx( "show" ), 19849 slideUp: genFx( "hide" ), 19850 slideToggle: genFx( "toggle" ), 19851 fadeIn: { opacity: "show" }, 19852 fadeOut: { opacity: "hide" }, 19853 fadeToggle: { opacity: "toggle" } 19854}, function( name, props ) { 19855 jQuery.fn[ name ] = function( speed, easing, callback ) { 19856 return this.animate( props, speed, easing, callback ); 19857 }; 19858} ); 19859 19860jQuery.timers = []; 19861jQuery.fx.tick = function() { 19862 var timer, 19863 i = 0, 19864 timers = jQuery.timers; 19865 19866 fxNow = Date.now(); 19867 19868 for ( ; i < timers.length; i++ ) { 19869 timer = timers[ i ]; 19870 19871 // Run the timer and safely remove it when done (allowing for external removal) 19872 if ( !timer() && timers[ i ] === timer ) { 19873 timers.splice( i--, 1 ); 19874 } 19875 } 19876 19877 if ( !timers.length ) { 19878 jQuery.fx.stop(); 19879 } 19880 fxNow = undefined; 19881}; 19882 19883jQuery.fx.timer = function( timer ) { 19884 jQuery.timers.push( timer ); 19885 jQuery.fx.start(); 19886}; 19887 19888jQuery.fx.interval = 13; 19889jQuery.fx.start = function() { 19890 if ( inProgress ) { 19891 return; 19892 } 19893 19894 inProgress = true; 19895 schedule(); 19896}; 19897 19898jQuery.fx.stop = function() { 19899 inProgress = null; 19900}; 19901 19902jQuery.fx.speeds = { 19903 slow: 600, 19904 fast: 200, 19905 19906 // Default speed 19907 _default: 400 19908}; 19909 19910 19911// Based off of the plugin by Clint Helfers, with permission. 19912jQuery.fn.delay = function( time, type ) { 19913 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 19914 type = type || "fx"; 19915 19916 return this.queue( type, function( next, hooks ) { 19917 var timeout = window.setTimeout( next, time ); 19918 hooks.stop = function() { 19919 window.clearTimeout( timeout ); 19920 }; 19921 } ); 19922}; 19923 19924 19925( function() { 19926 var input = document.createElement( "input" ), 19927 select = document.createElement( "select" ), 19928 opt = select.appendChild( document.createElement( "option" ) ); 19929 19930 input.type = "checkbox"; 19931 19932 // Support: Android <=4.3 only 19933 // Default value for a checkbox should be "on" 19934 support.checkOn = input.value !== ""; 19935 19936 // Support: IE <=11 only 19937 // Must access selectedIndex to make default options select 19938 support.optSelected = opt.selected; 19939 19940 // Support: IE <=11 only 19941 // An input loses its value after becoming a radio 19942 input = document.createElement( "input" ); 19943 input.value = "t"; 19944 input.type = "radio"; 19945 support.radioValue = input.value === "t"; 19946} )(); 19947 19948 19949var boolHook, 19950 attrHandle = jQuery.expr.attrHandle; 19951 19952jQuery.fn.extend( { 19953 attr: function( name, value ) { 19954 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 19955 }, 19956 19957 removeAttr: function( name ) { 19958 return this.each( function() { 19959 jQuery.removeAttr( this, name ); 19960 } ); 19961 } 19962} ); 19963 19964jQuery.extend( { 19965 attr: function( elem, name, value ) { 19966 var ret, hooks, 19967 nType = elem.nodeType; 19968 19969 // Don't get/set attributes on text, comment and attribute nodes 19970 if ( nType === 3 || nType === 8 || nType === 2 ) { 19971 return; 19972 } 19973 19974 // Fallback to prop when attributes are not supported 19975 if ( typeof elem.getAttribute === "undefined" ) { 19976 return jQuery.prop( elem, name, value ); 19977 } 19978 19979 // Attribute hooks are determined by the lowercase version 19980 // Grab necessary hook if one is defined 19981 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 19982 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 19983 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 19984 } 19985 19986 if ( value !== undefined ) { 19987 if ( value === null ) { 19988 jQuery.removeAttr( elem, name ); 19989 return; 19990 } 19991 19992 if ( hooks && "set" in hooks && 19993 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 19994 return ret; 19995 } 19996 19997 elem.setAttribute( name, value + "" ); 19998 return value; 19999 } 20000 20001 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 20002 return ret; 20003 } 20004 20005 ret = jQuery.find.attr( elem, name ); 20006 20007 // Non-existent attributes return null, we normalize to undefined 20008 return ret == null ? undefined : ret; 20009 }, 20010 20011 attrHooks: { 20012 type: { 20013 set: function( elem, value ) { 20014 if ( !support.radioValue && value === "radio" && 20015 nodeName( elem, "input" ) ) { 20016 var val = elem.value; 20017 elem.setAttribute( "type", value ); 20018 if ( val ) { 20019 elem.value = val; 20020 } 20021 return value; 20022 } 20023 } 20024 } 20025 }, 20026 20027 removeAttr: function( elem, value ) { 20028 var name, 20029 i = 0, 20030 20031 // Attribute names can contain non-HTML whitespace characters 20032 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 20033 attrNames = value && value.match( rnothtmlwhite ); 20034 20035 if ( attrNames && elem.nodeType === 1 ) { 20036 while ( ( name = attrNames[ i++ ] ) ) { 20037 elem.removeAttribute( name ); 20038 } 20039 } 20040 } 20041} ); 20042 20043// Hooks for boolean attributes 20044boolHook = { 20045 set: function( elem, value, name ) { 20046 if ( value === false ) { 20047 20048 // Remove boolean attributes when set to false 20049 jQuery.removeAttr( elem, name ); 20050 } else { 20051 elem.setAttribute( name, name ); 20052 } 20053 return name; 20054 } 20055}; 20056 20057jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 20058 var getter = attrHandle[ name ] || jQuery.find.attr; 20059 20060 attrHandle[ name ] = function( elem, name, isXML ) { 20061 var ret, handle, 20062 lowercaseName = name.toLowerCase(); 20063 20064 if ( !isXML ) { 20065 20066 // Avoid an infinite loop by temporarily removing this function from the getter 20067 handle = attrHandle[ lowercaseName ]; 20068 attrHandle[ lowercaseName ] = ret; 20069 ret = getter( elem, name, isXML ) != null ? 20070 lowercaseName : 20071 null; 20072 attrHandle[ lowercaseName ] = handle; 20073 } 20074 return ret; 20075 }; 20076} ); 20077 20078 20079 20080 20081var rfocusable = /^(?:input|select|textarea|button)$/i, 20082 rclickable = /^(?:a|area)$/i; 20083 20084jQuery.fn.extend( { 20085 prop: function( name, value ) { 20086 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 20087 }, 20088 20089 removeProp: function( name ) { 20090 return this.each( function() { 20091 delete this[ jQuery.propFix[ name ] || name ]; 20092 } ); 20093 } 20094} ); 20095 20096jQuery.extend( { 20097 prop: function( elem, name, value ) { 20098 var ret, hooks, 20099 nType = elem.nodeType; 20100 20101 // Don't get/set properties on text, comment and attribute nodes 20102 if ( nType === 3 || nType === 8 || nType === 2 ) { 20103 return; 20104 } 20105 20106 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 20107 20108 // Fix name and attach hooks 20109 name = jQuery.propFix[ name ] || name; 20110 hooks = jQuery.propHooks[ name ]; 20111 } 20112 20113 if ( value !== undefined ) { 20114 if ( hooks && "set" in hooks && 20115 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 20116 return ret; 20117 } 20118 20119 return ( elem[ name ] = value ); 20120 } 20121 20122 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 20123 return ret; 20124 } 20125 20126 return elem[ name ]; 20127 }, 20128 20129 propHooks: { 20130 tabIndex: { 20131 get: function( elem ) { 20132 20133 // Support: IE <=9 - 11 only 20134 // elem.tabIndex doesn't always return the 20135 // correct value when it hasn't been explicitly set 20136 // Use proper attribute retrieval (trac-12072) 20137 var tabindex = jQuery.find.attr( elem, "tabindex" ); 20138 20139 if ( tabindex ) { 20140 return parseInt( tabindex, 10 ); 20141 } 20142 20143 if ( 20144 rfocusable.test( elem.nodeName ) || 20145 rclickable.test( elem.nodeName ) && 20146 elem.href 20147 ) { 20148 return 0; 20149 } 20150 20151 return -1; 20152 } 20153 } 20154 }, 20155 20156 propFix: { 20157 "for": "htmlFor", 20158 "class": "className" 20159 } 20160} ); 20161 20162// Support: IE <=11 only 20163// Accessing the selectedIndex property 20164// forces the browser to respect setting selected 20165// on the option 20166// The getter ensures a default option is selected 20167// when in an optgroup 20168// eslint rule "no-unused-expressions" is disabled for this code 20169// since it considers such accessions noop 20170if ( !support.optSelected ) { 20171 jQuery.propHooks.selected = { 20172 get: function( elem ) { 20173 20174 /* eslint no-unused-expressions: "off" */ 20175 20176 var parent = elem.parentNode; 20177 if ( parent && parent.parentNode ) { 20178 parent.parentNode.selectedIndex; 20179 } 20180 return null; 20181 }, 20182 set: function( elem ) { 20183 20184 /* eslint no-unused-expressions: "off" */ 20185 20186 var parent = elem.parentNode; 20187 if ( parent ) { 20188 parent.selectedIndex; 20189 20190 if ( parent.parentNode ) { 20191 parent.parentNode.selectedIndex; 20192 } 20193 } 20194 } 20195 }; 20196} 20197 20198jQuery.each( [ 20199 "tabIndex", 20200 "readOnly", 20201 "maxLength", 20202 "cellSpacing", 20203 "cellPadding", 20204 "rowSpan", 20205 "colSpan", 20206 "useMap", 20207 "frameBorder", 20208 "contentEditable" 20209], function() { 20210 jQuery.propFix[ this.toLowerCase() ] = this; 20211} ); 20212 20213 20214 20215 20216 // Strip and collapse whitespace according to HTML spec 20217 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 20218 function stripAndCollapse( value ) { 20219 var tokens = value.match( rnothtmlwhite ) || []; 20220 return tokens.join( " " ); 20221 } 20222 20223 20224function getClass( elem ) { 20225 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 20226} 20227 20228function classesToArray( value ) { 20229 if ( Array.isArray( value ) ) { 20230 return value; 20231 } 20232 if ( typeof value === "string" ) { 20233 return value.match( rnothtmlwhite ) || []; 20234 } 20235 return []; 20236} 20237 20238jQuery.fn.extend( { 20239 addClass: function( value ) { 20240 var classNames, cur, curValue, className, i, finalValue; 20241 20242 if ( isFunction( value ) ) { 20243 return this.each( function( j ) { 20244 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 20245 } ); 20246 } 20247 20248 classNames = classesToArray( value ); 20249 20250 if ( classNames.length ) { 20251 return this.each( function() { 20252 curValue = getClass( this ); 20253 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 20254 20255 if ( cur ) { 20256 for ( i = 0; i < classNames.length; i++ ) { 20257 className = classNames[ i ]; 20258 if ( cur.indexOf( " " + className + " " ) < 0 ) { 20259 cur += className + " "; 20260 } 20261 } 20262 20263 // Only assign if different to avoid unneeded rendering. 20264 finalValue = stripAndCollapse( cur ); 20265 if ( curValue !== finalValue ) { 20266 this.setAttribute( "class", finalValue ); 20267 } 20268 } 20269 } ); 20270 } 20271 20272 return this; 20273 }, 20274 20275 removeClass: function( value ) { 20276 var classNames, cur, curValue, className, i, finalValue; 20277 20278 if ( isFunction( value ) ) { 20279 return this.each( function( j ) { 20280 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 20281 } ); 20282 } 20283 20284 if ( !arguments.length ) { 20285 return this.attr( "class", "" ); 20286 } 20287 20288 classNames = classesToArray( value ); 20289 20290 if ( classNames.length ) { 20291 return this.each( function() { 20292 curValue = getClass( this ); 20293 20294 // This expression is here for better compressibility (see addClass) 20295 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 20296 20297 if ( cur ) { 20298 for ( i = 0; i < classNames.length; i++ ) { 20299 className = classNames[ i ]; 20300 20301 // Remove *all* instances 20302 while ( cur.indexOf( " " + className + " " ) > -1 ) { 20303 cur = cur.replace( " " + className + " ", " " ); 20304 } 20305 } 20306 20307 // Only assign if different to avoid unneeded rendering. 20308 finalValue = stripAndCollapse( cur ); 20309 if ( curValue !== finalValue ) { 20310 this.setAttribute( "class", finalValue ); 20311 } 20312 } 20313 } ); 20314 } 20315 20316 return this; 20317 }, 20318 20319 toggleClass: function( value, stateVal ) { 20320 var classNames, className, i, self, 20321 type = typeof value, 20322 isValidValue = type === "string" || Array.isArray( value ); 20323 20324 if ( isFunction( value ) ) { 20325 return this.each( function( i ) { 20326 jQuery( this ).toggleClass( 20327 value.call( this, i, getClass( this ), stateVal ), 20328 stateVal 20329 ); 20330 } ); 20331 } 20332 20333 if ( typeof stateVal === "boolean" && isValidValue ) { 20334 return stateVal ? this.addClass( value ) : this.removeClass( value ); 20335 } 20336 20337 classNames = classesToArray( value ); 20338 20339 return this.each( function() { 20340 if ( isValidValue ) { 20341 20342 // Toggle individual class names 20343 self = jQuery( this ); 20344 20345 for ( i = 0; i < classNames.length; i++ ) { 20346 className = classNames[ i ]; 20347 20348 // Check each className given, space separated list 20349 if ( self.hasClass( className ) ) { 20350 self.removeClass( className ); 20351 } else { 20352 self.addClass( className ); 20353 } 20354 } 20355 20356 // Toggle whole class name 20357 } else if ( value === undefined || type === "boolean" ) { 20358 className = getClass( this ); 20359 if ( className ) { 20360 20361 // Store className if set 20362 dataPriv.set( this, "__className__", className ); 20363 } 20364 20365 // If the element has a class name or if we're passed `false`, 20366 // then remove the whole classname (if there was one, the above saved it). 20367 // Otherwise bring back whatever was previously saved (if anything), 20368 // falling back to the empty string if nothing was stored. 20369 if ( this.setAttribute ) { 20370 this.setAttribute( "class", 20371 className || value === false ? 20372 "" : 20373 dataPriv.get( this, "__className__" ) || "" 20374 ); 20375 } 20376 } 20377 } ); 20378 }, 20379 20380 hasClass: function( selector ) { 20381 var className, elem, 20382 i = 0; 20383 20384 className = " " + selector + " "; 20385 while ( ( elem = this[ i++ ] ) ) { 20386 if ( elem.nodeType === 1 && 20387 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 20388 return true; 20389 } 20390 } 20391 20392 return false; 20393 } 20394} ); 20395 20396 20397 20398 20399var rreturn = /\r/g; 20400 20401jQuery.fn.extend( { 20402 val: function( value ) { 20403 var hooks, ret, valueIsFunction, 20404 elem = this[ 0 ]; 20405 20406 if ( !arguments.length ) { 20407 if ( elem ) { 20408 hooks = jQuery.valHooks[ elem.type ] || 20409 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 20410 20411 if ( hooks && 20412 "get" in hooks && 20413 ( ret = hooks.get( elem, "value" ) ) !== undefined 20414 ) { 20415 return ret; 20416 } 20417 20418 ret = elem.value; 20419 20420 // Handle most common string cases 20421 if ( typeof ret === "string" ) { 20422 return ret.replace( rreturn, "" ); 20423 } 20424 20425 // Handle cases where value is null/undef or number 20426 return ret == null ? "" : ret; 20427 } 20428 20429 return; 20430 } 20431 20432 valueIsFunction = isFunction( value ); 20433 20434 return this.each( function( i ) { 20435 var val; 20436 20437 if ( this.nodeType !== 1 ) { 20438 return; 20439 } 20440 20441 if ( valueIsFunction ) { 20442 val = value.call( this, i, jQuery( this ).val() ); 20443 } else { 20444 val = value; 20445 } 20446 20447 // Treat null/undefined as ""; convert numbers to string 20448 if ( val == null ) { 20449 val = ""; 20450 20451 } else if ( typeof val === "number" ) { 20452 val += ""; 20453 20454 } else if ( Array.isArray( val ) ) { 20455 val = jQuery.map( val, function( value ) { 20456 return value == null ? "" : value + ""; 20457 } ); 20458 } 20459 20460 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 20461 20462 // If set returns undefined, fall back to normal setting 20463 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 20464 this.value = val; 20465 } 20466 } ); 20467 } 20468} ); 20469 20470jQuery.extend( { 20471 valHooks: { 20472 option: { 20473 get: function( elem ) { 20474 20475 var val = jQuery.find.attr( elem, "value" ); 20476 return val != null ? 20477 val : 20478 20479 // Support: IE <=10 - 11 only 20480 // option.text throws exceptions (trac-14686, trac-14858) 20481 // Strip and collapse whitespace 20482 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 20483 stripAndCollapse( jQuery.text( elem ) ); 20484 } 20485 }, 20486 select: { 20487 get: function( elem ) { 20488 var value, option, i, 20489 options = elem.options, 20490 index = elem.selectedIndex, 20491 one = elem.type === "select-one", 20492 values = one ? null : [], 20493 max = one ? index + 1 : options.length; 20494 20495 if ( index < 0 ) { 20496 i = max; 20497 20498 } else { 20499 i = one ? index : 0; 20500 } 20501 20502 // Loop through all the selected options 20503 for ( ; i < max; i++ ) { 20504 option = options[ i ]; 20505 20506 // Support: IE <=9 only 20507 // IE8-9 doesn't update selected after form reset (trac-2551) 20508 if ( ( option.selected || i === index ) && 20509 20510 // Don't return options that are disabled or in a disabled optgroup 20511 !option.disabled && 20512 ( !option.parentNode.disabled || 20513 !nodeName( option.parentNode, "optgroup" ) ) ) { 20514 20515 // Get the specific value for the option 20516 value = jQuery( option ).val(); 20517 20518 // We don't need an array for one selects 20519 if ( one ) { 20520 return value; 20521 } 20522 20523 // Multi-Selects return an array 20524 values.push( value ); 20525 } 20526 } 20527 20528 return values; 20529 }, 20530 20531 set: function( elem, value ) { 20532 var optionSet, option, 20533 options = elem.options, 20534 values = jQuery.makeArray( value ), 20535 i = options.length; 20536 20537 while ( i-- ) { 20538 option = options[ i ]; 20539 20540 /* eslint-disable no-cond-assign */ 20541 20542 if ( option.selected = 20543 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 20544 ) { 20545 optionSet = true; 20546 } 20547 20548 /* eslint-enable no-cond-assign */ 20549 } 20550 20551 // Force browsers to behave consistently when non-matching value is set 20552 if ( !optionSet ) { 20553 elem.selectedIndex = -1; 20554 } 20555 return values; 20556 } 20557 } 20558 } 20559} ); 20560 20561// Radios and checkboxes getter/setter 20562jQuery.each( [ "radio", "checkbox" ], function() { 20563 jQuery.valHooks[ this ] = { 20564 set: function( elem, value ) { 20565 if ( Array.isArray( value ) ) { 20566 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 20567 } 20568 } 20569 }; 20570 if ( !support.checkOn ) { 20571 jQuery.valHooks[ this ].get = function( elem ) { 20572 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 20573 }; 20574 } 20575} ); 20576 20577 20578 20579 20580// Return jQuery for attributes-only inclusion 20581 20582 20583support.focusin = "onfocusin" in window; 20584 20585 20586var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 20587 stopPropagationCallback = function( e ) { 20588 e.stopPropagation(); 20589 }; 20590 20591jQuery.extend( jQuery.event, { 20592 20593 trigger: function( event, data, elem, onlyHandlers ) { 20594 20595 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 20596 eventPath = [ elem || document ], 20597 type = hasOwn.call( event, "type" ) ? event.type : event, 20598 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 20599 20600 cur = lastElement = tmp = elem = elem || document; 20601 20602 // Don't do events on text and comment nodes 20603 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 20604 return; 20605 } 20606 20607 // focus/blur morphs to focusin/out; ensure we're not firing them right now 20608 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 20609 return; 20610 } 20611 20612 if ( type.indexOf( "." ) > -1 ) { 20613 20614 // Namespaced trigger; create a regexp to match event type in handle() 20615 namespaces = type.split( "." ); 20616 type = namespaces.shift(); 20617 namespaces.sort(); 20618 } 20619 ontype = type.indexOf( ":" ) < 0 && "on" + type; 20620 20621 // Caller can pass in a jQuery.Event object, Object, or just an event type string 20622 event = event[ jQuery.expando ] ? 20623 event : 20624 new jQuery.Event( type, typeof event === "object" && event ); 20625 20626 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 20627 event.isTrigger = onlyHandlers ? 2 : 3; 20628 event.namespace = namespaces.join( "." ); 20629 event.rnamespace = event.namespace ? 20630 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 20631 null; 20632 20633 // Clean up the event in case it is being reused 20634 event.result = undefined; 20635 if ( !event.target ) { 20636 event.target = elem; 20637 } 20638 20639 // Clone any incoming data and prepend the event, creating the handler arg list 20640 data = data == null ? 20641 [ event ] : 20642 jQuery.makeArray( data, [ event ] ); 20643 20644 // Allow special events to draw outside the lines 20645 special = jQuery.event.special[ type ] || {}; 20646 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 20647 return; 20648 } 20649 20650 // Determine event propagation path in advance, per W3C events spec (trac-9951) 20651 // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) 20652 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 20653 20654 bubbleType = special.delegateType || type; 20655 if ( !rfocusMorph.test( bubbleType + type ) ) { 20656 cur = cur.parentNode; 20657 } 20658 for ( ; cur; cur = cur.parentNode ) { 20659 eventPath.push( cur ); 20660 tmp = cur; 20661 } 20662 20663 // Only add window if we got to document (e.g., not plain obj or detached DOM) 20664 if ( tmp === ( elem.ownerDocument || document ) ) { 20665 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 20666 } 20667 } 20668 20669 // Fire handlers on the event path 20670 i = 0; 20671 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 20672 lastElement = cur; 20673 event.type = i > 1 ? 20674 bubbleType : 20675 special.bindType || type; 20676 20677 // jQuery handler 20678 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 20679 dataPriv.get( cur, "handle" ); 20680 if ( handle ) { 20681 handle.apply( cur, data ); 20682 } 20683 20684 // Native handler 20685 handle = ontype && cur[ ontype ]; 20686 if ( handle && handle.apply && acceptData( cur ) ) { 20687 event.result = handle.apply( cur, data ); 20688 if ( event.result === false ) { 20689 event.preventDefault(); 20690 } 20691 } 20692 } 20693 event.type = type; 20694 20695 // If nobody prevented the default action, do it now 20696 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 20697 20698 if ( ( !special._default || 20699 special._default.apply( eventPath.pop(), data ) === false ) && 20700 acceptData( elem ) ) { 20701 20702 // Call a native DOM method on the target with the same name as the event. 20703 // Don't do default actions on window, that's where global variables be (trac-6170) 20704 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 20705 20706 // Don't re-trigger an onFOO event when we call its FOO() method 20707 tmp = elem[ ontype ]; 20708 20709 if ( tmp ) { 20710 elem[ ontype ] = null; 20711 } 20712 20713 // Prevent re-triggering of the same event, since we already bubbled it above 20714 jQuery.event.triggered = type; 20715 20716 if ( event.isPropagationStopped() ) { 20717 lastElement.addEventListener( type, stopPropagationCallback ); 20718 } 20719 20720 elem[ type ](); 20721 20722 if ( event.isPropagationStopped() ) { 20723 lastElement.removeEventListener( type, stopPropagationCallback ); 20724 } 20725 20726 jQuery.event.triggered = undefined; 20727 20728 if ( tmp ) { 20729 elem[ ontype ] = tmp; 20730 } 20731 } 20732 } 20733 } 20734 20735 return event.result; 20736 }, 20737 20738 // Piggyback on a donor event to simulate a different one 20739 // Used only for `focus(in | out)` events 20740 simulate: function( type, elem, event ) { 20741 var e = jQuery.extend( 20742 new jQuery.Event(), 20743 event, 20744 { 20745 type: type, 20746 isSimulated: true 20747 } 20748 ); 20749 20750 jQuery.event.trigger( e, null, elem ); 20751 } 20752 20753} ); 20754 20755jQuery.fn.extend( { 20756 20757 trigger: function( type, data ) { 20758 return this.each( function() { 20759 jQuery.event.trigger( type, data, this ); 20760 } ); 20761 }, 20762 triggerHandler: function( type, data ) { 20763 var elem = this[ 0 ]; 20764 if ( elem ) { 20765 return jQuery.event.trigger( type, data, elem, true ); 20766 } 20767 } 20768} ); 20769 20770 20771// Support: Firefox <=44 20772// Firefox doesn't have focus(in | out) events 20773// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 20774// 20775// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 20776// focus(in | out) events fire after focus & blur events, 20777// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 20778// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 20779if ( !support.focusin ) { 20780 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 20781 20782 // Attach a single capturing handler on the document while someone wants focusin/focusout 20783 var handler = function( event ) { 20784 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 20785 }; 20786 20787 jQuery.event.special[ fix ] = { 20788 setup: function() { 20789 20790 // Handle: regular nodes (via `this.ownerDocument`), window 20791 // (via `this.document`) & document (via `this`). 20792 var doc = this.ownerDocument || this.document || this, 20793 attaches = dataPriv.access( doc, fix ); 20794 20795 if ( !attaches ) { 20796 doc.addEventListener( orig, handler, true ); 20797 } 20798 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 20799 }, 20800 teardown: function() { 20801 var doc = this.ownerDocument || this.document || this, 20802 attaches = dataPriv.access( doc, fix ) - 1; 20803 20804 if ( !attaches ) { 20805 doc.removeEventListener( orig, handler, true ); 20806 dataPriv.remove( doc, fix ); 20807 20808 } else { 20809 dataPriv.access( doc, fix, attaches ); 20810 } 20811 } 20812 }; 20813 } ); 20814} 20815var location = window.location; 20816 20817var nonce = { guid: Date.now() }; 20818 20819var rquery = ( /\?/ ); 20820 20821 20822 20823// Cross-browser xml parsing 20824jQuery.parseXML = function( data ) { 20825 var xml, parserErrorElem; 20826 if ( !data || typeof data !== "string" ) { 20827 return null; 20828 } 20829 20830 // Support: IE 9 - 11 only 20831 // IE throws on parseFromString with invalid input. 20832 try { 20833 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 20834 } catch ( e ) {} 20835 20836 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 20837 if ( !xml || parserErrorElem ) { 20838 jQuery.error( "Invalid XML: " + ( 20839 parserErrorElem ? 20840 jQuery.map( parserErrorElem.childNodes, function( el ) { 20841 return el.textContent; 20842 } ).join( "\n" ) : 20843 data 20844 ) ); 20845 } 20846 return xml; 20847}; 20848 20849 20850var 20851 rbracket = /\[\]$/, 20852 rCRLF = /\r?\n/g, 20853 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 20854 rsubmittable = /^(?:input|select|textarea|keygen)/i; 20855 20856function buildParams( prefix, obj, traditional, add ) { 20857 var name; 20858 20859 if ( Array.isArray( obj ) ) { 20860 20861 // Serialize array item. 20862 jQuery.each( obj, function( i, v ) { 20863 if ( traditional || rbracket.test( prefix ) ) { 20864 20865 // Treat each array item as a scalar. 20866 add( prefix, v ); 20867 20868 } else { 20869 20870 // Item is non-scalar (array or object), encode its numeric index. 20871 buildParams( 20872 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 20873 v, 20874 traditional, 20875 add 20876 ); 20877 } 20878 } ); 20879 20880 } else if ( !traditional && toType( obj ) === "object" ) { 20881 20882 // Serialize object item. 20883 for ( name in obj ) { 20884 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 20885 } 20886 20887 } else { 20888 20889 // Serialize scalar item. 20890 add( prefix, obj ); 20891 } 20892} 20893 20894// Serialize an array of form elements or a set of 20895// key/values into a query string 20896jQuery.param = function( a, traditional ) { 20897 var prefix, 20898 s = [], 20899 add = function( key, valueOrFunction ) { 20900 20901 // If value is a function, invoke it and use its return value 20902 var value = isFunction( valueOrFunction ) ? 20903 valueOrFunction() : 20904 valueOrFunction; 20905 20906 s[ s.length ] = encodeURIComponent( key ) + "=" + 20907 encodeURIComponent( value == null ? "" : value ); 20908 }; 20909 20910 if ( a == null ) { 20911 return ""; 20912 } 20913 20914 // If an array was passed in, assume that it is an array of form elements. 20915 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 20916 20917 // Serialize the form elements 20918 jQuery.each( a, function() { 20919 add( this.name, this.value ); 20920 } ); 20921 20922 } else { 20923 20924 // If traditional, encode the "old" way (the way 1.3.2 or older 20925 // did it), otherwise encode params recursively. 20926 for ( prefix in a ) { 20927 buildParams( prefix, a[ prefix ], traditional, add ); 20928 } 20929 } 20930 20931 // Return the resulting serialization 20932 return s.join( "&" ); 20933}; 20934 20935jQuery.fn.extend( { 20936 serialize: function() { 20937 return jQuery.param( this.serializeArray() ); 20938 }, 20939 serializeArray: function() { 20940 return this.map( function() { 20941 20942 // Can add propHook for "elements" to filter or add form elements 20943 var elements = jQuery.prop( this, "elements" ); 20944 return elements ? jQuery.makeArray( elements ) : this; 20945 } ).filter( function() { 20946 var type = this.type; 20947 20948 // Use .is( ":disabled" ) so that fieldset[disabled] works 20949 return this.name && !jQuery( this ).is( ":disabled" ) && 20950 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 20951 ( this.checked || !rcheckableType.test( type ) ); 20952 } ).map( function( _i, elem ) { 20953 var val = jQuery( this ).val(); 20954 20955 if ( val == null ) { 20956 return null; 20957 } 20958 20959 if ( Array.isArray( val ) ) { 20960 return jQuery.map( val, function( val ) { 20961 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 20962 } ); 20963 } 20964 20965 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 20966 } ).get(); 20967 } 20968} ); 20969 20970 20971var 20972 r20 = /%20/g, 20973 rhash = /#.*$/, 20974 rantiCache = /([?&])_=[^&]*/, 20975 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 20976 20977 // trac-7653, trac-8125, trac-8152: local protocol detection 20978 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 20979 rnoContent = /^(?:GET|HEAD)$/, 20980 rprotocol = /^\/\//, 20981 20982 /* Prefilters 20983 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 20984 * 2) These are called: 20985 * - BEFORE asking for a transport 20986 * - AFTER param serialization (s.data is a string if s.processData is true) 20987 * 3) key is the dataType 20988 * 4) the catchall symbol "*" can be used 20989 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 20990 */ 20991 prefilters = {}, 20992 20993 /* Transports bindings 20994 * 1) key is the dataType 20995 * 2) the catchall symbol "*" can be used 20996 * 3) selection will start with transport dataType and THEN go to "*" if needed 20997 */ 20998 transports = {}, 20999 21000 // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression 21001 allTypes = "*/".concat( "*" ), 21002 21003 // Anchor tag for parsing the document origin 21004 originAnchor = document.createElement( "a" ); 21005 21006originAnchor.href = location.href; 21007 21008// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 21009function addToPrefiltersOrTransports( structure ) { 21010 21011 // dataTypeExpression is optional and defaults to "*" 21012 return function( dataTypeExpression, func ) { 21013 21014 if ( typeof dataTypeExpression !== "string" ) { 21015 func = dataTypeExpression; 21016 dataTypeExpression = "*"; 21017 } 21018 21019 var dataType, 21020 i = 0, 21021 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 21022 21023 if ( isFunction( func ) ) { 21024 21025 // For each dataType in the dataTypeExpression 21026 while ( ( dataType = dataTypes[ i++ ] ) ) { 21027 21028 // Prepend if requested 21029 if ( dataType[ 0 ] === "+" ) { 21030 dataType = dataType.slice( 1 ) || "*"; 21031 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 21032 21033 // Otherwise append 21034 } else { 21035 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 21036 } 21037 } 21038 } 21039 }; 21040} 21041 21042// Base inspection function for prefilters and transports 21043function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 21044 21045 var inspected = {}, 21046 seekingTransport = ( structure === transports ); 21047 21048 function inspect( dataType ) { 21049 var selected; 21050 inspected[ dataType ] = true; 21051 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 21052 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 21053 if ( typeof dataTypeOrTransport === "string" && 21054 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 21055 21056 options.dataTypes.unshift( dataTypeOrTransport ); 21057 inspect( dataTypeOrTransport ); 21058 return false; 21059 } else if ( seekingTransport ) { 21060 return !( selected = dataTypeOrTransport ); 21061 } 21062 } ); 21063 return selected; 21064 } 21065 21066 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 21067} 21068 21069// A special extend for ajax options 21070// that takes "flat" options (not to be deep extended) 21071// Fixes trac-9887 21072function ajaxExtend( target, src ) { 21073 var key, deep, 21074 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 21075 21076 for ( key in src ) { 21077 if ( src[ key ] !== undefined ) { 21078 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 21079 } 21080 } 21081 if ( deep ) { 21082 jQuery.extend( true, target, deep ); 21083 } 21084 21085 return target; 21086} 21087 21088/* Handles responses to an ajax request: 21089 * - finds the right dataType (mediates between content-type and expected dataType) 21090 * - returns the corresponding response 21091 */ 21092function ajaxHandleResponses( s, jqXHR, responses ) { 21093 21094 var ct, type, finalDataType, firstDataType, 21095 contents = s.contents, 21096 dataTypes = s.dataTypes; 21097 21098 // Remove auto dataType and get content-type in the process 21099 while ( dataTypes[ 0 ] === "*" ) { 21100 dataTypes.shift(); 21101 if ( ct === undefined ) { 21102 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 21103 } 21104 } 21105 21106 // Check if we're dealing with a known content-type 21107 if ( ct ) { 21108 for ( type in contents ) { 21109 if ( contents[ type ] && contents[ type ].test( ct ) ) { 21110 dataTypes.unshift( type ); 21111 break; 21112 } 21113 } 21114 } 21115 21116 // Check to see if we have a response for the expected dataType 21117 if ( dataTypes[ 0 ] in responses ) { 21118 finalDataType = dataTypes[ 0 ]; 21119 } else { 21120 21121 // Try convertible dataTypes 21122 for ( type in responses ) { 21123 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 21124 finalDataType = type; 21125 break; 21126 } 21127 if ( !firstDataType ) { 21128 firstDataType = type; 21129 } 21130 } 21131 21132 // Or just use first one 21133 finalDataType = finalDataType || firstDataType; 21134 } 21135 21136 // If we found a dataType 21137 // We add the dataType to the list if needed 21138 // and return the corresponding response 21139 if ( finalDataType ) { 21140 if ( finalDataType !== dataTypes[ 0 ] ) { 21141 dataTypes.unshift( finalDataType ); 21142 } 21143 return responses[ finalDataType ]; 21144 } 21145} 21146 21147/* Chain conversions given the request and the original response 21148 * Also sets the responseXXX fields on the jqXHR instance 21149 */ 21150function ajaxConvert( s, response, jqXHR, isSuccess ) { 21151 var conv2, current, conv, tmp, prev, 21152 converters = {}, 21153 21154 // Work with a copy of dataTypes in case we need to modify it for conversion 21155 dataTypes = s.dataTypes.slice(); 21156 21157 // Create converters map with lowercased keys 21158 if ( dataTypes[ 1 ] ) { 21159 for ( conv in s.converters ) { 21160 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 21161 } 21162 } 21163 21164 current = dataTypes.shift(); 21165 21166 // Convert to each sequential dataType 21167 while ( current ) { 21168 21169 if ( s.responseFields[ current ] ) { 21170 jqXHR[ s.responseFields[ current ] ] = response; 21171 } 21172 21173 // Apply the dataFilter if provided 21174 if ( !prev && isSuccess && s.dataFilter ) { 21175 response = s.dataFilter( response, s.dataType ); 21176 } 21177 21178 prev = current; 21179 current = dataTypes.shift(); 21180 21181 if ( current ) { 21182 21183 // There's only work to do if current dataType is non-auto 21184 if ( current === "*" ) { 21185 21186 current = prev; 21187 21188 // Convert response if prev dataType is non-auto and differs from current 21189 } else if ( prev !== "*" && prev !== current ) { 21190 21191 // Seek a direct converter 21192 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 21193 21194 // If none found, seek a pair 21195 if ( !conv ) { 21196 for ( conv2 in converters ) { 21197 21198 // If conv2 outputs current 21199 tmp = conv2.split( " " ); 21200 if ( tmp[ 1 ] === current ) { 21201 21202 // If prev can be converted to accepted input 21203 conv = converters[ prev + " " + tmp[ 0 ] ] || 21204 converters[ "* " + tmp[ 0 ] ]; 21205 if ( conv ) { 21206 21207 // Condense equivalence converters 21208 if ( conv === true ) { 21209 conv = converters[ conv2 ]; 21210 21211 // Otherwise, insert the intermediate dataType 21212 } else if ( converters[ conv2 ] !== true ) { 21213 current = tmp[ 0 ]; 21214 dataTypes.unshift( tmp[ 1 ] ); 21215 } 21216 break; 21217 } 21218 } 21219 } 21220 } 21221 21222 // Apply converter (if not an equivalence) 21223 if ( conv !== true ) { 21224 21225 // Unless errors are allowed to bubble, catch and return them 21226 if ( conv && s.throws ) { 21227 response = conv( response ); 21228 } else { 21229 try { 21230 response = conv( response ); 21231 } catch ( e ) { 21232 return { 21233 state: "parsererror", 21234 error: conv ? e : "No conversion from " + prev + " to " + current 21235 }; 21236 } 21237 } 21238 } 21239 } 21240 } 21241 } 21242 21243 return { state: "success", data: response }; 21244} 21245 21246jQuery.extend( { 21247 21248 // Counter for holding the number of active queries 21249 active: 0, 21250 21251 // Last-Modified header cache for next request 21252 lastModified: {}, 21253 etag: {}, 21254 21255 ajaxSettings: { 21256 url: location.href, 21257 type: "GET", 21258 isLocal: rlocalProtocol.test( location.protocol ), 21259 global: true, 21260 processData: true, 21261 async: true, 21262 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 21263 21264 /* 21265 timeout: 0, 21266 data: null, 21267 dataType: null, 21268 username: null, 21269 password: null, 21270 cache: null, 21271 throws: false, 21272 traditional: false, 21273 headers: {}, 21274 */ 21275 21276 accepts: { 21277 "*": allTypes, 21278 text: "text/plain", 21279 html: "text/html", 21280 xml: "application/xml, text/xml", 21281 json: "application/json, text/javascript" 21282 }, 21283 21284 contents: { 21285 xml: /\bxml\b/, 21286 html: /\bhtml/, 21287 json: /\bjson\b/ 21288 }, 21289 21290 responseFields: { 21291 xml: "responseXML", 21292 text: "responseText", 21293 json: "responseJSON" 21294 }, 21295 21296 // Data converters 21297 // Keys separate source (or catchall "*") and destination types with a single space 21298 converters: { 21299 21300 // Convert anything to text 21301 "* text": String, 21302 21303 // Text to html (true = no transformation) 21304 "text html": true, 21305 21306 // Evaluate text as a json expression 21307 "text json": JSON.parse, 21308 21309 // Parse text as xml 21310 "text xml": jQuery.parseXML 21311 }, 21312 21313 // For options that shouldn't be deep extended: 21314 // you can add your own custom options here if 21315 // and when you create one that shouldn't be 21316 // deep extended (see ajaxExtend) 21317 flatOptions: { 21318 url: true, 21319 context: true 21320 } 21321 }, 21322 21323 // Creates a full fledged settings object into target 21324 // with both ajaxSettings and settings fields. 21325 // If target is omitted, writes into ajaxSettings. 21326 ajaxSetup: function( target, settings ) { 21327 return settings ? 21328 21329 // Building a settings object 21330 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 21331 21332 // Extending ajaxSettings 21333 ajaxExtend( jQuery.ajaxSettings, target ); 21334 }, 21335 21336 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 21337 ajaxTransport: addToPrefiltersOrTransports( transports ), 21338 21339 // Main method 21340 ajax: function( url, options ) { 21341 21342 // If url is an object, simulate pre-1.5 signature 21343 if ( typeof url === "object" ) { 21344 options = url; 21345 url = undefined; 21346 } 21347 21348 // Force options to be an object 21349 options = options || {}; 21350 21351 var transport, 21352 21353 // URL without anti-cache param 21354 cacheURL, 21355 21356 // Response headers 21357 responseHeadersString, 21358 responseHeaders, 21359 21360 // timeout handle 21361 timeoutTimer, 21362 21363 // Url cleanup var 21364 urlAnchor, 21365 21366 // Request state (becomes false upon send and true upon completion) 21367 completed, 21368 21369 // To know if global events are to be dispatched 21370 fireGlobals, 21371 21372 // Loop variable 21373 i, 21374 21375 // uncached part of the url 21376 uncached, 21377 21378 // Create the final options object 21379 s = jQuery.ajaxSetup( {}, options ), 21380 21381 // Callbacks context 21382 callbackContext = s.context || s, 21383 21384 // Context for global events is callbackContext if it is a DOM node or jQuery collection 21385 globalEventContext = s.context && 21386 ( callbackContext.nodeType || callbackContext.jquery ) ? 21387 jQuery( callbackContext ) : 21388 jQuery.event, 21389 21390 // Deferreds 21391 deferred = jQuery.Deferred(), 21392 completeDeferred = jQuery.Callbacks( "once memory" ), 21393 21394 // Status-dependent callbacks 21395 statusCode = s.statusCode || {}, 21396 21397 // Headers (they are sent all at once) 21398 requestHeaders = {}, 21399 requestHeadersNames = {}, 21400 21401 // Default abort message 21402 strAbort = "canceled", 21403 21404 // Fake xhr 21405 jqXHR = { 21406 readyState: 0, 21407 21408 // Builds headers hashtable if needed 21409 getResponseHeader: function( key ) { 21410 var match; 21411 if ( completed ) { 21412 if ( !responseHeaders ) { 21413 responseHeaders = {}; 21414 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 21415 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 21416 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 21417 .concat( match[ 2 ] ); 21418 } 21419 } 21420 match = responseHeaders[ key.toLowerCase() + " " ]; 21421 } 21422 return match == null ? null : match.join( ", " ); 21423 }, 21424 21425 // Raw string 21426 getAllResponseHeaders: function() { 21427 return completed ? responseHeadersString : null; 21428 }, 21429 21430 // Caches the header 21431 setRequestHeader: function( name, value ) { 21432 if ( completed == null ) { 21433 name = requestHeadersNames[ name.toLowerCase() ] = 21434 requestHeadersNames[ name.toLowerCase() ] || name; 21435 requestHeaders[ name ] = value; 21436 } 21437 return this; 21438 }, 21439 21440 // Overrides response content-type header 21441 overrideMimeType: function( type ) { 21442 if ( completed == null ) { 21443 s.mimeType = type; 21444 } 21445 return this; 21446 }, 21447 21448 // Status-dependent callbacks 21449 statusCode: function( map ) { 21450 var code; 21451 if ( map ) { 21452 if ( completed ) { 21453 21454 // Execute the appropriate callbacks 21455 jqXHR.always( map[ jqXHR.status ] ); 21456 } else { 21457 21458 // Lazy-add the new callbacks in a way that preserves old ones 21459 for ( code in map ) { 21460 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 21461 } 21462 } 21463 } 21464 return this; 21465 }, 21466 21467 // Cancel the request 21468 abort: function( statusText ) { 21469 var finalText = statusText || strAbort; 21470 if ( transport ) { 21471 transport.abort( finalText ); 21472 } 21473 done( 0, finalText ); 21474 return this; 21475 } 21476 }; 21477 21478 // Attach deferreds 21479 deferred.promise( jqXHR ); 21480 21481 // Add protocol if not provided (prefilters might expect it) 21482 // Handle falsy url in the settings object (trac-10093: consistency with old signature) 21483 // We also use the url parameter if available 21484 s.url = ( ( url || s.url || location.href ) + "" ) 21485 .replace( rprotocol, location.protocol + "//" ); 21486 21487 // Alias method option to type as per ticket trac-12004 21488 s.type = options.method || options.type || s.method || s.type; 21489 21490 // Extract dataTypes list 21491 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 21492 21493 // A cross-domain request is in order when the origin doesn't match the current origin. 21494 if ( s.crossDomain == null ) { 21495 urlAnchor = document.createElement( "a" ); 21496 21497 // Support: IE <=8 - 11, Edge 12 - 15 21498 // IE throws exception on accessing the href property if url is malformed, 21499 // e.g. http://example.com:80x/ 21500 try { 21501 urlAnchor.href = s.url; 21502 21503 // Support: IE <=8 - 11 only 21504 // Anchor's host property isn't correctly set when s.url is relative 21505 urlAnchor.href = urlAnchor.href; 21506 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 21507 urlAnchor.protocol + "//" + urlAnchor.host; 21508 } catch ( e ) { 21509 21510 // If there is an error parsing the URL, assume it is crossDomain, 21511 // it can be rejected by the transport if it is invalid 21512 s.crossDomain = true; 21513 } 21514 } 21515 21516 // Convert data if not already a string 21517 if ( s.data && s.processData && typeof s.data !== "string" ) { 21518 s.data = jQuery.param( s.data, s.traditional ); 21519 } 21520 21521 // Apply prefilters 21522 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 21523 21524 // If request was aborted inside a prefilter, stop there 21525 if ( completed ) { 21526 return jqXHR; 21527 } 21528 21529 // We can fire global events as of now if asked to 21530 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) 21531 fireGlobals = jQuery.event && s.global; 21532 21533 // Watch for a new set of requests 21534 if ( fireGlobals && jQuery.active++ === 0 ) { 21535 jQuery.event.trigger( "ajaxStart" ); 21536 } 21537 21538 // Uppercase the type 21539 s.type = s.type.toUpperCase(); 21540 21541 // Determine if request has content 21542 s.hasContent = !rnoContent.test( s.type ); 21543 21544 // Save the URL in case we're toying with the If-Modified-Since 21545 // and/or If-None-Match header later on 21546 // Remove hash to simplify url manipulation 21547 cacheURL = s.url.replace( rhash, "" ); 21548 21549 // More options handling for requests with no content 21550 if ( !s.hasContent ) { 21551 21552 // Remember the hash so we can put it back 21553 uncached = s.url.slice( cacheURL.length ); 21554 21555 // If data is available and should be processed, append data to url 21556 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 21557 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 21558 21559 // trac-9682: remove data so that it's not used in an eventual retry 21560 delete s.data; 21561 } 21562 21563 // Add or update anti-cache param if needed 21564 if ( s.cache === false ) { 21565 cacheURL = cacheURL.replace( rantiCache, "$1" ); 21566 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 21567 uncached; 21568 } 21569 21570 // Put hash and anti-cache on the URL that will be requested (gh-1732) 21571 s.url = cacheURL + uncached; 21572 21573 // Change '%20' to '+' if this is encoded form body content (gh-2658) 21574 } else if ( s.data && s.processData && 21575 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 21576 s.data = s.data.replace( r20, "+" ); 21577 } 21578 21579 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 21580 if ( s.ifModified ) { 21581 if ( jQuery.lastModified[ cacheURL ] ) { 21582 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 21583 } 21584 if ( jQuery.etag[ cacheURL ] ) { 21585 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 21586 } 21587 } 21588 21589 // Set the correct header, if data is being sent 21590 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 21591 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 21592 } 21593 21594 // Set the Accepts header for the server, depending on the dataType 21595 jqXHR.setRequestHeader( 21596 "Accept", 21597 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 21598 s.accepts[ s.dataTypes[ 0 ] ] + 21599 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 21600 s.accepts[ "*" ] 21601 ); 21602 21603 // Check for headers option 21604 for ( i in s.headers ) { 21605 jqXHR.setRequestHeader( i, s.headers[ i ] ); 21606 } 21607 21608 // Allow custom headers/mimetypes and early abort 21609 if ( s.beforeSend && 21610 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 21611 21612 // Abort if not done already and return 21613 return jqXHR.abort(); 21614 } 21615 21616 // Aborting is no longer a cancellation 21617 strAbort = "abort"; 21618 21619 // Install callbacks on deferreds 21620 completeDeferred.add( s.complete ); 21621 jqXHR.done( s.success ); 21622 jqXHR.fail( s.error ); 21623 21624 // Get transport 21625 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 21626 21627 // If no transport, we auto-abort 21628 if ( !transport ) { 21629 done( -1, "No Transport" ); 21630 } else { 21631 jqXHR.readyState = 1; 21632 21633 // Send global event 21634 if ( fireGlobals ) { 21635 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 21636 } 21637 21638 // If request was aborted inside ajaxSend, stop there 21639 if ( completed ) { 21640 return jqXHR; 21641 } 21642 21643 // Timeout 21644 if ( s.async && s.timeout > 0 ) { 21645 timeoutTimer = window.setTimeout( function() { 21646 jqXHR.abort( "timeout" ); 21647 }, s.timeout ); 21648 } 21649 21650 try { 21651 completed = false; 21652 transport.send( requestHeaders, done ); 21653 } catch ( e ) { 21654 21655 // Rethrow post-completion exceptions 21656 if ( completed ) { 21657 throw e; 21658 } 21659 21660 // Propagate others as results 21661 done( -1, e ); 21662 } 21663 } 21664 21665 // Callback for when everything is done 21666 function done( status, nativeStatusText, responses, headers ) { 21667 var isSuccess, success, error, response, modified, 21668 statusText = nativeStatusText; 21669 21670 // Ignore repeat invocations 21671 if ( completed ) { 21672 return; 21673 } 21674 21675 completed = true; 21676 21677 // Clear timeout if it exists 21678 if ( timeoutTimer ) { 21679 window.clearTimeout( timeoutTimer ); 21680 } 21681 21682 // Dereference transport for early garbage collection 21683 // (no matter how long the jqXHR object will be used) 21684 transport = undefined; 21685 21686 // Cache response headers 21687 responseHeadersString = headers || ""; 21688 21689 // Set readyState 21690 jqXHR.readyState = status > 0 ? 4 : 0; 21691 21692 // Determine if successful 21693 isSuccess = status >= 200 && status < 300 || status === 304; 21694 21695 // Get response data 21696 if ( responses ) { 21697 response = ajaxHandleResponses( s, jqXHR, responses ); 21698 } 21699 21700 // Use a noop converter for missing script but not if jsonp 21701 if ( !isSuccess && 21702 jQuery.inArray( "script", s.dataTypes ) > -1 && 21703 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 21704 s.converters[ "text script" ] = function() {}; 21705 } 21706 21707 // Convert no matter what (that way responseXXX fields are always set) 21708 response = ajaxConvert( s, response, jqXHR, isSuccess ); 21709 21710 // If successful, handle type chaining 21711 if ( isSuccess ) { 21712 21713 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 21714 if ( s.ifModified ) { 21715 modified = jqXHR.getResponseHeader( "Last-Modified" ); 21716 if ( modified ) { 21717 jQuery.lastModified[ cacheURL ] = modified; 21718 } 21719 modified = jqXHR.getResponseHeader( "etag" ); 21720 if ( modified ) { 21721 jQuery.etag[ cacheURL ] = modified; 21722 } 21723 } 21724 21725 // if no content 21726 if ( status === 204 || s.type === "HEAD" ) { 21727 statusText = "nocontent"; 21728 21729 // if not modified 21730 } else if ( status === 304 ) { 21731 statusText = "notmodified"; 21732 21733 // If we have data, let's convert it 21734 } else { 21735 statusText = response.state; 21736 success = response.data; 21737 error = response.error; 21738 isSuccess = !error; 21739 } 21740 } else { 21741 21742 // Extract error from statusText and normalize for non-aborts 21743 error = statusText; 21744 if ( status || !statusText ) { 21745 statusText = "error"; 21746 if ( status < 0 ) { 21747 status = 0; 21748 } 21749 } 21750 } 21751 21752 // Set data for the fake xhr object 21753 jqXHR.status = status; 21754 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 21755 21756 // Success/Error 21757 if ( isSuccess ) { 21758 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 21759 } else { 21760 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 21761 } 21762 21763 // Status-dependent callbacks 21764 jqXHR.statusCode( statusCode ); 21765 statusCode = undefined; 21766 21767 if ( fireGlobals ) { 21768 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 21769 [ jqXHR, s, isSuccess ? success : error ] ); 21770 } 21771 21772 // Complete 21773 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 21774 21775 if ( fireGlobals ) { 21776 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 21777 21778 // Handle the global AJAX counter 21779 if ( !( --jQuery.active ) ) { 21780 jQuery.event.trigger( "ajaxStop" ); 21781 } 21782 } 21783 } 21784 21785 return jqXHR; 21786 }, 21787 21788 getJSON: function( url, data, callback ) { 21789 return jQuery.get( url, data, callback, "json" ); 21790 }, 21791 21792 getScript: function( url, callback ) { 21793 return jQuery.get( url, undefined, callback, "script" ); 21794 } 21795} ); 21796 21797jQuery.each( [ "get", "post" ], function( _i, method ) { 21798 jQuery[ method ] = function( url, data, callback, type ) { 21799 21800 // Shift arguments if data argument was omitted 21801 if ( isFunction( data ) ) { 21802 type = type || callback; 21803 callback = data; 21804 data = undefined; 21805 } 21806 21807 // The url can be an options object (which then must have .url) 21808 return jQuery.ajax( jQuery.extend( { 21809 url: url, 21810 type: method, 21811 dataType: type, 21812 data: data, 21813 success: callback 21814 }, jQuery.isPlainObject( url ) && url ) ); 21815 }; 21816} ); 21817 21818jQuery.ajaxPrefilter( function( s ) { 21819 var i; 21820 for ( i in s.headers ) { 21821 if ( i.toLowerCase() === "content-type" ) { 21822 s.contentType = s.headers[ i ] || ""; 21823 } 21824 } 21825} ); 21826 21827 21828jQuery._evalUrl = function( url, options, doc ) { 21829 return jQuery.ajax( { 21830 url: url, 21831 21832 // Make this explicit, since user can override this through ajaxSetup (trac-11264) 21833 type: "GET", 21834 dataType: "script", 21835 cache: true, 21836 async: false, 21837 global: false, 21838 21839 // Only evaluate the response if it is successful (gh-4126) 21840 // dataFilter is not invoked for failure responses, so using it instead 21841 // of the default converter is kludgy but it works. 21842 converters: { 21843 "text script": function() {} 21844 }, 21845 dataFilter: function( response ) { 21846 jQuery.globalEval( response, options, doc ); 21847 } 21848 } ); 21849}; 21850 21851 21852jQuery.fn.extend( { 21853 wrapAll: function( html ) { 21854 var wrap; 21855 21856 if ( this[ 0 ] ) { 21857 if ( isFunction( html ) ) { 21858 html = html.call( this[ 0 ] ); 21859 } 21860 21861 // The elements to wrap the target around 21862 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 21863 21864 if ( this[ 0 ].parentNode ) { 21865 wrap.insertBefore( this[ 0 ] ); 21866 } 21867 21868 wrap.map( function() { 21869 var elem = this; 21870 21871 while ( elem.firstElementChild ) { 21872 elem = elem.firstElementChild; 21873 } 21874 21875 return elem; 21876 } ).append( this ); 21877 } 21878 21879 return this; 21880 }, 21881 21882 wrapInner: function( html ) { 21883 if ( isFunction( html ) ) { 21884 return this.each( function( i ) { 21885 jQuery( this ).wrapInner( html.call( this, i ) ); 21886 } ); 21887 } 21888 21889 return this.each( function() { 21890 var self = jQuery( this ), 21891 contents = self.contents(); 21892 21893 if ( contents.length ) { 21894 contents.wrapAll( html ); 21895 21896 } else { 21897 self.append( html ); 21898 } 21899 } ); 21900 }, 21901 21902 wrap: function( html ) { 21903 var htmlIsFunction = isFunction( html ); 21904 21905 return this.each( function( i ) { 21906 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 21907 } ); 21908 }, 21909 21910 unwrap: function( selector ) { 21911 this.parent( selector ).not( "body" ).each( function() { 21912 jQuery( this ).replaceWith( this.childNodes ); 21913 } ); 21914 return this; 21915 } 21916} ); 21917 21918 21919jQuery.expr.pseudos.hidden = function( elem ) { 21920 return !jQuery.expr.pseudos.visible( elem ); 21921}; 21922jQuery.expr.pseudos.visible = function( elem ) { 21923 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 21924}; 21925 21926 21927 21928 21929jQuery.ajaxSettings.xhr = function() { 21930 try { 21931 return new window.XMLHttpRequest(); 21932 } catch ( e ) {} 21933}; 21934 21935var xhrSuccessStatus = { 21936 21937 // File protocol always yields status code 0, assume 200 21938 0: 200, 21939 21940 // Support: IE <=9 only 21941 // trac-1450: sometimes IE returns 1223 when it should be 204 21942 1223: 204 21943 }, 21944 xhrSupported = jQuery.ajaxSettings.xhr(); 21945 21946support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 21947support.ajax = xhrSupported = !!xhrSupported; 21948 21949jQuery.ajaxTransport( function( options ) { 21950 var callback, errorCallback; 21951 21952 // Cross domain only allowed if supported through XMLHttpRequest 21953 if ( support.cors || xhrSupported && !options.crossDomain ) { 21954 return { 21955 send: function( headers, complete ) { 21956 var i, 21957 xhr = options.xhr(); 21958 21959 xhr.open( 21960 options.type, 21961 options.url, 21962 options.async, 21963 options.username, 21964 options.password 21965 ); 21966 21967 // Apply custom fields if provided 21968 if ( options.xhrFields ) { 21969 for ( i in options.xhrFields ) { 21970 xhr[ i ] = options.xhrFields[ i ]; 21971 } 21972 } 21973 21974 // Override mime type if needed 21975 if ( options.mimeType && xhr.overrideMimeType ) { 21976 xhr.overrideMimeType( options.mimeType ); 21977 } 21978 21979 // X-Requested-With header 21980 // For cross-domain requests, seeing as conditions for a preflight are 21981 // akin to a jigsaw puzzle, we simply never set it to be sure. 21982 // (it can always be set on a per-request basis or even using ajaxSetup) 21983 // For same-domain requests, won't change header if already provided. 21984 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 21985 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 21986 } 21987 21988 // Set headers 21989 for ( i in headers ) { 21990 xhr.setRequestHeader( i, headers[ i ] ); 21991 } 21992 21993 // Callback 21994 callback = function( type ) { 21995 return function() { 21996 if ( callback ) { 21997 callback = errorCallback = xhr.onload = 21998 xhr.onerror = xhr.onabort = xhr.ontimeout = 21999 xhr.onreadystatechange = null; 22000 22001 if ( type === "abort" ) { 22002 xhr.abort(); 22003 } else if ( type === "error" ) { 22004 22005 // Support: IE <=9 only 22006 // On a manual native abort, IE9 throws 22007 // errors on any property access that is not readyState 22008 if ( typeof xhr.status !== "number" ) { 22009 complete( 0, "error" ); 22010 } else { 22011 complete( 22012 22013 // File: protocol always yields status 0; see trac-8605, trac-14207 22014 xhr.status, 22015 xhr.statusText 22016 ); 22017 } 22018 } else { 22019 complete( 22020 xhrSuccessStatus[ xhr.status ] || xhr.status, 22021 xhr.statusText, 22022 22023 // Support: IE <=9 only 22024 // IE9 has no XHR2 but throws on binary (trac-11426) 22025 // For XHR2 non-text, let the caller handle it (gh-2498) 22026 ( xhr.responseType || "text" ) !== "text" || 22027 typeof xhr.responseText !== "string" ? 22028 { binary: xhr.response } : 22029 { text: xhr.responseText }, 22030 xhr.getAllResponseHeaders() 22031 ); 22032 } 22033 } 22034 }; 22035 }; 22036 22037 // Listen to events 22038 xhr.onload = callback(); 22039 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 22040 22041 // Support: IE 9 only 22042 // Use onreadystatechange to replace onabort 22043 // to handle uncaught aborts 22044 if ( xhr.onabort !== undefined ) { 22045 xhr.onabort = errorCallback; 22046 } else { 22047 xhr.onreadystatechange = function() { 22048 22049 // Check readyState before timeout as it changes 22050 if ( xhr.readyState === 4 ) { 22051 22052 // Allow onerror to be called first, 22053 // but that will not handle a native abort 22054 // Also, save errorCallback to a variable 22055 // as xhr.onerror cannot be accessed 22056 window.setTimeout( function() { 22057 if ( callback ) { 22058 errorCallback(); 22059 } 22060 } ); 22061 } 22062 }; 22063 } 22064 22065 // Create the abort callback 22066 callback = callback( "abort" ); 22067 22068 try { 22069 22070 // Do send the request (this may raise an exception) 22071 xhr.send( options.hasContent && options.data || null ); 22072 } catch ( e ) { 22073 22074 // trac-14683: Only rethrow if this hasn't been notified as an error yet 22075 if ( callback ) { 22076 throw e; 22077 } 22078 } 22079 }, 22080 22081 abort: function() { 22082 if ( callback ) { 22083 callback(); 22084 } 22085 } 22086 }; 22087 } 22088} ); 22089 22090 22091 22092 22093// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 22094jQuery.ajaxPrefilter( function( s ) { 22095 if ( s.crossDomain ) { 22096 s.contents.script = false; 22097 } 22098} ); 22099 22100// Install script dataType 22101jQuery.ajaxSetup( { 22102 accepts: { 22103 script: "text/javascript, application/javascript, " + 22104 "application/ecmascript, application/x-ecmascript" 22105 }, 22106 contents: { 22107 script: /\b(?:java|ecma)script\b/ 22108 }, 22109 converters: { 22110 "text script": function( text ) { 22111 jQuery.globalEval( text ); 22112 return text; 22113 } 22114 } 22115} ); 22116 22117// Handle cache's special case and crossDomain 22118jQuery.ajaxPrefilter( "script", function( s ) { 22119 if ( s.cache === undefined ) { 22120 s.cache = false; 22121 } 22122 if ( s.crossDomain ) { 22123 s.type = "GET"; 22124 } 22125} ); 22126 22127// Bind script tag hack transport 22128jQuery.ajaxTransport( "script", function( s ) { 22129 22130 // This transport only deals with cross domain or forced-by-attrs requests 22131 if ( s.crossDomain || s.scriptAttrs ) { 22132 var script, callback; 22133 return { 22134 send: function( _, complete ) { 22135 script = jQuery( "<script>" ) 22136 .attr( s.scriptAttrs || {} ) 22137 .prop( { charset: s.scriptCharset, src: s.url } ) 22138 .on( "load error", callback = function( evt ) { 22139 script.remove(); 22140 callback = null; 22141 if ( evt ) { 22142 complete( evt.type === "error" ? 404 : 200, evt.type ); 22143 } 22144 } ); 22145 22146 // Use native DOM manipulation to avoid our domManip AJAX trickery 22147 document.head.appendChild( script[ 0 ] ); 22148 }, 22149 abort: function() { 22150 if ( callback ) { 22151 callback(); 22152 } 22153 } 22154 }; 22155 } 22156} ); 22157 22158 22159 22160 22161var oldCallbacks = [], 22162 rjsonp = /(=)\?(?=&|$)|\?\?/; 22163 22164// Default jsonp settings 22165jQuery.ajaxSetup( { 22166 jsonp: "callback", 22167 jsonpCallback: function() { 22168 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 22169 this[ callback ] = true; 22170 return callback; 22171 } 22172} ); 22173 22174// Detect, normalize options and install callbacks for jsonp requests 22175jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 22176 22177 var callbackName, overwritten, responseContainer, 22178 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 22179 "url" : 22180 typeof s.data === "string" && 22181 ( s.contentType || "" ) 22182 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 22183 rjsonp.test( s.data ) && "data" 22184 ); 22185 22186 // Handle iff the expected data type is "jsonp" or we have a parameter to set 22187 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 22188 22189 // Get callback name, remembering preexisting value associated with it 22190 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 22191 s.jsonpCallback() : 22192 s.jsonpCallback; 22193 22194 // Insert callback into url or form data 22195 if ( jsonProp ) { 22196 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 22197 } else if ( s.jsonp !== false ) { 22198 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 22199 } 22200 22201 // Use data converter to retrieve json after script execution 22202 s.converters[ "script json" ] = function() { 22203 if ( !responseContainer ) { 22204 jQuery.error( callbackName + " was not called" ); 22205 } 22206 return responseContainer[ 0 ]; 22207 }; 22208 22209 // Force json dataType 22210 s.dataTypes[ 0 ] = "json"; 22211 22212 // Install callback 22213 overwritten = window[ callbackName ]; 22214 window[ callbackName ] = function() { 22215 responseContainer = arguments; 22216 }; 22217 22218 // Clean-up function (fires after converters) 22219 jqXHR.always( function() { 22220 22221 // If previous value didn't exist - remove it 22222 if ( overwritten === undefined ) { 22223 jQuery( window ).removeProp( callbackName ); 22224 22225 // Otherwise restore preexisting value 22226 } else { 22227 window[ callbackName ] = overwritten; 22228 } 22229 22230 // Save back as free 22231 if ( s[ callbackName ] ) { 22232 22233 // Make sure that re-using the options doesn't screw things around 22234 s.jsonpCallback = originalSettings.jsonpCallback; 22235 22236 // Save the callback name for future use 22237 oldCallbacks.push( callbackName ); 22238 } 22239 22240 // Call if it was a function and we have a response 22241 if ( responseContainer && isFunction( overwritten ) ) { 22242 overwritten( responseContainer[ 0 ] ); 22243 } 22244 22245 responseContainer = overwritten = undefined; 22246 } ); 22247 22248 // Delegate to script 22249 return "script"; 22250 } 22251} ); 22252 22253 22254 22255 22256// Support: Safari 8 only 22257// In Safari 8 documents created via document.implementation.createHTMLDocument 22258// collapse sibling forms: the second one becomes a child of the first one. 22259// Because of that, this security measure has to be disabled in Safari 8. 22260// https://bugs.webkit.org/show_bug.cgi?id=137337 22261support.createHTMLDocument = ( function() { 22262 var body = document.implementation.createHTMLDocument( "" ).body; 22263 body.innerHTML = "<form></form><form></form>"; 22264 return body.childNodes.length === 2; 22265} )(); 22266 22267 22268// Argument "data" should be string of html 22269// context (optional): If specified, the fragment will be created in this context, 22270// defaults to document 22271// keepScripts (optional): If true, will include scripts passed in the html string 22272jQuery.parseHTML = function( data, context, keepScripts ) { 22273 if ( typeof data !== "string" ) { 22274 return []; 22275 } 22276 if ( typeof context === "boolean" ) { 22277 keepScripts = context; 22278 context = false; 22279 } 22280 22281 var base, parsed, scripts; 22282 22283 if ( !context ) { 22284 22285 // Stop scripts or inline event handlers from being executed immediately 22286 // by using document.implementation 22287 if ( support.createHTMLDocument ) { 22288 context = document.implementation.createHTMLDocument( "" ); 22289 22290 // Set the base href for the created document 22291 // so any parsed elements with URLs 22292 // are based on the document's URL (gh-2965) 22293 base = context.createElement( "base" ); 22294 base.href = document.location.href; 22295 context.head.appendChild( base ); 22296 } else { 22297 context = document; 22298 } 22299 } 22300 22301 parsed = rsingleTag.exec( data ); 22302 scripts = !keepScripts && []; 22303 22304 // Single tag 22305 if ( parsed ) { 22306 return [ context.createElement( parsed[ 1 ] ) ]; 22307 } 22308 22309 parsed = buildFragment( [ data ], context, scripts ); 22310 22311 if ( scripts && scripts.length ) { 22312 jQuery( scripts ).remove(); 22313 } 22314 22315 return jQuery.merge( [], parsed.childNodes ); 22316}; 22317 22318 22319/** 22320 * Load a url into a page 22321 */ 22322jQuery.fn.load = function( url, params, callback ) { 22323 var selector, type, response, 22324 self = this, 22325 off = url.indexOf( " " ); 22326 22327 if ( off > -1 ) { 22328 selector = stripAndCollapse( url.slice( off ) ); 22329 url = url.slice( 0, off ); 22330 } 22331 22332 // If it's a function 22333 if ( isFunction( params ) ) { 22334 22335 // We assume that it's the callback 22336 callback = params; 22337 params = undefined; 22338 22339 // Otherwise, build a param string 22340 } else if ( params && typeof params === "object" ) { 22341 type = "POST"; 22342 } 22343 22344 // If we have elements to modify, make the request 22345 if ( self.length > 0 ) { 22346 jQuery.ajax( { 22347 url: url, 22348 22349 // If "type" variable is undefined, then "GET" method will be used. 22350 // Make value of this field explicit since 22351 // user can override it through ajaxSetup method 22352 type: type || "GET", 22353 dataType: "html", 22354 data: params 22355 } ).done( function( responseText ) { 22356 22357 // Save response for use in complete callback 22358 response = arguments; 22359 22360 self.html( selector ? 22361 22362 // If a selector was specified, locate the right elements in a dummy div 22363 // Exclude scripts to avoid IE 'Permission Denied' errors 22364 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 22365 22366 // Otherwise use the full result 22367 responseText ); 22368 22369 // If the request succeeds, this function gets "data", "status", "jqXHR" 22370 // but they are ignored because response was set above. 22371 // If it fails, this function gets "jqXHR", "status", "error" 22372 } ).always( callback && function( jqXHR, status ) { 22373 self.each( function() { 22374 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 22375 } ); 22376 } ); 22377 } 22378 22379 return this; 22380}; 22381 22382 22383 22384 22385jQuery.expr.pseudos.animated = function( elem ) { 22386 return jQuery.grep( jQuery.timers, function( fn ) { 22387 return elem === fn.elem; 22388 } ).length; 22389}; 22390 22391 22392 22393 22394jQuery.offset = { 22395 setOffset: function( elem, options, i ) { 22396 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 22397 position = jQuery.css( elem, "position" ), 22398 curElem = jQuery( elem ), 22399 props = {}; 22400 22401 // Set position first, in-case top/left are set even on static elem 22402 if ( position === "static" ) { 22403 elem.style.position = "relative"; 22404 } 22405 22406 curOffset = curElem.offset(); 22407 curCSSTop = jQuery.css( elem, "top" ); 22408 curCSSLeft = jQuery.css( elem, "left" ); 22409 calculatePosition = ( position === "absolute" || position === "fixed" ) && 22410 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 22411 22412 // Need to be able to calculate position if either 22413 // top or left is auto and position is either absolute or fixed 22414 if ( calculatePosition ) { 22415 curPosition = curElem.position(); 22416 curTop = curPosition.top; 22417 curLeft = curPosition.left; 22418 22419 } else { 22420 curTop = parseFloat( curCSSTop ) || 0; 22421 curLeft = parseFloat( curCSSLeft ) || 0; 22422 } 22423 22424 if ( isFunction( options ) ) { 22425 22426 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 22427 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 22428 } 22429 22430 if ( options.top != null ) { 22431 props.top = ( options.top - curOffset.top ) + curTop; 22432 } 22433 if ( options.left != null ) { 22434 props.left = ( options.left - curOffset.left ) + curLeft; 22435 } 22436 22437 if ( "using" in options ) { 22438 options.using.call( elem, props ); 22439 22440 } else { 22441 curElem.css( props ); 22442 } 22443 } 22444}; 22445 22446jQuery.fn.extend( { 22447 22448 // offset() relates an element's border box to the document origin 22449 offset: function( options ) { 22450 22451 // Preserve chaining for setter 22452 if ( arguments.length ) { 22453 return options === undefined ? 22454 this : 22455 this.each( function( i ) { 22456 jQuery.offset.setOffset( this, options, i ); 22457 } ); 22458 } 22459 22460 var rect, win, 22461 elem = this[ 0 ]; 22462 22463 if ( !elem ) { 22464 return; 22465 } 22466 22467 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 22468 // Support: IE <=11 only 22469 // Running getBoundingClientRect on a 22470 // disconnected node in IE throws an error 22471 if ( !elem.getClientRects().length ) { 22472 return { top: 0, left: 0 }; 22473 } 22474 22475 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 22476 rect = elem.getBoundingClientRect(); 22477 win = elem.ownerDocument.defaultView; 22478 return { 22479 top: rect.top + win.pageYOffset, 22480 left: rect.left + win.pageXOffset 22481 }; 22482 }, 22483 22484 // position() relates an element's margin box to its offset parent's padding box 22485 // This corresponds to the behavior of CSS absolute positioning 22486 position: function() { 22487 if ( !this[ 0 ] ) { 22488 return; 22489 } 22490 22491 var offsetParent, offset, doc, 22492 elem = this[ 0 ], 22493 parentOffset = { top: 0, left: 0 }; 22494 22495 // position:fixed elements are offset from the viewport, which itself always has zero offset 22496 if ( jQuery.css( elem, "position" ) === "fixed" ) { 22497 22498 // Assume position:fixed implies availability of getBoundingClientRect 22499 offset = elem.getBoundingClientRect(); 22500 22501 } else { 22502 offset = this.offset(); 22503 22504 // Account for the *real* offset parent, which can be the document or its root element 22505 // when a statically positioned element is identified 22506 doc = elem.ownerDocument; 22507 offsetParent = elem.offsetParent || doc.documentElement; 22508 while ( offsetParent && 22509 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 22510 jQuery.css( offsetParent, "position" ) === "static" ) { 22511 22512 offsetParent = offsetParent.parentNode; 22513 } 22514 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 22515 22516 // Incorporate borders into its offset, since they are outside its content origin 22517 parentOffset = jQuery( offsetParent ).offset(); 22518 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 22519 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 22520 } 22521 } 22522 22523 // Subtract parent offsets and element margins 22524 return { 22525 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 22526 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 22527 }; 22528 }, 22529 22530 // This method will return documentElement in the following cases: 22531 // 1) For the element inside the iframe without offsetParent, this method will return 22532 // documentElement of the parent window 22533 // 2) For the hidden or detached element 22534 // 3) For body or html element, i.e. in case of the html node - it will return itself 22535 // 22536 // but those exceptions were never presented as a real life use-cases 22537 // and might be considered as more preferable results. 22538 // 22539 // This logic, however, is not guaranteed and can change at any point in the future 22540 offsetParent: function() { 22541 return this.map( function() { 22542 var offsetParent = this.offsetParent; 22543 22544 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 22545 offsetParent = offsetParent.offsetParent; 22546 } 22547 22548 return offsetParent || documentElement; 22549 } ); 22550 } 22551} ); 22552 22553// Create scrollLeft and scrollTop methods 22554jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 22555 var top = "pageYOffset" === prop; 22556 22557 jQuery.fn[ method ] = function( val ) { 22558 return access( this, function( elem, method, val ) { 22559 22560 // Coalesce documents and windows 22561 var win; 22562 if ( isWindow( elem ) ) { 22563 win = elem; 22564 } else if ( elem.nodeType === 9 ) { 22565 win = elem.defaultView; 22566 } 22567 22568 if ( val === undefined ) { 22569 return win ? win[ prop ] : elem[ method ]; 22570 } 22571 22572 if ( win ) { 22573 win.scrollTo( 22574 !top ? val : win.pageXOffset, 22575 top ? val : win.pageYOffset 22576 ); 22577 22578 } else { 22579 elem[ method ] = val; 22580 } 22581 }, method, val, arguments.length ); 22582 }; 22583} ); 22584 22585// Support: Safari <=7 - 9.1, Chrome <=37 - 49 22586// Add the top/left cssHooks using jQuery.fn.position 22587// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 22588// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 22589// getComputedStyle returns percent when specified for top/left/bottom/right; 22590// rather than make the css module depend on the offset module, just check for it here 22591jQuery.each( [ "top", "left" ], function( _i, prop ) { 22592 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 22593 function( elem, computed ) { 22594 if ( computed ) { 22595 computed = curCSS( elem, prop ); 22596 22597 // If curCSS returns percentage, fallback to offset 22598 return rnumnonpx.test( computed ) ? 22599 jQuery( elem ).position()[ prop ] + "px" : 22600 computed; 22601 } 22602 } 22603 ); 22604} ); 22605 22606 22607// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 22608jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 22609 jQuery.each( { 22610 padding: "inner" + name, 22611 content: type, 22612 "": "outer" + name 22613 }, function( defaultExtra, funcName ) { 22614 22615 // Margin is only for outerHeight, outerWidth 22616 jQuery.fn[ funcName ] = function( margin, value ) { 22617 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 22618 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 22619 22620 return access( this, function( elem, type, value ) { 22621 var doc; 22622 22623 if ( isWindow( elem ) ) { 22624 22625 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 22626 return funcName.indexOf( "outer" ) === 0 ? 22627 elem[ "inner" + name ] : 22628 elem.document.documentElement[ "client" + name ]; 22629 } 22630 22631 // Get document width or height 22632 if ( elem.nodeType === 9 ) { 22633 doc = elem.documentElement; 22634 22635 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 22636 // whichever is greatest 22637 return Math.max( 22638 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 22639 elem.body[ "offset" + name ], doc[ "offset" + name ], 22640 doc[ "client" + name ] 22641 ); 22642 } 22643 22644 return value === undefined ? 22645 22646 // Get width or height on the element, requesting but not forcing parseFloat 22647 jQuery.css( elem, type, extra ) : 22648 22649 // Set width or height on the element 22650 jQuery.style( elem, type, value, extra ); 22651 }, type, chainable ? margin : undefined, chainable ); 22652 }; 22653 } ); 22654} ); 22655 22656 22657jQuery.each( [ 22658 "ajaxStart", 22659 "ajaxStop", 22660 "ajaxComplete", 22661 "ajaxError", 22662 "ajaxSuccess", 22663 "ajaxSend" 22664], function( _i, type ) { 22665 jQuery.fn[ type ] = function( fn ) { 22666 return this.on( type, fn ); 22667 }; 22668} ); 22669 22670 22671 22672 22673jQuery.fn.extend( { 22674 22675 bind: function( types, data, fn ) { 22676 return this.on( types, null, data, fn ); 22677 }, 22678 unbind: function( types, fn ) { 22679 return this.off( types, null, fn ); 22680 }, 22681 22682 delegate: function( selector, types, data, fn ) { 22683 return this.on( types, selector, data, fn ); 22684 }, 22685 undelegate: function( selector, types, fn ) { 22686 22687 // ( namespace ) or ( selector, types [, fn] ) 22688 return arguments.length === 1 ? 22689 this.off( selector, "**" ) : 22690 this.off( types, selector || "**", fn ); 22691 }, 22692 22693 hover: function( fnOver, fnOut ) { 22694 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 22695 } 22696} ); 22697 22698jQuery.each( 22699 ( "blur focus focusin focusout resize scroll click dblclick " + 22700 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 22701 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 22702 function( _i, name ) { 22703 22704 // Handle event binding 22705 jQuery.fn[ name ] = function( data, fn ) { 22706 return arguments.length > 0 ? 22707 this.on( name, null, data, fn ) : 22708 this.trigger( name ); 22709 }; 22710 } 22711); 22712 22713 22714 22715 22716// Support: Android <=4.0 only 22717// Make sure we trim BOM and NBSP 22718// Require that the "whitespace run" starts from a non-whitespace 22719// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. 22720var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; 22721 22722// Bind a function to a context, optionally partially applying any 22723// arguments. 22724// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 22725// However, it is not slated for removal any time soon 22726jQuery.proxy = function( fn, context ) { 22727 var tmp, args, proxy; 22728 22729 if ( typeof context === "string" ) { 22730 tmp = fn[ context ]; 22731 context = fn; 22732 fn = tmp; 22733 } 22734 22735 // Quick check to determine if target is callable, in the spec 22736 // this throws a TypeError, but we will just return undefined. 22737 if ( !isFunction( fn ) ) { 22738 return undefined; 22739 } 22740 22741 // Simulated bind 22742 args = slice.call( arguments, 2 ); 22743 proxy = function() { 22744 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 22745 }; 22746 22747 // Set the guid of unique handler to the same of original handler, so it can be removed 22748 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 22749 22750 return proxy; 22751}; 22752 22753jQuery.holdReady = function( hold ) { 22754 if ( hold ) { 22755 jQuery.readyWait++; 22756 } else { 22757 jQuery.ready( true ); 22758 } 22759}; 22760jQuery.isArray = Array.isArray; 22761jQuery.parseJSON = JSON.parse; 22762jQuery.nodeName = nodeName; 22763jQuery.isFunction = isFunction; 22764jQuery.isWindow = isWindow; 22765jQuery.camelCase = camelCase; 22766jQuery.type = toType; 22767 22768jQuery.now = Date.now; 22769 22770jQuery.isNumeric = function( obj ) { 22771 22772 // As of jQuery 3.0, isNumeric is limited to 22773 // strings and numbers (primitives or objects) 22774 // that can be coerced to finite numbers (gh-2662) 22775 var type = jQuery.type( obj ); 22776 return ( type === "number" || type === "string" ) && 22777 22778 // parseFloat NaNs numeric-cast false positives ("") 22779 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 22780 // subtraction forces infinities to NaN 22781 !isNaN( obj - parseFloat( obj ) ); 22782}; 22783 22784jQuery.trim = function( text ) { 22785 return text == null ? 22786 "" : 22787 ( text + "" ).replace( rtrim, "$1" ); 22788}; 22789 22790 22791 22792// Register as a named AMD module, since jQuery can be concatenated with other 22793// files that may use define, but not via a proper concatenation script that 22794// understands anonymous AMD modules. A named AMD is safest and most robust 22795// way to register. Lowercase jquery is used because AMD module names are 22796// derived from file names, and jQuery is normally delivered in a lowercase 22797// file name. Do this after creating the global so that if an AMD module wants 22798// to call noConflict to hide this version of jQuery, it will work. 22799 22800// Note that for maximum portability, libraries that are not jQuery should 22801// declare themselves as anonymous modules, and avoid setting a global if an 22802// AMD loader is present. jQuery is a special case. For more information, see 22803// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 22804 22805if ( typeof define === "function" && define.amd ) { 22806 define( "jquery", [], function() { 22807 return jQuery; 22808 } ); 22809} 22810 22811 22812 22813 22814var 22815 22816 // Map over jQuery in case of overwrite 22817 _jQuery = window.jQuery, 22818 22819 // Map over the $ in case of overwrite 22820 _$ = window.$; 22821 22822jQuery.noConflict = function( deep ) { 22823 if ( window.$ === jQuery ) { 22824 window.$ = _$; 22825 } 22826 22827 if ( deep && window.jQuery === jQuery ) { 22828 window.jQuery = _jQuery; 22829 } 22830 22831 return jQuery; 22832}; 22833 22834// Expose jQuery and $ identifiers, even in AMD 22835// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557) 22836// and CommonJS for browser emulators (trac-13566) 22837if ( typeof noGlobal === "undefined" ) { 22838 window.jQuery = window.$ = jQuery; 22839} 22840 22841 22842 22843 22844return jQuery; 22845} ); 22846 22847 22848 22849 22850/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module))) 22851 22852/***/ }), 22853
vendor: 804 bytes, lines 22854-22887
22854/***/ "./node_modules/webpack/buildin/module.js": 22855/*!***********************************!*\ 22856 !*** (webpack)/buildin/module.js ***! 22857 \***********************************/ 22858/*! no static exports found */ 22859/***/ (function(module, exports) { 22860 22861module.exports = function (module) { 22862 if (!module.webpackPolyfill) { 22863 module.deprecate = function () {}; 22864 22865 module.paths = []; // module.parent = undefined by default 22866 22867 if (!module.children) module.children = []; 22868 Object.defineProperty(module, "loaded", { 22869 enumerable: true, 22870 get: function get() { 22871 return module.l; 22872 } 22873 }); 22874 Object.defineProperty(module, "id", { 22875 enumerable: true, 22876 get: function get() { 22877 return module.i; 22878 } 22879 }); 22880 module.webpackPolyfill = 1; 22881 } 22882 22883 return module; 22884}; 22885 22886/***/ }), 22887
vendor: 16,564 bytes, lines 22888-23394
22888/***/ "./node_modules/what-input/dist/what-input.js": 22889/*!****************************************************!*\ 22890 !*** ./node_modules/what-input/dist/what-input.js ***! 22891 \****************************************************/ 22892/*! no static exports found */ 22893/***/ (function(module, exports, __webpack_require__) { 22894 22895/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 22896 22897/** 22898 * what-input - A global utility for tracking the current input method (mouse, keyboard or touch). 22899 * @version v5.1.2 22900 * @link https://github.com/ten1seven/what-input 22901 * @license MIT 22902 */ 22903(function webpackUniversalModuleDefinition(root, factory) { 22904 if (( false ? undefined : _typeof(exports)) === 'object' && ( false ? undefined : _typeof(module)) === 'object') module.exports = factory();else if (true) !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 22905 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 22906 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 22907 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {} 22908})(this, function () { 22909 return ( 22910 /******/ 22911 function (modules) { 22912 // webpackBootstrap 22913 22914 /******/ 22915 // The module cache 22916 22917 /******/ 22918 var installedModules = {}; 22919 /******/ 22920 // The require function 22921 22922 /******/ 22923 22924 function __webpack_require__(moduleId) { 22925 /******/ 22926 // Check if module is in cache 22927 22928 /******/ 22929 if (installedModules[moduleId]) 22930 /******/ 22931 return installedModules[moduleId].exports; 22932 /******/ 22933 // Create a new module (and put it into the cache) 22934 22935 /******/ 22936 22937 var module = installedModules[moduleId] = { 22938 /******/ 22939 exports: {}, 22940 22941 /******/ 22942 id: moduleId, 22943 22944 /******/ 22945 loaded: false 22946 /******/ 22947 22948 }; 22949 /******/ 22950 // Execute the module function 22951 22952 /******/ 22953 22954 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22955 /******/ 22956 // Flag the module as loaded 22957 22958 /******/ 22959 22960 module.loaded = true; 22961 /******/ 22962 // Return the exports of the module 22963 22964 /******/ 22965 22966 return module.exports; 22967 /******/ 22968 } 22969 /******/ 22970 // expose the modules object (__webpack_modules__) 22971 22972 /******/ 22973 22974 22975 __webpack_require__.m = modules; 22976 /******/ 22977 // expose the module cache 22978 22979 /******/ 22980 22981 __webpack_require__.c = installedModules; 22982 /******/ 22983 // __webpack_public_path__ 22984 22985 /******/ 22986 22987 __webpack_require__.p = ""; 22988 /******/ 22989 // Load entry module and return exports 22990 22991 /******/ 22992 22993 return __webpack_require__(0); 22994 /******/ 22995 }( 22996 /************************************************************************/ 22997 22998 /******/ 22999 [ 23000 /* 0 */ 23001 23002 /***/ 23003 function (module, exports) { 23004 'use strict'; 23005 23006 module.exports = function () { 23007 /* 23008 * bail out if there is no document or window 23009 * (i.e. in a node/non-DOM environment) 23010 * 23011 * Return a stubbed API instead 23012 */ 23013 if (typeof document === 'undefined' || typeof window === 'undefined') { 23014 return { 23015 // always return "initial" because no interaction will ever be detected 23016 ask: function ask() { 23017 return 'initial'; 23018 }, 23019 // always return null 23020 element: function element() { 23021 return null; 23022 }, 23023 // no-op 23024 ignoreKeys: function ignoreKeys() {}, 23025 // no-op 23026 specificKeys: function specificKeys() {}, 23027 // no-op 23028 registerOnChange: function registerOnChange() {}, 23029 // no-op 23030 unRegisterOnChange: function unRegisterOnChange() {} 23031 }; 23032 } 23033 /* 23034 * variables 23035 */ 23036 // cache document.documentElement 23037 23038 23039 var docElem = document.documentElement; // currently focused dom element 23040 23041 var currentElement = null; // last used input type 23042 23043 var currentInput = 'initial'; // last used input intent 23044 23045 var currentIntent = currentInput; // check for sessionStorage support 23046 // then check for session variables and use if available 23047 23048 try { 23049 if (window.sessionStorage.getItem('what-input')) { 23050 currentInput = window.sessionStorage.getItem('what-input'); 23051 } 23052 23053 if (window.sessionStorage.getItem('what-intent')) { 23054 currentIntent = window.sessionStorage.getItem('what-intent'); 23055 } 23056 } catch (e) {} // event buffer timer 23057 23058 23059 var eventTimer = null; // form input types 23060 23061 var formInputs = ['input', 'select', 'textarea']; // empty array for holding callback functions 23062 23063 var functionList = []; // list of modifier keys commonly used with the mouse and 23064 // can be safely ignored to prevent false keyboard detection 23065 23066 var ignoreMap = [16, // shift 23067 17, // control 23068 18, // alt 23069 91, // Windows key / left Apple cmd 23070 93 // Windows menu / right Apple cmd 23071 ]; 23072 var specificMap = []; // mapping of events to input types 23073 23074 var inputMap = { 23075 keydown: 'keyboard', 23076 keyup: 'keyboard', 23077 mousedown: 'mouse', 23078 mousemove: 'mouse', 23079 MSPointerDown: 'pointer', 23080 MSPointerMove: 'pointer', 23081 pointerdown: 'pointer', 23082 pointermove: 'pointer', 23083 touchstart: 'touch' // boolean: true if touch buffer is active 23084 23085 }; 23086 var isBuffering = false; // boolean: true if the page is being scrolled 23087 23088 var isScrolling = false; // store current mouse position 23089 23090 var mousePos = { 23091 x: null, 23092 y: null // map of IE 10 pointer events 23093 23094 }; 23095 var pointerMap = { 23096 2: 'touch', 23097 3: 'touch', 23098 // treat pen like touch 23099 4: 'mouse' // check support for passive event listeners 23100 23101 }; 23102 var supportsPassive = false; 23103 23104 try { 23105 var opts = Object.defineProperty({}, 'passive', { 23106 get: function get() { 23107 supportsPassive = true; 23108 } 23109 }); 23110 window.addEventListener('test', null, opts); 23111 } catch (e) {} 23112 /* 23113 * set up 23114 */ 23115 23116 23117 var setUp = function setUp() { 23118 // add correct mouse wheel event mapping to `inputMap` 23119 inputMap[detectWheel()] = 'mouse'; 23120 addListeners(); 23121 doUpdate('input'); 23122 doUpdate('intent'); 23123 }; 23124 /* 23125 * events 23126 */ 23127 23128 23129 var addListeners = function addListeners() { 23130 // `pointermove`, `MSPointerMove`, `mousemove` and mouse wheel event binding 23131 // can only demonstrate potential, but not actual, interaction 23132 // and are treated separately 23133 var options = supportsPassive ? { 23134 passive: true 23135 } : false; // pointer events (mouse, pen, touch) 23136 23137 if (window.PointerEvent) { 23138 window.addEventListener('pointerdown', setInput); 23139 window.addEventListener('pointermove', setIntent); 23140 } else if (window.MSPointerEvent) { 23141 window.addEventListener('MSPointerDown', setInput); 23142 window.addEventListener('MSPointerMove', setIntent); 23143 } else { 23144 // mouse events 23145 window.addEventListener('mousedown', setInput); 23146 window.addEventListener('mousemove', setIntent); // touch events 23147 23148 if ('ontouchstart' in window) { 23149 window.addEventListener('touchstart', eventBuffer, options); 23150 window.addEventListener('touchend', setInput); 23151 } 23152 } // mouse wheel 23153 23154 23155 window.addEventListener(detectWheel(), setIntent, options); // keyboard events 23156 23157 window.addEventListener('keydown', eventBuffer); 23158 window.addEventListener('keyup', eventBuffer); // focus events 23159 23160 window.addEventListener('focusin', setElement); 23161 window.addEventListener('focusout', clearElement); 23162 }; // checks conditions before updating new input 23163 23164 23165 var setInput = function setInput(event) { 23166 // only execute if the event buffer timer isn't running 23167 if (!isBuffering) { 23168 var eventKey = event.which; 23169 var value = inputMap[event.type]; 23170 23171 if (value === 'pointer') { 23172 value = pointerType(event); 23173 } 23174 23175 var ignoreMatch = !specificMap.length && ignoreMap.indexOf(eventKey) === -1; 23176 var specificMatch = specificMap.length && specificMap.indexOf(eventKey) !== -1; 23177 var shouldUpdate = value === 'keyboard' && eventKey && (ignoreMatch || specificMatch) || value === 'mouse' || value === 'touch'; 23178 23179 if (currentInput !== value && shouldUpdate) { 23180 currentInput = value; 23181 23182 try { 23183 window.sessionStorage.setItem('what-input', currentInput); 23184 } catch (e) {} 23185 23186 doUpdate('input'); 23187 } 23188 23189 if (currentIntent !== value && shouldUpdate) { 23190 // preserve intent for keyboard typing in form fields 23191 var activeElem = document.activeElement; 23192 var notFormInput = activeElem && activeElem.nodeName && formInputs.indexOf(activeElem.nodeName.toLowerCase()) === -1; 23193 23194 if (notFormInput) { 23195 currentIntent = value; 23196 23197 try { 23198 window.sessionStorage.setItem('what-intent', currentIntent); 23199 } catch (e) {} 23200 23201 doUpdate('intent'); 23202 } 23203 } 23204 } 23205 }; // updates the doc and `inputTypes` array with new input 23206 23207 23208 var doUpdate = function doUpdate(which) { 23209 docElem.setAttribute('data-what' + which, which === 'input' ? currentInput : currentIntent); 23210 fireFunctions(which); 23211 }; // updates input intent for `mousemove` and `pointermove` 23212 23213 23214 var setIntent = function setIntent(event) { 23215 // test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove 23216 detectScrolling(event); // only execute if the event buffer timer isn't running 23217 // or scrolling isn't happening 23218 23219 if (!isBuffering && !isScrolling) { 23220 var value = inputMap[event.type]; 23221 23222 if (value === 'pointer') { 23223 value = pointerType(event); 23224 } 23225 23226 if (currentIntent !== value) { 23227 currentIntent = value; 23228 23229 try { 23230 window.sessionStorage.setItem('what-intent', currentIntent); 23231 } catch (e) {} 23232 23233 doUpdate('intent'); 23234 } 23235 } 23236 }; 23237 23238 var setElement = function setElement(event) { 23239 if (!event.target.nodeName) { 23240 // If nodeName is undefined, clear the element 23241 // This can happen if click inside an <svg> element. 23242 clearElement(); 23243 return; 23244 } 23245 23246 currentElement = event.target.nodeName.toLowerCase(); 23247 docElem.setAttribute('data-whatelement', currentElement); 23248 23249 if (event.target.classList && event.target.classList.length) { 23250 docElem.setAttribute('data-whatclasses', event.target.classList.toString().replace(' ', ',')); 23251 } 23252 }; 23253 23254 var clearElement = function clearElement() { 23255 currentElement = null; 23256 docElem.removeAttribute('data-whatelement'); 23257 docElem.removeAttribute('data-whatclasses'); 23258 }; // buffers events that frequently also fire mouse events 23259 23260 23261 var eventBuffer = function eventBuffer(event) { 23262 // set the current input 23263 setInput(event); // clear the timer if it happens to be running 23264 23265 window.clearTimeout(eventTimer); // set the isBuffering to `true` 23266 23267 isBuffering = true; // run the timer 23268 23269 eventTimer = window.setTimeout(function () { 23270 // if the timer runs out, set isBuffering back to `false` 23271 isBuffering = false; 23272 }, 100); 23273 }; 23274 /* 23275 * utilities 23276 */ 23277 23278 23279 var pointerType = function pointerType(event) { 23280 if (typeof event.pointerType === 'number') { 23281 return pointerMap[event.pointerType]; 23282 } else { 23283 // treat pen like touch 23284 return event.pointerType === 'pen' ? 'touch' : event.pointerType; 23285 } 23286 }; // detect version of mouse wheel event to use 23287 // via https://developer.mozilla.org/en-US/docs/Web/Events/wheel 23288 23289 23290 var detectWheel = function detectWheel() { 23291 var wheelType = void 0; // Modern browsers support "wheel" 23292 23293 if ('onwheel' in document.createElement('div')) { 23294 wheelType = 'wheel'; 23295 } else { 23296 // Webkit and IE support at least "mousewheel" 23297 // or assume that remaining browsers are older Firefox 23298 wheelType = document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll'; 23299 } 23300 23301 return wheelType; 23302 }; // runs callback functions 23303 23304 23305 var fireFunctions = function fireFunctions(type) { 23306 for (var i = 0, len = functionList.length; i < len; i++) { 23307 if (functionList[i].type === type) { 23308 functionList[i].fn.call(undefined, type === 'input' ? currentInput : currentIntent); 23309 } 23310 } 23311 }; // finds matching element in an object 23312 23313 23314 var objPos = function objPos(match) { 23315 for (var i = 0, len = functionList.length; i < len; i++) { 23316 if (functionList[i].fn === match) { 23317 return i; 23318 } 23319 } 23320 }; 23321 23322 var detectScrolling = function detectScrolling(event) { 23323 if (mousePos['x'] !== event.screenX || mousePos['y'] !== event.screenY) { 23324 isScrolling = false; 23325 mousePos['x'] = event.screenX; 23326 mousePos['y'] = event.screenY; 23327 } else { 23328 isScrolling = true; 23329 } 23330 }; 23331 /* 23332 * init 23333 */ 23334 // don't start script unless browser cuts the mustard 23335 // (also passes if polyfills are used) 23336 23337 23338 if ('addEventListener' in window && Array.prototype.indexOf) { 23339 setUp(); 23340 } 23341 /* 23342 * api 23343 */ 23344 23345 23346 return { 23347 // returns string: the current input type 23348 // opt: 'intent'|'input' 23349 // 'input' (default): returns the same value as the `data-whatinput` attribute 23350 // 'intent': includes `data-whatintent` value if it's different than `data-whatinput` 23351 ask: function ask(opt) { 23352 return opt === 'intent' ? currentIntent : currentInput; 23353 }, 23354 // returns string: the currently focused element or null 23355 element: function element() { 23356 return currentElement; 23357 }, 23358 // overwrites ignored keys with provided array 23359 ignoreKeys: function ignoreKeys(arr) { 23360 ignoreMap = arr; 23361 }, 23362 // overwrites specific char keys to update on 23363 specificKeys: function specificKeys(arr) { 23364 specificMap = arr; 23365 }, 23366 // attach functions to input and intent "events" 23367 // funct: function to fire on change 23368 // eventType: 'input'|'intent' 23369 registerOnChange: function registerOnChange(fn, eventType) { 23370 functionList.push({ 23371 fn: fn, 23372 type: eventType || 'input' 23373 }); 23374 }, 23375 unRegisterOnChange: function unRegisterOnChange(fn) { 23376 var position = objPos(fn); 23377 23378 if (position || position === 0) { 23379 functionList.splice(position, 1); 23380 } 23381 } 23382 }; 23383 }(); 23384 /***/ 23385 23386 }]) 23387 ); 23388}); 23389 23390; 23391/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module))) 23392 23393/***/ }), 23394
23395/***/ "./src/assets/js/app.js": 23396/*!******************************!*\ 23397 !*** ./src/assets/js/app.js ***! 23398 \******************************/ 23399/*! no exports provided */ 23400/***/ (function(module, __webpack_exports__, __webpack_require__) { 23401 23402"use strict"; 23403__webpack_require__.r(__webpack_exports__); 23404/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 23405/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 23406/* harmony import */ var what_input__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! what-input */ "./node_modules/what-input/dist/what-input.js"); 23407/* harmony import */ var what_input__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(what_input__WEBPACK_IMPORTED_MODULE_1__); 23408 23409 // Foundation JS relies on a global varaible. In ES6, all imports are hoisted 23410// to the top of the file so if we used`import` to import Foundation, 23411// it would execute earlier than we have assigned the global variable. 23412// This is why we have to use CommonJS require() here since it doesn't 23413// have the hoisting behavior. 23414 23415window.jQuery = jquery__WEBPACK_IMPORTED_MODULE_0___default.a; 23416 23417__webpack_require__(/*! foundation-sites */ "./node_modules/foundation-sites/dist/js/foundation.esm.js"); // If you want to pick and choose which modules to include, comment out the above and uncomment 23418// the line below 23419//import './lib/foundation-explicit-pieces'; 23420 23421 23422jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).foundation(); 23423/* ==================================================== 23424 DOSING CALCULATOR --RA- PSA -AS 23425 ==================================================== */ 23426 23427var dose = 0; 23428var cal_lb = 95; 23429var cal_kg = 43; 23430var cal_mg = 0; 23431var cal_vials = 0; 23432var cal_ml = 0; 23433jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).ready(function ($) { 23434 // get dose value - only use by RA 23435 $(".does").change(function () { 23436 /* $( "select option:selected" ).each(function() { 23437 dose = $( this ).val(); 23438 });*/ 23439 dose = $(".does option:selected").text(); 23440 $(".result_mg").html(""); 23441 $(".result_vials").html(""); 23442 $(".result_ml").html(""); 23443 }).change(); // convet lb to kg 23444 23445 $(".cal_lb").change(function () { 23446 cal_lb = $(".cal_lb option:selected").text(); 23447 cal_kg = Math.round(cal_lb / 2.2); 23448 $(".kg").html(cal_kg); 23449 $(".result_mg").html(""); 23450 $(".result_vials").html(""); 23451 $(".result_ml").html(""); 23452 }).change(); 23453 $('.enter_btn').on('click', function (e) { 23454 if ($(this).hasClass("psa") || $(this).hasClass("as")) { 23455 // PSA and AS 23456 dose = 5; 23457 } else { 23458 // ra 23459 dose = $("#RA_dose").val(); 23460 } 23461 23462 cal_mg = dose * cal_kg; 23463 cal_vials = Math.ceil(cal_mg / 100); 23464 cal_ml = cal_mg / 10; 23465 $(".result_mg").html(cal_mg); 23466 $(".result_vials").html(cal_vials); 23467 $(".result_ml").html(cal_ml); //console.log("line 78 enter clicked-- " + cal_lb + "-" + cal_kg + "-" + cal_dose+"-" +cal_mg + "-" + cal_vials + "-" + cal_ml); 23468 }); 23469}); 23470/* ==================================================== 23471 VIDEO 23472 ==================================================== */ 23473 23474jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).ready(function ($) { 23475 videojs("myPlayerID").ready(function () { 23476 var player = this; 23477 player.one("loadedmetadata", function () { 23478 $("#pic1").click(function () { 23479 player.currentTime(0); 23480 var tt = player.textTracks()[0]; 23481 23482 tt.oncuechange = function () { 23483 if (tt.activeCues[0] !== undefined) { 23484 var dynamicHTML = "id: " + tt.activeCues[0].id + ", "; 23485 dynamicHTML += "text: " + tt.activeCues[0].text + ", "; 23486 dynamicHTML += "startTime: " + tt.activeCues[0].startTime + ", "; 23487 dynamicHTML += "endTime: " + tt.activeCues[0].endTime; 23488 document.getElementById("insertionPoint").innerHTML += dynamicHTML + "<br/>"; 23489 23490 if (tt.activeCues[0].endTime > 369) { 23491 player.pause(); 23492 } 23493 } 23494 }; 23495 23496 player.play(); 23497 }); 23498 $('.close-button').click(function () { 23499 player.pause(); 23500 }); 23501 $("#pic2").click(function () { 23502 player.currentTime(370); 23503 player.play(); 23504 }); 23505 $("#pic5").click(function () { 23506 player.currentTime(1650); 23507 player.play(); 23508 }); 23509 $("#pic6").click(function () { 23510 player.currentTime(1907); 23511 player.play(); 23512 }); 23513 $("#pic4").click(function () { 23514 player.currentTime(1227); 23515 player.play(); 23516 }); 23517 $("#pic3").click(function () { 23518 player.currentTime(761); 23519 var tt = player.textTracks()[0]; 23520 23521 tt.oncuechange = function () { 23522 if (tt.activeCues[0] !== undefined) { 23523 var dynamicHTML = "id: " + tt.activeCues[0].id + ", "; 23524 dynamicHTML += "text: " + tt.activeCues[0].text + ", "; 23525 dynamicHTML += "startTime: " + tt.activeCues[0].startTime + ", "; 23526 dynamicHTML += "endTime: " + tt.activeCues[0].endTime; 23527 document.getElementById("insertionPoint").innerHTML += dynamicHTML + "<br/>"; 23528 } 23529 }; 23530 23531 player.play(); 23532 }); 23533 }); 23534 }); 23535}); 23536/* ==================================================== 23537 Adding class to mobile main menu 23538 ==================================================== */ 23539 23540jquery__WEBPACK_IMPORTED_MODULE_0___default()(document).ready(function ($) { 23541 // Get current url 23542 // Select an a element that has the matching href and apply a class of 'active'. Also prepend a - to the content of the link 23543 var url = window.location.href; // Will also work for relative and absolute hrefs 23544 23545 $('ul.menu a').each(function () { 23546 if (this.href == window.location.href) { 23547 $(this).parents('li').find('> a').addClass("active"); 23548 } 23549 }); // for POPUP button remove is-reveal-open class from html prevent content disappear 23550 23551 $('.popup').each(function () { 23552 $(this).on('click', function (e) { 23553 setTimeout(function () { 23554 $('html').removeClass('is-reveal-open'); 23555 }, 30); 23556 }); 23557 }); // hide product menu 23558 23559 $('.product_home').on('click', function (e) { 23560 $(this).toggleClass('on'); 23561 $('.product_menu').toggleClass('hide'); 23562 $('.product_overlay').toggleClass('hide'); 23563 }); 23564 $('.product_overlay').on('click', function (e) { 23565 $(this).removeClass('on'); 23566 $('.product_home').removeClass('on'); 23567 $('.product_menu').addClass('hide'); 23568 $('.product_overlay').addClass('hide'); 23569 }); 23570 23571 /***Immunology-therapies Popup***/ 23572 //therapies button - open popup 23573 $('.therapy-btn-plus').on('click', function (e) { 23574 $('.therapies-popup').removeClass('hide'); 23575 $('#therapies-button').addClass('hide'); 23576 $('#therapies-popup-overlay').removeClass('hide'); 23577 $('body').addClass('noscroll'); 23578 }); 23579 23580 // Close popup when clicking outside modal content. 23581 $('.therapies-popup').on('click', function (e) { 23582 if (!$(e.target).closest('.modal-content').length) { 23583 $('.therapies-popup').addClass('hide'); 23584 $('#therapies-button').removeClass('hide'); 23585 $('#therapies-popup-overlay').addClass('hide'); 23586 $('body').removeClass('noscroll'); 23587 } 23588 }); 23589 23590 //therapies button - close popup 23591 $('.therapy-btn-minus, .btn-close, #close-popup').on('click', function (e) { 23592 $('.therapies-popup').addClass('hide'); 23593 $('#therapies-button').removeClass('hide'); 23594 $('#therapies-popup-overlay').addClass('hide'); 23595 $('body').removeClass('noscroll'); 23596 }); 23597 23598 //close popup when clicking on overlay 23599 $('#therapies-popup-overlay').on('click', function (e) { 23600 $('.therapies-popup').addClass('hide'); 23601 $('#therapies-button').removeClass('hide'); 23602 $('#therapies-popup-overlay').addClass('hide'); 23603 $('body').removeClass('noscroll'); 23604 }); 23605 /**end**/ 23606 23607 // for herf link to #tag in different page 23608 setTimeout(function () { 23609 $('html,body').animate({ 23610 scrollTop: $(window.location.hash).offset().top - 160 23611 }); 23612 console.log("jumplink"); 23613 }, 300); //==== for hash in same page pad top 23614 23615 $('.inpageHash').click(function () { 23616 console.log("inpageHash"); 23617 var id = $(this).attr("href"), 23618 $id = $(id), 23619 dataID = id.substr(1); // Our scroll target : the top position of the 23620 // section that has the id referenced by our href. 23621 23622 var target = $(id).offset().top - 120; //$id.attr('data-id',dataID).attr('id',''); 23623 //window.location.hash = id; 23624 /// $id.attr('id',dataID); 23625 23626 $('html,body').animate({ 23627 scrollTop: target 23628 }, 500); 23629 }); //====== hide mobile menu when click elsewhere 23630 23631 $('.menu-icon').click(function () { 23632 $('body').toggleClass('mobile-nav-opened'); 23633 return false;
23634 }); 23635 $('html').click(function () { 23636 if ($('body').hasClass('mobile-nav-opened')) { 23637 $('#mobile-menu').css('display', 'none'); 23638 $('body').removeClass('mobile-nav-opened'); 23639 } 23640 }); 23641 $('#mobile-menu').click(function (e) { 23642 e.stopPropagation(); 23643 }); 23644}); 23645/* ==================================================== 23646 window scroll hide products popup 23647 ==================================================== */ 23648 23649jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scroll(function () { 23650 // if scroll is greater/equal then 10 hide products popup 23651 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).scrollTop() > 10) { 23652 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.product_home').removeClass('on'); 23653 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.product_menu').addClass('hide'); 23654 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.product_overlay').addClass('hide'); 23655 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.nav-bar').addClass('is-stuck'); 23656 } 23657 23658 if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).scrollTop() == 0) { 23659 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.nav-bar').removeClass('is-stuck'); 23660 } 23661}); 23662/* ==================================================== 23663 External Link Modal Pop Ups 23664 ==================================================== */ 23665 23666/* =========================== 23667 Third Party Links 23668 =========================== */ 23669 23670jquery__WEBPACK_IMPORTED_MODULE_0___default()('a.extlink').on("mousedown touchstart", function (e) { 23671 e.preventDefault(); // Prevent the href from redirecting directly 23672 23673 var linkURLThirdparty = jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).attr("href"); 23674 warnBeforeRedirectThirdparty(linkURLThirdparty); 23675}); 23676 23677window.warnBeforeRedirectThirdparty = function warnBeforeRedirectThirdparty(linkURLThirdparty) { 23678 swal({ 23679 title: "Thank you for visiting www.remicadehcp.com.", 23680 html: "<p>By clicking âcontinueâ below, you will be taken to a Web site that may contain links or references to other Web sites to which our Privacy Policy may not apply. We encourage you to read the Privacy Policy of every Web site you visit.</p><p>You are solely responsible for your interactions with such Web sites</p>", 23681 cancelButtonText: 'Cancel >', 23682 confirmButtonText: 'Continue >', 23683 allowOutsideClick: true, 23684 showCloseButton: true, 23685 showCancelButton: true, 23686 useRejections: true, 23687 animation: false 23688 }).then(function (okay) { 23689 // Redirect the user 23690 if (okay) { 23691 window.open(linkURLThirdparty); 23692 } 23693 }); 23694}; 23695/* ==================================================== 23696 ISI 23697 ==================================================== */ 23698 var isstage = ''; 23699 var site_domain = window.location.href; 23700 var isi_domain = 'https://isi.janssenos.com'; 23701 // PLEASE UPDATE THE NON PRODUCTION URLS ACCORDINGLY. 23702 if (site_domain.indexOf("localhost") >= 0 || site_domain.indexOf("dev") >= 0) { 23703 console.log('Loading ISI Review version'); 23704 isstage = '?env=test'; 23705 } 23706 var isi_params = 'English/unitedStates/remicade/Professional'; 23707 //isi_params += '/cp-62063v2'; 23708 23709 var isi_url = isi_domain + '/isi/' + isi_params + isstage; 23710 if (isi_url !== null) { 23711 $.ajax({ 23712 url: isi_url, 23713 cache: !0, 23714 async: !0 23715 }).done(function (isi_content) { 23716 if (isi_content !== undefined) { 23717 $("#janssen-isi-content-wrapper").html(isi_content.data); 23718 $("#janssen-isi-content-wrapper-2").html(isi_content.data); 23719 } else { 23720 console.log('ISI - No data to fetch / or invalid query.') 23721 } 23722 }).fail(function (jqXHR, exception) { 23723 23724 }); 23725 } 23726 23727var isiwaypoint = new Waypoint({ 23728 element: document.getElementById('isi-waypoint'), 23729 handler: function handler(direction) { 23730 if (direction == 'down') { 23731 jquery__WEBPACK_IMPORTED_MODULE_0___default()('#section-isi').hide(); 23732 } else if (direction == 'up') { 23733 jquery__WEBPACK_IMPORTED_MODULE_0___default()('#section-isi').show(); 23734 } //console.log('Direction: ' + direction); 23735 23736 }, 23737 offset: '75%' 23738}); //--------------BIND BUTTONS 23739 23740jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on("load", function () { 23741 setTimeout(function () { 23742 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollTop(0); //scroll to top on refresh 23743 }); 23744 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.backtotop').on('click', function (e) { 23745 jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).scrollTop(0); 23746 }); 23747 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.isiexpand').on('click', function (e) { 23748 // window.scrollTo(0,document.body.scrollHeight); 23749 e.preventDefault(); 23750 jquery__WEBPACK_IMPORTED_MODULE_0___default()('html, body').animate({ 23751 scrollTop: jquery__WEBPACK_IMPORTED_MODULE_0___default()("#isi-waypoint").offset().top - 300 23752 }, 300, 'linear'); 23753 }); /// QAbtn on access page 23754 23755 jquery__WEBPACK_IMPORTED_MODULE_0___default()('.QAbtn').on('click', function (e) { 23756 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).siblings().removeClass('on'); 23757 jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).toggleClass('on'); 23758 }); 23759 23760}); 23761 23762 23763 23764//----- mobile ISI ----------------------- 23765 23766 jQuery(window).on("load resize", function () { 23767 if (jQuery(this).width() > 1023) { 23768 jQuery('#section-isi').removeClass('mob_isi'); 23769 //jQuery(".s_header").unbind(); 23770 } else if (jQuery(this).width() <= 23771 1023) { // add mobile style and button in 23772 jQuery('#section-isi').addClass('mob_isi'); 23773 jQuery('#section-isi #isi_head').unbind('click').bind('click', function (e) { 23774 if (jQuery("#section-isi #isi").hasClass('isiOn')) { 23775 jQuery('#section-isi #isi').removeClass('isiOn'); 23776 jQuery('.mob_isi').removeClass('open'); 23777 jQuery("body").removeClass("noscroll"); 23778 } else { 23779 jQuery('#section-isi #isi').addClass('isiOn'); 23780 jQuery('.mob_isi').addClass('open'); 23781 jQuery("body").addClass("noscroll"); 23782 jQuery('#section-isi #indication').removeClass('isiOn'); 23783 } 23784 return false;
23785 }); 23786 23787 jQuery('#section-isi #head-indication').unbind('click').bind('click', function (e) { 23788 if (jQuery("#section-isi #indication").hasClass('isiOn')) { 23789 jQuery('#section-isi #indication').removeClass('isiOn'); 23790 jQuery('.mob_isi').removeClass('open'); 23791 jQuery("body").removeClass("noscroll"); 23792 } else { 23793 jQuery('#section-isi #indication').addClass('isiOn'); 23794 jQuery('.mob_isi').addClass('open'); 23795 jQuery('#section-isi #isi').removeClass('isiOn'); 23796 jQuery("body").addClass("noscroll"); 23797 } 23798 }); 23799 // console.log("smallp" + jQuery(this).width()); 23800 } 23801 }); 23802 23803/***/ })
23803, 23804 23805/***/ 0: 23806/*!************************************!*\ 23807 !*** multi ./src/assets/js/app.js ***! 23808 \************************************/ 23809/*! no static exports found */ 23810/***/ (function(module, exports, __webpack_require__) { 23811 23812module.exports = __webpack_require__(/*! /Users/nwagley/projects/REM.061 - Remicade Website (Patient and HCP)/REM.061.1/Source/Remicade_HCP_061/HCP/src/assets/js/app.js */"./src/assets/js/app.js"); 23813 23814 23815/***/ }) 23816 23817/******/ }); 23818//# 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.