text: import { asArray } from './utils/array.esm.js';
  import { getTabbableNodes, getAllTabbableNodes, parentAutofocusables, getCommonParent } from './utils/DOMutils.esm.js';
  import pickFirstFocus, { pickFocusable } from './utils/firstFocus.esm.js';
  import getAllAffectedNodes from './utils/all-affected.esm.js';
  
  var findAutoFocused = function findAutoFocused(autoFocusables) {
    return function (node) {
      return !!node.autofocus || node.dataset && !!node.dataset.autofocus || autoFocusables.indexOf(node) >= 0;
    };
  };
  
  var isGuard = function isGuard(node) {
    return node && node.dataset && node.dataset.focusGuard;
  };
  var notAGuard = function notAGuard(node) {
    return !isGuard(node);
  };
  
  var newFocus = function newFocus(innerNodes, outerNodes, activeElement, lastNode, autoFocused) {
    var cnt = innerNodes.length;
    var firstFocus = innerNodes[0];
    var lastFocus = innerNodes[cnt - 1];
    var isOnGuard = isGuard(activeElement);
  
    // focus is inside
    if (innerNodes.indexOf(activeElement) >= 0) {
      return undefined;
    }
  
    var activeIndex = outerNodes.indexOf(activeElement);
    var lastIndex = outerNodes.indexOf(lastNode || activeIndex);
    var lastNodeInside = innerNodes.indexOf(lastNode);
    var indexDiff = activeIndex - lastIndex;
    var firstNodeIndex = outerNodes.indexOf(firstFocus);
    var lastNodeIndex = outerNodes.indexOf(lastFocus);
  
    var returnFirstNode = pickFocusable(innerNodes, 0);
    var returnLastNode = pickFocusable(innerNodes, cnt - 1);
  
    // new focus
    if (activeIndex === -1 || lastNodeInside === -1) {
      return innerNodes.indexOf(autoFocused && autoFocused.length ? pickFirstFocus(autoFocused) : pickFirstFocus(innerNodes));
    }
    // old focus
    if (!indexDiff && lastNodeInside >= 0) {
      return lastNodeInside;
    }
    // first element
    if (activeIndex <= firstNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
      return returnLastNode;
    }
    // last element
    if (activeIndex >= firstNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
      return returnFirstNode;
    }
    // jump out, but not on the guard
    if (indexDiff && Math.abs(indexDiff) > 1) {
      return lastNodeInside;
    }
    // focus above lock
    if (activeIndex <= firstNodeIndex) {
      return returnLastNode;
    }
    // focus below lock
    if (activeIndex > lastNodeIndex) {
      return returnFirstNode;
    }
    // index is inside tab order, but outside Lock
    if (indexDiff) {
      if (Math.abs(indexDiff) > 1) {
        return lastNodeInside;
      }
      return (cnt + lastNodeInside + indexDiff) % cnt;
    }
    // do nothing
    return undefined;
  };
  
  var getTopCommonParent = function getTopCommonParent(baseActiveElement, leftEntry, rightEntries) {
    var activeElements = asArray(baseActiveElement);
    var leftEntries = asArray(leftEntry);
    var activeElement = activeElements[0];
    var topCommon = null;
    leftEntries.filter(Boolean).forEach(function (entry) {
      topCommon = getCommonParent(topCommon || entry, entry) || topCommon;
      rightEntries.filter(Boolean).forEach(function (subEntry) {
        var common = getCommonParent(activeElement, subEntry);
        if (common) {
          if (!topCommon || common.contains(topCommon)) {
            topCommon = common;
          } else {
            topCommon = getCommonParent(common, topCommon);
          }
        }
      });
    });
    return topCommon;
  };
  
  var allParentAutofocusables = function allParentAutofocusables(entries) {
    return entries.reduce(function (acc, node) {
      return acc.concat(parentAutofocusables(node));
    }, []);
  };
  
  var reorderNodes = function reorderNodes(srcNodes, dstNodes) {
    var remap = new Map();
    // no Set(dstNodes) for IE11 :(
    dstNodes.forEach(function (entity) {
      return remap.set(entity.node, entity);
    });
    // remap to dstNodes
    return srcNodes.map(function (node) {
      return remap.get(node);
    }).filter(Boolean);
  };
  
  var getFocusabledIn = function getFocusabledIn(topNode) {
    var entries = getAllAffectedNodes(topNode).filter(notAGuard);
    var commonParent = getTopCommonParent(topNode, topNode, entries);
    var outerNodes = getTabbableNodes([commonParent], true);
    var innerElements = getTabbableNodes(entries).filter(function (_ref) {
      var node = _ref.node;
      return notAGuard(node);
    }).map(function (_ref2) {
      var node = _ref2.node;
      return node;
    });
  
    return outerNodes.map(function (_ref3) {
      var node = _ref3.node,
          index = _ref3.index;
      return {
        node: node,
        index: index,
        lockItem: innerElements.indexOf(node) >= 0,
        guard: isGuard(node)
      };
    });
  };
  
  var getFocusMerge = function getFocusMerge(topNode, lastNode) {
    var activeElement = document && document.activeElement;
    var entries = getAllAffectedNodes(topNode).filter(notAGuard);
  
    var commonParent = getTopCommonParent(activeElement || topNode, topNode, entries);
  
    var innerElements = getTabbableNodes(entries).filter(function (_ref4) {
      var node = _ref4.node;
      return notAGuard(node);
    });
  
    if (!innerElements[0]) {
      innerElements = getAllTabbableNodes(entries).filter(function (_ref5) {
        var node = _ref5.node;
        return notAGuard(node);
      });
      if (!innerElements[0]) {
        return undefined;
      }
    }
  
    var outerNodes = getTabbableNodes([commonParent]).map(function (_ref6) {
      var node = _ref6.node;
      return node;
    });
    var orderedInnerElements = reorderNodes(outerNodes, innerElements);
    var innerNodes = orderedInnerElements.map(function (_ref7) {
      var node = _ref7.node;
      return node;
    });
  
    var newId = newFocus(innerNodes, outerNodes, activeElement, lastNode, innerNodes.filter(findAutoFocused(allParentAutofocusables(entries))));
  
    if (newId === undefined) {
      return newId;
    }
    return orderedInnerElements[newId];
  };
  
  export default getFocusMerge;
  export { getFocusabledIn, newFocus };
  //# sourceMappingURL=focusMerge.esm.js.map
  