/**
 * interact.js v1.3.4
 *
 * Copyright (c) 2012-2018 Taye Adeyemi <dev@taye.me>
 * Released under the MIT License.
 * https://raw.github.com/taye/interact.js/master/LICENSE
 */
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.interact = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
        'use strict';

        /*
 * In a (windowless) server environment this file exports a factory function
 * that takes the window to use.
 *
 *     var interact = require('interact.js')(windowObject);
 *
 * See https://github.com/taye/interact.js/issues/187
 */
        if (typeof window === 'undefined') {
            module.exports = function (window) {
                require('./src/utils/window').init(window);

                return require('./src/index');
            };
        } else {
            module.exports = require('./src/index');
        }

    },{"./src/index":19,"./src/utils/window":52}],2:[function(require,module,exports){
        'use strict';

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var extend = require('./utils/extend.js');

        function fireUntilImmediateStopped(event, listeners) {
            for (var _i = 0; _i < listeners.length; _i++) {
                var _ref;

                _ref = listeners[_i];
                var listener = _ref;

                if (event.immediatePropagationStopped) {
                    break;
                }

                listener(event);
            }
        }

        var Eventable = function () {
            function Eventable(options) {
                _classCallCheck(this, Eventable);

                this.options = extend({}, options || {});
            }

            Eventable.prototype.fire = function fire(event) {
                var listeners = void 0;
                var onEvent = 'on' + event.type;
                var global = this.global;

                // Interactable#on() listeners
                if (listeners = this[event.type]) {
                    fireUntilImmediateStopped(event, listeners);
                }

                // interactable.onevent listener
                if (this[onEvent]) {
                    this[onEvent](event);
                }

                // interact.on() listeners
                if (!event.propagationStopped && global && (listeners = global[event.type])) {
                    fireUntilImmediateStopped(event, listeners);
                }
            };

            Eventable.prototype.on = function on(eventType, listener) {
                // if this type of event was never bound
                if (this[eventType]) {
                    this[eventType].push(listener);
                } else {
                    this[eventType] = [listener];
                }
            };

            Eventable.prototype.off = function off(eventType, listener) {
                // if it is an action event type
                var eventList = this[eventType];
                var index = eventList ? eventList.indexOf(listener) : -1;

                if (index !== -1) {
                    eventList.splice(index, 1);
                }

                if (eventList && eventList.length === 0 || !listener) {
                    this[eventType] = undefined;
                }
            };

            return Eventable;
        }();

        module.exports = Eventable;

    },{"./utils/extend.js":41}],3:[function(require,module,exports){
        'use strict';

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var extend = require('./utils/extend');
        var getOriginXY = require('./utils/getOriginXY');
        var defaults = require('./defaultOptions');
        var signals = require('./utils/Signals').new();

        var InteractEvent = function () {
            /** */
            function InteractEvent(interaction, event, action, phase, element, related) {
                var preEnd = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;

                _classCallCheck(this, InteractEvent);

                var target = interaction.target;
                var deltaSource = (target && target.options || defaults).deltaSource;
                var origin = getOriginXY(target, element, action);
                var starting = phase === 'start';
                var ending = phase === 'end';
                var coords = starting ? interaction.startCoords : interaction.curCoords;
                var prevEvent = interaction.prevEvent;

                element = element || interaction.element;

                var page = extend({}, coords.page);
                var client = extend({}, coords.client);

                page.x -= origin.x;
                page.y -= origin.y;

                client.x -= origin.x;
                client.y -= origin.y;

                this.ctrlKey = event.ctrlKey;
                this.altKey = event.altKey;
                this.shiftKey = event.shiftKey;
                this.metaKey = event.metaKey;
                this.button = event.button;
                this.buttons = event.buttons;
                this.target = element;
                this.currentTarget = element;
                this.relatedTarget = related || null;
                this.preEnd = preEnd;
                this.type = action + (phase || '');
                this.interaction = interaction;
                this.interactable = target;

                this.t0 = starting ? interaction.downTimes[interaction.downTimes.length - 1] : prevEvent.t0;

                var signalArg = {
                    interaction: interaction,
                    event: event,
                    action: action,
                    phase: phase,
                    element: element,
                    related: related,
                    page: page,
                    client: client,
                    coords: coords,
                    starting: starting,
                    ending: ending,
                    deltaSource: deltaSource,
                    iEvent: this
                };

                signals.fire('set-xy', signalArg);

                if (ending) {
                    // use previous coords when ending
                    this.pageX = prevEvent.pageX;
                    this.pageY = prevEvent.pageY;
                    this.clientX = prevEvent.clientX;
                    this.clientY = prevEvent.clientY;
                } else {
                    this.pageX = page.x;
                    this.pageY = page.y;
                    this.clientX = client.x;
                    this.clientY = client.y;
                }

                this.x0 = interaction.startCoords.page.x - origin.x;
                this.y0 = interaction.startCoords.page.y - origin.y;
                this.clientX0 = interaction.startCoords.client.x - origin.x;
                this.clientY0 = interaction.startCoords.client.y - origin.y;

                signals.fire('set-delta', signalArg);

                this.timeStamp = coords.timeStamp;
                this.dt = interaction.pointerDelta.timeStamp;
                this.duration = this.timeStamp - this.t0;

                // speed and velocity in pixels per second
                this.speed = interaction.pointerDelta[deltaSource].speed;
                this.velocityX = interaction.pointerDelta[deltaSource].vx;
                this.velocityY = interaction.pointerDelta[deltaSource].vy;

                this.swipe = ending || phase === 'inertiastart' ? this.getSwipe() : null;

                signals.fire('new', signalArg);
            }

            InteractEvent.prototype.getSwipe = function getSwipe() {
                var interaction = this.interaction;

                if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {
                    return null;
                }

                var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;
                var overlap = 22.5;

                if (angle < 0) {
                    angle += 360;
                }

                var left = 135 - overlap <= angle && angle < 225 + overlap;
                var up = 225 - overlap <= angle && angle < 315 + overlap;

                var right = !left && (315 - overlap <= angle || angle < 45 + overlap);
                var down = !up && 45 - overlap <= angle && angle < 135 + overlap;

                return {
                    up: up,
                    down: down,
                    left: left,
                    right: right,
                    angle: angle,
                    speed: interaction.prevEvent.speed,
                    velocity: {
                        x: interaction.prevEvent.velocityX,
                        y: interaction.prevEvent.velocityY
                    }
                };
            };

            InteractEvent.prototype.preventDefault = function preventDefault() {};

            /** */


            InteractEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {
                this.immediatePropagationStopped = this.propagationStopped = true;
            };

            /** */


            InteractEvent.prototype.stopPropagation = function stopPropagation() {
                this.propagationStopped = true;
            };

            return InteractEvent;
        }();

        signals.on('set-delta', function (_ref) {
            var iEvent = _ref.iEvent,
                interaction = _ref.interaction,
                starting = _ref.starting,
                deltaSource = _ref.deltaSource;

            var prevEvent = starting ? iEvent : interaction.prevEvent;

            if (deltaSource === 'client') {
                iEvent.dx = iEvent.clientX - prevEvent.clientX;
                iEvent.dy = iEvent.clientY - prevEvent.clientY;
            } else {
                iEvent.dx = iEvent.pageX - prevEvent.pageX;
                iEvent.dy = iEvent.pageY - prevEvent.pageY;
            }
        });

        InteractEvent.signals = signals;

        module.exports = InteractEvent;

    },{"./defaultOptions":18,"./utils/Signals":34,"./utils/extend":41,"./utils/getOriginXY":42}],4:[function(require,module,exports){
        'use strict';

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var clone = require('./utils/clone');
        var is = require('./utils/is');
        var events = require('./utils/events');
        var extend = require('./utils/extend');
        var actions = require('./actions/base');
        var scope = require('./scope');
        var Eventable = require('./Eventable');
        var defaults = require('./defaultOptions');
        var signals = require('./utils/Signals').new();

        var _require = require('./utils/domUtils'),
            getElementRect = _require.getElementRect,
            nodeContains = _require.nodeContains,
            trySelector = _require.trySelector,
            matchesSelector = _require.matchesSelector;

        var _require2 = require('./utils/window'),
            getWindow = _require2.getWindow;

        var _require3 = require('./utils/arr'),
            contains = _require3.contains;

        var _require4 = require('./utils/browser'),
            wheelEvent = _require4.wheelEvent;

// all set interactables


        scope.interactables = [];

        var Interactable = function () {
            /** */
            function Interactable(target, options) {
                _classCallCheck(this, Interactable);

                options = options || {};

                this.target = target;
                this.events = new Eventable();
                this._context = options.context || scope.document;
                this._win = getWindow(trySelector(target) ? this._context : target);
                this._doc = this._win.document;

                signals.fire('new', {
                    target: target,
                    options: options,
                    interactable: this,
                    win: this._win
                });

                scope.addDocument(this._doc, this._win);

                scope.interactables.push(this);

                this.set(options);
            }

            Interactable.prototype.setOnEvents = function setOnEvents(action, phases) {
                var onAction = 'on' + action;

                if (is.function(phases.onstart)) {
                    this.events[onAction + 'start'] = phases.onstart;
                }
                if (is.function(phases.onmove)) {
                    this.events[onAction + 'move'] = phases.onmove;
                }
                if (is.function(phases.onend)) {
                    this.events[onAction + 'end'] = phases.onend;
                }
                if (is.function(phases.oninertiastart)) {
                    this.events[onAction + 'inertiastart'] = phases.oninertiastart;
                }

                return this;
            };

            Interactable.prototype.setPerAction = function setPerAction(action, options) {
                // for all the default per-action options
                for (var option in options) {
                    // if this option exists for this action
                    if (option in defaults[action]) {
                        // if the option in the options arg is an object value
                        if (is.object(options[option])) {
                            // duplicate the object and merge
                            this.options[action][option] = clone(this.options[action][option] || {});
                            extend(this.options[action][option], options[option]);

                            if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {
                                this.options[action][option].enabled = options[option].enabled === false ? false : true;
                            }
                        } else if (is.bool(options[option]) && is.object(defaults.perAction[option])) {
                            this.options[action][option].enabled = options[option];
                        } else if (options[option] !== undefined) {
                            // or if it's not undefined, do a plain assignment
                            this.options[action][option] = options[option];
                        }
                    }
                }
            };

            /**
             * The default function to get an Interactables bounding rect. Can be
             * overridden using {@link Interactable.rectChecker}.
             *
             * @param {Element} [element] The element to measure.
             * @return {object} The object's bounding rectangle.
             */


            Interactable.prototype.getRect = function getRect(element) {
                element = element || this.target;

                if (is.string(this.target) && !is.element(element)) {
                    element = this._context.querySelector(this.target);
                }

                return getElementRect(element);
            };

            /**
             * Returns or sets the function used to calculate the interactable's
             * element's rectangle
             *
             * @param {function} [checker] A function which returns this Interactable's
             * bounding rectangle. See {@link Interactable.getRect}
             * @return {function | object} The checker function or this Interactable
             */


            Interactable.prototype.rectChecker = function rectChecker(checker) {
                if (is.function(checker)) {
                    this.getRect = checker;

                    return this;
                }

                if (checker === null) {
                    delete this.options.getRect;

                    return this;
                }

                return this.getRect;
            };

            Interactable.prototype._backCompatOption = function _backCompatOption(optionName, newValue) {
                if (trySelector(newValue) || is.object(newValue)) {
                    this.options[optionName] = newValue;

                    for (var _i = 0; _i < actions.names.length; _i++) {
                        var _ref;

                        _ref = actions.names[_i];
                        var action = _ref;

                        this.options[action][optionName] = newValue;
                    }

                    return this;
                }

                return this.options[optionName];
            };

            /**
             * Gets or sets the origin of the Interactable's element.  The x and y
             * of the origin will be subtracted from action event coordinates.
             *
             * @param {Element | object | string} [origin] An HTML or SVG Element whose
             * rect will be used, an object eg. { x: 0, y: 0 } or string 'parent', 'self'
             * or any CSS selector
             *
             * @return {object} The current origin or this Interactable
             */


            Interactable.prototype.origin = function origin(newValue) {
                return this._backCompatOption('origin', newValue);
            };

            /**
             * Returns or sets the mouse coordinate types used to calculate the
             * movement of the pointer.
             *
             * @param {string} [newValue] Use 'client' if you will be scrolling while
             * interacting; Use 'page' if you want autoScroll to work
             * @return {string | object} The current deltaSource or this Interactable
             */


            Interactable.prototype.deltaSource = function deltaSource(newValue) {
                if (newValue === 'page' || newValue === 'client') {
                    this.options.deltaSource = newValue;

                    return this;
                }

                return this.options.deltaSource;
            };

            /**
             * Gets the selector context Node of the Interactable. The default is
             * `window.document`.
             *
             * @return {Node} The context Node of this Interactable
             */


            Interactable.prototype.context = function context() {
                return this._context;
            };

            Interactable.prototype.inContext = function inContext(element) {
                return this._context === element.ownerDocument || nodeContains(this._context, element);
            };

            /**
             * Calls listeners for the given InteractEvent type bound globally
             * and directly to this Interactable
             *
             * @param {InteractEvent} iEvent The InteractEvent object to be fired on this
             * Interactable
             * @return {Interactable} this Interactable
             */


            Interactable.prototype.fire = function fire(iEvent) {
                this.events.fire(iEvent);

                return this;
            };

            Interactable.prototype._onOffMultiple = function _onOffMultiple(method, eventType, listener, options) {
                if (is.string(eventType) && eventType.search(' ') !== -1) {
                    eventType = eventType.trim().split(/ +/);
                }

                if (is.array(eventType)) {
                    for (var _i2 = 0; _i2 < eventType.length; _i2++) {
                        var _ref2;

                        _ref2 = eventType[_i2];
                        var type = _ref2;

                        this[method](type, listener, options);
                    }

                    return true;
                }

                if (is.object(eventType)) {
                    for (var prop in eventType) {
                        this[method](prop, eventType[prop], listener);
                    }

                    return true;
                }
            };

            /**
             * Binds a listener for an InteractEvent, pointerEvent or DOM event.
             *
             * @param {string | array | object} eventType  The types of events to listen
             * for
             * @param {function} listener   The function event (s)
             * @param {object | boolean} [options]    options object or useCapture flag
             * for addEventListener
             * @return {object} This Interactable
             */


            Interactable.prototype.on = function on(eventType, listener, options) {
                if (this._onOffMultiple('on', eventType, listener, options)) {
                    return this;
                }

                if (eventType === 'wheel') {
                    eventType = wheelEvent;
                }

                if (contains(Interactable.eventTypes, eventType)) {
                    this.events.on(eventType, listener);
                }
                // delegated event for selector
                else if (is.string(this.target)) {
                    events.addDelegate(this.target, this._context, eventType, listener, options);
                } else {
                    events.add(this.target, eventType, listener, options);
                }

                return this;
            };

            /**
             * Removes an InteractEvent, pointerEvent or DOM event listener
             *
             * @param {string | array | object} eventType The types of events that were
             * listened for
             * @param {function} listener The listener function to be removed
             * @param {object | boolean} [options] options object or useCapture flag for
             * removeEventListener
             * @return {object} This Interactable
             */


            Interactable.prototype.off = function off(eventType, listener, options) {
                if (this._onOffMultiple('off', eventType, listener, options)) {
                    return this;
                }

                if (eventType === 'wheel') {
                    eventType = wheelEvent;
                }

                // if it is an action event type
                if (contains(Interactable.eventTypes, eventType)) {
                    this.events.off(eventType, listener);
                }
                // delegated event
                else if (is.string(this.target)) {
                    events.removeDelegate(this.target, this._context, eventType, listener, options);
                }
                // remove listener from this Interatable's element
                else {
                    events.remove(this.target, eventType, listener, options);
                }

                return this;
            };

            /**
             * Reset the options of this Interactable
             *
             * @param {object} options The new settings to apply
             * @return {object} This Interactable
             */


            Interactable.prototype.set = function set(options) {
                if (!is.object(options)) {
                    options = {};
                }

                this.options = clone(defaults.base);

                var perActions = clone(defaults.perAction);

                for (var actionName in actions.methodDict) {
                    var methodName = actions.methodDict[actionName];

                    this.options[actionName] = clone(defaults[actionName]);

                    this.setPerAction(actionName, perActions);

                    this[methodName](options[actionName]);
                }

                for (var _i3 = 0; _i3 < Interactable.settingsMethods.length; _i3++) {
                    var _ref3;

                    _ref3 = Interactable.settingsMethods[_i3];
                    var setting = _ref3;

                    this.options[setting] = defaults.base[setting];

                    if (setting in options) {
                        this[setting](options[setting]);
                    }
                }

                signals.fire('set', {
                    options: options,
                    interactable: this
                });

                return this;
            };

            /**
             * Remove this interactable from the list of interactables and remove it's
             * action capabilities and event listeners
             *
             * @return {interact}
             */


            Interactable.prototype.unset = function unset() {
                events.remove(this.target, 'all');

                if (is.string(this.target)) {
                    // remove delegated events
                    for (var type in events.delegatedEvents) {
                        var delegated = events.delegatedEvents[type];

                        if (delegated.selectors[0] === this.target && delegated.contexts[0] === this._context) {

                            delegated.selectors.splice(0, 1);
                            delegated.contexts.splice(0, 1);
                            delegated.listeners.splice(0, 1);

                            // remove the arrays if they are empty
                            if (!delegated.selectors.length) {
                                delegated[type] = null;
                            }
                        }

                        events.remove(this._context, type, events.delegateListener);
                        events.remove(this._context, type, events.delegateUseCapture, true);
                    }
                } else {
                    events.remove(this, 'all');
                }

                signals.fire('unset', { interactable: this });

                scope.interactables.splice(scope.interactables.indexOf(this), 1);

                // Stop related interactions when an Interactable is unset
                for (var _i4 = 0; _i4 < (scope.interactions || []).length; _i4++) {
                    var _ref4;

                    _ref4 = (scope.interactions || [])[_i4];
                    var interaction = _ref4;

                    if (interaction.target === this && interaction.interacting() && !interaction._ending) {
                        interaction.stop();
                    }
                }

                return scope.interact;
            };

            return Interactable;
        }();

        scope.interactables.indexOfElement = function indexOfElement(target, context) {
            context = context || scope.document;

            for (var i = 0; i < this.length; i++) {
                var interactable = this[i];

                if (interactable.target === target && interactable._context === context) {
                    return i;
                }
            }
            return -1;
        };

        scope.interactables.get = function interactableGet(element, options, dontCheckInContext) {
            var ret = this[this.indexOfElement(element, options && options.context)];

            return ret && (is.string(element) || dontCheckInContext || ret.inContext(element)) ? ret : null;
        };

        scope.interactables.forEachMatch = function (element, callback) {
            for (var _i5 = 0; _i5 < this.length; _i5++) {
                var _ref5;

                _ref5 = this[_i5];
                var interactable = _ref5;

                var ret = void 0;

                if ((is.string(interactable.target)
                    // target is a selector and the element matches
                    ? is.element(element) && matchesSelector(element, interactable.target) :
                    // target is the element
                    element === interactable.target) &&
                    // the element is in context
                    interactable.inContext(element)) {
                    ret = callback(interactable);
                }

                if (ret !== undefined) {
                    return ret;
                }
            }
        };

// all interact.js eventTypes
        Interactable.eventTypes = scope.eventTypes = [];

        Interactable.signals = signals;

        Interactable.settingsMethods = ['deltaSource', 'origin', 'preventDefault', 'rectChecker'];

        module.exports = Interactable;

    },{"./Eventable":2,"./actions/base":6,"./defaultOptions":18,"./scope":33,"./utils/Signals":34,"./utils/arr":35,"./utils/browser":36,"./utils/clone":37,"./utils/domUtils":39,"./utils/events":40,"./utils/extend":41,"./utils/is":46,"./utils/window":52}],5:[function(require,module,exports){
        'use strict';

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var scope = require('./scope');
        var utils = require('./utils');
        var events = require('./utils/events');
        var browser = require('./utils/browser');
        var domObjects = require('./utils/domObjects');
        var finder = require('./utils/interactionFinder');
        var signals = require('./utils/Signals').new();

        var listeners = {};
        var methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer'];

// for ignoring browser's simulated mouse events
        var prevTouchTime = 0;

// all active and idle interactions
        scope.interactions = [];

        var Interaction = function () {
            /** */
            function Interaction(_ref) {
                var pointerType = _ref.pointerType;

                _classCallCheck(this, Interaction);

                this.target = null; // current interactable being interacted with
                this.element = null; // the target element of the interactable

                this.prepared = { // action that's ready to be fired on next move event
                    name: null,
                    axis: null,
                    edges: null
                };

                // keep track of added pointers
                this.pointers = [];
                this.pointerIds = [];
                this.downTargets = [];
                this.downTimes = [];

                // Previous native pointer move event coordinates
                this.prevCoords = {
                    page: { x: 0, y: 0 },
                    client: { x: 0, y: 0 },
                    timeStamp: 0
                };
                // current native pointer move event coordinates
                this.curCoords = {
                    page: { x: 0, y: 0 },
                    client: { x: 0, y: 0 },
                    timeStamp: 0
                };

                // Starting InteractEvent pointer coordinates
                this.startCoords = {
                    page: { x: 0, y: 0 },
                    client: { x: 0, y: 0 },
                    timeStamp: 0
                };

                // Change in coordinates and time of the pointer
                this.pointerDelta = {
                    page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },
                    client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },
                    timeStamp: 0
                };

                this.downEvent = null; // pointerdown/mousedown/touchstart event
                this.downPointer = {};

                this._eventTarget = null;
                this._curEventTarget = null;

                this.prevEvent = null; // previous action event

                this.pointerIsDown = false;
                this.pointerWasMoved = false;
                this._interacting = false;
                this._ending = false;

                this.pointerType = pointerType;

                signals.fire('new', this);

                scope.interactions.push(this);
            }

            Interaction.prototype.pointerDown = function pointerDown(pointer, event, eventTarget) {
                var pointerIndex = this.updatePointer(pointer, event, true);

                signals.fire('down', {
                    pointer: pointer,
                    event: event,
                    eventTarget: eventTarget,
                    pointerIndex: pointerIndex,
                    interaction: this
                });
            };

            /**
             * ```js
             * interact(target)
             *   .draggable({
   *     // disable the default drag start by down->move
   *     manualStart: true
   *   })
             *   // start dragging after the user holds the pointer down
             *   .on('hold', function (event) {
   *     var interaction = event.interaction;
   *
   *     if (!interaction.interacting()) {
   *       interaction.start({ name: 'drag' },
   *                         event.interactable,
   *                         event.currentTarget);
   *     }
   * });
             * ```
             *
             * Start an action with the given Interactable and Element as tartgets. The
             * action must be enabled for the target Interactable and an appropriate
             * number of pointers must be held down - 1 for drag/resize, 2 for gesture.
             *
             * Use it with `interactable.<action>able({ manualStart: false })` to always
             * [start actions manually](https://github.com/taye/interact.js/issues/114)
             *
             * @param {object} action   The action to be performed - drag, resize, etc.
             * @param {Interactable} target  The Interactable to target
             * @param {Element} element The DOM Element to target
             * @return {object} interact
             */


            Interaction.prototype.start = function start(action, target, element) {
                if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {
                    return;
                }

                // if this interaction had been removed after stopping
                // add it back
                if (scope.interactions.indexOf(this) === -1) {
                    scope.interactions.push(this);
                }

                utils.copyAction(this.prepared, action);
                this.target = target;
                this.element = element;

                signals.fire('action-start', {
                    interaction: this,
                    event: this.downEvent
                });
            };

            Interaction.prototype.pointerMove = function pointerMove(pointer, event, eventTarget) {
                if (!this.simulation) {
                    this.updatePointer(pointer);
                    utils.setCoords(this.curCoords, this.pointers);
                }

                var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;

                var dx = void 0;
                var dy = void 0;

                // register movement greater than pointerMoveTolerance
                if (this.pointerIsDown && !this.pointerWasMoved) {
                    dx = this.curCoords.client.x - this.startCoords.client.x;
                    dy = this.curCoords.client.y - this.startCoords.client.y;

                    this.pointerWasMoved = utils.hypot(dx, dy) > Interaction.pointerMoveTolerance;
                }

                var signalArg = {
                    pointer: pointer,
                    pointerIndex: this.getPointerIndex(pointer),
                    event: event,
                    eventTarget: eventTarget,
                    dx: dx,
                    dy: dy,
                    duplicate: duplicateMove,
                    interaction: this,
                    interactingBeforeMove: this.interacting()
                };

                if (!duplicateMove) {
                    // set pointer coordinate, time changes and speeds
                    utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);
                }

                signals.fire('move', signalArg);

                if (!duplicateMove) {
                    // if interacting, fire an 'action-move' signal etc
                    if (this.interacting()) {
                        this.doMove(signalArg);
                    }

                    if (this.pointerWasMoved) {
                        utils.copyCoords(this.prevCoords, this.curCoords);
                    }
                }
            };

            /**
             * ```js
             * interact(target)
             *   .draggable(true)
             *   .on('dragmove', function (event) {
   *     if (someCondition) {
   *       // change the snap settings
   *       event.interactable.draggable({ snap: { targets: [] }});
   *       // fire another move event with re-calculated snap
   *       event.interaction.doMove();
   *     }
   *   });
             * ```
             *
             * Force a move of the current action at the same coordinates. Useful if
             * snap/restrict has been changed and you want a movement with the new
             * settings.
             */


            Interaction.prototype.doMove = function doMove(signalArg) {
                signalArg = utils.extend({
                    pointer: this.pointers[0],
                    event: this.prevEvent,
                    eventTarget: this._eventTarget,
                    interaction: this
                }, signalArg || {});

                signals.fire('before-action-move', signalArg);

                if (!this._dontFireMove) {
                    signals.fire('action-move', signalArg);
                }

                this._dontFireMove = false;
            };

            // End interact move events and stop auto-scroll unless simulation is running


            Interaction.prototype.pointerUp = function pointerUp(pointer, event, eventTarget, curEventTarget) {
                var pointerIndex = this.getPointerIndex(pointer);

                signals.fire(/cancel$/i.test(event.type) ? 'cancel' : 'up', {
                    pointer: pointer,
                    pointerIndex: pointerIndex,
                    event: event,
                    eventTarget: eventTarget,
                    curEventTarget: curEventTarget,
                    interaction: this
                });

                if (!this.simulation) {
                    this.end(event);
                }

                this.pointerIsDown = false;
                this.removePointer(pointer, event);
            };

            /**
             * ```js
             * interact(target)
             *   .draggable(true)
             *   .on('move', function (event) {
   *     if (event.pageX > 1000) {
   *       // end the current action
   *       event.interaction.end();
   *       // stop all further listeners from being called
   *       event.stopImmediatePropagation();
   *     }
   *   });
             * ```
             *
             * Stop the current action and fire an end event. Inertial movement does
             * not happen.
             *
             * @param {PointerEvent} [event]
             */


            Interaction.prototype.end = function end(event) {
                this._ending = true;

                event = event || this.prevEvent;

                if (this.interacting()) {
                    signals.fire('action-end', {
                        event: event,
                        interaction: this
                    });
                }

                this.stop();
                this._ending = false;
            };

            Interaction.prototype.currentAction = function currentAction() {
                return this._interacting ? this.prepared.name : null;
            };

            Interaction.prototype.interacting = function interacting() {
                return this._interacting;
            };

            /** */


            Interaction.prototype.stop = function stop() {
                signals.fire('stop', { interaction: this });

                if (this._interacting) {
                    signals.fire('stop-active', { interaction: this });
                    signals.fire('stop-' + this.prepared.name, { interaction: this });
                }

                this.target = this.element = null;

                this._interacting = false;
                this.prepared.name = this.prevEvent = null;
            };

            Interaction.prototype.getPointerIndex = function getPointerIndex(pointer) {
                // mouse and pen interactions may have only one pointer
                if (this.pointerType === 'mouse' || this.pointerType === 'pen') {
                    return 0;
                }

                return this.pointerIds.indexOf(utils.getPointerId(pointer));
            };

            Interaction.prototype.updatePointer = function updatePointer(pointer, event) {
                var down = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : event && /(down|start)$/i.test(event.type);

                var id = utils.getPointerId(pointer);
                var index = this.getPointerIndex(pointer);

                if (index === -1) {
                    index = this.pointerIds.length;
                    this.pointerIds[index] = id;
                }

                if (down) {
                    signals.fire('update-pointer-down', {
                        pointer: pointer,
                        event: event,
                        down: down,
                        pointerId: id,
                        pointerIndex: index,
                        interaction: this
                    });
                }

                this.pointers[index] = pointer;

                return index;
            };

            Interaction.prototype.removePointer = function removePointer(pointer, event) {
                var index = this.getPointerIndex(pointer);

                if (index === -1) {
                    return;
                }

                signals.fire('remove-pointer', {
                    pointer: pointer,
                    event: event,
                    pointerIndex: index,
                    interaction: this
                });

                this.pointers.splice(index, 1);
                this.pointerIds.splice(index, 1);
                this.downTargets.splice(index, 1);
                this.downTimes.splice(index, 1);
            };

            Interaction.prototype._updateEventTargets = function _updateEventTargets(target, currentTarget) {
                this._eventTarget = target;
                this._curEventTarget = currentTarget;
            };

            return Interaction;
        }();

        for (var _i = 0; _i < methodNames.length; _i++) {
            var method = methodNames[_i];
            listeners[method] = doOnInteractions(method);
        }

        function doOnInteractions(method) {
            return function (event) {
                var pointerType = utils.getPointerType(event);

                var _utils$getEventTarget = utils.getEventTargets(event),
                    eventTarget = _utils$getEventTarget[0],
                    curEventTarget = _utils$getEventTarget[1];

                var matches = []; // [ [pointer, interaction], ...]

                if (browser.supportsTouch && /touch/.test(event.type)) {
                    prevTouchTime = new Date().getTime();

                    for (var _i2 = 0; _i2 < event.changedTouches.length; _i2++) {
                        var _ref2;

                        _ref2 = event.changedTouches[_i2];
                        var changedTouch = _ref2;

                        var pointer = changedTouch;
                        var interaction = finder.search(pointer, event.type, eventTarget);

                        matches.push([pointer, interaction || new Interaction({ pointerType: pointerType })]);
                    }
                } else {
                    var invalidPointer = false;

                    if (!browser.supportsPointerEvent && /mouse/.test(event.type)) {
                        // ignore mouse events while touch interactions are active
                        for (var i = 0; i < scope.interactions.length && !invalidPointer; i++) {
                            invalidPointer = scope.interactions[i].pointerType !== 'mouse' && scope.interactions[i].pointerIsDown;
                        }

                        // try to ignore mouse events that are simulated by the browser
                        // after a touch event
                        invalidPointer = invalidPointer || new Date().getTime() - prevTouchTime < 500
                            // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated
                            || event.timeStamp === 0;
                    }

                    if (!invalidPointer) {
                        var _interaction = finder.search(event, event.type, eventTarget);

                        if (!_interaction) {
                            _interaction = new Interaction({ pointerType: pointerType });
                        }

                        matches.push([event, _interaction]);
                    }
                }

                for (var _i3 = 0; _i3 < matches.length; _i3++) {
                    var _ref3 = matches[_i3];
                    var _pointer = _ref3[0];
                    var _interaction2 = _ref3[1];

                    _interaction2._updateEventTargets(eventTarget, curEventTarget);
                    _interaction2[method](_pointer, event, eventTarget, curEventTarget);
                }
            };
        }

        function endAll(event) {
            for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {
                var _ref4;

                _ref4 = scope.interactions[_i4];
                var interaction = _ref4;

                interaction.end(event);
                signals.fire('endall', { event: event, interaction: interaction });
            }
        }

        var docEvents = {/* 'eventType': listenerFunc */};
        var pEventTypes = browser.pEventTypes;

        if (domObjects.PointerEvent) {
            docEvents[pEventTypes.down] = listeners.pointerDown;
            docEvents[pEventTypes.move] = listeners.pointerMove;
            docEvents[pEventTypes.up] = listeners.pointerUp;
            docEvents[pEventTypes.cancel] = listeners.pointerUp;
        } else {
            docEvents.mousedown = listeners.pointerDown;
            docEvents.mousemove = listeners.pointerMove;
            docEvents.mouseup = listeners.pointerUp;

            docEvents.touchstart = listeners.pointerDown;
            docEvents.touchmove = listeners.pointerMove;
            docEvents.touchend = listeners.pointerUp;
            docEvents.touchcancel = listeners.pointerUp;
        }

        docEvents.blur = endAll;

        function onDocSignal(_ref5, signalName) {
            var doc = _ref5.doc;

            var eventMethod = signalName.indexOf('add') === 0 ? events.add : events.remove;

            // delegate event listener
            for (var eventType in scope.delegatedEvents) {
                eventMethod(doc, eventType, events.delegateListener);
                eventMethod(doc, eventType, events.delegateUseCapture, true);
            }

            for (var _eventType in docEvents) {
                eventMethod(doc, _eventType, docEvents[_eventType], browser.isIOS ? { passive: false } : undefined);
            }
        }

        signals.on('update-pointer-down', function (_ref6) {
            var interaction = _ref6.interaction,
                pointer = _ref6.pointer,
                pointerId = _ref6.pointerId,
                pointerIndex = _ref6.pointerIndex,
                event = _ref6.event,
                eventTarget = _ref6.eventTarget,
                down = _ref6.down;

            interaction.pointerIds[pointerIndex] = pointerId;
            interaction.pointers[pointerIndex] = pointer;

            if (down) {
                interaction.pointerIsDown = true;
            }

            if (!interaction.interacting()) {
                utils.setCoords(interaction.startCoords, interaction.pointers);

                utils.copyCoords(interaction.curCoords, interaction.startCoords);
                utils.copyCoords(interaction.prevCoords, interaction.startCoords);

                interaction.downEvent = event;
                interaction.downTimes[pointerIndex] = interaction.curCoords.timeStamp;
                interaction.downTargets[pointerIndex] = eventTarget || event && utils.getEventTargets(event)[0];
                interaction.pointerWasMoved = false;

                utils.pointerExtend(interaction.downPointer, pointer);
            }
        });

        scope.signals.on('add-document', onDocSignal);
        scope.signals.on('remove-document', onDocSignal);

        Interaction.pointerMoveTolerance = 1;
        Interaction.doOnInteractions = doOnInteractions;
        Interaction.endAll = endAll;
        Interaction.signals = signals;
        Interaction.docEvents = docEvents;

        scope.endAllInteractions = endAll;

        module.exports = Interaction;

    },{"./scope":33,"./utils":44,"./utils/Signals":34,"./utils/browser":36,"./utils/domObjects":38,"./utils/events":40,"./utils/interactionFinder":45}],6:[function(require,module,exports){
        'use strict';

        var Interaction = require('../Interaction');
        var InteractEvent = require('../InteractEvent');

        var actions = {
            firePrepared: firePrepared,
            names: [],
            methodDict: {}
        };

        Interaction.signals.on('action-start', function (_ref) {
            var interaction = _ref.interaction,
                event = _ref.event;

            interaction._interacting = true;
            firePrepared(interaction, event, 'start');
        });

        Interaction.signals.on('action-move', function (_ref2) {
            var interaction = _ref2.interaction,
                event = _ref2.event,
                preEnd = _ref2.preEnd;

            firePrepared(interaction, event, 'move', preEnd);

            // if the action was ended in a listener
            if (!interaction.interacting()) {
                return false;
            }
        });

        Interaction.signals.on('action-end', function (_ref3) {
            var interaction = _ref3.interaction,
                event = _ref3.event;

            firePrepared(interaction, event, 'end');
        });

        function firePrepared(interaction, event, phase, preEnd) {
            var actionName = interaction.prepared.name;

            var newEvent = new InteractEvent(interaction, event, actionName, phase, interaction.element, null, preEnd);

            interaction.target.fire(newEvent);
            interaction.prevEvent = newEvent;
        }

        module.exports = actions;

    },{"../InteractEvent":3,"../Interaction":5}],7:[function(require,module,exports){
        'use strict';

        var actions = require('./base');
        var utils = require('../utils');
        var InteractEvent = require('../InteractEvent');
        /** @lends Interactable */
        var Interactable = require('../Interactable');
        var Interaction = require('../Interaction');
        var defaultOptions = require('../defaultOptions');

        var drag = {
            defaults: {
                enabled: false,
                mouseButtons: null,

                origin: null,
                snap: null,
                restrict: null,
                inertia: null,
                autoScroll: null,

                startAxis: 'xy',
                lockAxis: 'xy'
            },

            checker: function checker(pointer, event, interactable) {
                var dragOptions = interactable.options.drag;

                return dragOptions.enabled ? { name: 'drag', axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis } : null;
            },

            getCursor: function getCursor() {
                return 'move';
            }
        };

        Interaction.signals.on('before-action-move', function (_ref) {
            var interaction = _ref.interaction;

            if (interaction.prepared.name !== 'drag') {
                return;
            }

            var axis = interaction.prepared.axis;

            if (axis === 'x') {
                interaction.curCoords.page.y = interaction.startCoords.page.y;
                interaction.curCoords.client.y = interaction.startCoords.client.y;

                interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);
                interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);
                interaction.pointerDelta.client.vy = 0;
                interaction.pointerDelta.page.vy = 0;
            } else if (axis === 'y') {
                interaction.curCoords.page.x = interaction.startCoords.page.x;
                interaction.curCoords.client.x = interaction.startCoords.client.x;

                interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);
                interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);
                interaction.pointerDelta.client.vx = 0;
                interaction.pointerDelta.page.vx = 0;
            }
        });

// dragmove
        InteractEvent.signals.on('new', function (_ref2) {
            var iEvent = _ref2.iEvent,
                interaction = _ref2.interaction;

            if (iEvent.type !== 'dragmove') {
                return;
            }

            var axis = interaction.prepared.axis;

            if (axis === 'x') {
                iEvent.pageY = interaction.startCoords.page.y;
                iEvent.clientY = interaction.startCoords.client.y;
                iEvent.dy = 0;
            } else if (axis === 'y') {
                iEvent.pageX = interaction.startCoords.page.x;
                iEvent.clientX = interaction.startCoords.client.x;
                iEvent.dx = 0;
            }
        });

        /**
         * ```js
         * interact(element).draggable({
 *     onstart: function (event) {},
 *     onmove : function (event) {},
 *     onend  : function (event) {},
 *
 *     // the axis in which the first movement must be
 *     // for the drag sequence to start
 *     // 'xy' by default - any direction
 *     startAxis: 'x' || 'y' || 'xy',
 *
 *     // 'xy' by default - don't restrict to one axis (move in any direction)
 *     // 'x' or 'y' to restrict movement to either axis
 *     // 'start' to restrict movement to the axis the drag started in
 *     lockAxis: 'x' || 'y' || 'xy' || 'start',
 *
 *     // max number of drags that can happen concurrently
 *     // with elements of this Interactable. Infinity by default
 *     max: Infinity,
 *
 *     // max number of drags that can target the same element+Interactable
 *     // 1 by default
 *     maxPerElement: 2
 * });
         *
         * var isDraggable = interact('element').draggable(); // true
         * ```
         *
         * Get or set whether drag actions can be performed on the target
         *
         * @param {boolean | object} [options] true/false or An object with event
         * listeners to be fired on drag events (object makes the Interactable
         * draggable)
         * @return {boolean | Interactable} boolean indicating if this can be the
         * target of drag events, or this Interctable
         */
        Interactable.prototype.draggable = function (options) {
            if (utils.is.object(options)) {
                this.options.drag.enabled = options.enabled === false ? false : true;
                this.setPerAction('drag', options);
                this.setOnEvents('drag', options);

                if (/^(xy|x|y|start)$/.test(options.lockAxis)) {
                    this.options.drag.lockAxis = options.lockAxis;
                }
                if (/^(xy|x|y)$/.test(options.startAxis)) {
                    this.options.drag.startAxis = options.startAxis;
                }

                return this;
            }

            if (utils.is.bool(options)) {
                this.options.drag.enabled = options;

                if (!options) {
                    this.ondragstart = this.ondragstart = this.ondragend = null;
                }

                return this;
            }

            return this.options.drag;
        };

        actions.drag = drag;
        actions.names.push('drag');
        utils.merge(Interactable.eventTypes, ['dragstart', 'dragmove', 'draginertiastart', 'draginertiaresume', 'dragend']);
        actions.methodDict.drag = 'draggable';

        defaultOptions.drag = drag.defaults;

        module.exports = drag;

    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"./base":6}],8:[function(require,module,exports){
        'use strict';

        var actions = require('./base');
        var utils = require('../utils');
        var scope = require('../scope');
        /** @lends module:interact */
        var interact = require('../interact');
        var InteractEvent = require('../InteractEvent');
        /** @lends Interactable */
        var Interactable = require('../Interactable');
        var Interaction = require('../Interaction');
        var defaultOptions = require('../defaultOptions');

        var drop = {
            defaults: {
                enabled: false,
                accept: null,
                overlap: 'pointer'
            }
        };

        var dynamicDrop = false;

        Interaction.signals.on('action-start', function (_ref) {
            var interaction = _ref.interaction,
                event = _ref.event;

            if (interaction.prepared.name !== 'drag') {
                return;
            }

            // reset active dropzones
            interaction.activeDrops.dropzones = [];
            interaction.activeDrops.elements = [];
            interaction.activeDrops.rects = [];

            interaction.dropEvents = null;

            if (!interaction.dynamicDrop) {
                setActiveDrops(interaction.activeDrops, interaction.element);
            }

            var dragEvent = interaction.prevEvent;
            var dropEvents = getDropEvents(interaction, event, dragEvent);

            if (dropEvents.activate) {
                fireActiveDrops(interaction.activeDrops, dropEvents.activate);
            }
        });

        InteractEvent.signals.on('new', function (_ref2) {
            var interaction = _ref2.interaction,
                iEvent = _ref2.iEvent,
                event = _ref2.event;

            if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {
                return;
            }

            var draggableElement = interaction.element;
            var dragEvent = iEvent;
            var dropResult = getDrop(dragEvent, event, draggableElement);

            interaction.dropTarget = dropResult.dropzone;
            interaction.dropElement = dropResult.element;

            interaction.dropEvents = getDropEvents(interaction, event, dragEvent);
        });

        Interaction.signals.on('action-move', function (_ref3) {
            var interaction = _ref3.interaction;

            if (interaction.prepared.name !== 'drag') {
                return;
            }

            fireDropEvents(interaction, interaction.dropEvents);
        });

        Interaction.signals.on('action-end', function (_ref4) {
            var interaction = _ref4.interaction;

            if (interaction.prepared.name === 'drag') {
                fireDropEvents(interaction, interaction.dropEvents);
            }
        });

        Interaction.signals.on('stop-drag', function (_ref5) {
            var interaction = _ref5.interaction;

            interaction.activeDrops = {
                dropzones: null,
                elements: null,
                rects: null
            };

            interaction.dropEvents = null;
        });

        function collectDrops(activeDrops, element) {
            var drops = [];
            var elements = [];

            // collect all dropzones and their elements which qualify for a drop
            for (var _i = 0; _i < scope.interactables.length; _i++) {
                var _ref6;

                _ref6 = scope.interactables[_i];
                var current = _ref6;

                if (!current.options.drop.enabled) {
                    continue;
                }

                var accept = current.options.drop.accept;

                // test the draggable element against the dropzone's accept setting
                if (utils.is.element(accept) && accept !== element || utils.is.string(accept) && !utils.matchesSelector(element, accept)) {

                    continue;
                }

                // query for new elements if necessary
                var dropElements = utils.is.string(current.target) ? current._context.querySelectorAll(current.target) : [current.target];

                for (var _i2 = 0; _i2 < dropElements.length; _i2++) {
                    var _ref7;

                    _ref7 = dropElements[_i2];
                    var currentElement = _ref7;

                    if (currentElement !== element) {
                        drops.push(current);
                        elements.push(currentElement);
                    }
                }
            }

            return {
                elements: elements,
                dropzones: drops
            };
        }

        function fireActiveDrops(activeDrops, event) {
            var prevElement = void 0;

            // loop through all active dropzones and trigger event
            for (var i = 0; i < activeDrops.dropzones.length; i++) {
                var current = activeDrops.dropzones[i];
                var currentElement = activeDrops.elements[i];

                // prevent trigger of duplicate events on same element
                if (currentElement !== prevElement) {
                    // set current element as event target
                    event.target = currentElement;
                    current.fire(event);
                }
                prevElement = currentElement;
            }
        }

// Collect a new set of possible drops and save them in activeDrops.
// setActiveDrops should always be called when a drag has just started or a
// drag event happens while dynamicDrop is true
        function setActiveDrops(activeDrops, dragElement) {
            // get dropzones and their elements that could receive the draggable
            var possibleDrops = collectDrops(activeDrops, dragElement);

            activeDrops.dropzones = possibleDrops.dropzones;
            activeDrops.elements = possibleDrops.elements;
            activeDrops.rects = [];

            for (var i = 0; i < activeDrops.dropzones.length; i++) {
                activeDrops.rects[i] = activeDrops.dropzones[i].getRect(activeDrops.elements[i]);
            }
        }

        function getDrop(dragEvent, event, dragElement) {
            var interaction = dragEvent.interaction;
            var validDrops = [];

            if (dynamicDrop) {
                setActiveDrops(interaction.activeDrops, dragElement);
            }

            // collect all dropzones and their elements which qualify for a drop
            for (var j = 0; j < interaction.activeDrops.dropzones.length; j++) {
                var current = interaction.activeDrops.dropzones[j];
                var currentElement = interaction.activeDrops.elements[j];
                var rect = interaction.activeDrops.rects[j];

                validDrops.push(current.dropCheck(dragEvent, event, interaction.target, dragElement, currentElement, rect) ? currentElement : null);
            }

            // get the most appropriate dropzone based on DOM depth and order
            var dropIndex = utils.indexOfDeepestElement(validDrops);

            return {
                dropzone: interaction.activeDrops.dropzones[dropIndex] || null,
                element: interaction.activeDrops.elements[dropIndex] || null
            };
        }

        function getDropEvents(interaction, pointerEvent, dragEvent) {
            var dropEvents = {
                enter: null,
                leave: null,
                activate: null,
                deactivate: null,
                move: null,
                drop: null
            };

            var tmpl = {
                dragEvent: dragEvent,
                interaction: interaction,
                target: interaction.dropElement,
                dropzone: interaction.dropTarget,
                relatedTarget: dragEvent.target,
                draggable: dragEvent.interactable,
                timeStamp: dragEvent.timeStamp
            };

            if (interaction.dropElement !== interaction.prevDropElement) {
                // if there was a prevDropTarget, create a dragleave event
                if (interaction.prevDropTarget) {
                    dropEvents.leave = utils.extend({ type: 'dragleave' }, tmpl);

                    dragEvent.dragLeave = dropEvents.leave.target = interaction.prevDropElement;
                    dragEvent.prevDropzone = dropEvents.leave.dropzone = interaction.prevDropTarget;
                }
                // if the dropTarget is not null, create a dragenter event
                if (interaction.dropTarget) {
                    dropEvents.enter = {
                        dragEvent: dragEvent,
                        interaction: interaction,
                        target: interaction.dropElement,
                        dropzone: interaction.dropTarget,
                        relatedTarget: dragEvent.target,
                        draggable: dragEvent.interactable,
                        timeStamp: dragEvent.timeStamp,
                        type: 'dragenter'
                    };

                    dragEvent.dragEnter = interaction.dropElement;
                    dragEvent.dropzone = interaction.dropTarget;
                }
            }

            if (dragEvent.type === 'dragend' && interaction.dropTarget) {
                dropEvents.drop = utils.extend({ type: 'drop' }, tmpl);

                dragEvent.dropzone = interaction.dropTarget;
                dragEvent.relatedTarget = interaction.dropElement;
            }
            if (dragEvent.type === 'dragstart') {
                dropEvents.activate = utils.extend({ type: 'dropactivate' }, tmpl);

                dropEvents.activate.target = null;
                dropEvents.activate.dropzone = null;
            }
            if (dragEvent.type === 'dragend') {
                dropEvents.deactivate = utils.extend({ type: 'dropdeactivate' }, tmpl);

                dropEvents.deactivate.target = null;
                dropEvents.deactivate.dropzone = null;
            }
            if (dragEvent.type === 'dragmove' && interaction.dropTarget) {
                dropEvents.move = utils.extend({
                    dragmove: dragEvent,
                    type: 'dropmove'
                }, tmpl);

                dragEvent.dropzone = interaction.dropTarget;
            }

            return dropEvents;
        }

        function fireDropEvents(interaction, dropEvents) {
            var activeDrops = interaction.activeDrops,
                prevDropTarget = interaction.prevDropTarget,
                dropTarget = interaction.dropTarget,
                dropElement = interaction.dropElement;


            if (dropEvents.leave) {
                prevDropTarget.fire(dropEvents.leave);
            }
            if (dropEvents.move) {
                dropTarget.fire(dropEvents.move);
            }
            if (dropEvents.enter) {
                dropTarget.fire(dropEvents.enter);
            }
            if (dropEvents.drop) {
                dropTarget.fire(dropEvents.drop);
            }
            if (dropEvents.deactivate) {
                fireActiveDrops(activeDrops, dropEvents.deactivate);
            }

            interaction.prevDropTarget = dropTarget;
            interaction.prevDropElement = dropElement;
        }

        /**
         * ```js
         * interact(target)
         * .dropChecker(function(dragEvent,         // related dragmove or dragend event
         *                       event,             // TouchEvent/PointerEvent/MouseEvent
         *                       dropped,           // bool result of the default checker
         *                       dropzone,          // dropzone Interactable
         *                       dropElement,       // dropzone elemnt
         *                       draggable,         // draggable Interactable
         *                       draggableElement) {// draggable element
 *
 *   return dropped && event.target.hasAttribute('allow-drop');
 * }
         * ```
         *
         * ```js
         * interact('.drop').dropzone({
 *   accept: '.can-drop' || document.getElementById('single-drop'),
 *   overlap: 'pointer' || 'center' || zeroToOne
 * }
         * ```
         *
         * Returns or sets whether draggables can be dropped onto this target to
         * trigger drop events
         *
         * Dropzones can receive the following events:
         *  - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends
         *  - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone
         *  - `dragmove` when a draggable that has entered the dropzone is moved
         *  - `drop` when a draggable is dropped into this dropzone
         *
         * Use the `accept` option to allow only elements that match the given CSS
         * selector or element. The value can be:
         *
         *  - **an Element** - only that element can be dropped into this dropzone.
         *  - **a string**, - the element being dragged must match it as a CSS selector.
         *  - **`null`** - accept options is cleared - it accepts any element.
         *
         * Use the `overlap` option to set how drops are checked for. The allowed
         * values are:
         *
         *   - `'pointer'`, the pointer must be over the dropzone (default)
         *   - `'center'`, the draggable element's center must be over the dropzone
         *   - a number from 0-1 which is the `(intersection area) / (draggable area)`.
         *   e.g. `0.5` for drop to happen when half of the area of the draggable is
         *   over the dropzone
         *
         * Use the `checker` option to specify a function to check if a dragged element
         * is over this Interactable.
         *
         * @param {boolean | object | null} [options] The new options to be set.
         * @return {boolean | Interactable} The current setting or this Interactable
         */
        Interactable.prototype.dropzone = function (options) {
            if (utils.is.object(options)) {
                this.options.drop.enabled = options.enabled === false ? false : true;

                if (utils.is.function(options.ondrop)) {
                    this.events.ondrop = options.ondrop;
                }
                if (utils.is.function(options.ondropactivate)) {
                    this.events.ondropactivate = options.ondropactivate;
                }
                if (utils.is.function(options.ondropdeactivate)) {
                    this.events.ondropdeactivate = options.ondropdeactivate;
                }
                if (utils.is.function(options.ondragenter)) {
                    this.events.ondragenter = options.ondragenter;
                }
                if (utils.is.function(options.ondragleave)) {
                    this.events.ondragleave = options.ondragleave;
                }
                if (utils.is.function(options.ondropmove)) {
                    this.events.ondropmove = options.ondropmove;
                }

                if (/^(pointer|center)$/.test(options.overlap)) {
                    this.options.drop.overlap = options.overlap;
                } else if (utils.is.number(options.overlap)) {
                    this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);
                }
                if ('accept' in options) {
                    this.options.drop.accept = options.accept;
                }
                if ('checker' in options) {
                    this.options.drop.checker = options.checker;
                }

                return this;
            }

            if (utils.is.bool(options)) {
                this.options.drop.enabled = options;

                if (!options) {
                    this.ondragenter = this.ondragleave = this.ondrop = this.ondropactivate = this.ondropdeactivate = null;
                }

                return this;
            }

            return this.options.drop;
        };

        Interactable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {
            var dropped = false;

            // if the dropzone has no rect (eg. display: none)
            // call the custom dropChecker or just return false
            if (!(rect = rect || this.getRect(dropElement))) {
                return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;
            }

            var dropOverlap = this.options.drop.overlap;

            if (dropOverlap === 'pointer') {
                var origin = utils.getOriginXY(draggable, draggableElement, 'drag');
                var page = utils.getPageXY(dragEvent);

                page.x += origin.x;
                page.y += origin.y;

                var horizontal = page.x > rect.left && page.x < rect.right;
                var vertical = page.y > rect.top && page.y < rect.bottom;

                dropped = horizontal && vertical;
            }

            var dragRect = draggable.getRect(draggableElement);

            if (dragRect && dropOverlap === 'center') {
                var cx = dragRect.left + dragRect.width / 2;
                var cy = dragRect.top + dragRect.height / 2;

                dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;
            }

            if (dragRect && utils.is.number(dropOverlap)) {
                var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));

                var overlapRatio = overlapArea / (dragRect.width * dragRect.height);

                dropped = overlapRatio >= dropOverlap;
            }

            if (this.options.drop.checker) {
                dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);
            }

            return dropped;
        };

        Interactable.signals.on('unset', function (_ref8) {
            var interactable = _ref8.interactable;

            interactable.dropzone(false);
        });

        Interactable.settingsMethods.push('dropChecker');

        Interaction.signals.on('new', function (interaction) {
            interaction.dropTarget = null; // the dropzone a drag target might be dropped into
            interaction.dropElement = null; // the element at the time of checking
            interaction.prevDropTarget = null; // the dropzone that was recently dragged away from
            interaction.prevDropElement = null; // the element at the time of checking
            interaction.dropEvents = null; // the dropEvents related to the current drag event

            interaction.activeDrops = {
                dropzones: [], // the dropzones that are mentioned below
                elements: [], // elements of dropzones that accept the target draggable
                rects: [] // the rects of the elements mentioned above
            };
        });

        Interaction.signals.on('stop', function (_ref9) {
            var interaction = _ref9.interaction;

            interaction.dropTarget = interaction.dropElement = interaction.prevDropTarget = interaction.prevDropElement = null;
        });

        /**
         * Returns or sets whether the dimensions of dropzone elements are calculated
         * on every dragmove or only on dragstart for the default dropChecker
         *
         * @param {boolean} [newValue] True to check on each move. False to check only
         * before start
         * @return {boolean | interact} The current setting or interact
         */
        interact.dynamicDrop = function (newValue) {
            if (utils.is.bool(newValue)) {
                //if (dragging && dynamicDrop !== newValue && !newValue) {
                //calcRects(dropzones);
                //}

                dynamicDrop = newValue;

                return interact;
            }
            return dynamicDrop;
        };

        utils.merge(Interactable.eventTypes, ['dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop']);
        actions.methodDict.drop = 'dropzone';

        defaultOptions.drop = drop.defaults;

        module.exports = drop;

    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../interact":21,"../scope":33,"../utils":44,"./base":6}],9:[function(require,module,exports){
        'use strict';

        var actions = require('./base');
        var utils = require('../utils');
        var InteractEvent = require('../InteractEvent');
        var Interactable = require('../Interactable');
        var Interaction = require('../Interaction');
        var defaultOptions = require('../defaultOptions');

        var gesture = {
            defaults: {
                enabled: false,
                origin: null,
                restrict: null
            },

            checker: function checker(pointer, event, interactable, element, interaction) {
                if (interaction.pointerIds.length >= 2) {
                    return { name: 'gesture' };
                }

                return null;
            },

            getCursor: function getCursor() {
                return '';
            }
        };

        InteractEvent.signals.on('new', function (_ref) {
            var iEvent = _ref.iEvent,
                interaction = _ref.interaction;

            if (iEvent.type !== 'gesturestart') {
                return;
            }
            iEvent.ds = 0;

            interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;
            interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;
            interaction.gesture.scale = 1;
        });

        InteractEvent.signals.on('new', function (_ref2) {
            var iEvent = _ref2.iEvent,
                interaction = _ref2.interaction;

            if (iEvent.type !== 'gesturemove') {
                return;
            }

            iEvent.ds = iEvent.scale - interaction.gesture.scale;

            interaction.target.fire(iEvent);

            interaction.gesture.prevAngle = iEvent.angle;
            interaction.gesture.prevDistance = iEvent.distance;

            if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) {

                interaction.gesture.scale = iEvent.scale;
            }
        });

        /**
         * ```js
         * interact(element).gesturable({
 *     onstart: function (event) {},
 *     onmove : function (event) {},
 *     onend  : function (event) {},
 *
 *     // limit multiple gestures.
 *     // See the explanation in {@link Interactable.draggable} example
 *     max: Infinity,
 *     maxPerElement: 1,
 * });
         *
         * var isGestureable = interact(element).gesturable();
         * ```
         *
         * Gets or sets whether multitouch gestures can be performed on the target
         *
         * @param {boolean | object} [options] true/false or An object with event
         * listeners to be fired on gesture events (makes the Interactable gesturable)
         * @return {boolean | Interactable} A boolean indicating if this can be the
         * target of gesture events, or this Interactable
         */
        Interactable.prototype.gesturable = function (options) {
            if (utils.is.object(options)) {
                this.options.gesture.enabled = options.enabled === false ? false : true;
                this.setPerAction('gesture', options);
                this.setOnEvents('gesture', options);

                return this;
            }

            if (utils.is.bool(options)) {
                this.options.gesture.enabled = options;

                if (!options) {
                    this.ongesturestart = this.ongesturestart = this.ongestureend = null;
                }

                return this;
            }

            return this.options.gesture;
        };

        InteractEvent.signals.on('set-delta', function (_ref3) {
            var interaction = _ref3.interaction,
                iEvent = _ref3.iEvent,
                action = _ref3.action,
                event = _ref3.event,
                starting = _ref3.starting,
                ending = _ref3.ending,
                deltaSource = _ref3.deltaSource;

            if (action !== 'gesture') {
                return;
            }

            var pointers = interaction.pointers;

            iEvent.touches = [pointers[0], pointers[1]];

            if (starting) {
                iEvent.distance = utils.touchDistance(pointers, deltaSource);
                iEvent.box = utils.touchBBox(pointers);
                iEvent.scale = 1;
                iEvent.ds = 0;
                iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);
                iEvent.da = 0;
            } else if (ending || event instanceof InteractEvent) {
                iEvent.distance = interaction.prevEvent.distance;
                iEvent.box = interaction.prevEvent.box;
                iEvent.scale = interaction.prevEvent.scale;
                iEvent.ds = iEvent.scale - 1;
                iEvent.angle = interaction.prevEvent.angle;
                iEvent.da = iEvent.angle - interaction.gesture.startAngle;
            } else {
                iEvent.distance = utils.touchDistance(pointers, deltaSource);
                iEvent.box = utils.touchBBox(pointers);
                iEvent.scale = iEvent.distance / interaction.gesture.startDistance;
                iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);

                iEvent.ds = iEvent.scale - interaction.gesture.prevScale;
                iEvent.da = iEvent.angle - interaction.gesture.prevAngle;
            }
        });

        Interaction.signals.on('new', function (interaction) {
            interaction.gesture = {
                start: { x: 0, y: 0 },

                startDistance: 0, // distance between two touches of touchStart
                prevDistance: 0,
                distance: 0,

                scale: 1, // gesture.distance / gesture.startDistance

                startAngle: 0, // angle of line joining two touches
                prevAngle: 0 // angle of the previous gesture event
            };
        });

        actions.gesture = gesture;
        actions.names.push('gesture');
        utils.merge(Interactable.eventTypes, ['gesturestart', 'gesturemove', 'gestureend']);
        actions.methodDict.gesture = 'gesturable';

        defaultOptions.gesture = gesture.defaults;

        module.exports = gesture;

    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"./base":6}],10:[function(require,module,exports){
        'use strict';

        var actions = require('./base');
        var utils = require('../utils');
        var browser = require('../utils/browser');
        var InteractEvent = require('../InteractEvent');
        /** @lends Interactable */
        var Interactable = require('../Interactable');
        var Interaction = require('../Interaction');
        var defaultOptions = require('../defaultOptions');

// Less Precision with touch input
        var defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;

        var resize = {
            defaults: {
                enabled: false,
                mouseButtons: null,

                origin: null,
                snap: null,
                restrict: null,
                inertia: null,
                autoScroll: null,

                square: false,
                preserveAspectRatio: false,
                axis: 'xy',

                // use default margin
                margin: NaN,

                // object with props left, right, top, bottom which are
                // true/false values to resize when the pointer is over that edge,
                // CSS selectors to match the handles for each direction
                // or the Elements for each handle
                edges: null,

                // a value of 'none' will limit the resize rect to a minimum of 0x0
                // 'negate' will alow the rect to have negative width/height
                // 'reposition' will keep the width/height positive by swapping
                // the top and bottom edges and/or swapping the left and right edges
                invert: 'none'
            },

            checker: function checker(pointer, event, interactable, element, interaction, rect) {
                if (!rect) {
                    return null;
                }

                var page = utils.extend({}, interaction.curCoords.page);
                var options = interactable.options;

                if (options.resize.enabled) {
                    var resizeOptions = options.resize;
                    var resizeEdges = { left: false, right: false, top: false, bottom: false };

                    // if using resize.edges
                    if (utils.is.object(resizeOptions.edges)) {
                        for (var edge in resizeEdges) {
                            resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || defaultMargin);
                        }

                        resizeEdges.left = resizeEdges.left && !resizeEdges.right;
                        resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;

                        if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {
                            return {
                                name: 'resize',
                                edges: resizeEdges
                            };
                        }
                    } else {
                        var right = options.resize.axis !== 'y' && page.x > rect.right - defaultMargin;
                        var bottom = options.resize.axis !== 'x' && page.y > rect.bottom - defaultMargin;

                        if (right || bottom) {
                            return {
                                name: 'resize',
                                axes: (right ? 'x' : '') + (bottom ? 'y' : '')
                            };
                        }
                    }
                }

                return null;
            },

            cursors: browser.isIe9 ? {
                x: 'e-resize',
                y: 's-resize',
                xy: 'se-resize',

                top: 'n-resize',
                left: 'w-resize',
                bottom: 's-resize',
                right: 'e-resize',
                topleft: 'se-resize',
                bottomright: 'se-resize',
                topright: 'ne-resize',
                bottomleft: 'ne-resize'
            } : {
                x: 'ew-resize',
                y: 'ns-resize',
                xy: 'nwse-resize',

                top: 'ns-resize',
                left: 'ew-resize',
                bottom: 'ns-resize',
                right: 'ew-resize',
                topleft: 'nwse-resize',
                bottomright: 'nwse-resize',
                topright: 'nesw-resize',
                bottomleft: 'nesw-resize'
            },

            getCursor: function getCursor(action) {
                if (action.axis) {
                    return resize.cursors[action.name + action.axis];
                } else if (action.edges) {
                    var cursorKey = '';
                    var edgeNames = ['top', 'bottom', 'left', 'right'];

                    for (var i = 0; i < 4; i++) {
                        if (action.edges[edgeNames[i]]) {
                            cursorKey += edgeNames[i];
                        }
                    }

                    return resize.cursors[cursorKey];
                }
            }
        };

// resizestart
        InteractEvent.signals.on('new', function (_ref) {
            var iEvent = _ref.iEvent,
                interaction = _ref.interaction;

            if (iEvent.type !== 'resizestart' || !interaction.prepared.edges) {
                return;
            }

            var startRect = interaction.target.getRect(interaction.element);
            var resizeOptions = interaction.target.options.resize;

            /*
   * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge
   * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make
   * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend
   * on the active edges and the edge being interacted with.
   */
            if (resizeOptions.square || resizeOptions.preserveAspectRatio) {
                var linkedEdges = utils.extend({}, interaction.prepared.edges);

                linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;
                linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;
                linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;
                linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;

                interaction.prepared._linkedEdges = linkedEdges;
            } else {
                interaction.prepared._linkedEdges = null;
            }

            // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize
            if (resizeOptions.preserveAspectRatio) {
                interaction.resizeStartAspectRatio = startRect.width / startRect.height;
            }

            interaction.resizeRects = {
                start: startRect,
                current: utils.extend({}, startRect),
                inverted: utils.extend({}, startRect),
                previous: utils.extend({}, startRect),
                delta: {
                    left: 0, right: 0, width: 0,
                    top: 0, bottom: 0, height: 0
                }
            };

            iEvent.rect = interaction.resizeRects.inverted;
            iEvent.deltaRect = interaction.resizeRects.delta;
        });

// resizemove
        InteractEvent.signals.on('new', function (_ref2) {
            var iEvent = _ref2.iEvent,
                phase = _ref2.phase,
                interaction = _ref2.interaction;

            if (phase !== 'move' || !interaction.prepared.edges) {
                return;
            }

            var resizeOptions = interaction.target.options.resize;
            var invert = resizeOptions.invert;
            var invertible = invert === 'reposition' || invert === 'negate';

            var edges = interaction.prepared.edges;

            var start = interaction.resizeRects.start;
            var current = interaction.resizeRects.current;
            var inverted = interaction.resizeRects.inverted;
            var delta = interaction.resizeRects.delta;
            var previous = utils.extend(interaction.resizeRects.previous, inverted);
            var originalEdges = edges;

            var dx = iEvent.dx;
            var dy = iEvent.dy;

            if (resizeOptions.preserveAspectRatio || resizeOptions.square) {
                // `resize.preserveAspectRatio` takes precedence over `resize.square`
                var startAspectRatio = resizeOptions.preserveAspectRatio ? interaction.resizeStartAspectRatio : 1;

                edges = interaction.prepared._linkedEdges;

                if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {
                    dy = -dx / startAspectRatio;
                } else if (originalEdges.left || originalEdges.right) {
                    dy = dx / startAspectRatio;
                } else if (originalEdges.top || originalEdges.bottom) {
                    dx = dy * startAspectRatio;
                }
            }

            // update the 'current' rect without modifications
            if (edges.top) {
                current.top += dy;
            }
            if (edges.bottom) {
                current.bottom += dy;
            }
            if (edges.left) {
                current.left += dx;
            }
            if (edges.right) {
                current.right += dx;
            }

            if (invertible) {
                // if invertible, copy the current rect
                utils.extend(inverted, current);

                if (invert === 'reposition') {
                    // swap edge values if necessary to keep width/height positive
                    var swap = void 0;

                    if (inverted.top > inverted.bottom) {
                        swap = inverted.top;

                        inverted.top = inverted.bottom;
                        inverted.bottom = swap;
                    }
                    if (inverted.left > inverted.right) {
                        swap = inverted.left;

                        inverted.left = inverted.right;
                        inverted.right = swap;
                    }
                }
            } else {
                // if not invertible, restrict to minimum of 0x0 rect
                inverted.top = Math.min(current.top, start.bottom);
                inverted.bottom = Math.max(current.bottom, start.top);
                inverted.left = Math.min(current.left, start.right);
                inverted.right = Math.max(current.right, start.left);
            }

            inverted.width = inverted.right - inverted.left;
            inverted.height = inverted.bottom - inverted.top;

            for (var edge in inverted) {
                delta[edge] = inverted[edge] - previous[edge];
            }

            iEvent.edges = interaction.prepared.edges;
            iEvent.rect = inverted;
            iEvent.deltaRect = delta;
        });

        /**
         * ```js
         * interact(element).resizable({
 *   onstart: function (event) {},
 *   onmove : function (event) {},
 *   onend  : function (event) {},
 *
 *   edges: {
 *     top   : true,       // Use pointer coords to check for resize.
 *     left  : false,      // Disable resizing from left edge.
 *     bottom: '.resize-s',// Resize if pointer target matches selector
 *     right : handleEl    // Resize if pointer target is the given Element
 *   },
 *
 *     // Width and height can be adjusted independently. When `true`, width and
 *     // height are adjusted at a 1:1 ratio.
 *     square: false,
 *
 *     // Width and height can be adjusted independently. When `true`, width and
 *     // height maintain the aspect ratio they had when resizing started.
 *     preserveAspectRatio: false,
 *
 *   // a value of 'none' will limit the resize rect to a minimum of 0x0
 *   // 'negate' will allow the rect to have negative width/height
 *   // 'reposition' will keep the width/height positive by swapping
 *   // the top and bottom edges and/or swapping the left and right edges
 *   invert: 'none' || 'negate' || 'reposition'
 *
 *   // limit multiple resizes.
 *   // See the explanation in the {@link Interactable.draggable} example
 *   max: Infinity,
 *   maxPerElement: 1,
 * });
         *
         * var isResizeable = interact(element).resizable();
         * ```
         *
         * Gets or sets whether resize actions can be performed on the target
         *
         * @param {boolean | object} [options] true/false or An object with event
         * listeners to be fired on resize events (object makes the Interactable
         * resizable)
         * @return {boolean | Interactable} A boolean indicating if this can be the
         * target of resize elements, or this Interactable
         */
        Interactable.prototype.resizable = function (options) {
            if (utils.is.object(options)) {
                this.options.resize.enabled = options.enabled === false ? false : true;
                this.setPerAction('resize', options);
                this.setOnEvents('resize', options);

                if (/^x$|^y$|^xy$/.test(options.axis)) {
                    this.options.resize.axis = options.axis;
                } else if (options.axis === null) {
                    this.options.resize.axis = defaultOptions.resize.axis;
                }

                if (utils.is.bool(options.preserveAspectRatio)) {
                    this.options.resize.preserveAspectRatio = options.preserveAspectRatio;
                } else if (utils.is.bool(options.square)) {
                    this.options.resize.square = options.square;
                }

                return this;
            }
            if (utils.is.bool(options)) {
                this.options.resize.enabled = options;

                if (!options) {
                    this.onresizestart = this.onresizestart = this.onresizeend = null;
                }

                return this;
            }
            return this.options.resize;
        };

        function checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {
            // false, '', undefined, null
            if (!value) {
                return false;
            }

            // true value, use pointer coords and element rect
            if (value === true) {
                // if dimensions are negative, "switch" edges
                var width = utils.is.number(rect.width) ? rect.width : rect.right - rect.left;
                var height = utils.is.number(rect.height) ? rect.height : rect.bottom - rect.top;

                if (width < 0) {
                    if (name === 'left') {
                        name = 'right';
                    } else if (name === 'right') {
                        name = 'left';
                    }
                }
                if (height < 0) {
                    if (name === 'top') {
                        name = 'bottom';
                    } else if (name === 'bottom') {
                        name = 'top';
                    }
                }

                if (name === 'left') {
                    return page.x < (width >= 0 ? rect.left : rect.right) + margin;
                }
                if (name === 'top') {
                    return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;
                }

                if (name === 'right') {
                    return page.x > (width >= 0 ? rect.right : rect.left) - margin;
                }
                if (name === 'bottom') {
                    return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;
                }
            }

            // the remaining checks require an element
            if (!utils.is.element(element)) {
                return false;
            }

            return utils.is.element(value)
                // the value is an element to use as a resize handle
                ? value === element
                // otherwise check if element matches value as selector
                : utils.matchesUpTo(element, value, interactableElement);
        }

        Interaction.signals.on('new', function (interaction) {
            interaction.resizeAxes = 'xy';
        });

        InteractEvent.signals.on('set-delta', function (_ref3) {
            var interaction = _ref3.interaction,
                iEvent = _ref3.iEvent,
                action = _ref3.action;

            if (action !== 'resize' || !interaction.resizeAxes) {
                return;
            }

            var options = interaction.target.options;

            if (options.resize.square) {
                if (interaction.resizeAxes === 'y') {
                    iEvent.dx = iEvent.dy;
                } else {
                    iEvent.dy = iEvent.dx;
                }
                iEvent.axes = 'xy';
            } else {
                iEvent.axes = interaction.resizeAxes;

                if (interaction.resizeAxes === 'x') {
                    iEvent.dy = 0;
                } else if (interaction.resizeAxes === 'y') {
                    iEvent.dx = 0;
                }
            }
        });

        actions.resize = resize;
        actions.names.push('resize');
        utils.merge(Interactable.eventTypes, ['resizestart', 'resizemove', 'resizeinertiastart', 'resizeinertiaresume', 'resizeend']);
        actions.methodDict.resize = 'resizable';

        defaultOptions.resize = resize.defaults;

        module.exports = resize;

    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"../utils/browser":36,"./base":6}],11:[function(require,module,exports){
        'use strict';

        var raf = require('./utils/raf');
        var getWindow = require('./utils/window').getWindow;
        var is = require('./utils/is');
        var domUtils = require('./utils/domUtils');
        var Interaction = require('./Interaction');
        var defaultOptions = require('./defaultOptions');

        var autoScroll = {
            defaults: {
                enabled: false,
                container: null, // the item that is scrolled (Window or HTMLElement)
                margin: 60,
                speed: 300 // the scroll speed in pixels per second
            },

            interaction: null,
            i: null, // the handle returned by window.setInterval
            x: 0, y: 0, // Direction each pulse is to scroll in

            isScrolling: false,
            prevTime: 0,

            start: function start(interaction) {
                autoScroll.isScrolling = true;
                raf.cancel(autoScroll.i);

                autoScroll.interaction = interaction;
                autoScroll.prevTime = new Date().getTime();
                autoScroll.i = raf.request(autoScroll.scroll);
            },

            stop: function stop() {
                autoScroll.isScrolling = false;
                raf.cancel(autoScroll.i);
            },

            // scroll the window by the values in scroll.x/y
            scroll: function scroll() {
                var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;
                var container = options.container || getWindow(autoScroll.interaction.element);
                var now = new Date().getTime();
                // change in time in seconds
                var dt = (now - autoScroll.prevTime) / 1000;
                // displacement
                var s = options.speed * dt;

                if (s >= 1) {
                    if (is.window(container)) {
                        container.scrollBy(autoScroll.x * s, autoScroll.y * s);
                    } else if (container) {
                        container.scrollLeft += autoScroll.x * s;
                        container.scrollTop += autoScroll.y * s;
                    }

                    autoScroll.prevTime = now;
                }

                if (autoScroll.isScrolling) {
                    raf.cancel(autoScroll.i);
                    autoScroll.i = raf.request(autoScroll.scroll);
                }
            },
            check: function check(interactable, actionName) {
                var options = interactable.options;

                return options[actionName].autoScroll && options[actionName].autoScroll.enabled;
            },
            onInteractionMove: function onInteractionMove(_ref) {
                var interaction = _ref.interaction,
                    pointer = _ref.pointer;

                if (!(interaction.interacting() && autoScroll.check(interaction.target, interaction.prepared.name))) {
                    return;
                }

                if (interaction.simulation) {
                    autoScroll.x = autoScroll.y = 0;
                    return;
                }

                var top = void 0;
                var right = void 0;
                var bottom = void 0;
                var left = void 0;

                var options = interaction.target.options[interaction.prepared.name].autoScroll;
                var container = options.container || getWindow(interaction.element);

                if (is.window(container)) {
                    left = pointer.clientX < autoScroll.margin;
                    top = pointer.clientY < autoScroll.margin;
                    right = pointer.clientX > container.innerWidth - autoScroll.margin;
                    bottom = pointer.clientY > container.innerHeight - autoScroll.margin;
                } else {
                    var rect = domUtils.getElementClientRect(container);

                    left = pointer.clientX < rect.left + autoScroll.margin;
                    top = pointer.clientY < rect.top + autoScroll.margin;
                    right = pointer.clientX > rect.right - autoScroll.margin;
                    bottom = pointer.clientY > rect.bottom - autoScroll.margin;
                }

                autoScroll.x = right ? 1 : left ? -1 : 0;
                autoScroll.y = bottom ? 1 : top ? -1 : 0;

                if (!autoScroll.isScrolling) {
                    // set the autoScroll properties to those of the target
                    autoScroll.margin = options.margin;
                    autoScroll.speed = options.speed;

                    autoScroll.start(interaction);
                }
            }
        };

        Interaction.signals.on('stop-active', function () {
            autoScroll.stop();
        });

        Interaction.signals.on('action-move', autoScroll.onInteractionMove);

        defaultOptions.perAction.autoScroll = autoScroll.defaults;

        module.exports = autoScroll;

    },{"./Interaction":5,"./defaultOptions":18,"./utils/domUtils":39,"./utils/is":46,"./utils/raf":50,"./utils/window":52}],12:[function(require,module,exports){
        'use strict';

        /** @lends Interactable */
        var Interactable = require('../Interactable');
        var actions = require('../actions/base');
        var is = require('../utils/is');
        var domUtils = require('../utils/domUtils');

        var _require = require('../utils'),
            warnOnce = _require.warnOnce;

        Interactable.prototype.getAction = function (pointer, event, interaction, element) {
            var action = this.defaultActionChecker(pointer, event, interaction, element);

            if (this.options.actionChecker) {
                return this.options.actionChecker(pointer, event, action, this, element, interaction);
            }

            return action;
        };

        /**
         * ```js
         * interact(element, { ignoreFrom: document.getElementById('no-action') });
         * // or
         * interact(element).ignoreFrom('input, textarea, a');
         * ```
         * @deprecated
         * If the target of the `mousedown`, `pointerdown` or `touchstart` event or any
         * of it's parents match the given CSS selector or Element, no
         * drag/resize/gesture is started.
         *
         * Don't use this method. Instead set the `ignoreFrom` option for each action
         * or for `pointerEvents`
         *
         * @example
         * interact(targett)
         *   .draggable({
 *     ignoreFrom: 'input, textarea, a[href]'',
 *   })
         *   .pointerEvents({
 *     ignoreFrom: '[no-pointer]',
 *   });
         *
         * @param {string | Element | null} [newValue] a CSS selector string, an
         * Element or `null` to not ignore any elements
         * @return {string | Element | object} The current ignoreFrom value or this
         * Interactable
         */
        Interactable.prototype.ignoreFrom = warnOnce(function (newValue) {
            return this._backCompatOption('ignoreFrom', newValue);
        }, 'Interactable.ignoreForm() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue}).');

        /**
         * ```js
         *
         * @deprecated
         * A drag/resize/gesture is started only If the target of the `mousedown`,
         * `pointerdown` or `touchstart` event or any of it's parents match the given
         * CSS selector or Element.
         *
         * Don't use this method. Instead set the `allowFrom` option for each action
         * or for `pointerEvents`
         *
         * @example
         * interact(targett)
         *   .resizable({
 *     allowFrom: '.resize-handle',
 *   .pointerEvents({
 *     allowFrom: '.handle',,
 *   });
 *
         * @param {string | Element | null} [newValue] a CSS selector string, an
         * Element or `null` to allow from any element
         * @return {string | Element | object} The current allowFrom value or this
         * Interactable
         */
        Interactable.prototype.allowFrom = warnOnce(function (newValue) {
            return this._backCompatOption('allowFrom', newValue);
        }, 'Interactable.allowForm() has been deprecated. Use Interactble.draggable({allowFrom: newValue}).');

        Interactable.prototype.testIgnore = function (ignoreFrom, interactableElement, element) {
            if (!ignoreFrom || !is.element(element)) {
                return false;
            }

            if (is.string(ignoreFrom)) {
                return domUtils.matchesUpTo(element, ignoreFrom, interactableElement);
            } else if (is.element(ignoreFrom)) {
                return domUtils.nodeContains(ignoreFrom, element);
            }

            return false;
        };

        Interactable.prototype.testAllow = function (allowFrom, interactableElement, element) {
            if (!allowFrom) {
                return true;
            }

            if (!is.element(element)) {
                return false;
            }

            if (is.string(allowFrom)) {
                return domUtils.matchesUpTo(element, allowFrom, interactableElement);
            } else if (is.element(allowFrom)) {
                return domUtils.nodeContains(allowFrom, element);
            }

            return false;
        };

        Interactable.prototype.testIgnoreAllow = function (options, interactableElement, eventTarget) {
            return !this.testIgnore(options.ignoreFrom, interactableElement, eventTarget) && this.testAllow(options.allowFrom, interactableElement, eventTarget);
        };

        /**
         * ```js
         * interact('.resize-drag')
         *   .resizable(true)
         *   .draggable(true)
         *   .actionChecker(function (pointer, event, action, interactable, element, interaction) {
 *
 *   if (interact.matchesSelector(event.target, '.drag-handle') {
 *     // force drag with handle target
 *     action.name = drag;
 *   }
 *   else {
 *     // resize from the top and right edges
 *     action.name  = 'resize';
 *     action.edges = { top: true, right: true };
 *   }
 *
 *   return action;
 * });
         * ```
         *
         * Gets or sets the function used to check action to be performed on
         * pointerDown
         *
         * @param {function | null} [checker] A function which takes a pointer event,
         * defaultAction string, interactable, element and interaction as parameters
         * and returns an object with name property 'drag' 'resize' or 'gesture' and
         * optionally an `edges` object with boolean 'top', 'left', 'bottom' and right
         * props.
         * @return {Function | Interactable} The checker function or this Interactable
         */
        Interactable.prototype.actionChecker = function (checker) {
            if (is.function(checker)) {
                this.options.actionChecker = checker;

                return this;
            }

            if (checker === null) {
                delete this.options.actionChecker;

                return this;
            }

            return this.options.actionChecker;
        };

        /**
         * Returns or sets whether the the cursor should be changed depending on the
         * action that would be performed if the mouse were pressed and dragged.
         *
         * @param {boolean} [newValue]
         * @return {boolean | Interactable} The current setting or this Interactable
         */
        Interactable.prototype.styleCursor = function (newValue) {
            if (is.bool(newValue)) {
                this.options.styleCursor = newValue;

                return this;
            }

            if (newValue === null) {
                delete this.options.styleCursor;

                return this;
            }

            return this.options.styleCursor;
        };

        Interactable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {
            var rect = this.getRect(element);
            var buttons = event.buttons || {
                0: 1,
                1: 4,
                3: 8,
                4: 16
            }[event.button];
            var action = null;

            for (var _i = 0; _i < actions.names.length; _i++) {
                var _ref;

                _ref = actions.names[_i];
                var actionName = _ref;

                // check mouseButton setting if the pointer is down
                if (interaction.pointerIsDown && /mouse|pointer/.test(interaction.pointerType) && (buttons & this.options[actionName].mouseButtons) === 0) {
                    continue;
                }

                action = actions[actionName].checker(pointer, event, this, element, interaction, rect);

                if (action) {
                    return action;
                }
            }
        };

    },{"../Interactable":4,"../actions/base":6,"../utils":44,"../utils/domUtils":39,"../utils/is":46}],13:[function(require,module,exports){
        'use strict';

        var interact = require('../interact');
        var Interactable = require('../Interactable');
        var Interaction = require('../Interaction');
        var actions = require('../actions/base');
        var defaultOptions = require('../defaultOptions');
        var scope = require('../scope');
        var utils = require('../utils');
        var signals = require('../utils/Signals').new();

        require('./InteractableMethods');

        var autoStart = {
            signals: signals,
            withinInteractionLimit: withinInteractionLimit,
            // Allow this many interactions to happen simultaneously
            maxInteractions: Infinity,
            defaults: {
                perAction: {
                    manualStart: false,
                    max: Infinity,
                    maxPerElement: 1,
                    allowFrom: null,
                    ignoreFrom: null,

                    // only allow left button by default
                    // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value
                    mouseButtons: 1
                }
            },
            setActionDefaults: function setActionDefaults(action) {
                utils.extend(action.defaults, autoStart.defaults.perAction);
            },
            validateAction: validateAction
        };

// set cursor style on mousedown
        Interaction.signals.on('down', function (_ref) {
            var interaction = _ref.interaction,
                pointer = _ref.pointer,
                event = _ref.event,
                eventTarget = _ref.eventTarget;

            if (interaction.interacting()) {
                return;
            }

            var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);
            prepare(interaction, actionInfo);
        });

// set cursor style on mousemove
        Interaction.signals.on('move', function (_ref2) {
            var interaction = _ref2.interaction,
                pointer = _ref2.pointer,
                event = _ref2.event,
                eventTarget = _ref2.eventTarget;

            if (interaction.pointerType !== 'mouse' || interaction.pointerIsDown || interaction.interacting()) {
                return;
            }

            var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);
            prepare(interaction, actionInfo);
        });

        Interaction.signals.on('move', function (arg) {
            var interaction = arg.interaction,
                event = arg.event;


            if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {
                return;
            }

            signals.fire('before-start', arg);

            var target = interaction.target;

            if (interaction.prepared.name && target) {
                // check manualStart and interaction limit
                if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) {
                    interaction.stop(event);
                } else {
                    interaction.start(interaction.prepared, target, interaction.element);
                }
            }
        });

// Check if the current target supports the action.
// If so, return the validated action. Otherwise, return null
        function validateAction(action, interactable, element, eventTarget) {
            if (utils.is.object(action) && interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action)) {
                return action;
            }

            return null;
        }

        function validateSelector(interaction, pointer, event, matches, matchElements, eventTarget) {
            for (var i = 0, len = matches.length; i < len; i++) {
                var match = matches[i];
                var matchElement = matchElements[i];
                var action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget);

                if (action) {
                    return {
                        action: action,
                        target: match,
                        element: matchElement
                    };
                }
            }

            return {};
        }

        function getActionInfo(interaction, pointer, event, eventTarget) {
            var matches = [];
            var matchElements = [];

            var element = eventTarget;

            function pushMatches(interactable) {
                matches.push(interactable);
                matchElements.push(element);
            }

            while (utils.is.element(element)) {
                matches = [];
                matchElements = [];

                scope.interactables.forEachMatch(element, pushMatches);

                var actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget);

                if (actionInfo.action && !actionInfo.target.options[actionInfo.action.name].manualStart) {
                    return actionInfo;
                }

                element = utils.parentNode(element);
            }

            return {};
        }

        function prepare(interaction, _ref3) {
            var action = _ref3.action,
                target = _ref3.target,
                element = _ref3.element;

            action = action || {};

            if (interaction.target && interaction.target.options.styleCursor) {
                interaction.target._doc.documentElement.style.cursor = '';
            }

            interaction.target = target;
            interaction.element = element;
            utils.copyAction(interaction.prepared, action);

            if (target && target.options.styleCursor) {
                var cursor = action ? actions[action.name].getCursor(action) : '';
                interaction.target._doc.documentElement.style.cursor = cursor;
            }

            signals.fire('prepared', { interaction: interaction });
        }

        Interaction.signals.on('stop', function (_ref4) {
            var interaction = _ref4.interaction;

            var target = interaction.target;

            if (target && target.options.styleCursor) {
                target._doc.documentElement.style.cursor = '';
            }
        });

        function withinInteractionLimit(interactable, element, action) {
            var options = interactable.options;
            var maxActions = options[action.name].max;
            var maxPerElement = options[action.name].maxPerElement;
            var activeInteractions = 0;
            var targetCount = 0;
            var targetElementCount = 0;

            // no actions if any of these values == 0
            if (!(maxActions && maxPerElement && autoStart.maxInteractions)) {
                return;
            }

            for (var _i = 0; _i < scope.interactions.length; _i++) {
                var _ref5;

                _ref5 = scope.interactions[_i];
                var interaction = _ref5;

                var otherAction = interaction.prepared.name;

                if (!interaction.interacting()) {
                    continue;
                }

                activeInteractions++;

                if (activeInteractions >= autoStart.maxInteractions) {
                    return false;
                }

                if (interaction.target !== interactable) {
                    continue;
                }

                targetCount += otherAction === action.name | 0;

                if (targetCount >= maxActions) {
                    return false;
                }

                if (interaction.element === element) {
                    targetElementCount++;

                    if (otherAction !== action.name || targetElementCount >= maxPerElement) {
                        return false;
                    }
                }
            }

            return autoStart.maxInteractions > 0;
        }

        /**
         * Returns or sets the maximum number of concurrent interactions allowed.  By
         * default only 1 interaction is allowed at a time (for backwards
         * compatibility). To allow multiple interactions on the same Interactables and
         * elements, you need to enable it in the draggable, resizable and gesturable
         * `'max'` and `'maxPerElement'` options.
         *
         * @alias module:interact.maxInteractions
         *
         * @param {number} [newValue] Any number. newValue <= 0 means no interactions.
         */
        interact.maxInteractions = function (newValue) {
            if (utils.is.number(newValue)) {
                autoStart.maxInteractions = newValue;

                return interact;
            }

            return autoStart.maxInteractions;
        };

        Interactable.settingsMethods.push('styleCursor');
        Interactable.settingsMethods.push('actionChecker');
        Interactable.settingsMethods.push('ignoreFrom');
        Interactable.settingsMethods.push('allowFrom');

        defaultOptions.base.actionChecker = null;
        defaultOptions.base.styleCursor = true;

        utils.extend(defaultOptions.perAction, autoStart.defaults.perAction);

        module.exports = autoStart;

    },{"../Interactable":4,"../Interaction":5,"../actions/base":6,"../defaultOptions":18,"../interact":21,"../scope":33,"../utils":44,"../utils/Signals":34,"./InteractableMethods":12}],14:[function(require,module,exports){
        'use strict';

        var autoStart = require('./base');
        var scope = require('../scope');
        var is = require('../utils/is');

        var _require = require('../utils/domUtils'),
            parentNode = _require.parentNode;

        autoStart.setActionDefaults(require('../actions/drag'));

        autoStart.signals.on('before-start', function (_ref) {
            var interaction = _ref.interaction,
                eventTarget = _ref.eventTarget,
                dx = _ref.dx,
                dy = _ref.dy;

            if (interaction.prepared.name !== 'drag') {
                return;
            }

            // check if a drag is in the correct axis
            var absX = Math.abs(dx);
            var absY = Math.abs(dy);
            var targetOptions = interaction.target.options.drag;
            var startAxis = targetOptions.startAxis;
            var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';

            interaction.prepared.axis = targetOptions.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'
                : targetOptions.lockAxis;

            // if the movement isn't in the startAxis of the interactable
            if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {
                // cancel the prepared action
                interaction.prepared.name = null;

                // then try to get a drag from another ineractable
                var element = eventTarget;

                var getDraggable = function getDraggable(interactable) {
                    if (interactable === interaction.target) {
                        return;
                    }

                    var options = interaction.target.options.drag;

                    if (!options.manualStart && interactable.testIgnoreAllow(options, element, eventTarget)) {

                        var action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);

                        if (action && action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart.validateAction(action, interactable, element, eventTarget)) {

                            return interactable;
                        }
                    }
                };

                // check all interactables
                while (is.element(element)) {
                    var interactable = scope.interactables.forEachMatch(element, getDraggable);

                    if (interactable) {
                        interaction.prepared.name = 'drag';
                        interaction.target = interactable;
                        interaction.element = element;
                        break;
                    }

                    element = parentNode(element);
                }
            }
        });

        function checkStartAxis(startAxis, interactable) {
            if (!interactable) {
                return false;
            }

            var thisAxis = interactable.options.drag.startAxis;

            return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;
        }

    },{"../actions/drag":7,"../scope":33,"../utils/domUtils":39,"../utils/is":46,"./base":13}],15:[function(require,module,exports){
        'use strict';

        require('./base').setActionDefaults(require('../actions/gesture'));

    },{"../actions/gesture":9,"./base":13}],16:[function(require,module,exports){
        'use strict';

        var autoStart = require('./base');
        var Interaction = require('../Interaction');

        autoStart.defaults.perAction.hold = 0;
        autoStart.defaults.perAction.delay = 0;

        Interaction.signals.on('new', function (interaction) {
            interaction.autoStartHoldTimer = null;
        });

        autoStart.signals.on('prepared', function (_ref) {
            var interaction = _ref.interaction;

            var hold = getHoldDuration(interaction);

            if (hold > 0) {
                interaction.autoStartHoldTimer = setTimeout(function () {
                    interaction.start(interaction.prepared, interaction.target, interaction.element);
                }, hold);
            }
        });

        Interaction.signals.on('move', function (_ref2) {
            var interaction = _ref2.interaction,
                duplicate = _ref2.duplicate;

            if (interaction.pointerWasMoved && !duplicate) {
                clearTimeout(interaction.autoStartHoldTimer);
            }
        });

// prevent regular down->move autoStart
        autoStart.signals.on('before-start', function (_ref3) {
            var interaction = _ref3.interaction;

            var hold = getHoldDuration(interaction);

            if (hold > 0) {
                interaction.prepared.name = null;
            }
        });

        function getHoldDuration(interaction) {
            var actionName = interaction.prepared && interaction.prepared.name;

            if (!actionName) {
                return null;
            }

            var options = interaction.target.options;

            return options[actionName].hold || options[actionName].delay;
        }

        module.exports = {
            getHoldDuration: getHoldDuration
        };

    },{"../Interaction":5,"./base":13}],17:[function(require,module,exports){
        'use strict';

        require('./base').setActionDefaults(require('../actions/resize'));

    },{"../actions/resize":10,"./base":13}],18:[function(require,module,exports){
        'use strict';

        module.exports = {
            base: {
                accept: null,
                preventDefault: 'auto',
                deltaSource: 'page'
            },

            perAction: {
                origin: { x: 0, y: 0 },

                inertia: {
                    enabled: false,
                    resistance: 10, // the lambda in exponential decay
                    minSpeed: 100, // target speed must be above this for inertia to start
                    endSpeed: 10, // the speed at which inertia is slow enough to stop
                    allowResume: true, // allow resuming an action in inertia phase
                    smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia
                }
            }
        };

    },{}],19:[function(require,module,exports){
        'use strict';

        /* browser entry point */

// inertia
        require('./inertia');

// modifiers
        require('./modifiers/snap');
        require('./modifiers/restrict');

// pointerEvents
        require('./pointerEvents/base');
        require('./pointerEvents/holdRepeat');
        require('./pointerEvents/interactableTargets');

// autoStart hold
        require('./autoStart/hold');

// actions
        require('./actions/gesture');
        require('./actions/resize');
        require('./actions/drag');
        require('./actions/drop');

// load these modifiers after resize is loaded
        require('./modifiers/snapSize');
        require('./modifiers/restrictEdges');
        require('./modifiers/restrictSize');

// autoStart actions
        require('./autoStart/gesture');
        require('./autoStart/resize');
        require('./autoStart/drag');

// Interactable preventDefault setting
        require('./interactablePreventDefault.js');

// autoScroll
        require('./autoScroll');

// export interact
        module.exports = require('./interact');

    },{"./actions/drag":7,"./actions/drop":8,"./actions/gesture":9,"./actions/resize":10,"./autoScroll":11,"./autoStart/drag":14,"./autoStart/gesture":15,"./autoStart/hold":16,"./autoStart/resize":17,"./inertia":20,"./interact":21,"./interactablePreventDefault.js":22,"./modifiers/restrict":24,"./modifiers/restrictEdges":25,"./modifiers/restrictSize":26,"./modifiers/snap":27,"./modifiers/snapSize":28,"./pointerEvents/base":30,"./pointerEvents/holdRepeat":31,"./pointerEvents/interactableTargets":32}],20:[function(require,module,exports){
        'use strict';

        var InteractEvent = require('./InteractEvent');
        var Interaction = require('./Interaction');
        var modifiers = require('./modifiers/base');
        var utils = require('./utils');
        var animationFrame = require('./utils/raf');

        Interaction.signals.on('new', function (interaction) {
            interaction.inertiaStatus = {
                active: false,
                smoothEnd: false,
                allowResume: false,

                startEvent: null,
                upCoords: {},

                xe: 0, ye: 0,
                sx: 0, sy: 0,

                t0: 0,
                vx0: 0, vys: 0,
                duration: 0,

                lambda_v0: 0,
                one_ve_v0: 0,
                i: null
            };

            interaction.boundInertiaFrame = function () {
                return inertiaFrame.apply(interaction);
            };
            interaction.boundSmoothEndFrame = function () {
                return smoothEndFrame.apply(interaction);
            };
        });

        Interaction.signals.on('down', function (_ref) {
            var interaction = _ref.interaction,
                event = _ref.event,
                pointer = _ref.pointer,
                eventTarget = _ref.eventTarget;

            var status = interaction.inertiaStatus;

            // Check if the down event hits the current inertia target
            if (status.active) {
                var element = eventTarget;

                // climb up the DOM tree from the event target
                while (utils.is.element(element)) {

                    // if interaction element is the current inertia target element
                    if (element === interaction.element) {
                        // stop inertia
                        animationFrame.cancel(status.i);
                        status.active = false;
                        interaction.simulation = null;

                        // update pointers to the down event's coordinates
                        interaction.updatePointer(pointer);
                        utils.setCoords(interaction.curCoords, interaction.pointers);

                        // fire appropriate signals
                        var signalArg = { interaction: interaction };
                        Interaction.signals.fire('before-action-move', signalArg);
                        Interaction.signals.fire('action-resume', signalArg);

                        // fire a reume event
                        var resumeEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiaresume', interaction.element);

                        interaction.target.fire(resumeEvent);
                        interaction.prevEvent = resumeEvent;
                        modifiers.resetStatuses(interaction.modifierStatuses);

                        utils.copyCoords(interaction.prevCoords, interaction.curCoords);
                        break;
                    }

                    element = utils.parentNode(element);
                }
            }
        });

        Interaction.signals.on('up', function (_ref2) {
            var interaction = _ref2.interaction,
                event = _ref2.event;

            var status = interaction.inertiaStatus;

            if (!interaction.interacting() || status.active) {
                return;
            }

            var target = interaction.target;
            var options = target && target.options;
            var inertiaOptions = options && interaction.prepared.name && options[interaction.prepared.name].inertia;

            var now = new Date().getTime();
            var statuses = {};
            var page = utils.extend({}, interaction.curCoords.page);
            var pointerSpeed = interaction.pointerDelta.client.speed;

            var smoothEnd = false;
            var modifierResult = void 0;

            // check if inertia should be started
            var inertiaPossible = inertiaOptions && inertiaOptions.enabled && interaction.prepared.name !== 'gesture' && event !== status.startEvent;

            var inertia = inertiaPossible && now - interaction.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;

            var modifierArg = {
                interaction: interaction,
                pageCoords: page,
                statuses: statuses,
                preEnd: true,
                requireEndOnly: true
            };

            // smoothEnd
            if (inertiaPossible && !inertia) {
                modifiers.resetStatuses(statuses);

                modifierResult = modifiers.setAll(modifierArg);

                if (modifierResult.shouldMove && modifierResult.locked) {
                    smoothEnd = true;
                }
            }

            if (!(inertia || smoothEnd)) {
                return;
            }

            utils.copyCoords(status.upCoords, interaction.curCoords);

            interaction.pointers[0] = status.startEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiastart', interaction.element);

            status.t0 = now;

            status.active = true;
            status.allowResume = inertiaOptions.allowResume;
            interaction.simulation = status;

            target.fire(status.startEvent);

            if (inertia) {
                status.vx0 = interaction.pointerDelta.client.vx;
                status.vy0 = interaction.pointerDelta.client.vy;
                status.v0 = pointerSpeed;

                calcInertia(interaction, status);

                utils.extend(page, interaction.curCoords.page);

                page.x += status.xe;
                page.y += status.ye;

                modifiers.resetStatuses(statuses);

                modifierResult = modifiers.setAll(modifierArg);

                status.modifiedXe += modifierResult.dx;
                status.modifiedYe += modifierResult.dy;

                status.i = animationFrame.request(interaction.boundInertiaFrame);
            } else {
                status.smoothEnd = true;
                status.xe = modifierResult.dx;
                status.ye = modifierResult.dy;

                status.sx = status.sy = 0;

                status.i = animationFrame.request(interaction.boundSmoothEndFrame);
            }
        });

        Interaction.signals.on('stop-active', function (_ref3) {
            var interaction = _ref3.interaction;

            var status = interaction.inertiaStatus;

            if (status.active) {
                animationFrame.cancel(status.i);
                status.active = false;
                interaction.simulation = null;
            }
        });

        function calcInertia(interaction, status) {
            var inertiaOptions = interaction.target.options[interaction.prepared.name].inertia;
            var lambda = inertiaOptions.resistance;
            var inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;

            status.x0 = interaction.prevEvent.pageX;
            status.y0 = interaction.prevEvent.pageY;
            status.t0 = status.startEvent.timeStamp / 1000;
            status.sx = status.sy = 0;

            status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;
            status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;
            status.te = inertiaDur;

            status.lambda_v0 = lambda / status.v0;
            status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;
        }

        function inertiaFrame() {
            updateInertiaCoords(this);
            utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);

            var status = this.inertiaStatus;
            var options = this.target.options[this.prepared.name].inertia;
            var lambda = options.resistance;
            var t = new Date().getTime() / 1000 - status.t0;

            if (t < status.te) {

                var progress = 1 - (Math.exp(-lambda * t) - status.lambda_v0) / status.one_ve_v0;

                if (status.modifiedXe === status.xe && status.modifiedYe === status.ye) {
                    status.sx = status.xe * progress;
                    status.sy = status.ye * progress;
                } else {
                    var quadPoint = utils.getQuadraticCurvePoint(0, 0, status.xe, status.ye, status.modifiedXe, status.modifiedYe, progress);

                    status.sx = quadPoint.x;
                    status.sy = quadPoint.y;
                }

                this.doMove();

                status.i = animationFrame.request(this.boundInertiaFrame);
            } else {
                status.sx = status.modifiedXe;
                status.sy = status.modifiedYe;

                this.doMove();
                this.end(status.startEvent);
                status.active = false;
                this.simulation = null;
            }

            utils.copyCoords(this.prevCoords, this.curCoords);
        }

        function smoothEndFrame() {
            updateInertiaCoords(this);

            var status = this.inertiaStatus;
            var t = new Date().getTime() - status.t0;
            var duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;

            if (t < duration) {
                status.sx = utils.easeOutQuad(t, 0, status.xe, duration);
                status.sy = utils.easeOutQuad(t, 0, status.ye, duration);

                this.pointerMove(status.startEvent, status.startEvent);

                status.i = animationFrame.request(this.boundSmoothEndFrame);
            } else {
                status.sx = status.xe;
                status.sy = status.ye;

                this.pointerMove(status.startEvent, status.startEvent);
                this.end(status.startEvent);

                status.smoothEnd = status.active = false;
                this.simulation = null;
            }
        }

        function updateInertiaCoords(interaction) {
            var status = interaction.inertiaStatus;

            // return if inertia isn't running
            if (!status.active) {
                return;
            }

            var pageUp = status.upCoords.page;
            var clientUp = status.upCoords.client;

            utils.setCoords(interaction.curCoords, [{
                pageX: pageUp.x + status.sx,
                pageY: pageUp.y + status.sy,
                clientX: clientUp.x + status.sx,
                clientY: clientUp.y + status.sy
            }]);
        }

    },{"./InteractEvent":3,"./Interaction":5,"./modifiers/base":23,"./utils":44,"./utils/raf":50}],21:[function(require,module,exports){
        'use strict';

        /** @module interact */

        var browser = require('./utils/browser');
        var events = require('./utils/events');
        var utils = require('./utils');
        var scope = require('./scope');
        var Interactable = require('./Interactable');
        var Interaction = require('./Interaction');

        var globalEvents = {};

        /**
         * ```js
         * interact('#draggable').draggable(true);
         *
         * var rectables = interact('rect');
         * rectables
         *   .gesturable(true)
         *   .on('gesturemove', function (event) {
 *       // ...
 *   });
         * ```
         *
         * The methods of this variable can be used to set elements as interactables
         * and also to change various default settings.
         *
         * Calling it as a function and passing an element or a valid CSS selector
         * string returns an Interactable object which has various methods to configure
         * it.
         *
         * @global
         *
         * @param {Element | string} element The HTML or SVG Element to interact with
         * or CSS selector
         * @return {Interactable}
         */
        function interact(element, options) {
            var interactable = scope.interactables.get(element, options);

            if (!interactable) {
                interactable = new Interactable(element, options);
                interactable.events.global = globalEvents;
            }

            return interactable;
        }

        /**
         * Check if an element or selector has been set with the {@link interact}
         * function
         *
         * @alias module:interact.isSet
         *
         * @param {Element} element The Element being searched for
         * @return {boolean} Indicates if the element or CSS selector was previously
         * passed to interact
         */
        interact.isSet = function (element, options) {
            return scope.interactables.indexOfElement(element, options && options.context) !== -1;
        };

        /**
         * Add a global listener for an InteractEvent or adds a DOM event to `document`
         *
         * @alias module:interact.on
         *
         * @param {string | array | object} type The types of events to listen for
         * @param {function} listener The function event (s)
         * @param {object | boolean} [options] object or useCapture flag for
         * addEventListener
         * @return {object} interact
         */
        interact.on = function (type, listener, options) {
            if (utils.is.string(type) && type.search(' ') !== -1) {
                type = type.trim().split(/ +/);
            }

            if (utils.is.array(type)) {
                for (var _i = 0; _i < type.length; _i++) {
                    var _ref;

                    _ref = type[_i];
                    var eventType = _ref;

                    interact.on(eventType, listener, options);
                }

                return interact;
            }

            if (utils.is.object(type)) {
                for (var prop in type) {
                    interact.on(prop, type[prop], listener);
                }

                return interact;
            }

            // if it is an InteractEvent type, add listener to globalEvents
            if (utils.contains(Interactable.eventTypes, type)) {
                // if this type of event was never bound
                if (!globalEvents[type]) {
                    globalEvents[type] = [listener];
                } else {
                    globalEvents[type].push(listener);
                }
            }
            // If non InteractEvent type, addEventListener to document
            else {
                events.add(scope.document, type, listener, { options: options });
            }

            return interact;
        };

        /**
         * Removes a global InteractEvent listener or DOM event from `document`
         *
         * @alias module:interact.off
         *
         * @param {string | array | object} type The types of events that were listened
         * for
         * @param {function} listener The listener function to be removed
         * @param {object | boolean} options [options] object or useCapture flag for
         * removeEventListener
         * @return {object} interact
         */
        interact.off = function (type, listener, options) {
            if (utils.is.string(type) && type.search(' ') !== -1) {
                type = type.trim().split(/ +/);
            }

            if (utils.is.array(type)) {
                for (var _i2 = 0; _i2 < type.length; _i2++) {
                    var _ref2;

                    _ref2 = type[_i2];
                    var eventType = _ref2;

                    interact.off(eventType, listener, options);
                }

                return interact;
            }

            if (utils.is.object(type)) {
                for (var prop in type) {
                    interact.off(prop, type[prop], listener);
                }

                return interact;
            }

            if (!utils.contains(Interactable.eventTypes, type)) {
                events.remove(scope.document, type, listener, options);
            } else {
                var index = void 0;

                if (type in globalEvents && (index = globalEvents[type].indexOf(listener)) !== -1) {
                    globalEvents[type].splice(index, 1);
                }
            }

            return interact;
        };

        /**
         * Returns an object which exposes internal data

         * @alias module:interact.debug
         *
         * @return {object} An object with properties that outline the current state
         * and expose internal functions and variables
         */
        interact.debug = function () {
            return scope;
        };

// expose the functions used to calculate multi-touch properties
        interact.getPointerAverage = utils.pointerAverage;
        interact.getTouchBBox = utils.touchBBox;
        interact.getTouchDistance = utils.touchDistance;
        interact.getTouchAngle = utils.touchAngle;

        interact.getElementRect = utils.getElementRect;
        interact.getElementClientRect = utils.getElementClientRect;
        interact.matchesSelector = utils.matchesSelector;
        interact.closest = utils.closest;

        /**
         * @alias module:interact.supportsTouch
         *
         * @return {boolean} Whether or not the browser supports touch input
         */
        interact.supportsTouch = function () {
            return browser.supportsTouch;
        };

        /**
         * @alias module:interact.supportsPointerEvent
         *
         * @return {boolean} Whether or not the browser supports PointerEvents
         */
        interact.supportsPointerEvent = function () {
            return browser.supportsPointerEvent;
        };

        /**
         * Cancels all interactions (end events are not fired)
         *
         * @alias module:interact.stop
         *
         * @param {Event} event An event on which to call preventDefault()
         * @return {object} interact
         */
        interact.stop = function (event) {
            for (var i = scope.interactions.length - 1; i >= 0; i--) {
                scope.interactions[i].stop(event);
            }

            return interact;
        };

        /**
         * Returns or sets the distance the pointer must be moved before an action
         * sequence occurs. This also affects tolerance for tap events.
         *
         * @alias module:interact.pointerMoveTolerance
         *
         * @param {number} [newValue] The movement from the start position must be greater than this value
         * @return {interact | number}
         */
        interact.pointerMoveTolerance = function (newValue) {
            if (utils.is.number(newValue)) {
                Interaction.pointerMoveTolerance = newValue;

                return interact;
            }

            return Interaction.pointerMoveTolerance;
        };

        interact.addDocument = scope.addDocument;
        interact.removeDocument = scope.removeDocument;

        scope.interact = interact;

        module.exports = interact;

    },{"./Interactable":4,"./Interaction":5,"./scope":33,"./utils":44,"./utils/browser":36,"./utils/events":40}],22:[function(require,module,exports){
        'use strict';

        var Interactable = require('./Interactable');
        var Interaction = require('./Interaction');
        var scope = require('./scope');
        var is = require('./utils/is');
        var events = require('./utils/events');
        var browser = require('./utils/browser');

        var _require = require('./utils/domUtils'),
            nodeContains = _require.nodeContains,
            matchesSelector = _require.matchesSelector;

        /**
         * Returns or sets whether to prevent the browser's default behaviour in
         * response to pointer events. Can be set to:
         *  - `'always'` to always prevent
         *  - `'never'` to never prevent
         *  - `'auto'` to let interact.js try to determine what would be best
         *
         * @param {string} [newValue] `true`, `false` or `'auto'`
         * @return {string | Interactable} The current setting or this Interactable
         */


        Interactable.prototype.preventDefault = function (newValue) {
            if (/^(always|never|auto)$/.test(newValue)) {
                this.options.preventDefault = newValue;
                return this;
            }

            if (is.bool(newValue)) {
                this.options.preventDefault = newValue ? 'always' : 'never';
                return this;
            }

            return this.options.preventDefault;
        };

        Interactable.prototype.checkAndPreventDefault = function (event) {
            var setting = this.options.preventDefault;

            if (setting === 'never') {
                return;
            }

            if (setting === 'always') {
                event.preventDefault();
                return;
            }

            // setting === 'auto'

            // don't preventDefault of touch{start,move} events if the browser supports passive
            // events listeners. CSS touch-action and user-selecct should be used instead
            if (events.supportsPassive && /^touch(start|move)$/.test(event.type) && !browser.isIOS) {
                return;
            }

            // don't preventDefault of pointerdown events
            if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {
                return;
            }

            // don't preventDefault on editable elements
            if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {
                return;
            }

            event.preventDefault();
        };

        function onInteractionEvent(_ref) {
            var interaction = _ref.interaction,
                event = _ref.event;

            if (interaction.target) {
                interaction.target.checkAndPreventDefault(event);
            }
        }

        var _arr = ['down', 'move', 'up', 'cancel'];
        for (var _i = 0; _i < _arr.length; _i++) {
            var eventSignal = _arr[_i];
            Interaction.signals.on(eventSignal, onInteractionEvent);
        }

// prevent native HTML5 drag on interact.js target elements
        Interaction.docEvents.dragstart = function preventNativeDrag(event) {
            for (var _i2 = 0; _i2 < scope.interactions.length; _i2++) {
                var _ref2;

                _ref2 = scope.interactions[_i2];
                var interaction = _ref2;


                if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {

                    interaction.target.checkAndPreventDefault(event);
                    return;
                }
            }
        };

    },{"./Interactable":4,"./Interaction":5,"./scope":33,"./utils/browser":36,"./utils/domUtils":39,"./utils/events":40,"./utils/is":46}],23:[function(require,module,exports){
        'use strict';

        var InteractEvent = require('../InteractEvent');
        var Interaction = require('../Interaction');
        var extend = require('../utils/extend');

        var modifiers = {
            names: [],

            setOffsets: function setOffsets(arg) {
                var interaction = arg.interaction,
                    page = arg.pageCoords;
                var target = interaction.target,
                    element = interaction.element,
                    startOffset = interaction.startOffset;

                var rect = target.getRect(element);

                if (rect) {
                    startOffset.left = page.x - rect.left;
                    startOffset.top = page.y - rect.top;

                    startOffset.right = rect.right - page.x;
                    startOffset.bottom = rect.bottom - page.y;

                    if (!('width' in rect)) {
                        rect.width = rect.right - rect.left;
                    }
                    if (!('height' in rect)) {
                        rect.height = rect.bottom - rect.top;
                    }
                } else {
                    startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;
                }

                arg.rect = rect;
                arg.interactable = target;
                arg.element = element;

                for (var _i = 0; _i < modifiers.names.length; _i++) {
                    var _ref;

                    _ref = modifiers.names[_i];
                    var modifierName = _ref;

                    arg.options = target.options[interaction.prepared.name][modifierName];

                    if (!arg.options) {
                        continue;
                    }

                    interaction.modifierOffsets[modifierName] = modifiers[modifierName].setOffset(arg);
                }
            },

            setAll: function setAll(arg) {
                var interaction = arg.interaction,
                    statuses = arg.statuses,
                    preEnd = arg.preEnd,
                    requireEndOnly = arg.requireEndOnly;

                var result = {
                    dx: 0,
                    dy: 0,
                    changed: false,
                    locked: false,
                    shouldMove: true
                };

                arg.modifiedCoords = extend({}, arg.pageCoords);

                for (var _i2 = 0; _i2 < modifiers.names.length; _i2++) {
                    var _ref2;

                    _ref2 = modifiers.names[_i2];
                    var modifierName = _ref2;

                    var modifier = modifiers[modifierName];
                    var options = interaction.target.options[interaction.prepared.name][modifierName];

                    if (!shouldDo(options, preEnd, requireEndOnly)) {
                        continue;
                    }

                    arg.status = arg.status = statuses[modifierName];
                    arg.options = options;
                    arg.offset = arg.interaction.modifierOffsets[modifierName];

                    modifier.set(arg);

                    if (arg.status.locked) {
                        arg.modifiedCoords.x += arg.status.dx;
                        arg.modifiedCoords.y += arg.status.dy;

                        result.dx += arg.status.dx;
                        result.dy += arg.status.dy;

                        result.locked = true;
                    }
                }

                // a move should be fired if:
                //  - there are no modifiers enabled,
                //  - no modifiers are "locked" i.e. have changed the pointer's coordinates, or
                //  - the locked coords have changed since the last pointer move
                result.shouldMove = !arg.status || !result.locked || arg.status.changed;

                return result;
            },

            resetStatuses: function resetStatuses(statuses) {
                for (var _i3 = 0; _i3 < modifiers.names.length; _i3++) {
                    var _ref3;

                    _ref3 = modifiers.names[_i3];
                    var modifierName = _ref3;

                    var status = statuses[modifierName] || {};

                    status.dx = status.dy = 0;
                    status.modifiedX = status.modifiedY = NaN;
                    status.locked = false;
                    status.changed = true;

                    statuses[modifierName] = status;
                }

                return statuses;
            },

            start: function start(_ref4, signalName) {
                var interaction = _ref4.interaction;

                var arg = {
                    interaction: interaction,
                    pageCoords: (signalName === 'action-resume' ? interaction.curCoords : interaction.startCoords).page,
                    startOffset: interaction.startOffset,
                    statuses: interaction.modifierStatuses,
                    preEnd: false,
                    requireEndOnly: false
                };

                modifiers.setOffsets(arg);
                modifiers.resetStatuses(arg.statuses);

                arg.pageCoords = extend({}, interaction.startCoords.page);
                interaction.modifierResult = modifiers.setAll(arg);
            },

            beforeMove: function beforeMove(_ref5) {
                var interaction = _ref5.interaction,
                    preEnd = _ref5.preEnd,
                    interactingBeforeMove = _ref5.interactingBeforeMove;

                var modifierResult = modifiers.setAll({
                    interaction: interaction,
                    preEnd: preEnd,
                    pageCoords: interaction.curCoords.page,
                    statuses: interaction.modifierStatuses,
                    requireEndOnly: false
                });

                // don't fire an action move if a modifier would keep the event in the same
                // cordinates as before
                if (!modifierResult.shouldMove && interactingBeforeMove) {
                    interaction._dontFireMove = true;
                }

                interaction.modifierResult = modifierResult;
            },

            end: function end(_ref6) {
                var interaction = _ref6.interaction,
                    event = _ref6.event;

                for (var _i4 = 0; _i4 < modifiers.names.length; _i4++) {
                    var _ref7;

                    _ref7 = modifiers.names[_i4];
                    var modifierName = _ref7;

                    var options = interaction.target.options[interaction.prepared.name][modifierName];

                    // if the endOnly option is true for any modifier
                    if (shouldDo(options, true, true)) {
                        // fire a move event at the modified coordinates
                        interaction.doMove({ event: event, preEnd: true });
                        break;
                    }
                }
            },

            setXY: function setXY(arg) {
                var iEvent = arg.iEvent,
                    interaction = arg.interaction;

                var modifierArg = extend({}, arg);

                for (var i = 0; i < modifiers.names.length; i++) {
                    var modifierName = modifiers.names[i];
                    modifierArg.options = interaction.target.options[interaction.prepared.name][modifierName];

                    if (!modifierArg.options) {
                        continue;
                    }

                    var modifier = modifiers[modifierName];

                    modifierArg.status = interaction.modifierStatuses[modifierName];

                    iEvent[modifierName] = modifier.modifyCoords(modifierArg);
                }
            }
        };

        Interaction.signals.on('new', function (interaction) {
            interaction.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };
            interaction.modifierOffsets = {};
            interaction.modifierStatuses = modifiers.resetStatuses({});
            interaction.modifierResult = null;
        });

        Interaction.signals.on('action-start', modifiers.start);
        Interaction.signals.on('action-resume', modifiers.start);
        Interaction.signals.on('before-action-move', modifiers.beforeMove);
        Interaction.signals.on('action-end', modifiers.end);

        InteractEvent.signals.on('set-xy', modifiers.setXY);

        function shouldDo(options, preEnd, requireEndOnly) {
            return options && options.enabled && (preEnd || !options.endOnly) && (!requireEndOnly || options.endOnly);
        }

        module.exports = modifiers;

    },{"../InteractEvent":3,"../Interaction":5,"../utils/extend":41}],24:[function(require,module,exports){
        'use strict';

        var modifiers = require('./base');
        var utils = require('../utils');
        var defaultOptions = require('../defaultOptions');

        var restrict = {
            defaults: {
                enabled: false,
                endOnly: false,
                restriction: null,
                elementRect: null
            },

            setOffset: function setOffset(_ref) {
                var rect = _ref.rect,
                    startOffset = _ref.startOffset,
                    options = _ref.options;

                var elementRect = options && options.elementRect;
                var offset = {};

                if (rect && elementRect) {
                    offset.left = startOffset.left - rect.width * elementRect.left;
                    offset.top = startOffset.top - rect.height * elementRect.top;

                    offset.right = startOffset.right - rect.width * (1 - elementRect.right);
                    offset.bottom = startOffset.bottom - rect.height * (1 - elementRect.bottom);
                } else {
                    offset.left = offset.top = offset.right = offset.bottom = 0;
                }

                return offset;
            },

            set: function set(_ref2) {
                var modifiedCoords = _ref2.modifiedCoords,
                    interaction = _ref2.interaction,
                    status = _ref2.status,
                    options = _ref2.options;

                if (!options) {
                    return status;
                }

                var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, modifiedCoords);

                var restriction = getRestrictionRect(options.restriction, interaction, page);

                if (!restriction) {
                    return status;
                }

                status.dx = 0;
                status.dy = 0;
                status.locked = false;

                var rect = restriction;
                var modifiedX = page.x;
                var modifiedY = page.y;

                var offset = interaction.modifierOffsets.restrict;

                // object is assumed to have
                // x, y, width, height or
                // left, top, right, bottom
                if ('x' in restriction && 'y' in restriction) {
                    modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right, page.x), rect.x + offset.left);
                    modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top);
                } else {
                    modifiedX = Math.max(Math.min(rect.right - offset.right, page.x), rect.left + offset.left);
                    modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top);
                }

                status.dx = modifiedX - page.x;
                status.dy = modifiedY - page.y;

                status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;
                status.locked = !!(status.dx || status.dy);

                status.modifiedX = modifiedX;
                status.modifiedY = modifiedY;
            },

            modifyCoords: function modifyCoords(_ref3) {
                var page = _ref3.page,
                    client = _ref3.client,
                    status = _ref3.status,
                    phase = _ref3.phase,
                    options = _ref3.options;

                var elementRect = options && options.elementRect;

                if (options && options.enabled && !(phase === 'start' && elementRect && status.locked)) {

                    if (status.locked) {
                        page.x += status.dx;
                        page.y += status.dy;
                        client.x += status.dx;
                        client.y += status.dy;

                        return {
                            dx: status.dx,
                            dy: status.dy
                        };
                    }
                }
            },

            getRestrictionRect: getRestrictionRect
        };

        function getRestrictionRect(value, interaction, page) {
            if (utils.is.function(value)) {
                return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);
            } else {
                return utils.resolveRectLike(value, interaction.target, interaction.element);
            }
        }

        modifiers.restrict = restrict;
        modifiers.names.push('restrict');

        defaultOptions.perAction.restrict = restrict.defaults;

        module.exports = restrict;

    },{"../defaultOptions":18,"../utils":44,"./base":23}],25:[function(require,module,exports){
        'use strict';

// This module adds the options.resize.restrictEdges setting which sets min and
// max for the top, left, bottom and right edges of the target being resized.
//
// interact(target).resize({
//   edges: { top: true, left: true },
//   restrictEdges: {
//     inner: { top: 200, left: 200, right: 400, bottom: 400 },
//     outer: { top:   0, left:   0, right: 600, bottom: 600 },
//   },
// });

        var modifiers = require('./base');
        var utils = require('../utils');
        var rectUtils = require('../utils/rect');
        var defaultOptions = require('../defaultOptions');
        var resize = require('../actions/resize');

        var _require = require('./restrict'),
            getRestrictionRect = _require.getRestrictionRect;

        var noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };
        var noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };

        var restrictEdges = {
            defaults: {
                enabled: false,
                endOnly: false,
                min: null,
                max: null,
                offset: null
            },

            setOffset: function setOffset(_ref) {
                var interaction = _ref.interaction,
                    startOffset = _ref.startOffset,
                    options = _ref.options;

                if (!options) {
                    return utils.extend({}, startOffset);
                }

                var offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);

                if (offset) {
                    return {
                        top: startOffset.top + offset.y,
                        left: startOffset.left + offset.x,
                        bottom: startOffset.bottom + offset.y,
                        right: startOffset.right + offset.x
                    };
                }

                return startOffset;
            },

            set: function set(_ref2) {
                var modifiedCoords = _ref2.modifiedCoords,
                    interaction = _ref2.interaction,
                    status = _ref2.status,
                    offset = _ref2.offset,
                    options = _ref2.options;

                var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;

                if (!interaction.interacting() || !edges) {
                    return;
                }

                var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, modifiedCoords);
                var inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;
                var outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;

                var modifiedX = page.x;
                var modifiedY = page.y;

                status.dx = 0;
                status.dy = 0;
                status.locked = false;

                if (edges.top) {
                    modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);
                } else if (edges.bottom) {
                    modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);
                }
                if (edges.left) {
                    modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);
                } else if (edges.right) {
                    modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);
                }

                status.dx = modifiedX - page.x;
                status.dy = modifiedY - page.y;

                status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;
                status.locked = !!(status.dx || status.dy);

                status.modifiedX = modifiedX;
                status.modifiedY = modifiedY;
            },

            modifyCoords: function modifyCoords(_ref3) {
                var page = _ref3.page,
                    client = _ref3.client,
                    status = _ref3.status,
                    phase = _ref3.phase,
                    options = _ref3.options;

                if (options && options.enabled && !(phase === 'start' && status.locked)) {

                    if (status.locked) {
                        page.x += status.dx;
                        page.y += status.dy;
                        client.x += status.dx;
                        client.y += status.dy;

                        return {
                            dx: status.dx,
                            dy: status.dy
                        };
                    }
                }
            },

            noInner: noInner,
            noOuter: noOuter,
            getRestrictionRect: getRestrictionRect
        };

        modifiers.restrictEdges = restrictEdges;
        modifiers.names.push('restrictEdges');

        defaultOptions.perAction.restrictEdges = restrictEdges.defaults;
        resize.defaults.restrictEdges = restrictEdges.defaults;

        module.exports = restrictEdges;

    },{"../actions/resize":10,"../defaultOptions":18,"../utils":44,"../utils/rect":51,"./base":23,"./restrict":24}],26:[function(require,module,exports){
        'use strict';

// This module adds the options.resize.restrictSize setting which sets min and
// max width and height for the target being resized.
//
// interact(target).resize({
//   edges: { top: true, left: true },
//   restrictSize: {
//     min: { width: -600, height: -600 },
//     max: { width:  600, height:  600 },
//   },
// });

        var modifiers = require('./base');
        var restrictEdges = require('./restrictEdges');
        var utils = require('../utils');
        var rectUtils = require('../utils/rect');
        var defaultOptions = require('../defaultOptions');
        var resize = require('../actions/resize');

        var noMin = { width: -Infinity, height: -Infinity };
        var noMax = { width: +Infinity, height: +Infinity };

        var restrictSize = {
            defaults: {
                enabled: false,
                endOnly: false,
                min: null,
                max: null
            },

            setOffset: function setOffset(_ref) {
                var interaction = _ref.interaction;

                return interaction.startOffset;
            },

            set: function set(arg) {
                var interaction = arg.interaction,
                    options = arg.options;

                var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;

                if (!interaction.interacting() || !edges) {
                    return;
                }

                var rect = rectUtils.xywhToTlbr(interaction.resizeRects.inverted);

                var minSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.min, interaction)) || noMin;
                var maxSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.max, interaction)) || noMax;

                arg.options = {
                    enabled: options.enabled,
                    endOnly: options.endOnly,
                    inner: utils.extend({}, restrictEdges.noInner),
                    outer: utils.extend({}, restrictEdges.noOuter)
                };

                if (edges.top) {
                    arg.options.inner.top = rect.bottom - minSize.height;
                    arg.options.outer.top = rect.bottom - maxSize.height;
                } else if (edges.bottom) {
                    arg.options.inner.bottom = rect.top + minSize.height;
                    arg.options.outer.bottom = rect.top + maxSize.height;
                }
                if (edges.left) {
                    arg.options.inner.left = rect.right - minSize.width;
                    arg.options.outer.left = rect.right - maxSize.width;
                } else if (edges.right) {
                    arg.options.inner.right = rect.left + minSize.width;
                    arg.options.outer.right = rect.left + maxSize.width;
                }

                restrictEdges.set(arg);
            },

            modifyCoords: restrictEdges.modifyCoords
        };

        modifiers.restrictSize = restrictSize;
        modifiers.names.push('restrictSize');

        defaultOptions.perAction.restrictSize = restrictSize.defaults;
        resize.defaults.restrictSize = restrictSize.defaults;

        module.exports = restrictSize;

    },{"../actions/resize":10,"../defaultOptions":18,"../utils":44,"../utils/rect":51,"./base":23,"./restrictEdges":25}],27:[function(require,module,exports){
        'use strict';

        var modifiers = require('./base');
        var interact = require('../interact');
        var utils = require('../utils');
        var defaultOptions = require('../defaultOptions');

        var snap = {
            defaults: {
                enabled: false,
                endOnly: false,
                range: Infinity,
                targets: null,
                offsets: null,

                relativePoints: null
            },

            setOffset: function setOffset(_ref) {
                var interaction = _ref.interaction,
                    interactable = _ref.interactable,
                    element = _ref.element,
                    rect = _ref.rect,
                    startOffset = _ref.startOffset,
                    options = _ref.options;

                var offsets = [];
                var optionsOrigin = utils.rectToXY(utils.resolveRectLike(options.origin));
                var origin = optionsOrigin || utils.getOriginXY(interactable, element, interaction.prepared.name);
                options = options || interactable.options[interaction.prepared.name].snap || {};

                var snapOffset = void 0;

                if (options.offset === 'startCoords') {
                    snapOffset = {
                        x: interaction.startCoords.page.x - origin.x,
                        y: interaction.startCoords.page.y - origin.y
                    };
                } else {
                    var offsetRect = utils.resolveRectLike(options.offset, interactable, element, [interaction]);

                    snapOffset = utils.rectToXY(offsetRect) || { x: 0, y: 0 };
                }

                if (rect && options.relativePoints && options.relativePoints.length) {
                    for (var _i = 0; _i < options.relativePoints.length; _i++) {
                        var _ref3;

                        _ref3 = options.relativePoints[_i];
                        var _ref2 = _ref3;
                        var relativeX = _ref2.x;
                        var relativeY = _ref2.y;

                        offsets.push({
                            x: startOffset.left - rect.width * relativeX + snapOffset.x,
                            y: startOffset.top - rect.height * relativeY + snapOffset.y
                        });
                    }
                } else {
                    offsets.push(snapOffset);
                }

                return offsets;
            },

            set: function set(_ref4) {
                var interaction = _ref4.interaction,
                    modifiedCoords = _ref4.modifiedCoords,
                    status = _ref4.status,
                    options = _ref4.options,
                    offsets = _ref4.offset;

                var targets = [];
                var target = void 0;
                var page = void 0;
                var i = void 0;

                if (status.useStatusXY) {
                    page = { x: status.x, y: status.y };
                } else {
                    var origin = utils.getOriginXY(interaction.target, interaction.element, interaction.prepared.name);

                    page = utils.extend({}, modifiedCoords);

                    page.x -= origin.x;
                    page.y -= origin.y;
                }

                status.realX = page.x;
                status.realY = page.y;

                var len = options.targets ? options.targets.length : 0;

                for (var _i2 = 0; _i2 < offsets.length; _i2++) {
                    var _ref6;

                    _ref6 = offsets[_i2];
                    var _ref5 = _ref6;
                    var offsetX = _ref5.x;
                    var offsetY = _ref5.y;

                    var relativeX = page.x - offsetX;
                    var relativeY = page.y - offsetY;

                    for (var _i3 = 0; _i3 < (options.targets || []).length; _i3++) {
                        var _ref7;

                        _ref7 = (options.targets || [])[_i3];
                        var snapTarget = _ref7;

                        if (utils.is.function(snapTarget)) {
                            target = snapTarget(relativeX, relativeY, interaction);
                        } else {
                            target = snapTarget;
                        }

                        if (!target) {
                            continue;
                        }

                        targets.push({
                            x: utils.is.number(target.x) ? target.x + offsetX : relativeX,
                            y: utils.is.number(target.y) ? target.y + offsetY : relativeY,

                            range: utils.is.number(target.range) ? target.range : options.range
                        });
                    }
                }

                var closest = {
                    target: null,
                    inRange: false,
                    distance: 0,
                    range: 0,
                    dx: 0,
                    dy: 0
                };

                for (i = 0, len = targets.length; i < len; i++) {
                    target = targets[i];

                    var range = target.range;
                    var dx = target.x - page.x;
                    var dy = target.y - page.y;
                    var distance = utils.hypot(dx, dy);
                    var inRange = distance <= range;

                    // Infinite targets count as being out of range
                    // compared to non infinite ones that are in range
                    if (range === Infinity && closest.inRange && closest.range !== Infinity) {
                        inRange = false;
                    }

                    if (!closest.target || (inRange
                        // is the closest target in range?
                        ? closest.inRange && range !== Infinity
                            // the pointer is relatively deeper in this target
                            ? distance / range < closest.distance / closest.range
                            // this target has Infinite range and the closest doesn't
                            : range === Infinity && closest.range !== Infinity ||
                            // OR this target is closer that the previous closest
                            distance < closest.distance :
                        // The other is not in range and the pointer is closer to this target
                        !closest.inRange && distance < closest.distance)) {

                        closest.target = target;
                        closest.distance = distance;
                        closest.range = range;
                        closest.inRange = inRange;
                        closest.dx = dx;
                        closest.dy = dy;

                        status.range = range;
                    }
                }

                var snapChanged = void 0;

                if (closest.target) {
                    snapChanged = status.modifiedX !== closest.target.x || status.modifiedY !== closest.target.y;

                    status.modifiedX = closest.target.x;
                    status.modifiedY = closest.target.y;
                } else {
                    snapChanged = true;

                    status.modifiedX = NaN;
                    status.modifiedY = NaN;
                }

                status.dx = closest.dx;
                status.dy = closest.dy;

                status.changed = snapChanged || closest.inRange && !status.locked;
                status.locked = closest.inRange;
            },

            modifyCoords: function modifyCoords(_ref8) {
                var page = _ref8.page,
                    client = _ref8.client,
                    status = _ref8.status,
                    phase = _ref8.phase,
                    options = _ref8.options;

                var relativePoints = options && options.relativePoints;

                if (options && options.enabled && !(phase === 'start' && relativePoints && relativePoints.length)) {

                    if (status.locked) {
                        page.x += status.dx;
                        page.y += status.dy;
                        client.x += status.dx;
                        client.y += status.dy;
                    }

                    return {
                        range: status.range,
                        locked: status.locked,
                        x: status.modifiedX,
                        y: status.modifiedY,
                        realX: status.realX,
                        realY: status.realY,
                        dx: status.dx,
                        dy: status.dy
                    };
                }
            }
        };

        interact.createSnapGrid = function (grid) {
            return function (x, y) {
                var limits = grid.limits || {
                    left: -Infinity,
                    right: Infinity,
                    top: -Infinity,
                    bottom: Infinity
                };
                var offsetX = 0;
                var offsetY = 0;

                if (utils.is.object(grid.offset)) {
                    offsetX = grid.offset.x;
                    offsetY = grid.offset.y;
                }

                var gridx = Math.round((x - offsetX) / grid.x);
                var gridy = Math.round((y - offsetY) / grid.y);

                var newX = Math.max(limits.left, Math.min(limits.right, gridx * grid.x + offsetX));
                var newY = Math.max(limits.top, Math.min(limits.bottom, gridy * grid.y + offsetY));

                return {
                    x: newX,
                    y: newY,
                    range: grid.range
                };
            };
        };

        modifiers.snap = snap;
        modifiers.names.push('snap');

        defaultOptions.perAction.snap = snap.defaults;

        module.exports = snap;

    },{"../defaultOptions":18,"../interact":21,"../utils":44,"./base":23}],28:[function(require,module,exports){
        'use strict';

// This module allows snapping of the size of targets during resize
// interactions.

        var modifiers = require('./base');
        var snap = require('./snap');
        var defaultOptions = require('../defaultOptions');
        var resize = require('../actions/resize');
        var utils = require('../utils/');

        var snapSize = {
            defaults: {
                enabled: false,
                endOnly: false,
                range: Infinity,
                targets: null,
                offsets: null
            },

            setOffset: function setOffset(arg) {
                var interaction = arg.interaction,
                    options = arg.options;

                var edges = interaction.prepared.edges;

                if (!edges) {
                    return;
                }

                arg.options = {
                    relativePoints: [{
                        x: edges.left ? 0 : 1,
                        y: edges.top ? 0 : 1
                    }],
                    origin: { x: 0, y: 0 },
                    offset: 'self',
                    range: options.range
                };

                var offsets = snap.setOffset(arg);
                arg.options = options;

                return offsets;
            },

            set: function set(arg) {
                var interaction = arg.interaction,
                    options = arg.options,
                    offset = arg.offset,
                    modifiedCoords = arg.modifiedCoords;

                var page = utils.extend({}, modifiedCoords);
                var relativeX = page.x - offset[0].x;
                var relativeY = page.y - offset[0].y;

                arg.options = utils.extend({}, options);
                arg.options.targets = [];

                for (var _i = 0; _i < (options.targets || []).length; _i++) {
                    var _ref;

                    _ref = (options.targets || [])[_i];
                    var snapTarget = _ref;

                    var target = void 0;

                    if (utils.is.function(snapTarget)) {
                        target = snapTarget(relativeX, relativeY, interaction);
                    } else {
                        target = snapTarget;
                    }

                    if (!target) {
                        continue;
                    }

                    if ('width' in target && 'height' in target) {
                        target.x = target.width;
                        target.y = target.height;
                    }

                    arg.options.targets.push(target);
                }

                snap.set(arg);
            },

            modifyCoords: function modifyCoords(arg) {
                var options = arg.options;


                arg.options = utils.extend({}, options);
                arg.options.enabled = options.enabled;
                arg.options.relativePoints = [null];

                snap.modifyCoords(arg);
            }
        };

        modifiers.snapSize = snapSize;
        modifiers.names.push('snapSize');

        defaultOptions.perAction.snapSize = snapSize.defaults;
        resize.defaults.snapSize = snapSize.defaults;

        module.exports = snapSize;

    },{"../actions/resize":10,"../defaultOptions":18,"../utils/":44,"./base":23,"./snap":27}],29:[function(require,module,exports){
        'use strict';

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var pointerUtils = require('../utils/pointerUtils');

        module.exports = function () {
            /** */
            function PointerEvent(type, pointer, event, eventTarget, interaction) {
                _classCallCheck(this, PointerEvent);

                pointerUtils.pointerExtend(this, event);

                if (event !== pointer) {
                    pointerUtils.pointerExtend(this, pointer);
                }

                this.interaction = interaction;

                this.timeStamp = new Date().getTime();
                this.originalEvent = event;
                this.type = type;
                this.pointerId = pointerUtils.getPointerId(pointer);
                this.pointerType = pointerUtils.getPointerType(pointer);
                this.target = eventTarget;
                this.currentTarget = null;

                if (type === 'tap') {
                    var pointerIndex = interaction.getPointerIndex(pointer);
                    this.dt = this.timeStamp - interaction.downTimes[pointerIndex];

                    var interval = this.timeStamp - interaction.tapTime;

                    this.double = !!(interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === this.target && interval < 500);
                } else if (type === 'doubletap') {
                    this.dt = pointer.timeStamp - interaction.tapTime;
                }
            }

            PointerEvent.prototype.subtractOrigin = function subtractOrigin(_ref) {
                var originX = _ref.x,
                    originY = _ref.y;

                this.pageX -= originX;
                this.pageY -= originY;
                this.clientX -= originX;
                this.clientY -= originY;

                return this;
            };

            PointerEvent.prototype.addOrigin = function addOrigin(_ref2) {
                var originX = _ref2.x,
                    originY = _ref2.y;

                this.pageX += originX;
                this.pageY += originY;
                this.clientX += originX;
                this.clientY += originY;

                return this;
            };

            /** */


            PointerEvent.prototype.preventDefault = function preventDefault() {
                this.originalEvent.preventDefault();
            };

            /** */


            PointerEvent.prototype.stopPropagation = function stopPropagation() {
                this.propagationStopped = true;
            };

            /** */


            PointerEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {
                this.immediatePropagationStopped = this.propagationStopped = true;
            };

            return PointerEvent;
        }();

    },{"../utils/pointerUtils":49}],30:[function(require,module,exports){
        'use strict';

        var PointerEvent = require('./PointerEvent');
        var Interaction = require('../Interaction');
        var utils = require('../utils');
        var defaults = require('../defaultOptions');
        var signals = require('../utils/Signals').new();

        var simpleSignals = ['down', 'up', 'cancel'];
        var simpleEvents = ['down', 'up', 'cancel'];

        var pointerEvents = {
            PointerEvent: PointerEvent,
            fire: fire,
            collectEventTargets: collectEventTargets,
            signals: signals,
            defaults: {
                holdDuration: 600,
                ignoreFrom: null,
                allowFrom: null,
                origin: { x: 0, y: 0 }
            },
            types: ['down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold']
        };

        function fire(arg) {
            var interaction = arg.interaction,
                pointer = arg.pointer,
                event = arg.event,
                eventTarget = arg.eventTarget,
                _arg$type = arg.type,
                type = _arg$type === undefined ? arg.pointerEvent.type : _arg$type,
                _arg$targets = arg.targets,
                targets = _arg$targets === undefined ? collectEventTargets(arg) : _arg$targets,
                _arg$pointerEvent = arg.pointerEvent,
                pointerEvent = _arg$pointerEvent === undefined ? new PointerEvent(type, pointer, event, eventTarget, interaction) : _arg$pointerEvent;


            var signalArg = {
                interaction: interaction,
                pointer: pointer,
                event: event,
                eventTarget: eventTarget,
                targets: targets,
                type: type,
                pointerEvent: pointerEvent
            };

            for (var i = 0; i < targets.length; i++) {
                var target = targets[i];

                for (var prop in target.props || {}) {
                    pointerEvent[prop] = target.props[prop];
                }

                var origin = utils.getOriginXY(target.eventable, target.element);

                pointerEvent.subtractOrigin(origin);
                pointerEvent.eventable = target.eventable;
                pointerEvent.currentTarget = target.element;

                target.eventable.fire(pointerEvent);

                pointerEvent.addOrigin(origin);

                if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].element !== pointerEvent.currentTarget) {
                    break;
                }
            }

            signals.fire('fired', signalArg);

            if (type === 'tap') {
                // if pointerEvent should make a double tap, create and fire a doubletap
                // PointerEvent and use that as the prevTap
                var prevTap = pointerEvent.double ? fire({
                    interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,
                    type: 'doubletap'
                }) : pointerEvent;

                interaction.prevTap = prevTap;
                interaction.tapTime = prevTap.timeStamp;
            }

            return pointerEvent;
        }

        function collectEventTargets(_ref) {
            var interaction = _ref.interaction,
                pointer = _ref.pointer,
                event = _ref.event,
                eventTarget = _ref.eventTarget,
                type = _ref.type;

            var pointerIndex = interaction.getPointerIndex(pointer);

            // do not fire a tap event if the pointer was moved before being lifted
            if (type === 'tap' && (interaction.pointerWasMoved
                // or if the pointerup target is different to the pointerdown target
                || !(interaction.downTargets[pointerIndex] && interaction.downTargets[pointerIndex] === eventTarget))) {
                return [];
            }

            var path = utils.getPath(eventTarget);
            var signalArg = {
                interaction: interaction,
                pointer: pointer,
                event: event,
                eventTarget: eventTarget,
                type: type,
                path: path,
                targets: [],
                element: null
            };

            for (var _i = 0; _i < path.length; _i++) {
                var _ref2;

                _ref2 = path[_i];
                var element = _ref2;

                signalArg.element = element;

                signals.fire('collect-targets', signalArg);
            }

            if (type === 'hold') {
                signalArg.targets = signalArg.targets.filter(function (target) {
                    return target.eventable.options.holdDuration === interaction.holdTimers[pointerIndex].duration;
                });
            }

            return signalArg.targets;
        }

        Interaction.signals.on('update-pointer-down', function (_ref3) {
            var interaction = _ref3.interaction,
                pointerIndex = _ref3.pointerIndex;

            interaction.holdTimers[pointerIndex] = { duration: Infinity, timeout: null };
        });

        Interaction.signals.on('remove-pointer', function (_ref4) {
            var interaction = _ref4.interaction,
                pointerIndex = _ref4.pointerIndex;

            interaction.holdTimers.splice(pointerIndex, 1);
        });

        Interaction.signals.on('move', function (_ref5) {
            var interaction = _ref5.interaction,
                pointer = _ref5.pointer,
                event = _ref5.event,
                eventTarget = _ref5.eventTarget,
                duplicateMove = _ref5.duplicateMove;

            var pointerIndex = interaction.getPointerIndex(pointer);

            if (!duplicateMove && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {
                if (interaction.pointerIsDown) {
                    clearTimeout(interaction.holdTimers[pointerIndex].timeout);
                }

                fire({
                    interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,
                    type: 'move'
                });
            }
        });

        Interaction.signals.on('down', function (_ref6) {
            var interaction = _ref6.interaction,
                pointer = _ref6.pointer,
                event = _ref6.event,
                eventTarget = _ref6.eventTarget,
                pointerIndex = _ref6.pointerIndex;

            var timer = interaction.holdTimers[pointerIndex];
            var path = utils.getPath(eventTarget);
            var signalArg = {
                interaction: interaction,
                pointer: pointer,
                event: event,
                eventTarget: eventTarget,
                type: 'hold',
                targets: [],
                path: path,
                element: null
            };

            for (var _i2 = 0; _i2 < path.length; _i2++) {
                var _ref7;

                _ref7 = path[_i2];
                var element = _ref7;

                signalArg.element = element;

                signals.fire('collect-targets', signalArg);
            }

            if (!signalArg.targets.length) {
                return;
            }

            var minDuration = Infinity;

            for (var _i3 = 0; _i3 < signalArg.targets.length; _i3++) {
                var _ref8;

                _ref8 = signalArg.targets[_i3];
                var target = _ref8;

                var holdDuration = target.eventable.options.holdDuration;

                if (holdDuration < minDuration) {
                    minDuration = holdDuration;
                }
            }

            timer.duration = minDuration;
            timer.timeout = setTimeout(function () {
                fire({
                    interaction: interaction,
                    eventTarget: eventTarget,
                    pointer: pointer,
                    event: event,
                    type: 'hold'
                });
            }, minDuration);
        });

        Interaction.signals.on('up', function (_ref9) {
            var interaction = _ref9.interaction,
                pointer = _ref9.pointer,
                event = _ref9.event,
                eventTarget = _ref9.eventTarget;

            if (!interaction.pointerWasMoved) {
                fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: 'tap' });
            }
        });

        var _arr = ['up', 'cancel'];
        for (var _i4 = 0; _i4 < _arr.length; _i4++) {
            var signalName = _arr[_i4];
            Interaction.signals.on(signalName, function (_ref11) {
                var interaction = _ref11.interaction,
                    pointerIndex = _ref11.pointerIndex;

                if (interaction.holdTimers[pointerIndex]) {
                    clearTimeout(interaction.holdTimers[pointerIndex].timeout);
                }
            });
        }

        function createSignalListener(type) {
            return function (_ref10) {
                var interaction = _ref10.interaction,
                    pointer = _ref10.pointer,
                    event = _ref10.event,
                    eventTarget = _ref10.eventTarget;

                fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: type });
            };
        }

        for (var i = 0; i < simpleSignals.length; i++) {
            Interaction.signals.on(simpleSignals[i], createSignalListener(simpleEvents[i]));
        }

        Interaction.signals.on('new', function (interaction) {
            interaction.prevTap = null; // the most recent tap event on this interaction
            interaction.tapTime = 0; // time of the most recent tap event
            interaction.holdTimers = []; // [{ duration, timeout }]
        });

        defaults.pointerEvents = pointerEvents.defaults;
        module.exports = pointerEvents;

    },{"../Interaction":5,"../defaultOptions":18,"../utils":44,"../utils/Signals":34,"./PointerEvent":29}],31:[function(require,module,exports){
        'use strict';

        var pointerEvents = require('./base');
        var Interaction = require('../Interaction');

        pointerEvents.signals.on('new', onNew);
        pointerEvents.signals.on('fired', onFired);

        var _arr = ['move', 'up', 'cancel', 'endall'];
        for (var _i = 0; _i < _arr.length; _i++) {
            var signal = _arr[_i];
            Interaction.signals.on(signal, endHoldRepeat);
        }

        function onNew(_ref) {
            var pointerEvent = _ref.pointerEvent;

            if (pointerEvent.type !== 'hold') {
                return;
            }

            pointerEvent.count = (pointerEvent.count || 0) + 1;
        }

        function onFired(_ref2) {
            var interaction = _ref2.interaction,
                pointerEvent = _ref2.pointerEvent,
                eventTarget = _ref2.eventTarget,
                targets = _ref2.targets;

            if (pointerEvent.type !== 'hold' || !targets.length) {
                return;
            }

            // get the repeat interval from the first eventable
            var interval = targets[0].eventable.options.holdRepeatInterval;

            // don't repeat if the interval is 0 or less
            if (interval <= 0) {
                return;
            }

            // set a timeout to fire the holdrepeat event
            interaction.holdIntervalHandle = setTimeout(function () {
                pointerEvents.fire({
                    interaction: interaction,
                    eventTarget: eventTarget,
                    type: 'hold',
                    pointer: pointerEvent,
                    event: pointerEvent
                });
            }, interval);
        }

        function endHoldRepeat(_ref3) {
            var interaction = _ref3.interaction;

            // set the interaction's holdStopTime property
            // to stop further holdRepeat events
            if (interaction.holdIntervalHandle) {
                clearInterval(interaction.holdIntervalHandle);
                interaction.holdIntervalHandle = null;
            }
        }

// don't repeat by default
        pointerEvents.defaults.holdRepeatInterval = 0;
        pointerEvents.types.push('holdrepeat');

        module.exports = {
            onNew: onNew,
            onFired: onFired,
            endHoldRepeat: endHoldRepeat
        };

    },{"../Interaction":5,"./base":30}],32:[function(require,module,exports){
        'use strict';

        var pointerEvents = require('./base');
        var Interactable = require('../Interactable');
        var is = require('../utils/is');
        var scope = require('../scope');
        var extend = require('../utils/extend');

        var _require = require('../utils/arr'),
            merge = _require.merge;

        pointerEvents.signals.on('collect-targets', function (_ref) {
            var targets = _ref.targets,
                element = _ref.element,
                type = _ref.type,
                eventTarget = _ref.eventTarget;

            scope.interactables.forEachMatch(element, function (interactable) {
                var eventable = interactable.events;
                var options = eventable.options;

                if (eventable[type] && is.element(element) && interactable.testIgnoreAllow(options, element, eventTarget)) {

                    targets.push({
                        element: element,
                        eventable: eventable,
                        props: { interactable: interactable }
                    });
                }
            });
        });

        Interactable.signals.on('new', function (_ref2) {
            var interactable = _ref2.interactable;

            interactable.events.getRect = function (element) {
                return interactable.getRect(element);
            };
        });

        Interactable.signals.on('set', function (_ref3) {
            var interactable = _ref3.interactable,
                options = _ref3.options;

            extend(interactable.events.options, pointerEvents.defaults);
            extend(interactable.events.options, options);
        });

        merge(Interactable.eventTypes, pointerEvents.types);

        Interactable.prototype.pointerEvents = function (options) {
            extend(this.events.options, options);

            return this;
        };

        var __backCompatOption = Interactable.prototype._backCompatOption;

        Interactable.prototype._backCompatOption = function (optionName, newValue) {
            var ret = __backCompatOption.call(this, optionName, newValue);

            if (ret === this) {
                this.events.options[optionName] = newValue;
            }

            return ret;
        };

        Interactable.settingsMethods.push('pointerEvents');

    },{"../Interactable":4,"../scope":33,"../utils/arr":35,"../utils/extend":41,"../utils/is":46,"./base":30}],33:[function(require,module,exports){
        'use strict';

        var utils = require('./utils');
        var events = require('./utils/events');
        var signals = require('./utils/Signals').new();

        var _require = require('./utils/window'),
            getWindow = _require.getWindow;

        var scope = {
            signals: signals,
            events: events,
            utils: utils,

            // main document
            document: require('./utils/domObjects').document,
            // all documents being listened to
            documents: [],

            addDocument: function addDocument(doc, win) {
                // do nothing if document is already known
                if (utils.contains(scope.documents, doc)) {
                    return false;
                }

                win = win || getWindow(doc);

                scope.documents.push(doc);
                events.documents.push(doc);

                // don't add an unload event for the main document
                // so that the page may be cached in browser history
                if (doc !== scope.document) {
                    events.add(win, 'unload', scope.onWindowUnload);
                }

                signals.fire('add-document', { doc: doc, win: win });
            },

            removeDocument: function removeDocument(doc, win) {
                var index = scope.documents.indexOf(doc);

                win = win || getWindow(doc);

                events.remove(win, 'unload', scope.onWindowUnload);

                scope.documents.splice(index, 1);
                events.documents.splice(index, 1);

                signals.fire('remove-document', { win: win, doc: doc });
            },

            onWindowUnload: function onWindowUnload() {
                scope.removeDocument(this.document, this);
            }
        };

        module.exports = scope;

    },{"./utils":44,"./utils/Signals":34,"./utils/domObjects":38,"./utils/events":40,"./utils/window":52}],34:[function(require,module,exports){
        "use strict";

        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

        var Signals = function () {
            function Signals() {
                _classCallCheck(this, Signals);

                this.listeners = {
                    // signalName: [listeners],
                };
            }

            Signals.prototype.on = function on(name, listener) {
                if (!this.listeners[name]) {
                    this.listeners[name] = [listener];
                    return;
                }

                this.listeners[name].push(listener);
            };

            Signals.prototype.off = function off(name, listener) {
                if (!this.listeners[name]) {
                    return;
                }

                var index = this.listeners[name].indexOf(listener);

                if (index !== -1) {
                    this.listeners[name].splice(index, 1);
                }
            };

            Signals.prototype.fire = function fire(name, arg) {
                var targetListeners = this.listeners[name];

                if (!targetListeners) {
                    return;
                }

                for (var _i = 0; _i < targetListeners.length; _i++) {
                    var _ref;

                    _ref = targetListeners[_i];
                    var listener = _ref;

                    if (listener(arg, name) === false) {
                        return;
                    }
                }
            };

            return Signals;
        }();

        Signals.new = function () {
            return new Signals();
        };

        module.exports = Signals;

    },{}],35:[function(require,module,exports){
        "use strict";

        function contains(array, target) {
            return array.indexOf(target) !== -1;
        }

        function merge(target, source) {
            for (var _i = 0; _i < source.length; _i++) {
                var _ref;

                _ref = source[_i];
                var item = _ref;

                target.push(item);
            }

            return target;
        }

        module.exports = {
            contains: contains,
            merge: merge
        };

    },{}],36:[function(require,module,exports){
        'use strict';

        var _require = require('./window'),
            window = _require.window;

        var is = require('./is');
        var domObjects = require('./domObjects');

        var Element = domObjects.Element;
        var navigator = window.navigator;

        var browser = {
            // Does the browser support touch input?
            supportsTouch: !!('ontouchstart' in window || is.function(window.DocumentTouch) && domObjects.document instanceof window.DocumentTouch),

            // Does the browser support PointerEvents
            supportsPointerEvent: !!domObjects.PointerEvent,

            isIOS: /iP(hone|od|ad)/.test(navigator.platform),

            // scrolling doesn't change the result of getClientRects on iOS 7
            isIOS7: /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\d]/.test(navigator.appVersion),

            isIe9: /MSIE 9/.test(navigator.userAgent),

            // prefix matchesSelector
            prefixedMatchesSelector: 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',

            pEventTypes: domObjects.PointerEvent ? domObjects.PointerEvent === window.MSPointerEvent ? {
                up: 'MSPointerUp',
                down: 'MSPointerDown',
                over: 'mouseover',
                out: 'mouseout',
                move: 'MSPointerMove',
                cancel: 'MSPointerCancel'
            } : {
                up: 'pointerup',
                down: 'pointerdown',
                over: 'pointerover',
                out: 'pointerout',
                move: 'pointermove',
                cancel: 'pointercancel'
            } : null,

            // because Webkit and Opera still use 'mousewheel' event type
            wheelEvent: 'onmousewheel' in domObjects.document ? 'mousewheel' : 'wheel'

        };

// Opera Mobile must be handled differently
        browser.isOperaMobile = navigator.appName === 'Opera' && browser.supportsTouch && navigator.userAgent.match('Presto');

        module.exports = browser;

    },{"./domObjects":38,"./is":46,"./window":52}],37:[function(require,module,exports){
        'use strict';

        var is = require('./is');

        module.exports = function clone(source) {
            var dest = {};
            for (var prop in source) {
                if (is.plainObject(source[prop])) {
                    dest[prop] = clone(source[prop]);
                } else {
                    dest[prop] = source[prop];
                }
            }
            return dest;
        };

    },{"./is":46}],38:[function(require,module,exports){
        'use strict';

        var domObjects = {};
        var win = require('./window').window;

        function blank() {}

        domObjects.document = win.document;
        domObjects.DocumentFragment = win.DocumentFragment || blank;
        domObjects.SVGElement = win.SVGElement || blank;
        domObjects.SVGSVGElement = win.SVGSVGElement || blank;
        domObjects.SVGElementInstance = win.SVGElementInstance || blank;
        domObjects.Element = win.Element || blank;
        domObjects.HTMLElement = win.HTMLElement || domObjects.Element;

        domObjects.Event = win.Event;
        domObjects.Touch = win.Touch || blank;
        domObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;

        module.exports = domObjects;

    },{"./window":52}],39:[function(require,module,exports){
        'use strict';

        var win = require('./window');
        var browser = require('./browser');
        var is = require('./is');
        var domObjects = require('./domObjects');

        var domUtils = {
            nodeContains: function nodeContains(parent, child) {
                while (child) {
                    if (child === parent) {
                        return true;
                    }

                    child = child.parentNode;
                }

                return false;
            },

            closest: function closest(element, selector) {
                while (is.element(element)) {
                    if (domUtils.matchesSelector(element, selector)) {
                        return element;
                    }

                    element = domUtils.parentNode(element);
                }

                return null;
            },

            parentNode: function parentNode(node) {
                var parent = node.parentNode;

                if (is.docFrag(parent)) {
                    // skip past #shado-root fragments
                    while ((parent = parent.host) && is.docFrag(parent)) {
                        continue;
                    }

                    return parent;
                }

                return parent;
            },

            matchesSelector: function matchesSelector(element, selector) {
                // remove /deep/ from selectors if shadowDOM polyfill is used
                if (win.window !== win.realWindow) {
                    selector = selector.replace(/\/deep\//g, ' ');
                }

                return element[browser.prefixedMatchesSelector](selector);
            },

            // Test for the element that's "above" all other qualifiers
            indexOfDeepestElement: function indexOfDeepestElement(elements) {
                var deepestZoneParents = [];
                var dropzoneParents = [];
                var dropzone = void 0;
                var deepestZone = elements[0];
                var index = deepestZone ? 0 : -1;
                var parent = void 0;
                var child = void 0;
                var i = void 0;
                var n = void 0;

                for (i = 1; i < elements.length; i++) {
                    dropzone = elements[i];

                    // an element might belong to multiple selector dropzones
                    if (!dropzone || dropzone === deepestZone) {
                        continue;
                    }

                    if (!deepestZone) {
                        deepestZone = dropzone;
                        index = i;
                        continue;
                    }

                    // check if the deepest or current are document.documentElement or document.rootElement
                    // - if the current dropzone is, do nothing and continue
                    if (dropzone.parentNode === dropzone.ownerDocument) {
                        continue;
                    }
                    // - if deepest is, update with the current dropzone and continue to next
                    else if (deepestZone.parentNode === dropzone.ownerDocument) {
                        deepestZone = dropzone;
                        index = i;
                        continue;
                    }

                    if (!deepestZoneParents.length) {
                        parent = deepestZone;
                        while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {
                            deepestZoneParents.unshift(parent);
                            parent = parent.parentNode;
                        }
                    }

                    // if this element is an svg element and the current deepest is
                    // an HTMLElement
                    if (deepestZone instanceof domObjects.HTMLElement && dropzone instanceof domObjects.SVGElement && !(dropzone instanceof domObjects.SVGSVGElement)) {

                        if (dropzone === deepestZone.parentNode) {
                            continue;
                        }

                        parent = dropzone.ownerSVGElement;
                    } else {
                        parent = dropzone;
                    }

                    dropzoneParents = [];

                    while (parent.parentNode !== parent.ownerDocument) {
                        dropzoneParents.unshift(parent);
                        parent = parent.parentNode;
                    }

                    n = 0;

                    // get (position of last common ancestor) + 1
                    while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {
                        n++;
                    }

                    var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];

                    child = parents[0].lastChild;

                    while (child) {
                        if (child === parents[1]) {
                            deepestZone = dropzone;
                            index = i;
                            deepestZoneParents = [];

                            break;
                        } else if (child === parents[2]) {
                            break;
                        }

                        child = child.previousSibling;
                    }
                }

                return index;
            },

            matchesUpTo: function matchesUpTo(element, selector, limit) {
                while (is.element(element)) {
                    if (domUtils.matchesSelector(element, selector)) {
                        return true;
                    }

                    element = domUtils.parentNode(element);

                    if (element === limit) {
                        return domUtils.matchesSelector(element, selector);
                    }
                }

                return false;
            },

            getActualElement: function getActualElement(element) {
                return element instanceof domObjects.SVGElementInstance ? element.correspondingUseElement : element;
            },

            getScrollXY: function getScrollXY(relevantWindow) {
                relevantWindow = relevantWindow || win.window;
                return {
                    x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,
                    y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop
                };
            },

            getElementClientRect: function getElementClientRect(element) {
                var clientRect = element instanceof domObjects.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];

                return clientRect && {
                    left: clientRect.left,
                    right: clientRect.right,
                    top: clientRect.top,
                    bottom: clientRect.bottom,
                    width: clientRect.width || clientRect.right - clientRect.left,
                    height: clientRect.height || clientRect.bottom - clientRect.top
                };
            },

            getElementRect: function getElementRect(element) {
                var clientRect = domUtils.getElementClientRect(element);

                if (!browser.isIOS7 && clientRect) {
                    var scroll = domUtils.getScrollXY(win.getWindow(element));

                    clientRect.left += scroll.x;
                    clientRect.right += scroll.x;
                    clientRect.top += scroll.y;
                    clientRect.bottom += scroll.y;
                }

                return clientRect;
            },

            getPath: function getPath(element) {
                var path = [];

                while (element) {
                    path.push(element);
                    element = domUtils.parentNode(element);
                }

                return path;
            },

            trySelector: function trySelector(value) {
                if (!is.string(value)) {
                    return false;
                }

                // an exception will be raised if it is invalid
                domObjects.document.querySelector(value);
                return true;
            }
        };

        module.exports = domUtils;

    },{"./browser":36,"./domObjects":38,"./is":46,"./window":52}],40:[function(require,module,exports){
        'use strict';

        var is = require('./is');
        var domUtils = require('./domUtils');
        var pointerUtils = require('./pointerUtils');
        var pExtend = require('./pointerExtend');

        var _require = require('./window'),
            window = _require.window;

        var _require2 = require('./arr'),
            contains = _require2.contains;

        var elements = [];
        var targets = [];

// {
//   type: {
//     selectors: ['selector', ...],
//     contexts : [document, ...],
//     listeners: [[listener, capture, passive], ...]
//   }
//  }
        var delegatedEvents = {};
        var documents = [];

        var supportsOptions = function () {
            var supported = false;

            window.document.createElement('div').addEventListener('test', null, {
                get capture() {
                    supported = true;
                }
            });

            return supported;
        }();

        function add(element, type, listener, optionalArg) {
            var options = getOptions(optionalArg);
            var elementIndex = elements.indexOf(element);
            var target = targets[elementIndex];

            if (!target) {
                target = {
                    events: {},
                    typeCount: 0
                };

                elementIndex = elements.push(element) - 1;
                targets.push(target);
            }

            if (!target.events[type]) {
                target.events[type] = [];
                target.typeCount++;
            }

            if (!contains(target.events[type], listener)) {
                element.addEventListener(type, listener, supportsOptions ? options : !!options.capture);
                target.events[type].push(listener);
            }
        }

        function remove(element, type, listener, optionalArg) {
            var options = getOptions(optionalArg);
            var elementIndex = elements.indexOf(element);
            var target = targets[elementIndex];

            if (!target || !target.events) {
                return;
            }

            if (type === 'all') {
                for (type in target.events) {
                    if (target.events.hasOwnProperty(type)) {
                        remove(element, type, 'all');
                    }
                }
                return;
            }

            if (target.events[type]) {
                var len = target.events[type].length;

                if (listener === 'all') {
                    for (var i = 0; i < len; i++) {
                        remove(element, type, target.events[type][i], options);
                    }
                    return;
                } else {
                    for (var _i = 0; _i < len; _i++) {
                        if (target.events[type][_i] === listener) {
                            element.removeEventListener('on' + type, listener, supportsOptions ? options : !!options.capture);
                            target.events[type].splice(_i, 1);

                            break;
                        }
                    }
                }

                if (target.events[type] && target.events[type].length === 0) {
                    target.events[type] = null;
                    target.typeCount--;
                }
            }

            if (!target.typeCount) {
                targets.splice(elementIndex, 1);
                elements.splice(elementIndex, 1);
            }
        }

        function addDelegate(selector, context, type, listener, optionalArg) {
            var options = getOptions(optionalArg);
            if (!delegatedEvents[type]) {
                delegatedEvents[type] = {
                    selectors: [],
                    contexts: [],
                    listeners: []
                };

                // add delegate listener functions
                for (var _i2 = 0; _i2 < documents.length; _i2++) {
                    var doc = documents[_i2];
                    add(doc, type, delegateListener);
                    add(doc, type, delegateUseCapture, true);
                }
            }

            var delegated = delegatedEvents[type];
            var index = void 0;

            for (index = delegated.selectors.length - 1; index >= 0; index--) {
                if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {
                    break;
                }
            }

            if (index === -1) {
                index = delegated.selectors.length;

                delegated.selectors.push(selector);
                delegated.contexts.push(context);
                delegated.listeners.push([]);
            }

            // keep listener and capture and passive flags
            delegated.listeners[index].push([listener, !!options.capture, options.passive]);
        }

        function removeDelegate(selector, context, type, listener, optionalArg) {
            var options = getOptions(optionalArg);
            var delegated = delegatedEvents[type];
            var matchFound = false;
            var index = void 0;

            if (!delegated) {
                return;
            }

            // count from last index of delegated to 0
            for (index = delegated.selectors.length - 1; index >= 0; index--) {
                // look for matching selector and context Node
                if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {

                    var listeners = delegated.listeners[index];

                    // each item of the listeners array is an array: [function, capture, passive]
                    for (var i = listeners.length - 1; i >= 0; i--) {
                        var _listeners$i = listeners[i],
                            fn = _listeners$i[0],
                            capture = _listeners$i[1],
                            passive = _listeners$i[2];

                        // check if the listener functions and capture and passive flags match

                        if (fn === listener && capture === !!options.capture && passive === options.passive) {
                            // remove the listener from the array of listeners
                            listeners.splice(i, 1);

                            // if all listeners for this interactable have been removed
                            // remove the interactable from the delegated arrays
                            if (!listeners.length) {
                                delegated.selectors.splice(index, 1);
                                delegated.contexts.splice(index, 1);
                                delegated.listeners.splice(index, 1);

                                // remove delegate function from context
                                remove(context, type, delegateListener);
                                remove(context, type, delegateUseCapture, true);

                                // remove the arrays if they are empty
                                if (!delegated.selectors.length) {
                                    delegatedEvents[type] = null;
                                }
                            }

                            // only remove one listener
                            matchFound = true;
                            break;
                        }
                    }

                    if (matchFound) {
                        break;
                    }
                }
            }
        }

// bound to the interactable context when a DOM event
// listener is added to a selector interactable
        function delegateListener(event, optionalArg) {
            var options = getOptions(optionalArg);
            var fakeEvent = {};
            var delegated = delegatedEvents[event.type];

            var _pointerUtils$getEven = pointerUtils.getEventTargets(event),
                eventTarget = _pointerUtils$getEven[0];

            var element = eventTarget;

            // duplicate the event so that currentTarget can be changed
            pExtend(fakeEvent, event);

            fakeEvent.originalEvent = event;
            fakeEvent.preventDefault = preventOriginalDefault;

            // climb up document tree looking for selector matches
            while (is.element(element)) {
                for (var i = 0; i < delegated.selectors.length; i++) {
                    var selector = delegated.selectors[i];
                    var context = delegated.contexts[i];

                    if (domUtils.matchesSelector(element, selector) && domUtils.nodeContains(context, eventTarget) && domUtils.nodeContains(context, element)) {

                        var listeners = delegated.listeners[i];

                        fakeEvent.currentTarget = element;

                        for (var j = 0; j < listeners.length; j++) {
                            var _listeners$j = listeners[j],
                                fn = _listeners$j[0],
                                capture = _listeners$j[1],
                                passive = _listeners$j[2];


                            if (capture === !!options.capture && passive === options.passive) {
                                fn(fakeEvent);
                            }
                        }
                    }
                }

                element = domUtils.parentNode(element);
            }
        }

        function delegateUseCapture(event) {
            return delegateListener.call(this, event, true);
        }

        function preventOriginalDefault() {
            this.originalEvent.preventDefault();
        }

        function getOptions(param) {
            return is.object(param) ? param : { capture: param };
        }

        module.exports = {
            add: add,
            remove: remove,

            addDelegate: addDelegate,
            removeDelegate: removeDelegate,

            delegateListener: delegateListener,
            delegateUseCapture: delegateUseCapture,
            delegatedEvents: delegatedEvents,
            documents: documents,

            supportsOptions: supportsOptions,

            _elements: elements,
            _targets: targets
        };

    },{"./arr":35,"./domUtils":39,"./is":46,"./pointerExtend":48,"./pointerUtils":49,"./window":52}],41:[function(require,module,exports){
        "use strict";

        module.exports = function extend(dest, source) {
            for (var prop in source) {
                dest[prop] = source[prop];
            }
            return dest;
        };

    },{}],42:[function(require,module,exports){
        'use strict';

        var _require = require('./rect'),
            resolveRectLike = _require.resolveRectLike,
            rectToXY = _require.rectToXY;

        module.exports = function (target, element, action) {
            var actionOptions = target.options[action];
            var actionOrigin = actionOptions && actionOptions.origin;
            var origin = actionOrigin || target.options.origin;

            var originRect = resolveRectLike(origin, target, element, [target && element]);

            return rectToXY(originRect) || { x: 0, y: 0 };
        };

    },{"./rect":51}],43:[function(require,module,exports){
        "use strict";

        module.exports = function (x, y) {
            return Math.sqrt(x * x + y * y);
        };

    },{}],44:[function(require,module,exports){
        'use strict';

        var extend = require('./extend');
        var win = require('./window');

        var utils = {
            warnOnce: function warnOnce(method, message) {
                var warned = false;

                return function () {
                    if (!warned) {
                        win.window.console.warn(message);
                        warned = true;
                    }

                    return method.apply(this, arguments);
                };
            },

            // http://stackoverflow.com/a/5634528/2280888
            _getQBezierValue: function _getQBezierValue(t, p1, p2, p3) {
                var iT = 1 - t;
                return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
            },

            getQuadraticCurvePoint: function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
                return {
                    x: utils._getQBezierValue(position, startX, cpX, endX),
                    y: utils._getQBezierValue(position, startY, cpY, endY)
                };
            },

            // http://gizma.com/easing/
            easeOutQuad: function easeOutQuad(t, b, c, d) {
                t /= d;
                return -c * t * (t - 2) + b;
            },

            copyAction: function copyAction(dest, src) {
                dest.name = src.name;
                dest.axis = src.axis;
                dest.edges = src.edges;

                return dest;
            },

            is: require('./is'),
            extend: extend,
            hypot: require('./hypot'),
            getOriginXY: require('./getOriginXY')
        };

        extend(utils, require('./arr'));
        extend(utils, require('./domUtils'));
        extend(utils, require('./pointerUtils'));
        extend(utils, require('./rect'));

        module.exports = utils;

    },{"./arr":35,"./domUtils":39,"./extend":41,"./getOriginXY":42,"./hypot":43,"./is":46,"./pointerUtils":49,"./rect":51,"./window":52}],45:[function(require,module,exports){
        'use strict';

        var scope = require('../scope');
        var utils = require('./index');

        var finder = {
            methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],

            search: function search(pointer, eventType, eventTarget) {
                var pointerType = utils.getPointerType(pointer);
                var pointerId = utils.getPointerId(pointer);
                var details = { pointer: pointer, pointerId: pointerId, pointerType: pointerType, eventType: eventType, eventTarget: eventTarget };

                for (var _i = 0; _i < finder.methodOrder.length; _i++) {
                    var _ref;

                    _ref = finder.methodOrder[_i];
                    var method = _ref;

                    var interaction = finder[method](details);

                    if (interaction) {
                        return interaction;
                    }
                }
            },

            // try to resume simulation with a new pointer
            simulationResume: function simulationResume(_ref2) {
                var pointerType = _ref2.pointerType,
                    eventType = _ref2.eventType,
                    eventTarget = _ref2.eventTarget;

                if (!/down|start/i.test(eventType)) {
                    return null;
                }

                for (var _i2 = 0; _i2 < scope.interactions.length; _i2++) {
                    var _ref3;

                    _ref3 = scope.interactions[_i2];
                    var interaction = _ref3;

                    var element = eventTarget;

                    if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {
                        while (element) {
                            // if the element is the interaction element
                            if (element === interaction.element) {
                                return interaction;
                            }
                            element = utils.parentNode(element);
                        }
                    }
                }

                return null;
            },

            // if it's a mouse or pen interaction
            mouseOrPen: function mouseOrPen(_ref4) {
                var pointerId = _ref4.pointerId,
                    pointerType = _ref4.pointerType,
                    eventType = _ref4.eventType;

                if (pointerType !== 'mouse' && pointerType !== 'pen') {
                    return null;
                }

                var firstNonActive = void 0;

                for (var _i3 = 0; _i3 < scope.interactions.length; _i3++) {
                    var _ref5;

                    _ref5 = scope.interactions[_i3];
                    var interaction = _ref5;

                    if (interaction.pointerType === pointerType) {
                        // if it's a down event, skip interactions with running simulations
                        if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) {
                            continue;
                        }

                        // if the interaction is active, return it immediately
                        if (interaction.interacting()) {
                            return interaction;
                        }
                        // otherwise save it and look for another active interaction
                        else if (!firstNonActive) {
                            firstNonActive = interaction;
                        }
                    }
                }

                // if no active mouse interaction was found use the first inactive mouse
                // interaction
                if (firstNonActive) {
                    return firstNonActive;
                }

                // find any mouse or pen interaction.
                // ignore the interaction if the eventType is a *down, and a simulation
                // is active
                for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {
                    var _ref6;

                    _ref6 = scope.interactions[_i4];
                    var _interaction = _ref6;

                    if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {
                        return _interaction;
                    }
                }

                return null;
            },

            // get interaction that has this pointer
            hasPointer: function hasPointer(_ref7) {
                var pointerId = _ref7.pointerId;

                for (var _i5 = 0; _i5 < scope.interactions.length; _i5++) {
                    var _ref8;

                    _ref8 = scope.interactions[_i5];
                    var interaction = _ref8;

                    if (utils.contains(interaction.pointerIds, pointerId)) {
                        return interaction;
                    }
                }
            },

            // get first idle interaction with a matching pointerType
            idle: function idle(_ref9) {
                var pointerType = _ref9.pointerType;

                for (var _i6 = 0; _i6 < scope.interactions.length; _i6++) {
                    var _ref10;

                    _ref10 = scope.interactions[_i6];
                    var interaction = _ref10;

                    // if there's already a pointer held down
                    if (interaction.pointerIds.length === 1) {
                        var target = interaction.target;
                        // don't add this pointer if there is a target interactable and it
                        // isn't gesturable
                        if (target && !target.options.gesture.enabled) {
                            continue;
                        }
                    }
                    // maximum of 2 pointers per interaction
                    else if (interaction.pointerIds.length >= 2) {
                        continue;
                    }

                    if (!interaction.interacting() && pointerType === interaction.pointerType) {
                        return interaction;
                    }
                }

                return null;
            }
        };

        module.exports = finder;

    },{"../scope":33,"./index":44}],46:[function(require,module,exports){
        'use strict';

        var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

        var win = require('./window');
        var isWindow = require('./isWindow');

        var is = {
            array: function array() {},

            window: function window(thing) {
                return thing === win.window || isWindow(thing);
            },

            docFrag: function docFrag(thing) {
                return is.object(thing) && thing.nodeType === 11;
            },

            object: function object(thing) {
                return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';
            },

            function: function _function(thing) {
                return typeof thing === 'function';
            },

            number: function number(thing) {
                return typeof thing === 'number';
            },

            bool: function bool(thing) {
                return typeof thing === 'boolean';
            },

            string: function string(thing) {
                return typeof thing === 'string';
            },

            element: function element(thing) {
                if (!thing || (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) !== 'object') {
                    return false;
                }

                var _window = win.getWindow(thing) || win.window;

                return (/object|function/.test(_typeof(_window.Element)) ? thing instanceof _window.Element //DOM2
                        : thing.nodeType === 1 && typeof thing.nodeName === 'string'
                );
            },

            plainObject: function plainObject(thing) {
                return is.object(thing) && thing.constructor.name === 'Object';
            }
        };

        is.array = function (thing) {
            return is.object(thing) && typeof thing.length !== 'undefined' && is.function(thing.splice);
        };

        module.exports = is;

    },{"./isWindow":47,"./window":52}],47:[function(require,module,exports){
        "use strict";

        module.exports = function (thing) {
            return !!(thing && thing.Window) && thing instanceof thing.Window;
        };

    },{}],48:[function(require,module,exports){
        'use strict';

        function pointerExtend(dest, source) {
            for (var prop in source) {
                var prefixedPropREs = module.exports.prefixedPropREs;
                var deprecated = false;

                // skip deprecated prefixed properties
                for (var vendor in prefixedPropREs) {
                    if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {
                        deprecated = true;
                        break;
                    }
                }

                if (!deprecated && typeof source[prop] !== 'function') {
                    dest[prop] = source[prop];
                }
            }
            return dest;
        }

        pointerExtend.prefixedPropREs = {
            webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/
        };

        module.exports = pointerExtend;

    },{}],49:[function(require,module,exports){
        'use strict';

        var hypot = require('./hypot');
        var browser = require('./browser');
        var dom = require('./domObjects');
        var domUtils = require('./domUtils');
        var domObjects = require('./domObjects');
        var is = require('./is');
        var pointerExtend = require('./pointerExtend');

        var pointerUtils = {
            copyCoords: function copyCoords(dest, src) {
                dest.page = dest.page || {};
                dest.page.x = src.page.x;
                dest.page.y = src.page.y;

                dest.client = dest.client || {};
                dest.client.x = src.client.x;
                dest.client.y = src.client.y;

                dest.timeStamp = src.timeStamp;
            },

            setCoordDeltas: function setCoordDeltas(targetObj, prev, cur) {
                targetObj.page.x = cur.page.x - prev.page.x;
                targetObj.page.y = cur.page.y - prev.page.y;
                targetObj.client.x = cur.client.x - prev.client.x;
                targetObj.client.y = cur.client.y - prev.client.y;
                targetObj.timeStamp = cur.timeStamp - prev.timeStamp;

                // set pointer velocity
                var dt = Math.max(targetObj.timeStamp / 1000, 0.001);

                targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;
                targetObj.page.vx = targetObj.page.x / dt;
                targetObj.page.vy = targetObj.page.y / dt;

                targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;
                targetObj.client.vx = targetObj.client.x / dt;
                targetObj.client.vy = targetObj.client.y / dt;
            },

            isNativePointer: function isNativePointer(pointer) {
                return pointer instanceof dom.Event || pointer instanceof dom.Touch;
            },

            // Get specified X/Y coords for mouse or event.touches[0]
            getXY: function getXY(type, pointer, xy) {
                xy = xy || {};
                type = type || 'page';

                xy.x = pointer[type + 'X'];
                xy.y = pointer[type + 'Y'];

                return xy;
            },

            getPageXY: function getPageXY(pointer, page) {
                page = page || {};

                // Opera Mobile handles the viewport and scrolling oddly
                if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {
                    pointerUtils.getXY('screen', pointer, page);

                    page.x += window.scrollX;
                    page.y += window.scrollY;
                } else {
                    pointerUtils.getXY('page', pointer, page);
                }

                return page;
            },

            getClientXY: function getClientXY(pointer, client) {
                client = client || {};

                if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {
                    // Opera Mobile handles the viewport and scrolling oddly
                    pointerUtils.getXY('screen', pointer, client);
                } else {
                    pointerUtils.getXY('client', pointer, client);
                }

                return client;
            },

            getPointerId: function getPointerId(pointer) {
                return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;
            },

            setCoords: function setCoords(targetObj, pointers, timeStamp) {
                var pointer = pointers.length > 1 ? pointerUtils.pointerAverage(pointers) : pointers[0];

                var tmpXY = {};

                pointerUtils.getPageXY(pointer, tmpXY);
                targetObj.page.x = tmpXY.x;
                targetObj.page.y = tmpXY.y;

                pointerUtils.getClientXY(pointer, tmpXY);
                targetObj.client.x = tmpXY.x;
                targetObj.client.y = tmpXY.y;

                targetObj.timeStamp = is.number(timeStamp) ? timeStamp : new Date().getTime();
            },

            pointerExtend: pointerExtend,

            getTouchPair: function getTouchPair(event) {
                var touches = [];

                // array of touches is supplied
                if (is.array(event)) {
                    touches[0] = event[0];
                    touches[1] = event[1];
                }
                // an event
                else {
                    if (event.type === 'touchend') {
                        if (event.touches.length === 1) {
                            touches[0] = event.touches[0];
                            touches[1] = event.changedTouches[0];
                        } else if (event.touches.length === 0) {
                            touches[0] = event.changedTouches[0];
                            touches[1] = event.changedTouches[1];
                        }
                    } else {
                        touches[0] = event.touches[0];
                        touches[1] = event.touches[1];
                    }
                }

                return touches;
            },

            pointerAverage: function pointerAverage(pointers) {
                var average = {
                    pageX: 0,
                    pageY: 0,
                    clientX: 0,
                    clientY: 0,
                    screenX: 0,
                    screenY: 0
                };

                for (var _i = 0; _i < pointers.length; _i++) {
                    var _ref;

                    _ref = pointers[_i];
                    var pointer = _ref;

                    for (var _prop in average) {
                        average[_prop] += pointer[_prop];
                    }
                }
                for (var prop in average) {
                    average[prop] /= pointers.length;
                }

                return average;
            },

            touchBBox: function touchBBox(event) {
                if (!event.length && !(event.touches && event.touches.length > 1)) {
                    return;
                }

                var touches = pointerUtils.getTouchPair(event);
                var minX = Math.min(touches[0].pageX, touches[1].pageX);
                var minY = Math.min(touches[0].pageY, touches[1].pageY);
                var maxX = Math.max(touches[0].pageX, touches[1].pageX);
                var maxY = Math.max(touches[0].pageY, touches[1].pageY);

                return {
                    x: minX,
                    y: minY,
                    left: minX,
                    top: minY,
                    width: maxX - minX,
                    height: maxY - minY
                };
            },

            touchDistance: function touchDistance(event, deltaSource) {
                var sourceX = deltaSource + 'X';
                var sourceY = deltaSource + 'Y';
                var touches = pointerUtils.getTouchPair(event);

                var dx = touches[0][sourceX] - touches[1][sourceX];
                var dy = touches[0][sourceY] - touches[1][sourceY];

                return hypot(dx, dy);
            },

            touchAngle: function touchAngle(event, prevAngle, deltaSource) {
                var sourceX = deltaSource + 'X';
                var sourceY = deltaSource + 'Y';
                var touches = pointerUtils.getTouchPair(event);
                var dx = touches[1][sourceX] - touches[0][sourceX];
                var dy = touches[1][sourceY] - touches[0][sourceY];
                var angle = 180 * Math.atan2(dy, dx) / Math.PI;

                return angle;
            },

            getPointerType: function getPointerType(pointer) {
                return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType]
                    // if the PointerEvent API isn't available, then the "pointer" must
                    // be either a MouseEvent, TouchEvent, or Touch object
                    : /touch/.test(pointer.type) || pointer instanceof domObjects.Touch ? 'touch' : 'mouse';
            },

            // [ event.target, event.currentTarget ]
            getEventTargets: function getEventTargets(event) {
                var path = is.function(event.composedPath) ? event.composedPath() : event.path;

                return [domUtils.getActualElement(path ? path[0] : event.target), domUtils.getActualElement(event.currentTarget)];
            }
        };

        module.exports = pointerUtils;

    },{"./browser":36,"./domObjects":38,"./domUtils":39,"./hypot":43,"./is":46,"./pointerExtend":48}],50:[function(require,module,exports){
        'use strict';

        var _require = require('./window'),
            window = _require.window;

        var vendors = ['ms', 'moz', 'webkit', 'o'];
        var lastTime = 0;
        var request = void 0;
        var cancel = void 0;

        for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
            request = window[vendors[x] + 'RequestAnimationFrame'];
            cancel = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
        }

        if (!request) {
            request = function request(callback) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = setTimeout(function () {
                    callback(currTime + timeToCall);
                }, timeToCall);

                lastTime = currTime + timeToCall;
                return id;
            };
        }

        if (!cancel) {
            cancel = function cancel(id) {
                clearTimeout(id);
            };
        }

        module.exports = {
            request: request,
            cancel: cancel
        };

    },{"./window":52}],51:[function(require,module,exports){
        'use strict';

        var extend = require('./extend');
        var is = require('./is');

        var _require = require('./domUtils'),
            closest = _require.closest,
            parentNode = _require.parentNode,
            getElementRect = _require.getElementRect;

        var rectUtils = {
            getStringOptionResult: function getStringOptionResult(value, interactable, element) {
                if (!is.string(value)) {
                    return null;
                }

                if (value === 'parent') {
                    value = parentNode(element);
                } else if (value === 'self') {
                    value = interactable.getRect(element);
                } else {
                    value = closest(element, value);
                }

                return value;
            },

            resolveRectLike: function resolveRectLike(value, interactable, element, functionArgs) {
                value = rectUtils.getStringOptionResult(value, interactable, element) || value;

                if (is.function(value)) {
                    value = value.apply(null, functionArgs);
                }

                if (is.element(value)) {
                    value = getElementRect(value);
                }

                return value;
            },

            rectToXY: function rectToXY(rect) {
                return rect && {
                    x: 'x' in rect ? rect.x : rect.left,
                    y: 'y' in rect ? rect.y : rect.top
                };
            },

            xywhToTlbr: function xywhToTlbr(rect) {
                if (rect && !('left' in rect && 'top' in rect)) {
                    rect = extend({}, rect);

                    rect.left = rect.x || 0;
                    rect.top = rect.y || 0;
                    rect.right = rect.right || rect.left + rect.width;
                    rect.bottom = rect.bottom || rect.top + rect.height;
                }

                return rect;
            },

            tlbrToXywh: function tlbrToXywh(rect) {
                if (rect && !('x' in rect && 'y' in rect)) {
                    rect = extend({}, rect);

                    rect.x = rect.left || 0;
                    rect.top = rect.top || 0;
                    rect.width = rect.width || rect.right - rect.x;
                    rect.height = rect.height || rect.bottom - rect.y;
                }

                return rect;
            }
        };

        module.exports = rectUtils;

    },{"./domUtils":39,"./extend":41,"./is":46}],52:[function(require,module,exports){
        'use strict';

        var win = module.exports;
        var isWindow = require('./isWindow');

        function init(window) {
            // get wrapped window if using Shadow DOM polyfill

            win.realWindow = window;

            // create a TextNode
            var el = window.document.createTextNode('');

            // check if it's wrapped by a polyfill
            if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {
                // use wrapped window
                window = window.wrap(window);
            }

            win.window = window;
        }

        if (typeof window === 'undefined') {
            win.window = undefined;
            win.realWindow = undefined;
        } else {
            init(window);
        }

        win.getWindow = function getWindow(node) {
            if (isWindow(node)) {
                return node;
            }

            var rootNode = node.ownerDocument || node;

            return rootNode.defaultView || rootNode.parentWindow || win.window;
        };

        win.init = init;

    },{"./isWindow":47}]},{},[1])(1)
});


//# sourceMappingURL=interact.js.map