PageSourceSearch

https://8proof.com/js/popper.js

js 8proof.com collected 2026-09-24 11:21:08 UTC 88,317 bytes, 2,612 lines download raw bytes

vendor: 4,678 bytes, lines 1-158
1/**!
2 * @fileOverview Kickass library to create and place poppers near their reference elements.
3 * @version 1.15.0
4 * @license
5 * Copyright (c) 2016 Federico Zivolo and contributors
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25(function (global, factory) {
26	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
27	typeof define === 'function' && define.amd ? define(factory) :
28	(global.Popper = factory());
29}(this, (function () { 'use strict';
30
31var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
32
33var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
34var timeoutDuration = 0;
35for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
36  if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
37    timeoutDuration = 1;
38    break;
39  }
40}
41
42function microtaskDebounce(fn) {
43  var called = false;
44  return function () {
45    if (called) {
46      return;
47    }
48    called = true;
49    window.Promise.resolve().then(function () {
50      called = false;
51      fn();
52    });
53  };
54}
55
56function taskDebounce(fn) {
57  var scheduled = false;
58  return function () {
59    if (!scheduled) {
60      scheduled = true;
61      setTimeout(function () {
62        scheduled = false;
63        fn();
64      }, timeoutDuration);
65    }
66  };
67}
68
69var supportsMicroTasks = isBrowser && window.Promise;
70
71/**
72* Create a debounced version of a method, that's asynchronously deferred
73* but called in the minimum time possible.
74*
75* @method
76* @memberof Popper.Utils
77* @argument {Function} fn
78* @returns {Function}
79*/
80var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
81
82/**
83 * Check if the given variable is a function
84 * @method
85 * @memberof Popper.Utils
86 * @argument {Any} functionToCheck - variable to check
87 * @returns {Boolean} answer to: is a function?
88 */
89function isFunction(functionToCheck) {
90  var getType = {};
91  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
92}
93
94/**
95 * Get CSS computed property of the given element
96 * @method
97 * @memberof Popper.Utils
98 * @argument {Eement} element
99 * @argument {String} property
100 */
101function getStyleComputedProperty(element, property) {
102  if (element.nodeType !== 1) {
103    return [];
104  }
105  // NOTE: 1 DOM access here
106  var window = element.ownerDocument.defaultView;
107  var css = window.getComputedStyle(element, null);
108  return property ? css[property] : css;
109}
110
111/**
112 * Returns the parentNode or the host of the element
113 * @method
114 * @memberof Popper.Utils
115 * @argument {Element} element
116 * @returns {Element} parent
117 */
118function getParentNode(element) {
119  if (element.nodeName === 'HTML') {
120    return element;
121  }
122  return element.parentNode || element.host;
123}
124
125/**
126 * Returns the scrolling parent of the given element
127 * @method
128 * @memberof Popper.Utils
129 * @argument {Element} element
130 * @returns {Element} scroll parent
131 */
132function getScrollParent(element) {
133  // Return body, `getScroll` will take care to get the correct `scrollTop` from it
134  if (!element) {
135    return document.body;
136  }
137
138  switch (element.nodeName) {
139    case 'HTML':
140    case 'BODY':
141      return element.ownerDocument.body;
142    case '#document':
143      return element.body;
144  }
145
146  // Firefox want us to check `-x` and `-y` variations as well
147
148  var _getStyleComputedProp = getStyleComputedProperty(element),
149      overflow = _getStyleComputedProp.overflow,
150      overflowX = _getStyleComputedProp.overflowX,
151      overflowY = _getStyleComputedProp.overflowY;
152
153  if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
154    return element;
155  }
156
157  return getScrollParent(getParentNode(element));
158}
vendor: 5,677 bytes, lines 158-343
158
159
160var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
161var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
162
163/**
164 * Determines if the browser is Internet Explorer
165 * @method
166 * @memberof Popper.Utils
167 * @param {Number} version to check
168 * @returns {Boolean} isIE
169 */
170function isIE(version) {
171  if (version === 11) {
172    return isIE11;
173  }
174  if (version === 10) {
175    return isIE10;
176  }
177  return isIE11 || isIE10;
178}
179
180/**
181 * Returns the offset parent of the given element
182 * @method
183 * @memberof Popper.Utils
184 * @argument {Element} element
185 * @returns {Element} offset parent
186 */
187function getOffsetParent(element) {
188  if (!element) {
189    return document.documentElement;
190  }
191
192  var noOffsetParent = isIE(10) ? document.body : null;
193
194  // NOTE: 1 DOM access here
195  var offsetParent = element.offsetParent || null;
196  // Skip hidden elements which don't have an offsetParent
197  while (offsetParent === noOffsetParent && element.nextElementSibling) {
198    offsetParent = (element = element.nextElementSibling).offsetParent;
199  }
200
201  var nodeName = offsetParent && offsetParent.nodeName;
202
203  if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
204    return element ? element.ownerDocument.documentElement : document.documentElement;
205  }
206
207  // .offsetParent will return the closest TH, TD or TABLE in case
208  // no offsetParent is present, I hate this job...
209  if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
210    return getOffsetParent(offsetParent);
211  }
212
213  return offsetParent;
214}
215
216function isOffsetContainer(element) {
217  var nodeName = element.nodeName;
218
219  if (nodeName === 'BODY') {
220    return false;
221  }
222  return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
223}
224
225/**
226 * Finds the root node (document, shadowDOM root) of the given element
227 * @method
228 * @memberof Popper.Utils
229 * @argument {Element} node
230 * @returns {Element} root node
231 */
232function getRoot(node) {
233  if (node.parentNode !== null) {
234    return getRoot(node.parentNode);
235  }
236
237  return node;
238}
239
240/**
241 * Finds the offset parent common to the two provided nodes
242 * @method
243 * @memberof Popper.Utils
244 * @argument {Element} element1
245 * @argument {Element} element2
246 * @returns {Element} common offset parent
247 */
248function findCommonOffsetParent(element1, element2) {
249  // This check is needed to avoid errors in case one of the elements isn't defined for any reason
250  if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
251    return document.documentElement;
252  }
253
254  // Here we make sure to give as "start" the element that comes first in the DOM
255  var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
256  var start = order ? element1 : element2;
257  var end = order ? element2 : element1;
258
259  // Get common ancestor container
260  var range = document.createRange();
261  range.setStart(start, 0);
262  range.setEnd(end, 0);
263  var commonAncestorContainer = range.commonAncestorContainer;
264
265  // Both nodes are inside #document
266
267  if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
268    if (isOffsetContainer(commonAncestorContainer)) {
269      return commonAncestorContainer;
270    }
271
272    return getOffsetParent(commonAncestorContainer);
273  }
274
275  // one of the nodes is inside shadowDOM, find which one
276  var element1root = getRoot(element1);
277  if (element1root.host) {
278    return findCommonOffsetParent(element1root.host, element2);
279  } else {
280    return findCommonOffsetParent(element1, getRoot(element2).host);
281  }
282}
283
284/**
285 * Gets the scroll value of the given element in the given side (top and left)
286 * @method
287 * @memberof Popper.Utils
288 * @argument {Element} element
289 * @argument {String} side `top` or `left`
290 * @returns {number} amount of scrolled pixels
291 */
292function getScroll(element) {
293  var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
294
295  var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
296  var nodeName = element.nodeName;
297
298  if (nodeName === 'BODY' || nodeName === 'HTML') {
299    var html = element.ownerDocument.documentElement;
300    var scrollingElement = element.ownerDocument.scrollingElement || html;
301    return scrollingElement[upperSide];
302  }
303
304  return element[upperSide];
305}
306
307/*
308 * Sum or subtract the element scroll values (left and top) from a given rect object
309 * @method
310 * @memberof Popper.Utils
311 * @param {Object} rect - Rect object you want to change
312 * @param {HTMLElement} element - The element from the function reads the scroll values
313 * @param {Boolean} subtract - set to true if you want to subtract the scroll values
314 * @return {Object} rect - The modifier rect object
315 */
316function includeScroll(rect, element) {
317  var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
318
319  var scrollTop = getScroll(element, 'top');
320  var scrollLeft = getScroll(element, 'left');
321  var modifier = subtract ? -1 : 1;
322  rect.top += scrollTop * modifier;
323  rect.bottom += scrollTop * modifier;
324  rect.left += scrollLeft * modifier;
325  rect.right += scrollLeft * modifier;
326  return rect;
327}
328
329/*
330 * Helper to detect borders of a given element
331 * @method
332 * @memberof Popper.Utils
333 * @param {CSSStyleDeclaration} styles
334 * Result of `getStyleComputedProperty` on the given element
335 * @param {String} axis - `x` or `y`
336 * @return {number} borders - The borders size of the given axis
337 */
338
339function getBordersSize(styles, axis) {
340  var sideA = axis === 'x' ? 'Left' : 'Top';
341  var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
342
343  return parseFloat(styles['border' + sideA + 'Width']
vendor: 2,732 bytes, lines 343-442
343, 10) + parseFloat(styles['border' + sideB + 'Width'], 10);
344}
345
346function getSize(axis, body, html, computedStyle) {
347  return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
348}
349
350function getWindowSizes(document) {
351  var body = document.body;
352  var html = document.documentElement;
353  var computedStyle = isIE(10) && getComputedStyle(html);
354
355  return {
356    height: getSize('Height', body, html, computedStyle),
357    width: getSize('Width', body, html, computedStyle)
358  };
359}
360
361var classCallCheck = function (instance, Constructor) {
362  if (!(instance instanceof Constructor)) {
363    throw new TypeError("Cannot call a class as a function");
364  }
365};
366
367var createClass = function () {
368  function defineProperties(target, props) {
369    for (var i = 0; i < props.length; i++) {
370      var descriptor = props[i];
371      descriptor.enumerable = descriptor.enumerable || false;
372      descriptor.configurable = true;
373      if ("value" in descriptor) descriptor.writable = true;
374      Object.defineProperty(target, descriptor.key, descriptor);
375    }
376  }
377
378  return function (Constructor, protoProps, staticProps) {
379    if (protoProps) defineProperties(Constructor.prototype, protoProps);
380    if (staticProps) defineProperties(Constructor, staticProps);
381    return Constructor;
382  };
383}();
384
385
386
387
388
389var defineProperty = function (obj, key, value) {
390  if (key in obj) {
391    Object.defineProperty(obj, key, {
392      value: value,
393      enumerable: true,
394      configurable: true,
395      writable: true
396    });
397  } else {
398    obj[key] = value;
399  }
400
401  return obj;
402};
403
404var _extends = Object.assign || function (target) {
405  for (var i = 1; i < arguments.length; i++) {
406    var source = arguments[i];
407
408    for (var key in source) {
409      if (Object.prototype.hasOwnProperty.call(source, key)) {
410        target[key] = source[key];
411      }
412    }
413  }
414
415  return target;
416};
417
418/**
419 * Given element offsets, generate an output similar to getBoundingClientRect
420 * @method
421 * @memberof Popper.Utils
422 * @argument {Object} offsets
423 * @returns {Object} ClientRect like output
424 */
425function getClientRect(offsets) {
426  return _extends({}, offsets, {
427    right: offsets.left + offsets.width,
428    bottom: offsets.top + offsets.height
429  });
430}
431
432/**
433 * Get bounding client rect of given element
434 * @method
435 * @memberof Popper.Utils
436 * @param {HTMLElement} element
437 * @return {Object} client rect
438 */
439function getBoundingClientRect(element) {
440  var rect = {};
441
442  // IE10 10 FIX: Please, don't ask, the element isn't
vendor: 4,668 bytes, lines 443-572
443  // considered in DOM in some circumstances...
444  // This isn't reproducible in IE10 compatibility mode of IE11
445  try {
446    if (isIE(10)) {
447      rect = element.getBoundingClientRect();
448      var scrollTop = getScroll(element, 'top');
449      var scrollLeft = getScroll(element, 'left');
450      rect.top += scrollTop;
451      rect.left += scrollLeft;
452      rect.bottom += scrollTop;
453      rect.right += scrollLeft;
454    } else {
455      rect = element.getBoundingClientRect();
456    }
457  } catch (e) {}
458
459  var result = {
460    left: rect.left,
461    top: rect.top,
462    width: rect.right - rect.left,
463    height: rect.bottom - rect.top
464  };
465
466  // subtract scrollbar size from sizes
467  var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
468  var width = sizes.width || element.clientWidth || result.right - result.left;
469  var height = sizes.height || element.clientHeight || result.bottom - result.top;
470
471  var horizScrollbar = element.offsetWidth - width;
472  var vertScrollbar = element.offsetHeight - height;
473
474  // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
475  // we make this check conditional for performance reasons
476  if (horizScrollbar || vertScrollbar) {
477    var styles = getStyleComputedProperty(element);
478    horizScrollbar -= getBordersSize(styles, 'x');
479    vertScrollbar -= getBordersSize(styles, 'y');
480
481    result.width -= horizScrollbar;
482    result.height -= vertScrollbar;
483  }
484
485  return getClientRect(result);
486}
487
488function getOffsetRectRelativeToArbitraryNode(children, parent) {
489  var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
490
491  var isIE10 = isIE(10);
492  var isHTML = parent.nodeName === 'HTML';
493  var childrenRect = getBoundingClientRect(children);
494  var parentRect = getBoundingClientRect(parent);
495  var scrollParent = getScrollParent(children);
496
497  var styles = getStyleComputedProperty(parent);
498  var borderTopWidth = parseFloat(styles.borderTopWidth, 10);
499  var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10);
500
501  // In cases where the parent is fixed, we must ignore negative scroll in offset calc
502  if (fixedPosition && isHTML) {
503    parentRect.top = Math.max(parentRect.top, 0);
504    parentRect.left = Math.max(parentRect.left, 0);
505  }
506  var offsets = getClientRect({
507    top: childrenRect.top - parentRect.top - borderTopWidth,
508    left: childrenRect.left - parentRect.left - borderLeftWidth,
509    width: childrenRect.width,
510    height: childrenRect.height
511  });
512  offsets.marginTop = 0;
513  offsets.marginLeft = 0;
514
515  // Subtract margins of documentElement in case it's being used as parent
516  // we do this only on HTML because it's the only element that behaves
517  // differently when margins are applied to it. The margins are included in
518  // the box of the documentElement, in the other cases not.
519  if (!isIE10 && isHTML) {
520    var marginTop = parseFloat(styles.marginTop, 10);
521    var marginLeft = parseFloat(styles.marginLeft, 10);
522
523    offsets.top -= borderTopWidth - marginTop;
524    offsets.bottom -= borderTopWidth - marginTop;
525    offsets.left -= borderLeftWidth - marginLeft;
526    offsets.right -= borderLeftWidth - marginLeft;
527
528    // Attach marginTop and marginLeft because in some circumstances we may need them
529    offsets.marginTop = marginTop;
530    offsets.marginLeft = marginLeft;
531  }
532
533  if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
534    offsets = includeScroll(offsets, parent);
535  }
536
537  return offsets;
538}
539
540function getViewportOffsetRectRelativeToArtbitraryNode(element) {
541  var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
542
543  var html = element.ownerDocument.documentElement;
544  var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
545  var width = Math.max(html.clientWidth, window.innerWidth || 0);
546  var height = Math.max(html.clientHeight, window.innerHeight || 0);
547
548  var scrollTop = !excludeScroll ? getScroll(html) : 0;
549  var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
550
551  var offset = {
552    top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
553    left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
554    width: width,
555    height: height
556  };
557
558  return getClientRect(offset);
559}
560
561/**
562 * Check if the given element is fixed or is inside a fixed parent
563 * @method
564 * @memberof Popper.Utils
565 * @argument {Element} element
566 * @argument {Element} customContainer
567 * @returns {Boolean} answer to "isFixed?"
568 */
569function isFixed(element) {
570  var nodeName = element.nodeName;
571  if (nodeName === 'BODY' || nodeName === 'HTML') {
572    return false;
vendor: 9,912 bytes, lines 573-880
573  }
574  if (getStyleComputedProperty(element, 'position') === 'fixed') {
575    return true;
576  }
577  var parentNode = getParentNode(element);
578  if (!parentNode) {
579    return false;
580  }
581  return isFixed(parentNode);
582}
583
584/**
585 * Finds the first parent of an element that has a transformed property defined
586 * @method
587 * @memberof Popper.Utils
588 * @argument {Element} element
589 * @returns {Element} first transformed parent or documentElement
590 */
591
592function getFixedPositionOffsetParent(element) {
593  // This check is needed to avoid errors in case one of the elements isn't defined for any reason
594  if (!element || !element.parentElement || isIE()) {
595    return document.documentElement;
596  }
597  var el = element.parentElement;
598  while (el && getStyleComputedProperty(el, 'transform') === 'none') {
599    el = el.parentElement;
600  }
601  return el || document.documentElement;
602}
603
604/**
605 * Computed the boundaries limits and return them
606 * @method
607 * @memberof Popper.Utils
608 * @param {HTMLElement} popper
609 * @param {HTMLElement} reference
610 * @param {number} padding
611 * @param {HTMLElement} boundariesElement - Element used to define the boundaries
612 * @param {Boolean} fixedPosition - Is in fixed position mode
613 * @returns {Object} Coordinates of the boundaries
614 */
615function getBoundaries(popper, reference, padding, boundariesElement) {
616  var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
617
618  // NOTE: 1 DOM access here
619
620  var boundaries = { top: 0, left: 0 };
621  var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference);
622
623  // Handle viewport case
624  if (boundariesElement === 'viewport') {
625    boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
626  } else {
627    // Handle other cases based on DOM element used as boundaries
628    var boundariesNode = void 0;
629    if (boundariesElement === 'scrollParent') {
630      boundariesNode = getScrollParent(getParentNode(reference));
631      if (boundariesNode.nodeName === 'BODY') {
632        boundariesNode = popper.ownerDocument.documentElement;
633      }
634    } else if (boundariesElement === 'window') {
635      boundariesNode = popper.ownerDocument.documentElement;
636    } else {
637      boundariesNode = boundariesElement;
638    }
639
640    var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
641
642    // In case of HTML, we need a different computation
643    if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
644      var _getWindowSizes = getWindowSizes(popper.ownerDocument),
645          height = _getWindowSizes.height,
646          width = _getWindowSizes.width;
647
648      boundaries.top += offsets.top - offsets.marginTop;
649      boundaries.bottom = height + offsets.top;
650      boundaries.left += offsets.left - offsets.marginLeft;
651      boundaries.right = width + offsets.left;
652    } else {
653      // for all the other DOM elements, this one is good
654      boundaries = offsets;
655    }
656  }
657
658  // Add paddings
659  padding = padding || 0;
660  var isPaddingNumber = typeof padding === 'number';
661  boundaries.left += isPaddingNumber ? padding : padding.left || 0;
662  boundaries.top += isPaddingNumber ? padding : padding.top || 0;
663  boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
664  boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
665
666  return boundaries;
667}
668
669function getArea(_ref) {
670  var width = _ref.width,
671      height = _ref.height;
672
673  return width * height;
674}
675
676/**
677 * Utility used to transform the `auto` placement to the placement with more
678 * available space.
679 * @method
680 * @memberof Popper.Utils
681 * @argument {Object} data - The data object generated by update method
682 * @argument {Object} options - Modifiers configuration and options
683 * @returns {Object} The data object, properly modified
684 */
685function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
686  var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
687
688  if (placement.indexOf('auto') === -1) {
689    return placement;
690  }
691
692  var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
693
694  var rects = {
695    top: {
696      width: boundaries.width,
697      height: refRect.top - boundaries.top
698    },
699    right: {
700      width: boundaries.right - refRect.right,
701      height: boundaries.height
702    },
703    bottom: {
704      width: boundaries.width,
705      height: boundaries.bottom - refRect.bottom
706    },
707    left: {
708      width: refRect.left - boundaries.left,
709      height: boundaries.height
710    }
711  };
712
713  var sortedAreas = Object.keys(rects).map(function (key) {
714    return _extends({
715      key: key
716    }, rects[key], {
717      area: getArea(rects[key])
718    });
719  }).sort(function (a, b) {
720    return b.area - a.area;
721  });
722
723  var filteredAreas = sortedAreas.filter(function (_ref2) {
724    var width = _ref2.width,
725        height = _ref2.height;
726    return width >= popper.clientWidth && height >= popper.clientHeight;
727  });
728
729  var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
730
731  var variation = placement.split('-')[1];
732
733  return computedPlacement + (variation ? '-' + variation : '');
734}
735
736/**
737 * Get offsets to the reference element
738 * @method
739 * @memberof Popper.Utils
740 * @param {Object} state
741 * @param {Element} popper - the popper element
742 * @param {Element} reference - the reference element (the popper will be relative to this)
743 * @param {Element} fixedPosition - is in fixed position mode
744 * @returns {Object} An object containing the offsets which will be applied to the popper
745 */
746function getReferenceOffsets(state, popper, reference) {
747  var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
748
749  var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference);
750  return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
751}
752
753/**
754 * Get the outer sizes of the given element (offset size + margins)
755 * @method
756 * @memberof Popper.Utils
757 * @argument {Element} element
758 * @returns {Object} object containing width and height properties
759 */
760function getOuterSizes(element) {
761  var window = element.ownerDocument.defaultView;
762  var styles = window.getComputedStyle(element);
763  var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
764  var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
765  var result = {
766    width: element.offsetWidth + y,
767    height: element.offsetHeight + x
768  };
769  return result;
770}
771
772/**
773 * Get the opposite placement of the given one
774 * @method
775 * @memberof Popper.Utils
776 * @argument {String} placement
777 * @returns {String} flipped placement
778 */
779function getOppositePlacement(placement) {
780  var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
781  return placement.replace(/left|right|bottom|top/g, function (matched) {
782    return hash[matched];
783  });
784}
785
786/**
787 * Get offsets to the popper
788 * @method
789 * @memberof Popper.Utils
790 * @param {Object} position - CSS position the Popper will get applied
791 * @param {HTMLElement} popper - the popper element
792 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
793 * @param {String} placement - one of the valid placement options
794 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
795 */
796function getPopperOffsets(popper, referenceOffsets, placement) {
797  placement = placement.split('-')[0];
798
799  // Get popper node sizes
800  var popperRect = getOuterSizes(popper);
801
802  // Add position, width and height to our offsets object
803  var popperOffsets = {
804    width: popperRect.width,
805    height: popperRect.height
806  };
807
808  // depending by the popper placement we have to compute its offsets slightly differently
809  var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
810  var mainSide = isHoriz ? 'top' : 'left';
811  var secondarySide = isHoriz ? 'left' : 'top';
812  var measurement = isHoriz ? 'height' : 'width';
813  var secondaryMeasurement = !isHoriz ? 'height' : 'width';
814
815  popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
816  if (placement === secondarySide) {
817    popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
818  } else {
819    popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
820  }
821
822  return popperOffsets;
823}
824
825/**
826 * Mimics the `find` method of Array
827 * @method
828 * @memberof Popper.Utils
829 * @argument {Array} arr
830 * @argument prop
831 * @argument value
832 * @returns index or -1
833 */
834function find(arr, check) {
835  // use native find if supported
836  if (Array.prototype.find) {
837    return arr.find(check);
838  }
839
840  // use `filter` to obtain the same behavior of `find`
841  return arr.filter(check)[0];
842}
843
844/**
845 * Return the index of the matching object
846 * @method
847 * @memberof Popper.Utils
848 * @argument {Array} arr
849 * @argument prop
850 * @argument value
851 * @returns index or -1
852 */
853function findIndex(arr, prop, value) {
854  // use native findIndex if supported
855  if (Array.prototype.findIndex) {
856    return arr.findIndex(function (cur) {
857      return cur[prop] === value;
858    });
859  }
860
861  // use `find` + `indexOf` if `findIndex` isn't supported
862  var match = find(arr, function (obj) {
863    return obj[prop] === value;
864  });
865  return arr.indexOf(match);
866}
867
868/**
869 * Loop trough the list of modifiers and run them in order,
870 * each of them will then edit the data object.
871 * @method
872 * @memberof Popper.Utils
873 * @param {dataObject} data
874 * @param {Array} modifiers
875 * @param {String} ends - Optional modifier name used as stopper
876 * @returns {dataObject}
877 */
878function runModifiers(modifiers, data, ends) {
879  var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
880
vendor: 4,062 bytes, lines 881-1011
881  modifiersToRun.forEach(function (modifier) {
882    if (modifier['function']) {
883      // eslint-disable-line dot-notation
884      console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
885    }
886    var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
887    if (modifier.enabled && isFunction(fn)) {
888      // Add properties to offsets to make them a complete clientRect object
889      // we do this before each modifier to make sure the previous one doesn't
890      // mess with these values
891      data.offsets.popper = getClientRect(data.offsets.popper);
892      data.offsets.reference = getClientRect(data.offsets.reference);
893
894      data = fn(data, modifier);
895    }
896  });
897
898  return data;
899}
900
901/**
902 * Updates the position of the popper, computing the new offsets and applying
903 * the new style.<br />
904 * Prefer `scheduleUpdate` over `update` because of performance reasons.
905 * @method
906 * @memberof Popper
907 */
908function update() {
909  // if popper is destroyed, don't perform any further update
910  if (this.state.isDestroyed) {
911    return;
912  }
913
914  var data = {
915    instance: this,
916    styles: {},
917    arrowStyles: {},
918    attributes: {},
919    flipped: false,
920    offsets: {}
921  };
922
923  // compute reference element offsets
924  data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
925
926  // compute auto placement, store placement inside the data object,
927  // modifiers will be able to edit `placement` if needed
928  // and refer to originalPlacement to know the original value
929  data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
930
931  // store the computed placement inside `originalPlacement`
932  data.originalPlacement = data.placement;
933
934  data.positionFixed = this.options.positionFixed;
935
936  // compute the popper offsets
937  data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
938
939  data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
940
941  // run the modifiers
942  data = runModifiers(this.modifiers, data);
943
944  // the first `update` will call `onCreate` callback
945  // the other ones will call `onUpdate` callback
946  if (!this.state.isCreated) {
947    this.state.isCreated = true;
948    this.options.onCreate(data);
949  } else {
950    this.options.onUpdate(data);
951  }
952}
953
954/**
955 * Helper used to know if the given modifier is enabled.
956 * @method
957 * @memberof Popper.Utils
958 * @returns {Boolean}
959 */
960function isModifierEnabled(modifiers, modifierName) {
961  return modifiers.some(function (_ref) {
962    var name = _ref.name,
963        enabled = _ref.enabled;
964    return enabled && name === modifierName;
965  });
966}
967
968/**
969 * Get the prefixed supported property name
970 * @method
971 * @memberof Popper.Utils
972 * @argument {String} property (camelCase)
973 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
974 */
975function getSupportedPropertyName(property) {
976  var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
977  var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
978
979  for (var i = 0; i < prefixes.length; i++) {
980    var prefix = prefixes[i];
981    var toCheck = prefix ? '' + prefix + upperProp : property;
982    if (typeof document.body.style[toCheck] !== 'undefined') {
983      return toCheck;
984    }
985  }
986  return null;
987}
988
989/**
990 * Destroys the popper.
991 * @method
992 * @memberof Popper
993 */
994function destroy() {
995  this.state.isDestroyed = true;
996
997  // touch DOM only if `applyStyle` modifier is enabled
998  if (isModifierEnabled(this.modifiers, 'applyStyle')) {
999    this.popper.removeAttribute('x-placement');
1000    this.popper.style.position = '';
1001    this.popper.style.top = '';
1002    this.popper.style.left = '';
1003    this.popper.style.right = '';
1004    this.popper.style.bottom = '';
1005    this.popper.style.willChange = '';
1006    this.popper.style[getSupportedPropertyName('transform')] = '';
1007  }
1008
1009  this.disableEventListeners();
1010
1011  // remove the popper if user explicit
vendor: 15,762 bytes, lines 1011-1460
1011y asked for the deletion on destroy
1012  // do not use `remove` because IE11 doesn't support it
1013  if (this.options.removeOnDestroy) {
1014    this.popper.parentNode.removeChild(this.popper);
1015  }
1016  return this;
1017}
1018
1019/**
1020 * Get the window associated with the element
1021 * @argument {Element} element
1022 * @returns {Window}
1023 */
1024function getWindow(element) {
1025  var ownerDocument = element.ownerDocument;
1026  return ownerDocument ? ownerDocument.defaultView : window;
1027}
1028
1029function attachToScrollParents(scrollParent, event, callback, scrollParents) {
1030  var isBody = scrollParent.nodeName === 'BODY';
1031  var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
1032  target.addEventListener(event, callback, { passive: true });
1033
1034  if (!isBody) {
1035    attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
1036  }
1037  scrollParents.push(target);
1038}
1039
1040/**
1041 * Setup needed event listeners used to update the popper position
1042 * @method
1043 * @memberof Popper.Utils
1044 * @private
1045 */
1046function setupEventListeners(reference, options, state, updateBound) {
1047  // Resize event listener on window
1048  state.updateBound = updateBound;
1049  getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
1050
1051  // Scroll event listener on scroll parents
1052  var scrollElement = getScrollParent(reference);
1053  attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
1054  state.scrollElement = scrollElement;
1055  state.eventsEnabled = true;
1056
1057  return state;
1058}
1059
1060/**
1061 * It will add resize/scroll events and start recalculating
1062 * position of the popper element when they are triggered.
1063 * @method
1064 * @memberof Popper
1065 */
1066function enableEventListeners() {
1067  if (!this.state.eventsEnabled) {
1068    this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
1069  }
1070}
1071
1072/**
1073 * Remove event listeners used to update the popper position
1074 * @method
1075 * @memberof Popper.Utils
1076 * @private
1077 */
1078function removeEventListeners(reference, state) {
1079  // Remove resize event listener on window
1080  getWindow(reference).removeEventListener('resize', state.updateBound);
1081
1082  // Remove scroll event listener on scroll parents
1083  state.scrollParents.forEach(function (target) {
1084    target.removeEventListener('scroll', state.updateBound);
1085  });
1086
1087  // Reset state
1088  state.updateBound = null;
1089  state.scrollParents = [];
1090  state.scrollElement = null;
1091  state.eventsEnabled = false;
1092  return state;
1093}
1094
1095/**
1096 * It will remove resize/scroll events and won't recalculate popper position
1097 * when they are triggered. It also won't trigger `onUpdate` callback anymore,
1098 * unless you call `update` method manually.
1099 * @method
1100 * @memberof Popper
1101 */
1102function disableEventListeners() {
1103  if (this.state.eventsEnabled) {
1104    cancelAnimationFrame(this.scheduleUpdate);
1105    this.state = removeEventListeners(this.reference, this.state);
1106  }
1107}
1108
1109/**
1110 * Tells if a given input is a number
1111 * @method
1112 * @memberof Popper.Utils
1113 * @param {*} input to check
1114 * @return {Boolean}
1115 */
1116function isNumeric(n) {
1117  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
1118}
1119
1120/**
1121 * Set the style to the given popper
1122 * @method
1123 * @memberof Popper.Utils
1124 * @argument {Element} element - Element to apply the style to
1125 * @argument {Object} styles
1126 * Object with a list of properties and values which will be applied to the element
1127 */
1128function setStyles(element, styles) {
1129  Object.keys(styles).forEach(function (prop) {
1130    var unit = '';
1131    // add unit if the value is numeric and is one of the following
1132    if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
1133      unit = 'px';
1134    }
1135    element.style[prop] = styles[prop] + unit;
1136  });
1137}
1138
1139/**
1140 * Set the attributes to the given popper
1141 * @method
1142 * @memberof Popper.Utils
1143 * @argument {Element} element - Element to apply the attributes to
1144 * @argument {Object} styles
1145 * Object with a list of properties and values which will be applied to the element
1146 */
1147function setAttributes(element, attributes) {
1148  Object.keys(attributes).forEach(function (prop) {
1149    var value = attributes[prop];
1150    if (value !== false) {
1151      element.setAttribute(prop, attributes[prop]);
1152    } else {
1153      element.removeAttribute(prop);
1154    }
1155  });
1156}
1157
1158/**
1159 * @function
1160 * @memberof Modifiers
1161 * @argument {Object} data - The data object generated by `update` method
1162 * @argument {Object} data.styles - List of style properties - values to apply to popper element
1163 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
1164 * @argument {Object} options - Modifiers configuration and options
1165 * @returns {Object} The same data object
1166 */
1167function applyStyle(data) {
1168  // any property present in `data.styles` will be applied to the popper,
1169  // in this way we can make the 3rd party modifiers add custom styles to it
1170  // Be aware, modifiers could override the properties defined in the previous
1171  // lines of this modifier!
1172  setStyles(data.instance.popper, data.styles);
1173
1174  // any property present in `data.attributes` will be applied to the popper,
1175  // they will be set as HTML attributes of the element
1176  setAttributes(data.instance.popper, data.attributes);
1177
1178  // if arrowElement is defined and arrowStyles has some properties
1179  if (data.arrowElement && Object.keys(data.arrowStyles).length) {
1180    setStyles(data.arrowElement, data.arrowStyles);
1181  }
1182
1183  return data;
1184}
1185
1186/**
1187 * Set the x-placement attribute before everything else because it could be used
1188 * to add margins to the popper margins needs to be calculated to get the
1189 * correct popper offsets.
1190 * @method
1191 * @memberof Popper.modifiers
1192 * @param {HTMLElement} reference - The reference element used to position the popper
1193 * @param {HTMLElement} popper - The HTML element used as popper
1194 * @param {Object} options - Popper.js options
1195 */
1196function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
1197  // compute reference element offsets
1198  var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
1199
1200  // compute auto placement, store placement inside the data object,
1201  // modifiers will be able to edit `placement` if needed
1202  // and refer to originalPlacement to know the original value
1203  var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
1204
1205  popper.setAttribute('x-placement', placement);
1206
1207  // Apply `position` to popper before anything else because
1208  // without the position applied we can't guarantee correct computations
1209  setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
1210
1211  return options;
1212}
1213
1214/**
1215 * @function
1216 * @memberof Popper.Utils
1217 * @argument {Object} data - The data object generated by `update` method
1218 * @argument {Boolean} shouldRound - If the offsets should be rounded at all
1219 * @returns {Object} The popper's position offsets rounded
1220 *
1221 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
1222 * good as it can be within reason.
1223 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
1224 *
1225 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
1226 * as well on High DPI screens).
1227 *
1228 * Firefox prefers no rounding for positioning and does not have blurriness on
1229 * high DPI screens.
1230 *
1231 * Only horizontal placement and left/right values need to be considered.
1232 */
1233function getRoundedOffsets(data, shouldRound) {
1234  var _data$offsets = data.offsets,
1235      popper = _data$offsets.popper,
1236      reference = _data$offsets.reference;
1237  var round = Math.round,
1238      floor = Math.floor;
1239
1240  var noRound = function noRound(v) {
1241    return v;
1242  };
1243
1244  var referenceWidth = round(reference.width);
1245  var popperWidth = round(popper.width);
1246
1247  var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
1248  var isVariation = data.placement.indexOf('-') !== -1;
1249  var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
1250  var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
1251
1252  var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
1253  var verticalToInteger = !shouldRound ? noRound : round;
1254
1255  return {
1256    left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
1257    top: verticalToInteger(popper.top),
1258    bottom: verticalToInteger(popper.bottom),
1259    right: horizontalToInteger(popper.right)
1260  };
1261}
1262
1263var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
1264
1265/**
1266 * @function
1267 * @memberof Modifiers
1268 * @argument {Object} data - The data object generated by `update` method
1269 * @argument {Object} options - Modifiers configuration and options
1270 * @returns {Object} The data object, properly modified
1271 */
1272function computeStyle(data, options) {
1273  var x = options.x,
1274      y = options.y;
1275  var popper = data.offsets.popper;
1276
1277  // Remove this legacy support in Popper.js v2
1278
1279  var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
1280    return modifier.name === 'applyStyle';
1281  }).gpuAcceleration;
1282  if (legacyGpuAccelerationOption !== undefined) {
1283    console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
1284  }
1285  var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
1286
1287  var offsetParent = getOffsetParent(data.instance.popper);
1288  var offsetParentRect = getBoundingClientRect(offsetParent);
1289
1290  // Styles
1291  var styles = {
1292    position: popper.position
1293  };
1294
1295  var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
1296
1297  var sideA = x === 'bottom' ? 'top' : 'bottom';
1298  var sideB = y === 'right' ? 'left' : 'right';
1299
1300  // if gpuAcceleration is set to `true` and transform is supported,
1301  //  we use `translate3d` to apply the position to the popper we
1302  // automatically use the supported prefixed version if needed
1303  var prefixedProperty = getSupportedPropertyName('transform');
1304
1305  // now, let's make a step back and look at this code closely (wtf?)
1306  // If the content of the popper grows once it's been positioned, it
1307  // may happen that the popper gets misplaced because of the new content
1308  // overflowing its reference element
1309  // To avoid this problem, we provide two options (x and y), which allow
1310  // the consumer to define the offset origin.
1311  // If we position a popper on top of a reference element, we can set
1312  // `x` to `top` to make the popper grow towards its top instead of
1313  // its bottom.
1314  var left = void 0,
1315      top = void 0;
1316  if (sideA === 'bottom') {
1317    // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
1318    // and not the bottom of the html element
1319    if (offsetParent.nodeName === 'HTML') {
1320      top = -offsetParent.clientHeight + offsets.bottom;
1321    } else {
1322      top = -offsetParentRect.height + offsets.bottom;
1323    }
1324  } else {
1325    top = offsets.top;
1326  }
1327  if (sideB === 'right') {
1328    if (offsetParent.nodeName === 'HTML') {
1329      left = -offsetParent.clientWidth + offsets.right;
1330    } else {
1331      left = -offsetParentRect.width + offsets.right;
1332    }
1333  } else {
1334    left = offsets.left;
1335  }
1336  if (gpuAcceleration && prefixedProperty) {
1337    styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
1338    styles[sideA] = 0;
1339    styles[sideB] = 0;
1340    styles.willChange = 'transform';
1341  } else {
1342    // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
1343    var invertTop = sideA === 'bottom' ? -1 : 1;
1344    var invertLeft = sideB === 'right' ? -1 : 1;
1345    styles[sideA] = top * invertTop;
1346    styles[sideB] = left * invertLeft;
1347    styles.willChange = sideA + ', ' + sideB;
1348  }
1349
1350  // Attributes
1351  var attributes = {
1352    'x-placement': data.placement
1353  };
1354
1355  // Update `data` attributes, styles and arrowStyles
1356  data.attributes = _extends({}, attributes, data.attributes);
1357  data.styles = _extends({}, styles, data.styles);
1358  data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
1359
1360  return data;
1361}
1362
1363/**
1364 * Helper used to know if the given modifier depends from another one.<br />
1365 * It checks if the needed modifier is listed and enabled.
1366 * @method
1367 * @memberof Popper.Utils
1368 * @param {Array} modifiers - list of modifiers
1369 * @param {String} requestingName - name of requesting modifier
1370 * @param {String} requestedName - name of requested modifier
1371 * @returns {Boolean}
1372 */
1373function isModifierRequired(modifiers, requestingName, requestedName) {
1374  var requesting = find(modifiers, function (_ref) {
1375    var name = _ref.name;
1376    return name === requestingName;
1377  });
1378
1379  var isRequired = !!requesting && modifiers.some(function (modifier) {
1380    return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
1381  });
1382
1383  if (!isRequired) {
1384    var _requesting = '`' + requestingName + '`';
1385    var requested = '`' + requestedName + '`';
1386    console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
1387  }
1388  return isRequired;
1389}
1390
1391/**
1392 * @function
1393 * @memberof Modifiers
1394 * @argument {Object} data - The data object generated by update method
1395 * @argument {Object} options - Modifiers configuration and options
1396 * @returns {Object} The data object, properly modified
1397 */
1398function arrow(data, options) {
1399  var _data$offsets$arrow;
1400
1401  // arrow depends on keepTogether in order to work
1402  if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
1403    return data;
1404  }
1405
1406  var arrowElement = options.element;
1407
1408  // if arrowElement is a string, suppose it's a CSS selector
1409  if (typeof arrowElement === 'string') {
1410    arrowElement = data.instance.popper.querySelector(arrowElement);
1411
1412    // if arrowElement is not found, don't run the modifier
1413    if (!arrowElement) {
1414      return data;
1415    }
1416  } else {
1417    // if the arrowElement isn't a query selector we must check that the
1418    // provided DOM node is child of its popper node
1419    if (!data.instance.popper.contains(arrowElement)) {
1420      console.warn('WARNING: `arrow.element` must be child of its popper element!');
1421      return data;
1422    }
1423  }
1424
1425  var placement = data.placement.split('-')[0];
1426  var _data$offsets = data.offsets,
1427      popper = _data$offsets.popper,
1428      reference = _data$offsets.reference;
1429
1430  var isVertical = ['left', 'right'].indexOf(placement) !== -1;
1431
1432  var len = isVertical ? 'height' : 'width';
1433  var sideCapitalized = isVertical ? 'Top' : 'Left';
1434  var side = sideCapitalized.toLowerCase();
1435  var altSide = isVertical ? 'left' : 'top';
1436  var opSide = isVertical ? 'bottom' : 'right';
1437  var arrowElementSize = getOuterSizes(arrowElement)[len];
1438
1439  //
1440  // extends keepTogether behavior making sure the popper and its
1441  // reference have enough pixels in conjunction
1442  //
1443
1444  // top/left side
1445  if (reference[opSide] - arrowElementSize < popper[side]) {
1446    data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
1447  }
1448  // bottom/right side
1449  if (reference[side] + arrowElementSize > popper[opSide]) {
1450    data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
1451  }
1452  data.offsets.popper = getClientRect(data.offsets.popper);
1453
1454  // compute center of the popper
1455  var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
1456
1457  // Compute the sideValue using the updated popper offsets
1458  // take popper margin in account because we don't have this info available
1459  var css = getStyleComputedProperty(data.instance.popper);
1460  var popperMarginSide = parseFloat(css['margin' + sideCapitalized]
1460, 10);
1461  var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10
vendor: 21,597 bytes, lines 1461-2071
1461);
1462  var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
1463
1464  // prevent arrowElement from being placed not contiguously to its popper
1465  sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
1466
1467  data.arrowElement = arrowElement;
1468  data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
1469
1470  return data;
1471}
1472
1473/**
1474 * Get the opposite placement variation of the given one
1475 * @method
1476 * @memberof Popper.Utils
1477 * @argument {String} placement variation
1478 * @returns {String} flipped placement variation
1479 */
1480function getOppositeVariation(variation) {
1481  if (variation === 'end') {
1482    return 'start';
1483  } else if (variation === 'start') {
1484    return 'end';
1485  }
1486  return variation;
1487}
1488
1489/**
1490 * List of accepted placements to use as values of the `placement` option.<br />
1491 * Valid placements are:
1492 * - `auto`
1493 * - `top`
1494 * - `right`
1495 * - `bottom`
1496 * - `left`
1497 *
1498 * Each placement can have a variation from this list:
1499 * - `-start`
1500 * - `-end`
1501 *
1502 * Variations are interpreted easily if you think of them as the left to right
1503 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
1504 * is right.<br />
1505 * Vertically (`left` and `right`), `start` is top and `end` is bottom.
1506 *
1507 * Some valid examples are:
1508 * - `top-end` (on top of reference, right aligned)
1509 * - `right-start` (on right of reference, top aligned)
1510 * - `bottom` (on bottom, centered)
1511 * - `auto-end` (on the side with more space available, alignment depends by placement)
1512 *
1513 * @static
1514 * @type {Array}
1515 * @enum {String}
1516 * @readonly
1517 * @method placements
1518 * @memberof Popper
1519 */
1520var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
1521
1522// Get rid of `auto` `auto-start` and `auto-end`
1523var validPlacements = placements.slice(3);
1524
1525/**
1526 * Given an initial placement, returns all the subsequent placements
1527 * clockwise (or counter-clockwise).
1528 *
1529 * @method
1530 * @memberof Popper.Utils
1531 * @argument {String} placement - A valid placement (it accepts variations)
1532 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
1533 * @returns {Array} placements including their variations
1534 */
1535function clockwise(placement) {
1536  var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1537
1538  var index = validPlacements.indexOf(placement);
1539  var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
1540  return counter ? arr.reverse() : arr;
1541}
1542
1543var BEHAVIORS = {
1544  FLIP: 'flip',
1545  CLOCKWISE: 'clockwise',
1546  COUNTERCLOCKWISE: 'counterclockwise'
1547};
1548
1549/**
1550 * @function
1551 * @memberof Modifiers
1552 * @argument {Object} data - The data object generated by update method
1553 * @argument {Object} options - Modifiers configuration and options
1554 * @returns {Object} The data object, properly modified
1555 */
1556function flip(data, options) {
1557  // if `inner` modifier is enabled, we can't use the `flip` modifier
1558  if (isModifierEnabled(data.instance.modifiers, 'inner')) {
1559    return data;
1560  }
1561
1562  if (data.flipped && data.placement === data.originalPlacement) {
1563    // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
1564    return data;
1565  }
1566
1567  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
1568
1569  var placement = data.placement.split('-')[0];
1570  var placementOpposite = getOppositePlacement(placement);
1571  var variation = data.placement.split('-')[1] || '';
1572
1573  var flipOrder = [];
1574
1575  switch (options.behavior) {
1576    case BEHAVIORS.FLIP:
1577      flipOrder = [placement, placementOpposite];
1578      break;
1579    case BEHAVIORS.CLOCKWISE:
1580      flipOrder = clockwise(placement);
1581      break;
1582    case BEHAVIORS.COUNTERCLOCKWISE:
1583      flipOrder = clockwise(placement, true);
1584      break;
1585    default:
1586      flipOrder = options.behavior;
1587  }
1588
1589  flipOrder.forEach(function (step, index) {
1590    if (placement !== step || flipOrder.length === index + 1) {
1591      return data;
1592    }
1593
1594    placement = data.placement.split('-')[0];
1595    placementOpposite = getOppositePlacement(placement);
1596
1597    var popperOffsets = data.offsets.popper;
1598    var refOffsets = data.offsets.reference;
1599
1600    // using floor because the reference offsets may contain decimals we are not going to consider here
1601    var floor = Math.floor;
1602    var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
1603
1604    var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
1605    var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
1606    var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
1607    var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
1608
1609    var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
1610
1611    // flip the variation if required
1612    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
1613
1614    // flips variation if reference element overflows boundaries
1615    var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
1616
1617    // flips variation if popper content overflows boundaries
1618    var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
1619
1620    var flippedVariation = flippedVariationByRef || flippedVariationByContent;
1621
1622    if (overlapsRef || overflowsBoundaries || flippedVariation) {
1623      // this boolean to detect any flip loop
1624      data.flipped = true;
1625
1626      if (overlapsRef || overflowsBoundaries) {
1627        placement = flipOrder[index + 1];
1628      }
1629
1630      if (flippedVariation) {
1631        variation = getOppositeVariation(variation);
1632      }
1633
1634      data.placement = placement + (variation ? '-' + variation : '');
1635
1636      // this object contains `position`, we want to preserve it along with
1637      // any additional property we may add in the future
1638      data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
1639
1640      data = runModifiers(data.instance.modifiers, data, 'flip');
1641    }
1642  });
1643  return data;
1644}
1645
1646/**
1647 * @function
1648 * @memberof Modifiers
1649 * @argument {Object} data - The data object generated by update method
1650 * @argument {Object} options - Modifiers configuration and options
1651 * @returns {Object} The data object, properly modified
1652 */
1653function keepTogether(data) {
1654  var _data$offsets = data.offsets,
1655      popper = _data$offsets.popper,
1656      reference = _data$offsets.reference;
1657
1658  var placement = data.placement.split('-')[0];
1659  var floor = Math.floor;
1660  var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
1661  var side = isVertical ? 'right' : 'bottom';
1662  var opSide = isVertical ? 'left' : 'top';
1663  var measurement = isVertical ? 'width' : 'height';
1664
1665  if (popper[side] < floor(reference[opSide])) {
1666    data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
1667  }
1668  if (popper[opSide] > floor(reference[side])) {
1669    data.offsets.popper[opSide] = floor(reference[side]);
1670  }
1671
1672  return data;
1673}
1674
1675/**
1676 * Converts a string containing value + unit into a px value number
1677 * @function
1678 * @memberof {modifiers~offset}
1679 * @private
1680 * @argument {String} str - Value + unit string
1681 * @argument {String} measurement - `height` or `width`
1682 * @argument {Object} popperOffsets
1683 * @argument {Object} referenceOffsets
1684 * @returns {Number|String}
1685 * Value in pixels, or original string if no values were extracted
1686 */
1687function toValue(str, measurement, popperOffsets, referenceOffsets) {
1688  // separate value from unit
1689  var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
1690  var value = +split[1];
1691  var unit = split[2];
1692
1693  // If it's not a number it's an operator, I guess
1694  if (!value) {
1695    return str;
1696  }
1697
1698  if (unit.indexOf('%') === 0) {
1699    var element = void 0;
1700    switch (unit) {
1701      case '%p':
1702        element = popperOffsets;
1703        break;
1704      case '%':
1705      case '%r':
1706      default:
1707        element = referenceOffsets;
1708    }
1709
1710    var rect = getClientRect(element);
1711    return rect[measurement] / 100 * value;
1712  } else if (unit === 'vh' || unit === 'vw') {
1713    // if is a vh or vw, we calculate the size based on the viewport
1714    var size = void 0;
1715    if (unit === 'vh') {
1716      size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
1717    } else {
1718      size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
1719    }
1720    return size / 100 * value;
1721  } else {
1722    // if is an explicit pixel unit, we get rid of the unit and keep the value
1723    // if is an implicit unit, it's px, and we return just the value
1724    return value;
1725  }
1726}
1727
1728/**
1729 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
1730 * @function
1731 * @memberof {modifiers~offset}
1732 * @private
1733 * @argument {String} offset
1734 * @argument {Object} popperOffsets
1735 * @argument {Object} referenceOffsets
1736 * @argument {String} basePlacement
1737 * @returns {Array} a two cells array with x and y offsets in numbers
1738 */
1739function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
1740  var offsets = [0, 0];
1741
1742  // Use height if placement is left or right and index is 0 otherwise use width
1743  // in this way the first offset will use an axis and the second one
1744  // will use the other one
1745  var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
1746
1747  // Split the offset string to obtain a list of values and operands
1748  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
1749  var fragments = offset.split(/(\+|\-)/).map(function (frag) {
1750    return frag.trim();
1751  });
1752
1753  // Detect if the offset string contains a pair of values or a single one
1754  // they could be separated by comma or space
1755  var divider = fragments.indexOf(find(fragments, function (frag) {
1756    return frag.search(/,|\s/) !== -1;
1757  }));
1758
1759  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
1760    console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
1761  }
1762
1763  // If divider is found, we divide the list of values and operands to divide
1764  // them by ofset X and Y.
1765  var splitRegex = /\s*,\s*|\s+/;
1766  var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
1767
1768  // Convert the values with units to absolute pixels to allow our computations
1769  ops = ops.map(function (op, index) {
1770    // Most of the units rely on the orientation of the popper
1771    var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
1772    var mergeWithPrevious = false;
1773    return op
1774    // This aggregates any `+` or `-` sign that aren't considered operators
1775    // e.g.: 10 + +5 => [10, +, +5]
1776    .reduce(function (a, b) {
1777      if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
1778        a[a.length - 1] = b;
1779        mergeWithPrevious = true;
1780        return a;
1781      } else if (mergeWithPrevious) {
1782        a[a.length - 1] += b;
1783        mergeWithPrevious = false;
1784        return a;
1785      } else {
1786        return a.concat(b);
1787      }
1788    }, [])
1789    // Here we convert the string values into number values (in px)
1790    .map(function (str) {
1791      return toValue(str, measurement, popperOffsets, referenceOffsets);
1792    });
1793  });
1794
1795  // Loop trough the offsets arrays and execute the operations
1796  ops.forEach(function (op, index) {
1797    op.forEach(function (frag, index2) {
1798      if (isNumeric(frag)) {
1799        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
1800      }
1801    });
1802  });
1803  return offsets;
1804}
1805
1806/**
1807 * @function
1808 * @memberof Modifiers
1809 * @argument {Object} data - The data object generated by update method
1810 * @argument {Object} options - Modifiers configuration and options
1811 * @argument {Number|String} options.offset=0
1812 * The offset value as described in the modifier description
1813 * @returns {Object} The data object, properly modified
1814 */
1815function offset(data, _ref) {
1816  var offset = _ref.offset;
1817  var placement = data.placement,
1818      _data$offsets = data.offsets,
1819      popper = _data$offsets.popper,
1820      reference = _data$offsets.reference;
1821
1822  var basePlacement = placement.split('-')[0];
1823
1824  var offsets = void 0;
1825  if (isNumeric(+offset)) {
1826    offsets = [+offset, 0];
1827  } else {
1828    offsets = parseOffset(offset, popper, reference, basePlacement);
1829  }
1830
1831  if (basePlacement === 'left') {
1832    popper.top += offsets[0];
1833    popper.left -= offsets[1];
1834  } else if (basePlacement === 'right') {
1835    popper.top += offsets[0];
1836    popper.left += offsets[1];
1837  } else if (basePlacement === 'top') {
1838    popper.left += offsets[0];
1839    popper.top -= offsets[1];
1840  } else if (basePlacement === 'bottom') {
1841    popper.left += offsets[0];
1842    popper.top += offsets[1];
1843  }
1844
1845  data.popper = popper;
1846  return data;
1847}
1848
1849/**
1850 * @function
1851 * @memberof Modifiers
1852 * @argument {Object} data - The data object generated by `update` method
1853 * @argument {Object} options - Modifiers configuration and options
1854 * @returns {Object} The data object, properly modified
1855 */
1856function preventOverflow(data, options) {
1857  var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
1858
1859  // If offsetParent is the reference element, we really want to
1860  // go one step up and use the next offsetParent as reference to
1861  // avoid to make this modifier completely useless and look like broken
1862  if (data.instance.reference === boundariesElement) {
1863    boundariesElement = getOffsetParent(boundariesElement);
1864  }
1865
1866  // NOTE: DOM access here
1867  // resets the popper's position so that the document size can be calculated excluding
1868  // the size of the popper element itself
1869  var transformProp = getSupportedPropertyName('transform');
1870  var popperStyles = data.instance.popper.style; // assignment to help minification
1871  var top = popperStyles.top,
1872      left = popperStyles.left,
1873      transform = popperStyles[transformProp];
1874
1875  popperStyles.top = '';
1876  popperStyles.left = '';
1877  popperStyles[transformProp] = '';
1878
1879  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
1880
1881  // NOTE: DOM access here
1882  // restores the original style properties after the offsets have been computed
1883  popperStyles.top = top;
1884  popperStyles.left = left;
1885  popperStyles[transformProp] = transform;
1886
1887  options.boundaries = boundaries;
1888
1889  var order = options.priority;
1890  var popper = data.offsets.popper;
1891
1892  var check = {
1893    primary: function primary(placement) {
1894      var value = popper[placement];
1895      if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
1896        value = Math.max(popper[placement], boundaries[placement]);
1897      }
1898      return defineProperty({}, placement, value);
1899    },
1900    secondary: function secondary(placement) {
1901      var mainSide = placement === 'right' ? 'left' : 'top';
1902      var value = popper[mainSide];
1903      if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
1904        value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
1905      }
1906      return defineProperty({}, mainSide, value);
1907    }
1908  };
1909
1910  order.forEach(function (placement) {
1911    var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
1912    popper = _extends({}, popper, check[side](placement));
1913  });
1914
1915  data.offsets.popper = popper;
1916
1917  return data;
1918}
1919
1920/**
1921 * @function
1922 * @memberof Modifiers
1923 * @argument {Object} data - The data object generated by `update` method
1924 * @argument {Object} options - Modifiers configuration and options
1925 * @returns {Object} The data object, properly modified
1926 */
1927function shift(data) {
1928  var placement = data.placement;
1929  var basePlacement = placement.split('-')[0];
1930  var shiftvariation = placement.split('-')[1];
1931
1932  // if shift shiftvariation is specified, run the modifier
1933  if (shiftvariation) {
1934    var _data$offsets = data.offsets,
1935        reference = _data$offsets.reference,
1936        popper = _data$offsets.popper;
1937
1938    var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
1939    var side = isVertical ? 'left' : 'top';
1940    var measurement = isVertical ? 'width' : 'height';
1941
1942    var shiftOffsets = {
1943      start: defineProperty({}, side, reference[side]),
1944      end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
1945    };
1946
1947    data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
1948  }
1949
1950  return data;
1951}
1952
1953/**
1954 * @function
1955 * @memberof Modifiers
1956 * @argument {Object} data - The data object generated by update method
1957 * @argument {Object} options - Modifiers configuration and options
1958 * @returns {Object} The data object, properly modified
1959 */
1960function hide(data) {
1961  if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
1962    return data;
1963  }
1964
1965  var refRect = data.offsets.reference;
1966  var bound = find(data.instance.modifiers, function (modifier) {
1967    return modifier.name === 'preventOverflow';
1968  }).boundaries;
1969
1970  if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
1971    // Avoid unnecessary DOM access if visibility hasn't changed
1972    if (data.hide === true) {
1973      return data;
1974    }
1975
1976    data.hide = true;
1977    data.attributes['x-out-of-boundaries'] = '';
1978  } else {
1979    // Avoid unnecessary DOM access if visibility hasn't changed
1980    if (data.hide === false) {
1981      return data;
1982    }
1983
1984    data.hide = false;
1985    data.attributes['x-out-of-boundaries'] = false;
1986  }
1987
1988  return data;
1989}
1990
1991/**
1992 * @function
1993 * @memberof Modifiers
1994 * @argument {Object} data - The data object generated by `update` method
1995 * @argument {Object} options - Modifiers configuration and options
1996 * @returns {Object} The data object, properly modified
1997 */
1998function inner(data) {
1999  var placement = data.placement;
2000  var basePlacement = placement.split('-')[0];
2001  var _data$offsets = data.offsets,
2002      popper = _data$offsets.popper,
2003      reference = _data$offsets.reference;
2004
2005  var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
2006
2007  var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
2008
2009  popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
2010
2011  data.placement = getOppositePlacement(placement);
2012  data.offsets.popper = getClientRect(popper);
2013
2014  return data;
2015}
2016
2017/**
2018 * Modifier function, each modifier can have a function of this type assigned
2019 * to its `fn` property.<br />
2020 * These functions will be called on each update, this means that you must
2021 * make sure they are performant enough to avoid performance bottlenecks.
2022 *
2023 * @function ModifierFn
2024 * @argument {dataObject} data - The data object generated by `update` method
2025 * @argument {Object} options - Modifiers configuration and options
2026 * @returns {dataObject} The data object, properly modified
2027 */
2028
2029/**
2030 * Modifiers are plugins used to alter the behavior of your poppers.<br />
2031 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
2032 * needed by the library.
2033 *
2034 * Usually you don't want to override the `order`, `fn` and `onLoad` props.
2035 * All the other properties are configurations that could be tweaked.
2036 * @namespace modifiers
2037 */
2038var modifiers = {
2039  /**
2040   * Modifier used to shift the popper on the start or end of its reference
2041   * element.<br />
2042   * It will read the variation of the `placement` property.<br />
2043   * It can be one either `-end` or `-start`.
2044   * @memberof modifiers
2045   * @inner
2046   */
2047  shift: {
2048    /** @prop {number} order=100 - Index used to define the order of execution */
2049    order: 100,
2050    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2051    enabled: true,
2052    /** @prop {ModifierFn} */
2053    fn: shift
2054  },
2055
2056  /**
2057   * The `offset` modifier can shift your popper on both its axis.
2058   *
2059   * It accepts the following units:
2060   * - `px` or unit-less, interpreted as pixels
2061   * - `%` or `%r`, percentage relative to the length of the reference element
2062   * - `%p`, percentage relative to the length of the popper element
2063   * - `vw`, CSS viewport width unit
2064   * - `vh`, CSS viewport height unit
2065   *
2066   * For length is intended the main axis relative to the placement of the popper.<br />
2067   * This means that if the placement is `top` or `bottom`, the length will be the
2068   * `width`. In case of `left` or `right`, it will be the `height`.
2069   *
2070   * You can provide a single value (as `Number` or `String`), or a pair of values
2071   * as `String` divided by a comma or one (or more) white space
vendor: 9,957 bytes, lines 2071-2343
2071s.<br />
2072   * The latter is a deprecated method because it leads to confusion and will be
2073   * removed in v2.<br />
2074   * Additionally, it accepts additions and subtractions between different units.
2075   * Note that multiplications and divisions aren't supported.
2076   *
2077   * Valid examples are:
2078   * ```
2079   * 10
2080   * '10%'
2081   * '10, 10'
2082   * '10%, 10'
2083   * '10 + 10%'
2084   * '10 - 5vh + 3%'
2085   * '-10px + 5vh, 5px - 6%'
2086   * ```
2087   * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
2088   * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
2089   * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
2090   *
2091   * @memberof modifiers
2092   * @inner
2093   */
2094  offset: {
2095    /** @prop {number} order=200 - Index used to define the order of execution */
2096    order: 200,
2097    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2098    enabled: true,
2099    /** @prop {ModifierFn} */
2100    fn: offset,
2101    /** @prop {Number|String} offset=0
2102     * The offset value as described in the modifier description
2103     */
2104    offset: 0
2105  },
2106
2107  /**
2108   * Modifier used to prevent the popper from being positioned outside the boundary.
2109   *
2110   * A scenario exists where the reference itself is not within the boundaries.<br />
2111   * We can say it has "escaped the boundaries" — or just "escaped".<br />
2112   * In this case we need to decide whether the popper should either:
2113   *
2114   * - detach from the reference and remain "trapped" in the boundaries, or
2115   * - if it should ignore the boundary and "escape with its reference"
2116   *
2117   * When `escapeWithReference` is set to`true` and reference is completely
2118   * outside its boundaries, the popper will overflow (or completely leave)
2119   * the boundaries in order to remain attached to the edge of the reference.
2120   *
2121   * @memberof modifiers
2122   * @inner
2123   */
2124  preventOverflow: {
2125    /** @prop {number} order=300 - Index used to define the order of execution */
2126    order: 300,
2127    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2128    enabled: true,
2129    /** @prop {ModifierFn} */
2130    fn: preventOverflow,
2131    /**
2132     * @prop {Array} [priority=['left','right','top','bottom']]
2133     * Popper will try to prevent overflow following these priorities by default,
2134     * then, it could overflow on the left and on top of the `boundariesElement`
2135     */
2136    priority: ['left', 'right', 'top', 'bottom'],
2137    /**
2138     * @prop {number} padding=5
2139     * Amount of pixel used to define a minimum distance between the boundaries
2140     * and the popper. This makes sure the popper always has a little padding
2141     * between the edges of its container
2142     */
2143    padding: 5,
2144    /**
2145     * @prop {String|HTMLElement} boundariesElement='scrollParent'
2146     * Boundaries used by the modifier. Can be `scrollParent`, `window`,
2147     * `viewport` or any DOM element.
2148     */
2149    boundariesElement: 'scrollParent'
2150  },
2151
2152  /**
2153   * Modifier used to make sure the reference and its popper stay near each other
2154   * without leaving any gap between the two. Especially useful when the arrow is
2155   * enabled and you want to ensure that it points to its reference element.
2156   * It cares only about the first axis. You can still have poppers with margin
2157   * between the popper and its reference element.
2158   * @memberof modifiers
2159   * @inner
2160   */
2161  keepTogether: {
2162    /** @prop {number} order=400 - Index used to define the order of execution */
2163    order: 400,
2164    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2165    enabled: true,
2166    /** @prop {ModifierFn} */
2167    fn: keepTogether
2168  },
2169
2170  /**
2171   * This modifier is used to move the `arrowElement` of the popper to make
2172   * sure it is positioned between the reference element and its popper element.
2173   * It will read the outer size of the `arrowElement` node to detect how many
2174   * pixels of conjunction are needed.
2175   *
2176   * It has no effect if no `arrowElement` is provided.
2177   * @memberof modifiers
2178   * @inner
2179   */
2180  arrow: {
2181    /** @prop {number} order=500 - Index used to define the order of execution */
2182    order: 500,
2183    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2184    enabled: true,
2185    /** @prop {ModifierFn} */
2186    fn: arrow,
2187    /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
2188    element: '[x-arrow]'
2189  },
2190
2191  /**
2192   * Modifier used to flip the popper's placement when it starts to overlap its
2193   * reference element.
2194   *
2195   * Requires the `preventOverflow` modifier before it in order to work.
2196   *
2197   * **NOTE:** this modifier will interrupt the current update cycle and will
2198   * restart it if it detects the need to flip the placement.
2199   * @memberof modifiers
2200   * @inner
2201   */
2202  flip: {
2203    /** @prop {number} order=600 - Index used to define the order of execution */
2204    order: 600,
2205    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2206    enabled: true,
2207    /** @prop {ModifierFn} */
2208    fn: flip,
2209    /**
2210     * @prop {String|Array} behavior='flip'
2211     * The behavior used to change the popper's placement. It can be one of
2212     * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
2213     * placements (with optional variations)
2214     */
2215    behavior: 'flip',
2216    /**
2217     * @prop {number} padding=5
2218     * The popper will flip if it hits the edges of the `boundariesElement`
2219     */
2220    padding: 5,
2221    /**
2222     * @prop {String|HTMLElement} boundariesElement='viewport'
2223     * The element which will define the boundaries of the popper position.
2224     * The popper will never be placed outside of the defined boundaries
2225     * (except if `keepTogether` is enabled)
2226     */
2227    boundariesElement: 'viewport',
2228    /**
2229     * @prop {Boolean} flipVariations=false
2230     * The popper will switch placement variation between `-start` and `-end` when
2231     * the reference element overlaps its boundaries.
2232     *
2233     * The original placement should have a set variation.
2234     */
2235    flipVariations: false,
2236    /**
2237     * @prop {Boolean} flipVariationsByContent=false
2238     * The popper will switch placement variation between `-start` and `-end` when
2239     * the popper element overlaps its reference boundaries.
2240     *
2241     * The original placement should have a set variation.
2242     */
2243    flipVariationsByContent: false
2244  },
2245
2246  /**
2247   * Modifier used to make the popper flow toward the inner of the reference element.
2248   * By default, when this modifier is disabled, the popper will be placed outside
2249   * the reference element.
2250   * @memberof modifiers
2251   * @inner
2252   */
2253  inner: {
2254    /** @prop {number} order=700 - Index used to define the order of execution */
2255    order: 700,
2256    /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
2257    enabled: false,
2258    /** @prop {ModifierFn} */
2259    fn: inner
2260  },
2261
2262  /**
2263   * Modifier used to hide the popper when its reference element is outside of the
2264   * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
2265   * be used to hide with a CSS selector the popper when its reference is
2266   * out of boundaries.
2267   *
2268   * Requires the `preventOverflow` modifier before it in order to work.
2269   * @memberof modifiers
2270   * @inner
2271   */
2272  hide: {
2273    /** @prop {number} order=800 - Index used to define the order of execution */
2274    order: 800,
2275    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2276    enabled: true,
2277    /** @prop {ModifierFn} */
2278    fn: hide
2279  },
2280
2281  /**
2282   * Computes the style that will be applied to the popper element to gets
2283   * properly positioned.
2284   *
2285   * Note that this modifier will not touch the DOM, it just prepares the styles
2286   * so that `applyStyle` modifier can apply it. This separation is useful
2287   * in case you need to replace `applyStyle` with a custom implementation.
2288   *
2289   * This modifier has `850` as `order` value to maintain backward compatibility
2290   * with previous versions of Popper.js. Expect the modifiers ordering method
2291   * to change in future major versions of the library.
2292   *
2293   * @memberof modifiers
2294   * @inner
2295   */
2296  computeStyle: {
2297    /** @prop {number} order=850 - Index used to define the order of execution */
2298    order: 850,
2299    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2300    enabled: true,
2301    /** @prop {ModifierFn} */
2302    fn: computeStyle,
2303    /**
2304     * @prop {Boolean} gpuAcceleration=true
2305     * If true, it uses the CSS 3D transformation to position the popper.
2306     * Otherwise, it will use the `top` and `left` properties
2307     */
2308    gpuAcceleration: true,
2309    /**
2310     * @prop {string} [x='bottom']
2311     * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
2312     * Change this if your popper should grow in a direction different from `bottom`
2313     */
2314    x: 'bottom',
2315    /**
2316     * @prop {string} [x='left']
2317     * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
2318     * Change this if your popper should grow in a direction different from `right`
2319     */
2320    y: 'right'
2321  },
2322
2323  /**
2324   * Applies the computed styles to the popper element.
2325   *
2326   * All the DOM manipulations are limited to this modifier. This is useful in case
2327   * you want to integrate Popper.js inside a framework or view library and you
2328   * want to delegate all the DOM manipulations to it.
2329   *
2330   * Note that if you disable this modifier, you must make sure the popper element
2331   * has its position set to `absolute` before Popper.js can do its work!
2332   *
2333   * Just disable this modifier and define your own to achieve the desired effect.
2334   *
2335   * @memberof modifiers
2336   * @inner
2337   */
2338  applyStyle: {
2339    /** @prop {number} order=900 - Index used to define the order of execution */
2340    order: 900,
2341    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2342    enabled: true,
2343    /** @prop {ModifierFn} */
vendor: 4,828 bytes, lines 2344-2482
2344    fn: applyStyle,
2345    /** @prop {Function} */
2346    onLoad: applyStyleOnLoad,
2347    /**
2348     * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
2349     * @prop {Boolean} gpuAcceleration=true
2350     * If true, it uses the CSS 3D transformation to position the popper.
2351     * Otherwise, it will use the `top` and `left` properties
2352     */
2353    gpuAcceleration: undefined
2354  }
2355};
2356
2357/**
2358 * The `dataObject` is an object containing all the information used by Popper.js.
2359 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
2360 * @name dataObject
2361 * @property {Object} data.instance The Popper.js instance
2362 * @property {String} data.placement Placement applied to popper
2363 * @property {String} data.originalPlacement Placement originally defined on init
2364 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
2365 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
2366 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
2367 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
2368 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
2369 * @property {Object} data.boundaries Offsets of the popper boundaries
2370 * @property {Object} data.offsets The measurements of popper, reference and arrow elements
2371 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
2372 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
2373 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
2374 */
2375
2376/**
2377 * Default options provided to Popper.js constructor.<br />
2378 * These can be overridden using the `options` argument of Popper.js.<br />
2379 * To override an option, simply pass an object with the same
2380 * structure of the `options` object, as the 3rd argument. For example:
2381 * ```
2382 * new Popper(ref, pop, {
2383 *   modifiers: {
2384 *     preventOverflow: { enabled: false }
2385 *   }
2386 * })
2387 * ```
2388 * @type {Object}
2389 * @static
2390 * @memberof Popper
2391 */
2392var Defaults = {
2393  /**
2394   * Popper's placement.
2395   * @prop {Popper.placements} placement='bottom'
2396   */
2397  placement: 'bottom',
2398
2399  /**
2400   * Set this to true if you want popper to position it self in 'fixed' mode
2401   * @prop {Boolean} positionFixed=false
2402   */
2403  positionFixed: false,
2404
2405  /**
2406   * Whether events (resize, scroll) are initially enabled.
2407   * @prop {Boolean} eventsEnabled=true
2408   */
2409  eventsEnabled: true,
2410
2411  /**
2412   * Set to true if you want to automatically remove the popper when
2413   * you call the `destroy` method.
2414   * @prop {Boolean} removeOnDestroy=false
2415   */
2416  removeOnDestroy: false,
2417
2418  /**
2419   * Callback called when the popper is created.<br />
2420   * By default, it is set to no-op.<br />
2421   * Access Popper.js instance with `data.instance`.
2422   * @prop {onCreate}
2423   */
2424  onCreate: function onCreate() {},
2425
2426  /**
2427   * Callback called when the popper is updated. This callback is not called
2428   * on the initialization/creation of the popper, but only on subsequent
2429   * updates.<br />
2430   * By default, it is set to no-op.<br />
2431   * Access Popper.js instance with `data.instance`.
2432   * @prop {onUpdate}
2433   */
2434  onUpdate: function onUpdate() {},
2435
2436  /**
2437   * List of modifiers used to modify the offsets before they are applied to the popper.
2438   * They provide most of the functionalities of Popper.js.
2439   * @prop {modifiers}
2440   */
2441  modifiers: modifiers
2442};
2443
2444/**
2445 * @callback onCreate
2446 * @param {dataObject} data
2447 */
2448
2449/**
2450 * @callback onUpdate
2451 * @param {dataObject} data
2452 */
2453
2454// Utils
2455// Methods
2456var Popper = function () {
2457  /**
2458   * Creates a new Popper.js instance.
2459   * @class Popper
2460   * @param {Element|referenceObject} reference - The reference element used to position the popper
2461   * @param {Element} popper - The HTML / XML element used as the popper
2462   * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
2463   * @return {Object} instance - The generated Popper.js instance
2464   */
2465  function Popper(reference, popper) {
2466    var _this = this;
2467
2468    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2469    classCallCheck(this, Popper);
2470
2471    this.scheduleUpdate = function () {
2472      return requestAnimationFrame(_this.update);
2473    };
2474
2475    // make update() debounced, so that it only runs at most once-per-tick
2476    this.update = debounce(this.update.bind(this));
2477
2478    // with {} we create a new object with the options inside it
2479    this.options = _extends({}, Popper.Defaults, options);
2480
2481    // init state
2482    this.state = {
vendor: 4,356 bytes, lines 2483-2612
2483      isDestroyed: false,
2484      isCreated: false,
2485      scrollParents: []
2486    };
2487
2488    // get reference and popper elements (allow jQuery wrappers)
2489    this.reference = reference && reference.jquery ? reference[0] : reference;
2490    this.popper = popper && popper.jquery ? popper[0] : popper;
2491
2492    // Deep merge modifiers options
2493    this.options.modifiers = {};
2494    Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
2495      _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
2496    });
2497
2498    // Refactoring modifiers' list (Object => Array)
2499    this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
2500      return _extends({
2501        name: name
2502      }, _this.options.modifiers[name]);
2503    })
2504    // sort the modifiers by order
2505    .sort(function (a, b) {
2506      return a.order - b.order;
2507    });
2508
2509    // modifiers have the ability to execute arbitrary code when Popper.js get inited
2510    // such code is executed in the same order of its modifier
2511    // they could add new properties to their options configuration
2512    // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
2513    this.modifiers.forEach(function (modifierOptions) {
2514      if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
2515        modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
2516      }
2517    });
2518
2519    // fire the first update to position the popper in the right place
2520    this.update();
2521
2522    var eventsEnabled = this.options.eventsEnabled;
2523    if (eventsEnabled) {
2524      // setup event listeners, they will take care of update the position in specific situations
2525      this.enableEventListeners();
2526    }
2527
2528    this.state.eventsEnabled = eventsEnabled;
2529  }
2530
2531  // We can't use class properties because they don't get listed in the
2532  // class prototype and break stuff like Sinon stubs
2533
2534
2535  createClass(Popper, [{
2536    key: 'update',
2537    value: function update$$1() {
2538      return update.call(this);
2539    }
2540  }, {
2541    key: 'destroy',
2542    value: function destroy$$1() {
2543      return destroy.call(this);
2544    }
2545  }, {
2546    key: 'enableEventListeners',
2547    value: function enableEventListeners$$1() {
2548      return enableEventListeners.call(this);
2549    }
2550  }, {
2551    key: 'disableEventListeners',
2552    value: function disableEventListeners$$1() {
2553      return disableEventListeners.call(this);
2554    }
2555
2556    /**
2557     * Schedules an update. It will run on the next UI update available.
2558     * @method scheduleUpdate
2559     * @memberof Popper
2560     */
2561
2562
2563    /**
2564     * Collection of utilities useful when writing custom modifiers.
2565     * Starting from version 1.7, this method is available only if you
2566     * include `popper-utils.js` before `popper.js`.
2567     *
2568     * **DEPRECATION**: This way to access PopperUtils is deprecated
2569     * and will be removed in v2! Use the PopperUtils module directly instead.
2570     * Due to the high instability of the methods contained in Utils, we can't
2571     * guarantee them to follow semver. Use them at your own risk!
2572     * @static
2573     * @private
2574     * @type {Object}
2575     * @deprecated since version 1.8
2576     * @member Utils
2577     * @memberof Popper
2578     */
2579
2580  }]);
2581  return Popper;
2582}();
2583
2584/**
2585 * The `referenceObject` is an object that provides an interface compatible with Popper.js
2586 * and lets you use it as replacement of a real DOM node.<br />
2587 * You can use this method to position a popper relatively to a set of coordinates
2588 * in case you don't have a DOM node to use as reference.
2589 *
2590 * ```
2591 * new Popper(referenceObject, popperNode);
2592 * ```
2593 *
2594 * NB: This feature isn't supported in Internet Explorer 10.
2595 * @name referenceObject
2596 * @property {Function} data.getBoundingClientRect
2597 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
2598 * @property {number} data.clientWidth
2599 * An ES6 getter that will return the width of the virtual reference element.
2600 * @property {number} data.clientHeight
2601 * An ES6 getter that will return the height of the virtual reference element.
2602 */
2603
2604
2605Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
2606Popper.placements = placements;
2607Popper.Defaults = Defaults;
2608
2609return Popper;
2610
2611})));
2612//# sourceMappingURL=popper.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.