'use strict';

Liferay.Loader.define('ratings-taglib$dom-align@1.10.4/dist-node/index', ['module', 'exports', 'require'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    Object.defineProperty(exports, '__esModule', { value: true });

    var vendorPrefix;
    var jsCssMap = {
      Webkit: '-webkit-',
      Moz: '-moz-',
      // IE did it wrong again ...
      ms: '-ms-',
      O: '-o-'
    };

    function getVendorPrefix() {
      if (vendorPrefix !== undefined) {
        return vendorPrefix;
      }

      vendorPrefix = '';
      var style = document.createElement('p').style;


      for (var key in jsCssMap) {
        if (key + 'Transform' in style) {
          vendorPrefix = key;
        }
      }

      return vendorPrefix;
    }

    function getTransitionName() {
      return getVendorPrefix() ? "".concat(getVendorPrefix(), "TransitionProperty") : 'transitionProperty';
    }

    function getTransformName() {
      return getVendorPrefix() ? "".concat(getVendorPrefix(), "Transform") : 'transform';
    }
    function setTransitionProperty(node, value) {
      var name = getTransitionName();

      if (name) {
        node.style[name] = value;

        if (name !== 'transitionProperty') {
          node.style.transitionProperty = value;
        }
      }
    }

    function setTransform(node, value) {
      var name = getTransformName();

      if (name) {
        node.style[name] = value;

        if (name !== 'transform') {
          node.style.transform = value;
        }
      }
    }

    function getTransitionProperty(node) {
      return node.style.transitionProperty || node.style[getTransitionName()];
    }
    function getTransformXY(node) {
      var style = window.getComputedStyle(node, null);
      var transform = style.getPropertyValue('transform') || style.getPropertyValue(getTransformName());

      if (transform && transform !== 'none') {
        var matrix = transform.replace(/[^0-9\-.,]/g, '').split(',');
        return {
          x: parseFloat(matrix[12] || matrix[4], 0),
          y: parseFloat(matrix[13] || matrix[5], 0)
        };
      }

      return {
        x: 0,
        y: 0
      };
    }
    var matrix2d = /matrix\((.*)\)/;
    var matrix3d = /matrix3d\((.*)\)/;
    function setTransformXY(node, xy) {
      var style = window.getComputedStyle(node, null);
      var transform = style.getPropertyValue('transform') || style.getPropertyValue(getTransformName());

      if (transform && transform !== 'none') {
        var arr;
        var match2d = transform.match(matrix2d);

        if (match2d) {
          match2d = match2d[1];
          arr = match2d.split(',').map(function (item) {
            return parseFloat(item, 10);
          });
          arr[4] = xy.x;
          arr[5] = xy.y;
          setTransform(node, "matrix(".concat(arr.join(','), ")"));
        } else {
          var match3d = transform.match(matrix3d)[1];
          arr = match3d.split(',').map(function (item) {
            return parseFloat(item, 10);
          });
          arr[12] = xy.x;
          arr[13] = xy.y;
          setTransform(node, "matrix3d(".concat(arr.join(','), ")"));
        }
      } else {
        setTransform(node, "translateX(".concat(xy.x, "px) translateY(").concat(xy.y, "px) translateZ(0)"));
      }
    }

    function _typeof(obj) {
      if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
        _typeof = function _typeof(obj) {
          return typeof obj;
        };
      } else {
        _typeof = function _typeof(obj) {
          return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
        };
      }

      return _typeof(obj);
    }
    var RE_NUM = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source;
    var getComputedStyleX; // https://stackoverflow.com/a/3485654/3040605

    function forceRelayout(elem) {
      var originalStyle = elem.style.display;
      elem.style.display = 'none';
      elem.offsetHeight; // eslint-disable-line

      elem.style.display = originalStyle;
    }

    function css(el, name, v) {
      var value = v;

      if (_typeof(name) === 'object') {
        for (var i in name) {
          if (name.hasOwnProperty(i)) {
            css(el, i, name[i]);
          }
        }

        return undefined;
      }

      if (typeof value !== 'undefined') {
        if (typeof value === 'number') {
          value = "".concat(value, "px");
        }

        el.style[name] = value;
        return undefined;
      }

      return getComputedStyleX(el, name);
    }

    function getClientPosition(elem) {
      var box;
      var x;
      var y;
      var doc = elem.ownerDocument;
      var body = doc.body;
      var docElem = doc && doc.documentElement; // 根据 GBS 最新数据，A-Grade Browsers 都已支持 getBoundingClientRect 方法，不用再考虑传统的实现方式

      box = elem.getBoundingClientRect(); // 注：jQuery 还考虑减去 docElem.clientLeft/clientTop
      // 但测试发现，这样反而会导致当 html 和 body 有边距/边框样式时，获取的值不正确
      // 此外，ie6 会忽略 html 的 margin 值，幸运地是没有谁会去设置 html 的 margin

      x = box.left;
      y = box.top; // In IE, most of the time, 2 extra pixels are added to the top and left
      // due to the implicit 2-pixel inset border.  In IE6/7 quirks mode and
      // IE6 standards mode, this border can be overridden by setting the
      // document element's border to zero -- thus, we cannot rely on the
      // offset always being 2 pixels.
      // In quirks mode, the offset can be determined by querying the body's
      // clientLeft/clientTop, but in standards mode, it is found by querying
      // the document element's clientLeft/clientTop.  Since we already called
      // getClientBoundingRect we have already forced a reflow, so it is not
      // too expensive just to query them all.
      // ie 下应该减去窗口的边框吧，毕竟默认 absolute 都是相对窗口定位的
      // 窗口边框标准是设 documentElement ,quirks 时设置 body
      // 最好禁止在 body 和 html 上边框 ，但 ie < 9 html 默认有 2px ，减去
      // 但是非 ie 不可能设置窗口边框，body html 也不是窗口 ,ie 可以通过 html,body 设置
      // 标准 ie 下 docElem.clientTop 就是 border-top
      // ie7 html 即窗口边框改变不了。永远为 2
      // 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框，即使设了 border-top 也为 0

      x -= docElem.clientLeft || body.clientLeft || 0;
      y -= docElem.clientTop || body.clientTop || 0;
      return {
        left: x,
        top: y
      };
    }

    function getScroll(w, top) {
      var ret = w["page".concat(top ? 'Y' : 'X', "Offset")];
      var method = "scroll".concat(top ? 'Top' : 'Left');

      if (typeof ret !== 'number') {
        var d = w.document; // ie6,7,8 standard mode

        ret = d.documentElement[method];

        if (typeof ret !== 'number') {
          // quirks mode
          ret = d.body[method];
        }
      }

      return ret;
    }

    function getScrollLeft(w) {
      return getScroll(w);
    }

    function getScrollTop(w) {
      return getScroll(w, true);
    }

    function getOffset(el) {
      var pos = getClientPosition(el);
      var doc = el.ownerDocument;
      var w = doc.defaultView || doc.parentWindow;
      pos.left += getScrollLeft(w);
      pos.top += getScrollTop(w);
      return pos;
    }
    /**
     * A crude way of determining if an object is a window
     * @member util
     */

    function isWindow(obj) {
      // must use == for ie8

      /* eslint eqeqeq:0 */
      return obj !== null && obj !== undefined && obj == obj.window;
    }

    function getDocument(node) {
      if (isWindow(node)) {
        return node.document;
      }

      if (node.nodeType === 9) {
        return node;
      }

      return node.ownerDocument;
    }

    function _getComputedStyle(elem, name, cs) {
      var computedStyle = cs;
      var val = '';
      var d = getDocument(elem);
      computedStyle = computedStyle || d.defaultView.getComputedStyle(elem, null); // https://github.com/kissyteam/kissy/issues/61

      if (computedStyle) {
        val = computedStyle.getPropertyValue(name) || computedStyle[name];
      }

      return val;
    }

    var _RE_NUM_NO_PX = new RegExp("^(".concat(RE_NUM, ")(?!px)[a-z%]+$"), 'i');

    var RE_POS = /^(top|right|bottom|left)$/;
    var CURRENT_STYLE = 'currentStyle';
    var RUNTIME_STYLE = 'runtimeStyle';
    var LEFT = 'left';
    var PX = 'px';

    function _getComputedStyleIE(elem, name) {
      // currentStyle maybe null
      // http://msdn.microsoft.com/en-us/library/ms535231.aspx
      var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name]; // 当 width/height 设置为百分比时，通过 pixelLeft 方式转换的 width/height 值
      // 一开始就处理了! CUSTOM_STYLE.height,CUSTOM_STYLE.width ,cssHook 解决@2011-08-19
      // 在 ie 下不对，需要直接用 offset 方式
      // borderWidth 等值也有问题，但考虑到 borderWidth 设为百分比的概率很小，这里就不考虑了
      // From the awesome hack by Dean Edwards
      // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
      // If we're not dealing with a regular pixel number
      // but a number that has a weird ending, we need to convert it to pixels
      // exclude left right for relativity

      if (_RE_NUM_NO_PX.test(ret) && !RE_POS.test(name)) {
        // Remember the original values
        var style = elem.style;
        var left = style[LEFT];
        var rsLeft = elem[RUNTIME_STYLE][LEFT]; // prevent flashing of content

        elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT]; // Put in the new values to get a computed value out

        style[LEFT] = name === 'fontSize' ? '1em' : ret || 0;
        ret = style.pixelLeft + PX; // Revert the changed values

        style[LEFT] = left;
        elem[RUNTIME_STYLE][LEFT] = rsLeft;
      }

      return ret === '' ? 'auto' : ret;
    }

    if (typeof window !== 'undefined') {
      getComputedStyleX = window.getComputedStyle ? _getComputedStyle : _getComputedStyleIE;
    }

    function getOffsetDirection(dir, option) {
      if (dir === 'left') {
        return option.useCssRight ? 'right' : dir;
      }

      return option.useCssBottom ? 'bottom' : dir;
    }

    function oppositeOffsetDirection(dir) {
      if (dir === 'left') {
        return 'right';
      } else if (dir === 'right') {
        return 'left';
      } else if (dir === 'top') {
        return 'bottom';
      } else if (dir === 'bottom') {
        return 'top';
      }
    } // 设置 elem 相对 elem.ownerDocument 的坐标


    function setLeftTop(elem, offset, option) {
      // set position first, in-case top/left are set even on static elem
      if (css(elem, 'position') === 'static') {
        elem.style.position = 'relative';
      }

      var presetH = -999;
      var presetV = -999;
      var horizontalProperty = getOffsetDirection('left', option);
      var verticalProperty = getOffsetDirection('top', option);
      var oppositeHorizontalProperty = oppositeOffsetDirection(horizontalProperty);
      var oppositeVerticalProperty = oppositeOffsetDirection(verticalProperty);

      if (horizontalProperty !== 'left') {
        presetH = 999;
      }

      if (verticalProperty !== 'top') {
        presetV = 999;
      }

      var originalTransition = '';
      var originalOffset = getOffset(elem);

      if ('left' in offset || 'top' in offset) {
        originalTransition = getTransitionProperty(elem) || '';
        setTransitionProperty(elem, 'none');
      }

      if ('left' in offset) {
        elem.style[oppositeHorizontalProperty] = '';
        elem.style[horizontalProperty] = "".concat(presetH, "px");
      }

      if ('top' in offset) {
        elem.style[oppositeVerticalProperty] = '';
        elem.style[verticalProperty] = "".concat(presetV, "px");
      } // force relayout


      forceRelayout(elem);
      var old = getOffset(elem);
      var originalStyle = {};

      for (var key in offset) {
        if (offset.hasOwnProperty(key)) {
          var dir = getOffsetDirection(key, option);
          var preset = key === 'left' ? presetH : presetV;
          var off = originalOffset[key] - old[key];

          if (dir === key) {
            originalStyle[dir] = preset + off;
          } else {
            originalStyle[dir] = preset - off;
          }
        }
      }

      css(elem, originalStyle); // force relayout

      forceRelayout(elem);

      if ('left' in offset || 'top' in offset) {
        setTransitionProperty(elem, originalTransition);
      }

      var ret = {};

      for (var _key in offset) {
        if (offset.hasOwnProperty(_key)) {
          var _dir = getOffsetDirection(_key, option);

          var _off = offset[_key] - originalOffset[_key];

          if (_key === _dir) {
            ret[_dir] = originalStyle[_dir] + _off;
          } else {
            ret[_dir] = originalStyle[_dir] - _off;
          }
        }
      }

      css(elem, ret);
    }

    function setTransform$1(elem, offset) {
      var originalOffset = getOffset(elem);
      var originalXY = getTransformXY(elem);
      var resultXY = {
        x: originalXY.x,
        y: originalXY.y
      };

      if ('left' in offset) {
        resultXY.x = originalXY.x + offset.left - originalOffset.left;
      }

      if ('top' in offset) {
        resultXY.y = originalXY.y + offset.top - originalOffset.top;
      }

      setTransformXY(elem, resultXY);
    }

    function setOffset(elem, offset, option) {
      if (option.ignoreShake) {
        var oriOffset = getOffset(elem);
        var oLeft = oriOffset.left.toFixed(0);
        var oTop = oriOffset.top.toFixed(0);
        var tLeft = offset.left.toFixed(0);
        var tTop = offset.top.toFixed(0);

        if (oLeft === tLeft && oTop === tTop) {
          return;
        }
      }

      if (option.useCssRight || option.useCssBottom) {
        setLeftTop(elem, offset, option);
      } else if (option.useCssTransform && getTransformName() in document.body.style) {
        setTransform$1(elem, offset);
      } else {
        setLeftTop(elem, offset, option);
      }
    }

    function each(arr, fn) {
      for (var i = 0; i < arr.length; i++) {
        fn(arr[i]);
      }
    }

    function isBorderBoxFn(elem) {
      return getComputedStyleX(elem, 'boxSizing') === 'border-box';
    }

    var BOX_MODELS = ['margin', 'border', 'padding'];
    var CONTENT_INDEX = -1;
    var PADDING_INDEX = 2;
    var BORDER_INDEX = 1;
    var MARGIN_INDEX = 0;

    function swap(elem, options, callback) {
      var old = {};
      var style = elem.style;
      // Remember the old values, and insert the new ones

      for (var name in options) {
        if (options.hasOwnProperty(name)) {
          old[name] = style[name];
          style[name] = options[name];
        }
      }

      callback.call(elem); // Revert the old values

      for (name in options) {
        if (options.hasOwnProperty(name)) {
          style[name] = old[name];
        }
      }
    }

    function getPBMWidth(elem, props, which) {
      var value = 0;
      var prop;
      var j;
      var i;

      for (j = 0; j < props.length; j++) {
        prop = props[j];

        if (prop) {
          for (i = 0; i < which.length; i++) {
            var cssProp = void 0;

            if (prop === 'border') {
              cssProp = "".concat(prop).concat(which[i], "Width");
            } else {
              cssProp = prop + which[i];
            }

            value += parseFloat(getComputedStyleX(elem, cssProp)) || 0;
          }
        }
      }

      return value;
    }

    var domUtils = {
      getParent: function getParent(element) {
        var parent = element;

        do {
          if (parent.nodeType === 11 && parent.host) {
            parent = parent.host;
          } else {
            parent = parent.parentNode;
          }
        } while (parent && parent.nodeType !== 1 && parent.nodeType !== 9);

        return parent;
      }
    };
    each(['Width', 'Height'], function (name) {
      domUtils["doc".concat(name)] = function (refWin) {
        var d = refWin.document;
        return Math.max( // firefox chrome documentElement.scrollHeight< body.scrollHeight
        // ie standard mode : documentElement.scrollHeight> body.scrollHeight
        d.documentElement["scroll".concat(name)], // quirks : documentElement.scrollHeight 最大等于可视窗口多一点？
        d.body["scroll".concat(name)], domUtils["viewport".concat(name)](d));
      };

      domUtils["viewport".concat(name)] = function (win) {
        // pc browser includes scrollbar in window.innerWidth
        var prop = "client".concat(name);
        var doc = win.document;
        var body = doc.body;
        var documentElement = doc.documentElement;
        var documentElementProp = documentElement[prop]; // 标准模式取 documentElement
        // backcompat 取 body

        return doc.compatMode === 'CSS1Compat' && documentElementProp || body && body[prop] || documentElementProp;
      };
    });
    /*
     得到元素的大小信息
     @param elem
     @param name
     @param {String} [extra]  'padding' : (css width) + padding
     'border' : (css width) + padding + border
     'margin' : (css width) + padding + border + margin
     */

    function getWH(elem, name, ex) {
      var extra = ex;

      if (isWindow(elem)) {
        return name === 'width' ? domUtils.viewportWidth(elem) : domUtils.viewportHeight(elem);
      } else if (elem.nodeType === 9) {
        return name === 'width' ? domUtils.docWidth(elem) : domUtils.docHeight(elem);
      }

      var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];
      var borderBoxValue = name === 'width' ? elem.getBoundingClientRect().width : elem.getBoundingClientRect().height;
      getComputedStyleX(elem);

      var isBorderBox = isBorderBoxFn(elem);
      var cssBoxValue = 0;

      if (borderBoxValue === null || borderBoxValue === undefined || borderBoxValue <= 0) {
        borderBoxValue = undefined; // Fall back to computed then un computed css if necessary

        cssBoxValue = getComputedStyleX(elem, name);

        if (cssBoxValue === null || cssBoxValue === undefined || Number(cssBoxValue) < 0) {
          cssBoxValue = elem.style[name] || 0;
        } // Normalize '', auto, and prepare for extra


        cssBoxValue = parseFloat(cssBoxValue) || 0;
      }

      if (extra === undefined) {
        extra = isBorderBox ? BORDER_INDEX : CONTENT_INDEX;
      }

      var borderBoxValueOrIsBorderBox = borderBoxValue !== undefined || isBorderBox;
      var val = borderBoxValue || cssBoxValue;

      if (extra === CONTENT_INDEX) {
        if (borderBoxValueOrIsBorderBox) {
          return val - getPBMWidth(elem, ['border', 'padding'], which);
        }

        return cssBoxValue;
      } else if (borderBoxValueOrIsBorderBox) {
        if (extra === BORDER_INDEX) {
          return val;
        }

        return val + (extra === PADDING_INDEX ? -getPBMWidth(elem, ['border'], which) : getPBMWidth(elem, ['margin'], which));
      }

      return cssBoxValue + getPBMWidth(elem, BOX_MODELS.slice(extra), which);
    }

    var cssShow = {
      position: 'absolute',
      visibility: 'hidden',
      display: 'block'
    }; // fix #119 : https://github.com/kissyteam/kissy/issues/119

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

      var val;
      var elem = args[0]; // in case elem is window
      // elem.offsetWidth === undefined

      if (elem.offsetWidth !== 0) {
        val = getWH.apply(undefined, args);
      } else {
        swap(elem, cssShow, function () {
          val = getWH.apply(undefined, args);
        });
      }

      return val;
    }

    each(['width', 'height'], function (name) {
      var first = name.charAt(0).toUpperCase() + name.slice(1);

      domUtils["outer".concat(first)] = function (el, includeMargin) {
        return el && getWHIgnoreDisplay(el, name, includeMargin ? MARGIN_INDEX : BORDER_INDEX);
      };

      var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];

      domUtils[name] = function (elem, v) {
        var val = v;

        if (val !== undefined) {
          if (elem) {
            getComputedStyleX(elem);

            var isBorderBox = isBorderBoxFn(elem);

            if (isBorderBox) {
              val += getPBMWidth(elem, ['padding', 'border'], which);
            }

            return css(elem, name, val);
          }

          return undefined;
        }

        return elem && getWHIgnoreDisplay(elem, name, CONTENT_INDEX);
      };
    });

    function mix(to, from) {
      for (var i in from) {
        if (from.hasOwnProperty(i)) {
          to[i] = from[i];
        }
      }

      return to;
    }

    var utils = {
      getWindow: function getWindow(node) {
        if (node && node.document && node.setTimeout) {
          return node;
        }

        var doc = node.ownerDocument || node;
        return doc.defaultView || doc.parentWindow;
      },
      getDocument: getDocument,
      offset: function offset(el, value, option) {
        if (typeof value !== 'undefined') {
          setOffset(el, value, option || {});
        } else {
          return getOffset(el);
        }
      },
      isWindow: isWindow,
      each: each,
      css: css,
      clone: function clone(obj) {
        var ret = {};

        for (var i in obj) {
          if (obj.hasOwnProperty(i)) {
            ret[i] = obj[i];
          }
        }

        var overflow = obj.overflow;

        if (overflow) {
          for (i in obj) {
            if (obj.hasOwnProperty(i)) {
              ret.overflow[i] = obj.overflow[i];
            }
          }
        }

        return ret;
      },
      mix: mix,
      getWindowScrollLeft: function getWindowScrollLeft(w) {
        return getScrollLeft(w);
      },
      getWindowScrollTop: function getWindowScrollTop(w) {
        return getScrollTop(w);
      },
      merge: function merge() {
        var ret = {};

        for (var i = 0; i < arguments.length; i++) {
          utils.mix(ret, i < 0 || arguments.length <= i ? undefined : arguments[i]);
        }

        return ret;
      },
      viewportWidth: 0,
      viewportHeight: 0
    };
    mix(utils, domUtils);

    /**
     * 得到会导致元素显示不全的祖先元素
     */

    var getParent = utils.getParent;

    function getOffsetParent(element) {
      if (utils.isWindow(element) || element.nodeType === 9) {
        return null;
      } // ie 这个也不是完全可行

      /*
       <div style="width: 50px;height: 100px;overflow: hidden">
       <div style="width: 50px;height: 100px;position: relative;" id="d6">
       元素 6 高 100px 宽 50px<br/>
       </div>
       </div>
       */
      // element.offsetParent does the right thing in ie7 and below. Return parent with layout!
      //  In other browsers it only includes elements with position absolute, relative or
      // fixed, not elements with overflow set to auto or scroll.
      //        if (UA.ie && ieMode < 8) {
      //            return element.offsetParent;
      //        }
      // 统一的 offsetParent 方法


      var doc = utils.getDocument(element);
      var body = doc.body;
      var parent;
      var positionStyle = utils.css(element, 'position');
      var skipStatic = positionStyle === 'fixed' || positionStyle === 'absolute';

      if (!skipStatic) {
        return element.nodeName.toLowerCase() === 'html' ? null : getParent(element);
      }

      for (parent = getParent(element); parent && parent !== body && parent.nodeType !== 9; parent = getParent(parent)) {
        positionStyle = utils.css(parent, 'position');

        if (positionStyle !== 'static') {
          return parent;
        }
      }

      return null;
    }

    var getParent$1 = utils.getParent;
    function isAncestorFixed(element) {
      if (utils.isWindow(element) || element.nodeType === 9) {
        return false;
      }

      var doc = utils.getDocument(element);
      var body = doc.body;
      var parent = null;

      for (parent = getParent$1(element); parent && parent !== body; parent = getParent$1(parent)) {
        var positionStyle = utils.css(parent, 'position');

        if (positionStyle === 'fixed') {
          return true;
        }
      }

      return false;
    }

    /**
     * 获得元素的显示部分的区域
     */

    function getVisibleRectForElement(element) {
      var visibleRect = {
        left: 0,
        right: Infinity,
        top: 0,
        bottom: Infinity
      };
      var el = getOffsetParent(element);
      var doc = utils.getDocument(element);
      var win = doc.defaultView || doc.parentWindow;
      var body = doc.body;
      var documentElement = doc.documentElement; // Determine the size of the visible rect by climbing the dom accounting for
      // all scrollable containers.

      while (el) {
        // clientWidth is zero for inline block elements in ie.
        if ((navigator.userAgent.indexOf('MSIE') === -1 || el.clientWidth !== 0) && // body may have overflow set on it, yet we still get the entire
        // viewport. In some browsers, el.offsetParent may be
        // document.documentElement, so check for that too.
        el !== body && el !== documentElement && utils.css(el, 'overflow') !== 'visible') {
          var pos = utils.offset(el); // add border

          pos.left += el.clientLeft;
          pos.top += el.clientTop;
          visibleRect.top = Math.max(visibleRect.top, pos.top);
          visibleRect.right = Math.min(visibleRect.right, // consider area without scrollBar
          pos.left + el.clientWidth);
          visibleRect.bottom = Math.min(visibleRect.bottom, pos.top + el.clientHeight);
          visibleRect.left = Math.max(visibleRect.left, pos.left);
        } else if (el === body || el === documentElement) {
          break;
        }

        el = getOffsetParent(el);
      } // Set element position to fixed
      // make sure absolute element itself don't affect it's visible area
      // https://github.com/ant-design/ant-design/issues/7601


      var originalPosition = null;

      if (!utils.isWindow(element) && element.nodeType !== 9) {
        originalPosition = element.style.position;
        var position = utils.css(element, 'position');

        if (position === 'absolute') {
          element.style.position = 'fixed';
        }
      }

      var scrollX = utils.getWindowScrollLeft(win);
      var scrollY = utils.getWindowScrollTop(win);
      var viewportWidth = utils.viewportWidth(win);
      var viewportHeight = utils.viewportHeight(win);
      var documentWidth = documentElement.scrollWidth;
      var documentHeight = documentElement.scrollHeight; // scrollXXX on html is sync with body which means overflow: hidden on body gets wrong scrollXXX.
      // We should cut this ourself.

      var bodyStyle = window.getComputedStyle(body);

      if (bodyStyle.overflowX === 'hidden') {
        documentWidth = win.innerWidth;
      }

      if (bodyStyle.overflowY === 'hidden') {
        documentHeight = win.innerHeight;
      } // Reset element position after calculate the visible area


      if (element.style) {
        element.style.position = originalPosition;
      }

      if (isAncestorFixed(element)) {
        // Clip by viewport's size.
        visibleRect.left = Math.max(visibleRect.left, scrollX);
        visibleRect.top = Math.max(visibleRect.top, scrollY);
        visibleRect.right = Math.min(visibleRect.right, scrollX + viewportWidth);
        visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + viewportHeight);
      } else {
        // Clip by document's size.
        var maxVisibleWidth = Math.max(documentWidth, scrollX + viewportWidth);
        visibleRect.right = Math.min(visibleRect.right, maxVisibleWidth);
        var maxVisibleHeight = Math.max(documentHeight, scrollY + viewportHeight);
        visibleRect.bottom = Math.min(visibleRect.bottom, maxVisibleHeight);
      }

      return visibleRect.top >= 0 && visibleRect.left >= 0 && visibleRect.bottom > visibleRect.top && visibleRect.right > visibleRect.left ? visibleRect : null;
    }

    function adjustForViewport(elFuturePos, elRegion, visibleRect, overflow) {
      var pos = utils.clone(elFuturePos);
      var size = {
        width: elRegion.width,
        height: elRegion.height
      };

      if (overflow.adjustX && pos.left < visibleRect.left) {
        pos.left = visibleRect.left;
      } // Left edge inside and right edge outside viewport, try to resize it.


      if (overflow.resizeWidth && pos.left >= visibleRect.left && pos.left + size.width > visibleRect.right) {
        size.width -= pos.left + size.width - visibleRect.right;
      } // Right edge outside viewport, try to move it.


      if (overflow.adjustX && pos.left + size.width > visibleRect.right) {
        // 保证左边界和可视区域左边界对齐
        pos.left = Math.max(visibleRect.right - size.width, visibleRect.left);
      } // Top edge outside viewport, try to move it.


      if (overflow.adjustY && pos.top < visibleRect.top) {
        pos.top = visibleRect.top;
      } // Top edge inside and bottom edge outside viewport, try to resize it.


      if (overflow.resizeHeight && pos.top >= visibleRect.top && pos.top + size.height > visibleRect.bottom) {
        size.height -= pos.top + size.height - visibleRect.bottom;
      } // Bottom edge outside viewport, try to move it.


      if (overflow.adjustY && pos.top + size.height > visibleRect.bottom) {
        // 保证上边界和可视区域上边界对齐
        pos.top = Math.max(visibleRect.bottom - size.height, visibleRect.top);
      }

      return utils.mix(pos, size);
    }

    function getRegion(node) {
      var offset;
      var w;
      var h;

      if (!utils.isWindow(node) && node.nodeType !== 9) {
        offset = utils.offset(node);
        w = utils.outerWidth(node);
        h = utils.outerHeight(node);
      } else {
        var win = utils.getWindow(node);
        offset = {
          left: utils.getWindowScrollLeft(win),
          top: utils.getWindowScrollTop(win)
        };
        w = utils.viewportWidth(win);
        h = utils.viewportHeight(win);
      }

      offset.width = w;
      offset.height = h;
      return offset;
    }

    /**
     * 获取 node 上的 align 对齐点 相对于页面的坐标
     */
    function getAlignOffset(region, align) {
      var V = align.charAt(0);
      var H = align.charAt(1);
      var w = region.width;
      var h = region.height;
      var x = region.left;
      var y = region.top;

      if (V === 'c') {
        y += h / 2;
      } else if (V === 'b') {
        y += h;
      }

      if (H === 'c') {
        x += w / 2;
      } else if (H === 'r') {
        x += w;
      }

      return {
        left: x,
        top: y
      };
    }

    function getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset) {
      var p1 = getAlignOffset(refNodeRegion, points[1]);
      var p2 = getAlignOffset(elRegion, points[0]);
      var diff = [p2.left - p1.left, p2.top - p1.top];
      return {
        left: Math.round(elRegion.left - diff[0] + offset[0] - targetOffset[0]),
        top: Math.round(elRegion.top - diff[1] + offset[1] - targetOffset[1])
      };
    }

    /**
     * align dom node flexibly
     * @author yiminghe@gmail.com
     */

    function isFailX(elFuturePos, elRegion, visibleRect) {
      return elFuturePos.left < visibleRect.left || elFuturePos.left + elRegion.width > visibleRect.right;
    }

    function isFailY(elFuturePos, elRegion, visibleRect) {
      return elFuturePos.top < visibleRect.top || elFuturePos.top + elRegion.height > visibleRect.bottom;
    }

    function isCompleteFailX(elFuturePos, elRegion, visibleRect) {
      return elFuturePos.left > visibleRect.right || elFuturePos.left + elRegion.width < visibleRect.left;
    }

    function isCompleteFailY(elFuturePos, elRegion, visibleRect) {
      return elFuturePos.top > visibleRect.bottom || elFuturePos.top + elRegion.height < visibleRect.top;
    }

    function flip(points, reg, map) {
      var ret = [];
      utils.each(points, function (p) {
        ret.push(p.replace(reg, function (m) {
          return map[m];
        }));
      });
      return ret;
    }

    function flipOffset(offset, index) {
      offset[index] = -offset[index];
      return offset;
    }

    function convertOffset(str, offsetLen) {
      var n;

      if (/%$/.test(str)) {
        n = parseInt(str.substring(0, str.length - 1), 10) / 100 * offsetLen;
      } else {
        n = parseInt(str, 10);
      }

      return n || 0;
    }

    function normalizeOffset(offset, el) {
      offset[0] = convertOffset(offset[0], el.width);
      offset[1] = convertOffset(offset[1], el.height);
    }
    /**
     * @param el
     * @param tgtRegion 参照节点所占的区域: { left, top, width, height }
     * @param align
     */

    function doAlign(el, tgtRegion, align, isTgtRegionVisible) {
      var points = align.points;
      var offset = align.offset || [0, 0];
      var targetOffset = align.targetOffset || [0, 0];
      var overflow = align.overflow;
      var source = align.source || el;
      offset = [].concat(offset);
      targetOffset = [].concat(targetOffset);
      overflow = overflow || {};
      var newOverflowCfg = {};
      var fail = 0; // 当前节点可以被放置的显示区域

      var visibleRect = getVisibleRectForElement(source); // 当前节点所占的区域, left/top/width/height

      var elRegion = getRegion(source); // 将 offset 转换成数值，支持百分比

      normalizeOffset(offset, elRegion);
      normalizeOffset(targetOffset, tgtRegion); // 当前节点将要被放置的位置

      var elFuturePos = getElFuturePos(elRegion, tgtRegion, points, offset, targetOffset); // 当前节点将要所处的区域

      var newElRegion = utils.merge(elRegion, elFuturePos); // 如果可视区域不能完全放置当前节点时允许调整

      if (visibleRect && (overflow.adjustX || overflow.adjustY) && isTgtRegionVisible) {
        if (overflow.adjustX) {
          // 如果横向不能放下
          if (isFailX(elFuturePos, elRegion, visibleRect)) {
            // 对齐位置反下
            var newPoints = flip(points, /[lr]/gi, {
              l: 'r',
              r: 'l'
            }); // 偏移量也反下

            var newOffset = flipOffset(offset, 0);
            var newTargetOffset = flipOffset(targetOffset, 0);
            var newElFuturePos = getElFuturePos(elRegion, tgtRegion, newPoints, newOffset, newTargetOffset);

            if (!isCompleteFailX(newElFuturePos, elRegion, visibleRect)) {
              fail = 1;
              points = newPoints;
              offset = newOffset;
              targetOffset = newTargetOffset;
            }
          }
        }

        if (overflow.adjustY) {
          // 如果纵向不能放下
          if (isFailY(elFuturePos, elRegion, visibleRect)) {
            // 对齐位置反下
            var _newPoints = flip(points, /[tb]/gi, {
              t: 'b',
              b: 't'
            }); // 偏移量也反下


            var _newOffset = flipOffset(offset, 1);

            var _newTargetOffset = flipOffset(targetOffset, 1);

            var _newElFuturePos = getElFuturePos(elRegion, tgtRegion, _newPoints, _newOffset, _newTargetOffset);

            if (!isCompleteFailY(_newElFuturePos, elRegion, visibleRect)) {
              fail = 1;
              points = _newPoints;
              offset = _newOffset;
              targetOffset = _newTargetOffset;
            }
          }
        } // 如果失败，重新计算当前节点将要被放置的位置


        if (fail) {
          elFuturePos = getElFuturePos(elRegion, tgtRegion, points, offset, targetOffset);
          utils.mix(newElRegion, elFuturePos);
        }

        var isStillFailX = isFailX(elFuturePos, elRegion, visibleRect);
        var isStillFailY = isFailY(elFuturePos, elRegion, visibleRect); // 检查反下后的位置是否可以放下了，如果仍然放不下：
        // 1. 复原修改过的定位参数

        if (isStillFailX || isStillFailY) {
          points = align.points;
          offset = align.offset || [0, 0];
          targetOffset = align.targetOffset || [0, 0];
        } // 2. 只有指定了可以调整当前方向才调整


        newOverflowCfg.adjustX = overflow.adjustX && isStillFailX;
        newOverflowCfg.adjustY = overflow.adjustY && isStillFailY; // 确实要调整，甚至可能会调整高度宽度

        if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) {
          newElRegion = adjustForViewport(elFuturePos, elRegion, visibleRect, newOverflowCfg);
        }
      } // need judge to in case set fixed with in css on height auto element


      if (newElRegion.width !== elRegion.width) {
        utils.css(source, 'width', utils.width(source) + newElRegion.width - elRegion.width);
      }

      if (newElRegion.height !== elRegion.height) {
        utils.css(source, 'height', utils.height(source) + newElRegion.height - elRegion.height);
      } // https://github.com/kissyteam/kissy/issues/190
      // 相对于屏幕位置没变，而 left/top 变了
      // 例如 <div 'relative'><el absolute></div>


      utils.offset(source, {
        left: newElRegion.left,
        top: newElRegion.top
      }, {
        useCssRight: align.useCssRight,
        useCssBottom: align.useCssBottom,
        useCssTransform: align.useCssTransform,
        ignoreShake: align.ignoreShake
      });
      return {
        points: points,
        offset: offset,
        targetOffset: targetOffset,
        overflow: newOverflowCfg
      };
    }
    /**
     *  2012-04-26 yiminghe@gmail.com
     *   - 优化智能对齐算法
     *   - 慎用 resizeXX
     *
     *  2011-07-13 yiminghe@gmail.com note:
     *   - 增加智能对齐，以及大小调整选项
     **/

    function isOutOfVisibleRect(target) {
      var visibleRect = getVisibleRectForElement(target);
      var targetRegion = getRegion(target);
      return !visibleRect || targetRegion.left + targetRegion.width <= visibleRect.left || targetRegion.top + targetRegion.height <= visibleRect.top || targetRegion.left >= visibleRect.right || targetRegion.top >= visibleRect.bottom;
    }

    function alignElement(el, refNode, align) {
      var target = align.target || refNode;
      var refNodeRegion = getRegion(target);
      var isTargetNotOutOfVisible = !isOutOfVisibleRect(target);
      return doAlign(el, refNodeRegion, align, isTargetNotOutOfVisible);
    }

    alignElement.__getOffsetParent = getOffsetParent;
    alignElement.__getVisibleRectForElement = getVisibleRectForElement;

    function ownKeys(object, enumerableOnly) {
      var keys = Object.keys(object);

      if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) symbols = symbols.filter(function (sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });
        keys.push.apply(keys, symbols);
      }

      return keys;
    }

    function _objectSpread(target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i] != null ? arguments[i] : {};

        if (i % 2) {
          ownKeys(source, true).forEach(function (key) {
            _defineProperty(target, key, source[key]);
          });
        } else if (Object.getOwnPropertyDescriptors) {
          Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
        } else {
          ownKeys(source).forEach(function (key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
          });
        }
      }

      return target;
    }

    function _defineProperty(obj, key, value) {
      if (key in obj) {
        Object.defineProperty(obj, key, {
          value: value,
          enumerable: true,
          configurable: true,
          writable: true
        });
      } else {
        obj[key] = value;
      }

      return obj;
    }
    /**
     * `tgtPoint`: { pageX, pageY } or { clientX, clientY }.
     * If client position provided, will internal convert to page position.
     */

    function alignPoint(el, tgtPoint, align) {
      var pageX;
      var pageY;
      var doc = utils.getDocument(el);
      var win = doc.defaultView || doc.parentWindow;
      var scrollX = utils.getWindowScrollLeft(win);
      var scrollY = utils.getWindowScrollTop(win);
      var viewportWidth = utils.viewportWidth(win);
      var viewportHeight = utils.viewportHeight(win);

      if ('pageX' in tgtPoint) {
        pageX = tgtPoint.pageX;
      } else {
        pageX = scrollX + tgtPoint.clientX;
      }

      if ('pageY' in tgtPoint) {
        pageY = tgtPoint.pageY;
      } else {
        pageY = scrollY + tgtPoint.clientY;
      }

      var tgtRegion = {
        left: pageX,
        top: pageY,
        width: 0,
        height: 0
      };
      var pointInView = pageX >= 0 && pageX <= scrollX + viewportWidth && pageY >= 0 && pageY <= scrollY + viewportHeight; // Provide default target point

      var points = [align.points[0], 'cc'];
      return doAlign(el, tgtRegion, _objectSpread({}, align, {
        points: points
      }), pointInView);
    }

    exports.alignElement = alignElement;
    exports.alignPoint = alignPoint;
    exports.default = alignElement;
    //# sourceMappingURL=index.js.map
  }
});
//# sourceMappingURL=index.js.map