
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
        typeof define === 'function' && define.amd ? define(['exports'], factory) :
            (global = global || self, factory(global.Popper = {}));
}(this, (function (exports) { 'use strict';

    function getBoundingClientRect(element) {
        var rect = element.getBoundingClientRect();
        return {
            width: rect.width,
            height: rect.height,
            top: rect.top,
            right: rect.right,
            bottom: rect.bottom,
            left: rect.left,
            x: rect.left,
            y: rect.top
        };
    }

    /*:: import type { Window } from '../types'; */

    /*:: declare function getWindow(node: Node | Window): Window; */
    function getWindow(node) {
        if (node.toString() !== '[object Window]') {
            var ownerDocument = node.ownerDocument;
            return ownerDocument ? ownerDocument.defaultView : window;
        }

        return node;
    }

    function getWindowScroll(node) {
        var win = getWindow(node);
        var scrollLeft = win.pageXOffset;
        var scrollTop = win.pageYOffset;
        return {
            scrollLeft: scrollLeft,
            scrollTop: scrollTop
        };
    }

    /*:: declare function isElement(node: mixed): boolean %checks(node instanceof
      Element); */

    function isElement(node) {
        var OwnElement = getWindow(node).Element;
        return node instanceof OwnElement;
    }
    /*:: declare function isHTMLElement(node: mixed): boolean %checks(node instanceof
      HTMLElement); */


    function isHTMLElement(node) {
        var OwnElement = getWindow(node).HTMLElement;
        return node instanceof OwnElement;
    }

    function getHTMLElementScroll(element) {
        return {
            scrollLeft: element.scrollLeft,
            scrollTop: element.scrollTop
        };
    }

    function getNodeScroll(node) {
        if (node === getWindow(node) || !isHTMLElement(node)) {
            return getWindowScroll(node);
        } else {
            return getHTMLElementScroll(node);
        }
    }

    function getNodeName(element) {
        return element ? (element.nodeName || '').toLowerCase() : null;
    }

    function getDocumentElement(element) {
        // $FlowFixMe: assume body is always available
        return (isElement(element) ? element.ownerDocument : element.document).documentElement;
    }

    function getWindowScrollBarX(element) {
        // If <html> has a CSS width greater than the viewport, then this will be
        // incorrect for RTL.
        // Popper 1 is broken in this case and never had a bug report so let's assume
        // it's not an issue. I don't think anyone ever specifies width on <html>
        // anyway.
        // Browsers where the left scrollbar doesn't cause an issue report `0` for
        // this (e.g. Edge 2019, IE11, Safari)
        return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
    }

    // Composite means it takes into account transforms as well as layout.

    function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
        if (isFixed === void 0) {
            isFixed = false;
        }

        var documentElement;
        var rect = getBoundingClientRect(elementOrVirtualElement);
        var scroll = {
            scrollLeft: 0,
            scrollTop: 0
        };
        var offsets = {
            x: 0,
            y: 0
        };

        if (!isFixed) {
            if (getNodeName(offsetParent) !== 'body') {
                scroll = getNodeScroll(offsetParent);
            }

            if (isHTMLElement(offsetParent)) {
                offsets = getBoundingClientRect(offsetParent);
                offsets.x += offsetParent.clientLeft;
                offsets.y += offsetParent.clientTop;
            } else if (documentElement = getDocumentElement(offsetParent)) {
                offsets.x = getWindowScrollBarX(documentElement);
            }
        }

        return {
            x: rect.left + scroll.scrollLeft - offsets.x,
            y: rect.top + scroll.scrollTop - offsets.y,
            width: rect.width,
            height: rect.height
        };
    }

    // Returns the layout rect of an element relative to its offsetParent. Layout
    // means it doesn't take into account transforms.
    function getLayoutRect(element) {
        return {
            x: element.offsetLeft,
            y: element.offsetTop,
            width: element.offsetWidth,
            height: element.offsetHeight
        };
    }

    function getParentNode(element) {
        if (getNodeName(element) === 'html') {
            return element;
        }

        return element.parentNode || // DOM Element detected
            // $FlowFixMe: need a better way to handle this...
            element.host || // ShadowRoot detected
            document.ownerDocument || // Fallback to ownerDocument if available
            document.documentElement // Or to documentElement if everything else fails
            ;
    }

    function getComputedStyle(element) {
        return getWindow(element).getComputedStyle(element);
    }

    function getScrollParent(node) {
        if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
            // $FlowFixMe: assume body is always available
            return node.ownerDocument.body;
        }

        if (isHTMLElement(node)) {
            // Firefox wants us to check `-x` and `-y` variations as well
            var _getComputedStyle = getComputedStyle(node),
                overflow = _getComputedStyle.overflow,
                overflowX = _getComputedStyle.overflowX,
                overflowY = _getComputedStyle.overflowY;

            if (/auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX)) {
                return node;
            }
        }

        return getScrollParent(getParentNode(node));
    }

    function listScrollParents(element, list) {
        if (list === void 0) {
            list = [];
        }

        var scrollParent = getScrollParent(element);
        var isBody = getNodeName(scrollParent) === 'body';
        var target = isBody ? getWindow(scrollParent) : scrollParent;
        var updatedList = list.concat(target);
        return isBody ? updatedList : // $FlowFixMe: isBody tells us target will be an HTMLElement here
            updatedList.concat(listScrollParents(getParentNode(target)));
    }

    function isTableElement(element) {
        return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
    }

    var isFirefox = function isFirefox() {
        return typeof window.InstallTrigger !== 'undefined';
    };

    function getTrueOffsetParent(element) {
        var offsetParent;

        if (!isHTMLElement(element) || !(offsetParent = element.offsetParent) || // https://github.com/popperjs/popper-core/issues/837
            isFirefox() && getComputedStyle(offsetParent).position === 'fixed') {
            return null;
        }

        return offsetParent;
    }

    function getOffsetParent(element) {
        var window = getWindow(element);
        var offsetParent = getTrueOffsetParent(element); // Find the nearest non-table offsetParent

        while (offsetParent && isTableElement(offsetParent)) {
            offsetParent = getTrueOffsetParent(offsetParent);
        }

        if (offsetParent && getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static') {
            return window;
        }

        return offsetParent || window;
    }

    var top = 'top';
    var bottom = 'bottom';
    var right = 'right';
    var left = 'left';
    var auto = 'auto';
    var basePlacements = [top, bottom, right, left];
    var start = 'start';
    var end = 'end';
    var clippingParents = 'clippingParents';
    var viewport = 'viewport';
    var popper = 'popper';
    var reference = 'reference';
    var variationPlacements =
        /*#__PURE__*/
        basePlacements.reduce(function (acc, placement) {
            return acc.concat([placement + "-" + start, placement + "-" + end]);
        }, []);
    var placements =
        /*#__PURE__*/
        [].concat(basePlacements, [auto]).reduce(function (acc, placement) {
            return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
        }, []); // modifiers that need to read the DOM

    var beforeRead = 'beforeRead';
    var read = 'read';
    var afterRead = 'afterRead'; // pure-logic modifiers

    var beforeMain = 'beforeMain';
    var main = 'main';
    var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)

    var beforeWrite = 'beforeWrite';
    var write = 'write';
    var afterWrite = 'afterWrite';
    var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];

    function order(modifiers) {
        var map = new Map();
        var visited = new Set();
        var result = [];
        modifiers.forEach(function (modifier) {
            map.set(modifier.name, modifier);
        }); // On visiting object, check for its dependencies and visit them recursively

        function sort(modifier) {
            visited.add(modifier.name);
            var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
            requires.forEach(function (dep) {
                if (!visited.has(dep)) {
                    var depModifier = map.get(dep);

                    if (depModifier) {
                        sort(depModifier);
                    }
                }
            });
            result.push(modifier);
        }

        modifiers.forEach(function (modifier) {
            if (!visited.has(modifier.name)) {
                // check for visited object
                sort(modifier);
            }
        });
        return result;
    }

    function orderModifiers(modifiers) {
        // order based on dependencies
        var orderedModifiers = order(modifiers); // order based on phase

        return modifierPhases.reduce(function (acc, phase) {
            return acc.concat(orderedModifiers.filter(function (modifier) {
                return modifier.phase === phase;
            }));
        }, []);
    }

    function debounce(fn) {
        var pending;
        return function () {
            if (!pending) {
                pending = new Promise(function (resolve) {
                    Promise.resolve().then(function () {
                        pending = undefined;
                        resolve(fn());
                    });
                });
            }

            return pending;
        };
    }

    function format(str) {
        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
            args[_key - 1] = arguments[_key];
        }

        return [].concat(args).reduce(function (p, c) {
            return p.replace(/%s/, c);
        }, str);
    }

    var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
    var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
    var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options'];
    function validateModifiers(modifiers) {
        modifiers.forEach(function (modifier) {
            Object.keys(modifier).forEach(function (key) {
                switch (key) {
                    case 'name':
                        if (typeof modifier.name !== 'string') {
                            console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\""));
                        }

                        break;

                    case 'enabled':
                        if (typeof modifier.enabled !== 'boolean') {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\""));
                        }

                    case 'phase':
                        if (modifierPhases.indexOf(modifier.phase) < 0) {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\""));
                        }

                        break;

                    case 'fn':
                        if (typeof modifier.fn !== 'function') {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\""));
                        }

                        break;

                    case 'effect':
                        if (typeof modifier.effect !== 'function') {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\""));
                        }

                        break;

                    case 'requires':
                        if (!Array.isArray(modifier.requires)) {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\""));
                        }

                        break;

                    case 'requiresIfExists':
                        if (!Array.isArray(modifier.requiresIfExists)) {
                            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\""));
                        }

                        break;

                    case 'options':
                    case 'data':
                        break;

                    default:
                        console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) {
                            return "\"" + s + "\"";
                        }).join(', ') + "; but \"" + key + "\" was provided.");
                }

                modifier.requires && modifier.requires.forEach(function (requirement) {
                    if (modifiers.find(function (mod) {
                        return mod.name === requirement;
                    }) == null) {
                        console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
                    }
                });
            });
        });
    }

    function uniqueBy(arr, fn) {
        var identifiers = new Set();
        return arr.filter(function (item) {
            var identifier = fn(item);

            if (!identifiers.has(identifier)) {
                identifiers.add(identifier);
                return true;
            }
        });
    }

    function getBasePlacement(placement) {
        return placement.split('-')[0];
    }

    function mergeByName(modifiers) {
        var merged = modifiers.reduce(function (merged, current) {
            var existing = merged[current.name];
            merged[current.name] = existing ? Object.assign({}, existing, {}, current, {
                options: Object.assign({}, existing.options, {}, current.options),
                data: Object.assign({}, existing.data, {}, current.data)
            }) : current;
            return merged;
        }, {}); // IE11 does not support Object.values

        return Object.keys(merged).map(function (key) {
            return merged[key];
        });
    }

    var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';
    var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';
    var DEFAULT_OPTIONS = {
        placement: 'bottom',
        modifiers: [],
        strategy: 'absolute'
    };

    function areValidElements() {
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
        }

        return !args.some(function (element) {
            return !(element && typeof element.getBoundingClientRect === 'function');
        });
    }

    function popperGenerator(generatorOptions) {
        if (generatorOptions === void 0) {
            generatorOptions = {};
        }

        var _generatorOptions = generatorOptions,
            _generatorOptions$def = _generatorOptions.defaultModifiers,
            defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
            _generatorOptions$def2 = _generatorOptions.defaultOptions,
            defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
        return function createPopper(reference, popper, options) {
            if (options === void 0) {
                options = defaultOptions;
            }

            var state = {
                placement: 'bottom',
                orderedModifiers: [],
                options: Object.assign({}, DEFAULT_OPTIONS, {}, defaultOptions),
                modifiersData: {},
                elements: {
                    reference: reference,
                    popper: popper
                },
                attributes: {},
                styles: {}
            };
            var effectCleanupFns = [];
            var isDestroyed = false;
            var instance = {
                state: state,
                setOptions: function setOptions(options) {
                    cleanupModifierEffects();
                    state.options = Object.assign({}, defaultOptions, {}, state.options, {}, options);
                    state.scrollParents = {
                        reference: isElement(reference) ? listScrollParents(reference) : [],
                        popper: listScrollParents(popper)
                    }; // Orders the modifiers based on their dependencies and `phase`
                    // properties

                    var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers

                    state.orderedModifiers = orderedModifiers.filter(function (m) {
                        return m.enabled;
                    }); // Validate the provided modifiers so that the consumer will get warned
                    // if one of the modifiers is invalid for any reason

                    {
                        var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {
                            var name = _ref.name;
                            return name;
                        });
                        validateModifiers(modifiers);

                        if (getBasePlacement(state.options.placement) === auto) {
                            var flipModifier = state.orderedModifiers.find(function (_ref2) {
                                var name = _ref2.name;
                                return name === 'flip';
                            });

                            if (!flipModifier) {
                                console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' '));
                            }
                        }

                        var _getComputedStyle = getComputedStyle(popper),
                            marginTop = _getComputedStyle.marginTop,
                            marginRight = _getComputedStyle.marginRight,
                            marginBottom = _getComputedStyle.marginBottom,
                            marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can
                        // cause bugs with positioning, so we'll warn the consumer


                        if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {
                            return parseFloat(margin);
                        })) {
                            console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));
                        }
                    }

                    runModifierEffects();
                    return instance.update();
                },
                // Sync update – it will always be executed, even if not necessary. This
                // is useful for low frequency updates where sync behavior simplifies the
                // logic.
                // For high frequency updates (e.g. `resize` and `scroll` events), always
                // prefer the async Popper#update method
                forceUpdate: function forceUpdate() {
                    if (isDestroyed) {
                        return;
                    }

                    var _state$elements = state.elements,
                        reference = _state$elements.reference,
                        popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
                    // anymore

                    if (!areValidElements(reference, popper)) {
                        {
                            console.error(INVALID_ELEMENT_ERROR);
                        }

                        return;
                    } // Store the reference and popper rects to be read by modifiers


                    state.rects = {
                        reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
                        popper: getLayoutRect(popper)
                    }; // Modifiers have the ability to reset the current update cycle. The
                    // most common use case for this is the `flip` modifier changing the
                    // placement, which then needs to re-run all the modifiers, because the
                    // logic was previously ran for the previous placement and is therefore
                    // stale/incorrect

                    state.reset = false;
                    state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
                    // is filled with the initial data specified by the modifier. This means
                    // it doesn't persist and is fresh on each update.
                    // To ensure persistent data, use `${name}#persistent`

                    state.orderedModifiers.forEach(function (modifier) {
                        return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
                    });
                    var __debug_loops__ = 0;

                    for (var index = 0; index < state.orderedModifiers.length; index++) {
                        {
                            __debug_loops__ += 1;

                            if (__debug_loops__ > 100) {
                                console.error(INFINITE_LOOP_ERROR);
                                break;
                            }
                        }

                        if (state.reset === true) {
                            state.reset = false;
                            index = -1;
                            continue;
                        }

                        var _state$orderedModifie = state.orderedModifiers[index],
                            fn = _state$orderedModifie.fn,
                            _state$orderedModifie2 = _state$orderedModifie.options,
                            _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
                            name = _state$orderedModifie.name;

                        if (typeof fn === 'function') {
                            state = fn({
                                state: state,
                                options: _options,
                                name: name,
                                instance: instance
                            }) || state;
                        }
                    }
                },
                // Async and optimistically optimized update – it will not be executed if
                // not necessary (debounced to run at most once-per-tick)
                update: debounce(function () {
                    return new Promise(function (resolve) {
                        instance.forceUpdate();
                        resolve(state);
                    });
                }),
                destroy: function destroy() {
                    cleanupModifierEffects();
                    isDestroyed = true;
                }
            };

            if (!areValidElements(reference, popper)) {
                {
                    console.error(INVALID_ELEMENT_ERROR);
                }

                return instance;
            }

            instance.setOptions(options).then(function (state) {
                if (!isDestroyed && options.onFirstUpdate) {
                    options.onFirstUpdate(state);
                }
            }); // Modifiers have the ability to execute arbitrary code before the first
            // update cycle runs. They will be executed in the same order as the update
            // cycle. This is useful when a modifier adds some persistent data that
            // other modifiers need to use, but the modifier is run after the dependent
            // one.

            function runModifierEffects() {
                state.orderedModifiers.forEach(function (_ref3) {
                    var name = _ref3.name,
                        _ref3$options = _ref3.options,
                        options = _ref3$options === void 0 ? {} : _ref3$options,
                        effect = _ref3.effect;

                    if (typeof effect === 'function') {
                        var cleanupFn = effect({
                            state: state,
                            name: name,
                            instance: instance,
                            options: options
                        });

                        var noopFn = function noopFn() {};

                        effectCleanupFns.push(cleanupFn || noopFn);
                    }
                });
            }

            function cleanupModifierEffects() {
                effectCleanupFns.forEach(function (fn) {
                    return fn();
                });
                effectCleanupFns = [];
            }

            return instance;
        };
    }

    var passive = {
        passive: true
    };

    function effect(_ref) {
        var state = _ref.state,
            instance = _ref.instance,
            options = _ref.options;
        var _options$scroll = options.scroll,
            scroll = _options$scroll === void 0 ? true : _options$scroll,
            _options$resize = options.resize,
            resize = _options$resize === void 0 ? true : _options$resize;
        var window = getWindow(state.elements.popper);
        var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);

        if (scroll) {
            scrollParents.forEach(function (scrollParent) {
                scrollParent.addEventListener('scroll', instance.update, passive);
            });
        }

        if (resize) {
            window.addEventListener('resize', instance.update, passive);
        }

        return function () {
            if (scroll) {
                scrollParents.forEach(function (scrollParent) {
                    scrollParent.removeEventListener('scroll', instance.update, passive);
                });
            }

            if (resize) {
                window.removeEventListener('resize', instance.update, passive);
            }
        };
    }

    var eventListeners = {
        name: 'eventListeners',
        enabled: true,
        phase: 'write',
        fn: function fn() {},
        effect: effect,
        data: {}
    };

    function getVariation(placement) {
        return placement.split('-')[1];
    }

    function getMainAxisFromPlacement(placement) {
        return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
    }

    function computeOffsets(_ref) {
        var reference = _ref.reference,
            element = _ref.element,
            placement = _ref.placement;
        var basePlacement = placement ? getBasePlacement(placement) : null;
        var variation = placement ? getVariation(placement) : null;
        var commonX = reference.x + reference.width / 2 - element.width / 2;
        var commonY = reference.y + reference.height / 2 - element.height / 2;
        var offsets;

        switch (basePlacement) {
            case top:
                offsets = {
                    x: commonX,
                    y: reference.y - element.height
                };
                break;

            case bottom:
                offsets = {
                    x: commonX,
                    y: reference.y + reference.height
                };
                break;

            case right:
                offsets = {
                    x: reference.x + reference.width,
                    y: commonY
                };
                break;

            case left:
                offsets = {
                    x: reference.x - element.width,
                    y: commonY
                };
                break;

            default:
                offsets = {
                    x: reference.x,
                    y: reference.y
                };
        }

        var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;

        if (mainAxis != null) {
            var len = mainAxis === 'y' ? 'height' : 'width';

            switch (variation) {
                case start:
                    offsets[mainAxis] = Math.floor(offsets[mainAxis]) - Math.floor(reference[len] / 2 - element[len] / 2);
                    break;

                case end:
                    offsets[mainAxis] = Math.floor(offsets[mainAxis]) + Math.ceil(reference[len] / 2 - element[len] / 2);
                    break;
            }
        }

        return offsets;
    }

    function popperOffsets(_ref) {
        var state = _ref.state,
            name = _ref.name;
        // Offsets are the actual position the popper needs to have to be
        // properly positioned near its reference element
        // This is the most basic placement, and will be adjusted by
        // the modifiers in the next step
        state.modifiersData[name] = computeOffsets({
            reference: state.rects.reference,
            element: state.rects.popper,
            strategy: 'absolute',
            placement: state.placement
        });
    }

    var popperOffsets$1 = {
        name: 'popperOffsets',
        enabled: true,
        phase: 'read',
        fn: popperOffsets,
        data: {}
    };

    var unsetSides = {
        top: 'auto',
        right: 'auto',
        bottom: 'auto',
        left: 'auto'
    }; // Round the offsets to the nearest suitable subpixel based on the DPR.
    // Zooming can change the DPR, but it seems to report a value that will
    // cleanly divide the values into the appropriate subpixels.

    function roundOffsets(_ref) {
        var x = _ref.x,
            y = _ref.y;
        var win = window;
        var dpr = win.devicePixelRatio || 1;
        return {
            x: Math.round(x * dpr) / dpr || 0,
            y: Math.round(y * dpr) / dpr || 0
        };
    }

    function mapToStyles(_ref2) {
        var _Object$assign2;

        var popper = _ref2.popper,
            popperRect = _ref2.popperRect,
            placement = _ref2.placement,
            offsets = _ref2.offsets,
            position = _ref2.position,
            gpuAcceleration = _ref2.gpuAcceleration,
            adaptive = _ref2.adaptive;

        var _roundOffsets = roundOffsets(offsets),
            x = _roundOffsets.x,
            y = _roundOffsets.y;

        var hasX = offsets.hasOwnProperty('x');
        var hasY = offsets.hasOwnProperty('y');
        var sideX = left;
        var sideY = top;
        var win = window;

        if (adaptive) {
            var offsetParent = getOffsetParent(popper);

            if (offsetParent === getWindow(popper)) {
                offsetParent = getDocumentElement(popper);
            } // $FlowFixMe: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it

            /*:: offsetParent = (offsetParent: Element); */


            if (placement === top) {
                sideY = bottom;
                y -= offsetParent.clientHeight - popperRect.height;
                y *= gpuAcceleration ? 1 : -1;
            }

            if (placement === left) {
                sideX = right;
                x -= offsetParent.clientWidth - popperRect.width;
                x *= gpuAcceleration ? 1 : -1;
            }
        }

        var commonStyles = Object.assign({
            position: position
        }, adaptive && unsetSides);

        if (gpuAcceleration) {
            var _Object$assign;

            return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
        }

        return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
    }

    function computeStyles(_ref3) {
        var state = _ref3.state,
            options = _ref3.options;
        var _options$gpuAccelerat = options.gpuAcceleration,
            gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
            _options$adaptive = options.adaptive,
            adaptive = _options$adaptive === void 0 ? true : _options$adaptive;

        {
            var _getComputedStyle = getComputedStyle(state.elements.popper),
                transitionProperty = _getComputedStyle.transitionProperty;

            if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
                return transitionProperty.indexOf(property) >= 0;
            })) {
                console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));
            }
        }

        var commonStyles = {
            placement: getBasePlacement(state.placement),
            popper: state.elements.popper,
            popperRect: state.rects.popper,
            gpuAcceleration: gpuAcceleration
        }; // popper offsets are always available

        state.styles.popper = Object.assign({}, state.styles.popper, {}, mapToStyles(Object.assign({}, commonStyles, {
            offsets: state.modifiersData.popperOffsets,
            position: state.options.strategy,
            adaptive: adaptive
        }))); // arrow offsets may not be available

        if (state.modifiersData.arrow != null) {
            state.styles.arrow = Object.assign({}, state.styles.arrow, {}, mapToStyles(Object.assign({}, commonStyles, {
                offsets: state.modifiersData.arrow,
                position: 'absolute',
                adaptive: false
            })));
        }

        state.attributes.popper = Object.assign({}, state.attributes.popper, {
            'data-popper-placement': state.placement
        });
    }

    var computeStyles$1 = {
        name: 'computeStyles',
        enabled: true,
        phase: 'beforeWrite',
        fn: computeStyles,
        data: {}
    };

    // and applies them to the HTMLElements such as popper and arrow

    function applyStyles(_ref) {
        var state = _ref.state;
        Object.keys(state.elements).forEach(function (name) {
            var style = state.styles[name] || {};
            var attributes = state.attributes[name] || {};
            var element = state.elements[name]; // arrow is optional + virtual elements

            if (!isHTMLElement(element) || !getNodeName(element)) {
                return;
            } // Flow doesn't support to extend this property, but it's the most
            // effective way to apply styles to an HTMLElement
            // $FlowFixMe


            Object.assign(element.style, style);
            Object.keys(attributes).forEach(function (name) {
                var value = attributes[name];

                if (value === false) {
                    element.removeAttribute(name);
                } else {
                    element.setAttribute(name, value === true ? '' : value);
                }
            });
        });
    }

    function effect$1(_ref2) {
        var state = _ref2.state;
        var initialStyles = {
            popper: {
                position: 'absolute',
                left: '0',
                top: '0',
                margin: '0'
            },
            arrow: {
                position: 'absolute'
            },
            reference: {}
        };
        Object.assign(state.elements.popper.style, initialStyles.popper);

        if (state.elements.arrow) {
            Object.assign(state.elements.arrow.style, initialStyles.arrow);
        }

        return function () {
            Object.keys(state.elements).forEach(function (name) {
                var element = state.elements[name];
                var attributes = state.attributes[name] || {};
                var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them

                var style = styleProperties.reduce(function (style, property) {
                    style[property] = '';
                    return style;
                }, {}); // arrow is optional + virtual elements

                if (!isHTMLElement(element) || !getNodeName(element)) {
                    return;
                } // Flow doesn't support to extend this property, but it's the most
                // effective way to apply styles to an HTMLElement
                // $FlowFixMe


                Object.assign(element.style, style);
                Object.keys(attributes).forEach(function (attribute) {
                    element.removeAttribute(attribute);
                });
            });
        };
    }

    var applyStyles$1 = {
        name: 'applyStyles',
        enabled: true,
        phase: 'write',
        fn: applyStyles,
        effect: effect$1,
        requires: ['computeStyles']
    };

    function distanceAndSkiddingToXY(placement, rects, offset) {
        var basePlacement = getBasePlacement(placement);
        var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;

        var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
                placement: placement
            })) : offset,
            skidding = _ref[0],
            distance = _ref[1];

        skidding = skidding || 0;
        distance = (distance || 0) * invertDistance;
        return [left, right].indexOf(basePlacement) >= 0 ? {
            x: distance,
            y: skidding
        } : {
            x: skidding,
            y: distance
        };
    }

    function offset(_ref2) {
        var state = _ref2.state,
            options = _ref2.options,
            name = _ref2.name;
        var _options$offset = options.offset,
            offset = _options$offset === void 0 ? [0, 0] : _options$offset;
        var data = placements.reduce(function (acc, placement) {
            acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
            return acc;
        }, {});
        var _data$state$placement = data[state.placement],
            x = _data$state$placement.x,
            y = _data$state$placement.y;
        state.modifiersData.popperOffsets.x += x;
        state.modifiersData.popperOffsets.y += y;
        state.modifiersData[name] = data;
    }

    var offset$1 = {
        name: 'offset',
        enabled: true,
        phase: 'main',
        requires: ['popperOffsets'],
        fn: offset
    };

    var hash = {
        left: 'right',
        right: 'left',
        bottom: 'top',
        top: 'bottom'
    };
    function getOppositePlacement(placement) {
        return placement.replace(/left|right|bottom|top/g, function (matched) {
            return hash[matched];
        });
    }

    var hash$1 = {
        start: 'end',
        end: 'start'
    };
    function getOppositeVariationPlacement(placement) {
        return placement.replace(/start|end/g, function (matched) {
            return hash$1[matched];
        });
    }

    function getViewportRect(element) {
        var win = getWindow(element);
        return {
            width: win.innerWidth,
            height: win.innerHeight,
            x: 0,
            y: 0
        };
    }

    function getDocumentRect(element) {
        var win = getWindow(element);
        var winScroll = getWindowScroll(element);
        var documentRect = getCompositeRect(getDocumentElement(element), win);
        documentRect.height = Math.max(documentRect.height, win.innerHeight);
        documentRect.width = Math.max(documentRect.width, win.innerWidth);
        documentRect.x = -winScroll.scrollLeft;
        documentRect.y = -winScroll.scrollTop;
        return documentRect;
    }

    function toNumber(cssValue) {
        return parseFloat(cssValue) || 0;
    }

    function getBorders(element) {
        var computedStyle = isHTMLElement(element) ? getComputedStyle(element) : {};
        return {
            top: toNumber(computedStyle.borderTopWidth),
            right: toNumber(computedStyle.borderRightWidth),
            bottom: toNumber(computedStyle.borderBottomWidth),
            left: toNumber(computedStyle.borderLeftWidth)
        };
    }

    function getDecorations(element) {
        var win = getWindow(element);
        var borders = getBorders(element);
        var isHTML = getNodeName(element) === 'html';
        var winScrollBarX = getWindowScrollBarX(element);
        var x = element.clientWidth + borders.right;
        var y = element.clientHeight + borders.bottom; // HACK:
        // document.documentElement.clientHeight on iOS reports the height of the
        // viewport including the bottom bar, even if the bottom bar isn't visible.
        // If the difference between window innerHeight and html clientHeight is more
        // than 50, we assume it's a mobile bottom bar and ignore scrollbars.
        // * A 50px thick scrollbar is likely non-existent (macOS is 15px and Windows
        //   is about 17px)
        // * The mobile bar is 114px tall

        if (isHTML && win.innerHeight - element.clientHeight > 50) {
            y = win.innerHeight - borders.bottom;
        }

        return {
            top: isHTML ? 0 : element.clientTop,
            right: // RTL scrollbar (scrolling containers only)
                element.clientLeft > borders.left ? borders.right : // LTR scrollbar
                    isHTML ? win.innerWidth - x - winScrollBarX : element.offsetWidth - x,
            bottom: isHTML ? win.innerHeight - y : element.offsetHeight - y,
            left: isHTML ? winScrollBarX : element.clientLeft
        };
    }

    function contains(parent, child) {
        // $FlowFixMe: hasOwnProperty doesn't seem to work in tests
        var isShadow = Boolean(child.getRootNode && child.getRootNode().host); // First, attempt with faster native method

        if (parent.contains(child)) {
            return true;
        } // then fallback to custom implementation with Shadow DOM support
        else if (isShadow) {
            var next = child;

            do {
                if (next && parent.isSameNode(next)) {
                    return true;
                } // $FlowFixMe: need a better way to handle this...


                next = next.parentNode || next.host;
            } while (next);
        } // Give up, the result is false


        return false;
    }

    function rectToClientRect(rect) {
        return Object.assign({}, rect, {
            left: rect.x,
            top: rect.y,
            right: rect.x + rect.width,
            bottom: rect.y + rect.height
        });
    }

    function getClientRectFromMixedType(element, clippingParent) {
        return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
    } // A "clipping parent" is an overflowable container with the characteristic of
    // clipping (or hiding) overflowing elements with a position different from
    // `initial`


    function getClippingParents(element) {
        var clippingParents = listScrollParents(element);
        var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
        var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;

        if (!isElement(clipperElement)) {
            return [];
        } // $FlowFixMe: https://github.com/facebook/flow/issues/1414


        return clippingParents.filter(function (clippingParent) {
            return isElement(clippingParent) && contains(clippingParent, clipperElement);
        });
    } // Gets the maximum area that the element is visible in due to any number of
    // clipping parents


    function getClippingRect(element, boundary, rootBoundary) {
        var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
        var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
        var firstClippingParent = clippingParents[0];
        var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
            var rect = getClientRectFromMixedType(element, clippingParent);
            var decorations = getDecorations(isHTMLElement(clippingParent) ? clippingParent : getDocumentElement(element));
            accRect.top = Math.max(rect.top + decorations.top, accRect.top);
            accRect.right = Math.min(rect.right - decorations.right, accRect.right);
            accRect.bottom = Math.min(rect.bottom - decorations.bottom, accRect.bottom);
            accRect.left = Math.max(rect.left + decorations.left, accRect.left);
            return accRect;
        }, getClientRectFromMixedType(element, firstClippingParent));
        clippingRect.width = clippingRect.right - clippingRect.left;
        clippingRect.height = clippingRect.bottom - clippingRect.top;
        clippingRect.x = clippingRect.left;
        clippingRect.y = clippingRect.top;
        return clippingRect;
    }

    function getFreshSideObject() {
        return {
            top: 0,
            right: 0,
            bottom: 0,
            left: 0
        };
    }

    function mergePaddingObject(paddingObject) {
        return Object.assign({}, getFreshSideObject(), {}, paddingObject);
    }

    function expandToHashMap(value, keys) {
        return keys.reduce(function (hashMap, key) {
            hashMap[key] = value;
            return hashMap;
        }, {});
    }

    function detectOverflow(state, options) {
        if (options === void 0) {
            options = {};
        }

        var _options = options,
            _options$placement = _options.placement,
            placement = _options$placement === void 0 ? state.placement : _options$placement,
            _options$boundary = _options.boundary,
            boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
            _options$rootBoundary = _options.rootBoundary,
            rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
            _options$elementConte = _options.elementContext,
            elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
            _options$altBoundary = _options.altBoundary,
            altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
            _options$padding = _options.padding,
            padding = _options$padding === void 0 ? 0 : _options$padding;
        var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
        var altContext = elementContext === popper ? reference : popper;
        var referenceElement = state.elements.reference;
        var popperRect = state.rects.popper;
        var element = state.elements[altBoundary ? altContext : elementContext];
        var clippingClientRect = getClippingRect(isElement(element) ? element : getDocumentElement(state.elements.popper), boundary, rootBoundary);
        var referenceClientRect = getBoundingClientRect(referenceElement);
        var popperOffsets = computeOffsets({
            reference: referenceClientRect,
            element: popperRect,
            strategy: 'absolute',
            placement: placement
        });
        var popperClientRect = rectToClientRect(Object.assign({}, popperRect, {}, popperOffsets));
        var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
        // 0 or negative = within the clipping rect

        var overflowOffsets = {
            top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
            bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
            left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
            right: elementClientRect.right - clippingClientRect.right + paddingObject.right
        };
        var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element

        if (elementContext === popper && offsetData) {
            var offset = offsetData[placement];
            Object.keys(overflowOffsets).forEach(function (key) {
                var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
                var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
                overflowOffsets[key] += offset[axis] * multiply;
            });
        }

        return overflowOffsets;
    }

    function computeAutoPlacement(state, options) {
        if (options === void 0) {
            options = {};
        }

        var _options = options,
            placement = _options.placement,
            boundary = _options.boundary,
            rootBoundary = _options.rootBoundary,
            padding = _options.padding,
            flipVariations = _options.flipVariations;
        var variation = getVariation(placement);
        var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
            return getVariation(placement) === variation;
        }) : basePlacements; // $FlowFixMe: Flow seems to have problems with two array unions...

        var overflows = placements.reduce(function (acc, placement) {
            acc[placement] = detectOverflow(state, {
                placement: placement,
                boundary: boundary,
                rootBoundary: rootBoundary,
                padding: padding
            })[getBasePlacement(placement)];
            return acc;
        }, {});
        return Object.keys(overflows).sort(function (a, b) {
            return overflows[a] - overflows[b];
        });
    }

    function getExpandedFallbackPlacements(placement) {
        if (getBasePlacement(placement) === auto) {
            return [];
        }

        var oppositePlacement = getOppositePlacement(placement);
        return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
    }

    function flip(_ref) {
        var state = _ref.state,
            options = _ref.options,
            name = _ref.name;

        if (state.modifiersData[name]._skip) {
            return;
        }

        var specifiedFallbackPlacements = options.fallbackPlacements,
            padding = options.padding,
            boundary = options.boundary,
            rootBoundary = options.rootBoundary,
            _options$flipVariatio = options.flipVariations,
            flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio;
        var preferredPlacement = state.options.placement;
        var basePlacement = getBasePlacement(preferredPlacement);
        var isBasePlacement = basePlacement === preferredPlacement;
        var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
        var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
            return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
                placement: placement,
                boundary: boundary,
                rootBoundary: rootBoundary,
                padding: padding,
                flipVariations: flipVariations
            }) : placement);
        }, []);
        var referenceRect = state.rects.reference;
        var popperRect = state.rects.popper;
        var checksMap = new Map();
        var makeFallbackChecks = true;
        var firstFittingPlacement = placements[0];

        for (var i = 0; i < placements.length; i++) {
            var placement = placements[i];

            var _basePlacement = getBasePlacement(placement);

            var isStartVariation = getVariation(placement) === start;
            var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
            var len = isVertical ? 'width' : 'height';
            var overflow = detectOverflow(state, {
                placement: placement,
                boundary: boundary,
                rootBoundary: rootBoundary,
                padding: padding
            });
            var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;

            if (referenceRect[len] > popperRect[len]) {
                mainVariationSide = getOppositePlacement(mainVariationSide);
            }

            var altVariationSide = getOppositePlacement(mainVariationSide);
            var checks = [overflow[_basePlacement] <= 0, overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0];

            if (checks.every(function (check) {
                return check;
            })) {
                firstFittingPlacement = placement;
                makeFallbackChecks = false;
                break;
            }

            checksMap.set(placement, checks);
        }

        if (makeFallbackChecks) {
            // `2` may be desired in some cases – research later
            var numberOfChecks = flipVariations ? 3 : 1;

            var _loop = function _loop(_i) {
                var fittingPlacement = placements.find(function (placement) {
                    var checks = checksMap.get(placement);

                    if (checks) {
                        return checks.slice(0, _i).every(function (check) {
                            return check;
                        });
                    }
                });

                if (fittingPlacement) {
                    firstFittingPlacement = fittingPlacement;
                    return "break";
                }
            };

            for (var _i = numberOfChecks; _i > 0; _i--) {
                var _ret = _loop(_i);

                if (_ret === "break") break;
            }
        }

        if (state.placement !== firstFittingPlacement) {
            state.modifiersData[name]._skip = true;
            state.placement = firstFittingPlacement;
            state.reset = true;
        }
    }

    var flip$1 = {
        name: 'flip',
        enabled: true,
        phase: 'main',
        fn: flip,
        requiresIfExists: ['offset'],
        data: {
            _skip: false
        }
    };

    function getAltAxis(axis) {
        return axis === 'x' ? 'y' : 'x';
    }

    function within(min, value, max) {
        return Math.max(min, Math.min(value, max));
    }

    function preventOverflow(_ref) {
        var state = _ref.state,
            options = _ref.options,
            name = _ref.name;
        var _options$mainAxis = options.mainAxis,
            checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
            _options$altAxis = options.altAxis,
            checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
            boundary = options.boundary,
            rootBoundary = options.rootBoundary,
            padding = options.padding,
            _options$tether = options.tether,
            tether = _options$tether === void 0 ? true : _options$tether,
            _options$tetherOffset = options.tetherOffset,
            tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
        var overflow = detectOverflow(state, {
            boundary: boundary,
            rootBoundary: rootBoundary,
            padding: padding
        });
        var basePlacement = getBasePlacement(state.placement);
        var variation = getVariation(state.placement);
        var isBasePlacement = !variation;
        var mainAxis = getMainAxisFromPlacement(basePlacement);
        var altAxis = getAltAxis(mainAxis);
        var popperOffsets = state.modifiersData.popperOffsets;
        var referenceRect = state.rects.reference;
        var popperRect = state.rects.popper;
        var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
            placement: state.placement
        })) : tetherOffset;
        var data = {
            x: 0,
            y: 0
        };

        if (checkMainAxis) {
            var mainSide = mainAxis === 'y' ? top : left;
            var altSide = mainAxis === 'y' ? bottom : right;
            var len = mainAxis === 'y' ? 'height' : 'width';
            var offset = popperOffsets[mainAxis];
            var min = popperOffsets[mainAxis] + overflow[mainSide];
            var max = popperOffsets[mainAxis] - overflow[altSide];
            var additive = tether ? -popperRect[len] / 2 : 0;
            var minLen = variation === start ? referenceRect[len] : popperRect[len];
            var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
            // outside the reference bounds

            var arrowElement = state.elements.arrow;
            var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
                width: 0,
                height: 0
            };
            var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
            var arrowPaddingMin = arrowPaddingObject[mainSide];
            var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
            // to include its full size in the calculation. If the reference is small
            // and near the edge of a boundary, the popper can overflow even if the
            // reference is not overflowing as well (e.g. virtual elements with no
            // width or height)

            var arrowLen = within(0, referenceRect[len], arrowRect[len]);
            var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;
            var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;
            var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0;
            var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue;
            var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;
            var preventedOffset = within(tether ? Math.min(min, tetherMin) : min, offset, tether ? Math.max(max, tetherMax) : max);
            popperOffsets[mainAxis] = preventedOffset;
            data[mainAxis] = preventedOffset - offset;
        }

        if (checkAltAxis) {
            var _mainSide = mainAxis === 'x' ? top : left;

            var _altSide = mainAxis === 'x' ? bottom : right;

            var _offset = popperOffsets[altAxis];

            var _min = _offset + overflow[_mainSide];

            var _max = _offset - overflow[_altSide];

            var _preventedOffset = within(_min, _offset, _max);

            state.modifiersData.popperOffsets[altAxis] = _preventedOffset;
            data[altAxis] = _preventedOffset - _offset;
        }

        state.modifiersData[name] = data;
    }

    var preventOverflow$1 = {
        name: 'preventOverflow',
        enabled: true,
        phase: 'main',
        fn: preventOverflow,
        requiresIfExists: ['offset']
    };

    function arrow(_ref) {
        var _state$modifiersData$;

        var state = _ref.state,
            name = _ref.name;
        var arrowElement = state.elements.arrow;
        var popperOffsets = state.modifiersData.popperOffsets;
        var basePlacement = getBasePlacement(state.placement);
        var axis = getMainAxisFromPlacement(basePlacement);
        var isVertical = [left, right].indexOf(basePlacement) >= 0;
        var len = isVertical ? 'height' : 'width';

        if (!arrowElement) {
            return;
        }

        var paddingObject = state.modifiersData[name + "#persistent"].padding;
        var arrowRect = getLayoutRect(arrowElement);
        var minProp = axis === 'y' ? top : left;
        var maxProp = axis === 'y' ? bottom : right;
        var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
        var startDiff = popperOffsets[axis] - state.rects.reference[axis];
        var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
        // outside of the popper bounds

        var center = within(paddingObject[minProp], state.rects.popper[len] / 2 - arrowRect[len] / 2 + centerToReference, state.rects.popper[len] - arrowRect[len] - paddingObject[maxProp]); // Prevents breaking syntax highlighting...

        var axisProp = axis;
        state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = center, _state$modifiersData$);
    }

    function effect$2(_ref2) {
        var state = _ref2.state,
            options = _ref2.options,
            name = _ref2.name;
        var _options$element = options.element,
            arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element,
            _options$padding = options.padding,
            padding = _options$padding === void 0 ? 0 : _options$padding; // CSS selector

        if (typeof arrowElement === 'string') {
            arrowElement = state.elements.popper.querySelector(arrowElement);

            if (!arrowElement) {
                return;
            }
        }

        if (!contains(state.elements.popper, arrowElement)) {
            {
                console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' '));
            }

            return;
        }

        state.elements.arrow = arrowElement;
        state.modifiersData[name + "#persistent"] = {
            padding: mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements))
        };
    }

    var arrow$1 = {
        name: 'arrow',
        enabled: true,
        phase: 'main',
        fn: arrow,
        effect: effect$2,
        requires: ['popperOffsets'],
        requiresIfExists: ['preventOverflow']
    };

    function getSideOffsets(overflow, rect, preventedOffsets) {
        if (preventedOffsets === void 0) {
            preventedOffsets = {
                x: 0,
                y: 0
            };
        }

        return {
            top: overflow.top - rect.height - preventedOffsets.y,
            right: overflow.right - rect.width + preventedOffsets.x,
            bottom: overflow.bottom - rect.height + preventedOffsets.y,
            left: overflow.left - rect.width - preventedOffsets.x
        };
    }

    function isAnySideFullyClipped(overflow) {
        return [top, right, bottom, left].some(function (side) {
            return overflow[side] >= 0;
        });
    }

    function hide(_ref) {
        var state = _ref.state,
            name = _ref.name;
        var referenceRect = state.rects.reference;
        var popperRect = state.rects.popper;
        var preventedOffsets = state.modifiersData.preventOverflow;
        var referenceOverflow = detectOverflow(state, {
            elementContext: 'reference'
        });
        var popperAltOverflow = detectOverflow(state, {
            altBoundary: true
        });
        var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
        var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
        var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
        var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
        state.modifiersData[name] = {
            referenceClippingOffsets: referenceClippingOffsets,
            popperEscapeOffsets: popperEscapeOffsets,
            isReferenceHidden: isReferenceHidden,
            hasPopperEscaped: hasPopperEscaped
        };
        state.attributes.popper = Object.assign({}, state.attributes.popper, {
            'data-popper-reference-hidden': isReferenceHidden,
            'data-popper-escaped': hasPopperEscaped
        });
    }

    var hide$1 = {
        name: 'hide',
        enabled: true,
        phase: 'main',
        requiresIfExists: ['preventOverflow'],
        fn: hide
    };

    var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];
    var createPopper =
        /*#__PURE__*/
        popperGenerator({
            defaultModifiers: defaultModifiers
        }); // eslint-disable-next-line import/no-unused-modules

    exports.createPopper = createPopper;
    exports.defaultModifiers = defaultModifiers;
    exports.popperGenerator = popperGenerator;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=popper.js.map