text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
  
  var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
  
  exports.warnOnlyTreeNode = warnOnlyTreeNode;
  exports.arrDel = arrDel;
  exports.arrAdd = arrAdd;
  exports.posToArr = posToArr;
  exports.getPosition = getPosition;
  exports.isTreeNode = isTreeNode;
  exports.getNodeChildren = getNodeChildren;
  exports.isCheckDisabled = isCheckDisabled;
  exports.traverseTreeNodes = traverseTreeNodes;
  exports.mapChildren = mapChildren;
  exports.getDragNodesKeys = getDragNodesKeys;
  exports.calcDropPosition = calcDropPosition;
  exports.calcSelectedKeys = calcSelectedKeys;
  exports.convertDataToTree = convertDataToTree;
  exports.convertTreeToEntities = convertTreeToEntities;
  exports.parseCheckedKeys = parseCheckedKeys;
  exports.conductCheck = conductCheck;
  exports.conductExpandParent = conductExpandParent;
  
  var _react = require('react');
  
  var _react2 = _interopRequireDefault(_react);
  
  var _toArray = require('rc-util/lib/Children/toArray');
  
  var _toArray2 = _interopRequireDefault(_toArray);
  
  var _warning = require('warning');
  
  var _warning2 = _interopRequireDefault(_warning);
  
  var _TreeNode = require('./TreeNode');
  
  var _TreeNode2 = _interopRequireDefault(_TreeNode);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  
  var DRAG_SIDE_RANGE = 0.25;
  var DRAG_MIN_GAP = 2;
  
  var onlyTreeNodeWarned = false;
  
  function warnOnlyTreeNode() {
    if (onlyTreeNodeWarned) return;
  
    onlyTreeNodeWarned = true;
    (0, _warning2['default'])(false, 'Tree only accept TreeNode as children.');
  }
  
  function arrDel(list, value) {
    var clone = list.slice();
    var index = clone.indexOf(value);
    if (index >= 0) {
      clone.splice(index, 1);
    }
    return clone;
  }
  
  function arrAdd(list, value) {
    var clone = list.slice();
    if (clone.indexOf(value) === -1) {
      clone.push(value);
    }
    return clone;
  }
  
  function posToArr(pos) {
    return pos.split('-');
  }
  
  function getPosition(level, index) {
    return level + '-' + index;
  }
  
  function isTreeNode(node) {
    return node && node.type && node.type.isTreeNode;
  }
  
  function getNodeChildren(children) {
    return (0, _toArray2['default'])(children).filter(isTreeNode);
  }
  
  function isCheckDisabled(node) {
    var _ref = node.props || {},
        disabled = _ref.disabled,
        disableCheckbox = _ref.disableCheckbox;
  
    return !!(disabled || disableCheckbox);
  }
  
  function traverseTreeNodes(treeNodes, callback) {
    function processNode(node, index, parent) {
      var children = node ? node.props.children : treeNodes;
      var pos = node ? getPosition(parent.pos, index) : 0;
  
      // Filter children
      var childList = getNodeChildren(children);
  
      // Process node if is not root
      if (node) {
        var data = {
          node: node,
          index: index,
          pos: pos,
          key: node.key || pos,
          parentPos: parent.node ? parent.pos : null
        };
  
        callback(data);
      }
  
      // Process children node
      _react.Children.forEach(childList, function (subNode, subIndex) {
        processNode(subNode, subIndex, { node: node, pos: pos });
      });
    }
  
    processNode(null);
  }
  
  /**
   * Use `rc-util` `toArray` to get the children list which keeps the key.
   * And return single node if children is only one(This can avoid `key` missing check).
   */
  function mapChildren(children, func) {
    var list = (0, _toArray2['default'])(children).map(func);
    if (list.length === 1) {
      return list[0];
    }
    return list;
  }
  
  function getDragNodesKeys(treeNodes, node) {
    var _node$props = node.props,
        eventKey = _node$props.eventKey,
        pos = _node$props.pos;
  
    var dragNodesKeys = [];
  
    traverseTreeNodes(treeNodes, function (_ref2) {
      var key = _ref2.key;
  
      dragNodesKeys.push(key);
    });
    dragNodesKeys.push(eventKey || pos);
    return dragNodesKeys;
  }
  
  // Only used when drag, not affect SSR.
  function calcDropPosition(event, treeNode) {
    var clientY = event.clientY;
  
    var _treeNode$selectHandl = treeNode.selectHandle.getBoundingClientRect(),
        top = _treeNode$selectHandl.top,
        bottom = _treeNode$selectHandl.bottom,
        height = _treeNode$selectHandl.height;
  
    var des = Math.max(height * DRAG_SIDE_RANGE, DRAG_MIN_GAP);
  
    if (clientY <= top + des) {
      return -1;
    } else if (clientY >= bottom - des) {
      return 1;
    }
  
    return 0;
  }
  
  /**
   * Return selectedKeys according with multiple prop
   * @param selectedKeys
   * @param props
   * @returns [string]
   */
  function calcSelectedKeys(selectedKeys, props) {
    if (!selectedKeys) return undefined;
  
    var multiple = props.multiple;
  
    if (multiple) {
      return selectedKeys.slice();
    }
  
    if (selectedKeys.length) {
      return [selectedKeys[0]];
    }
    return selectedKeys;
  }
  
  /**
   * Since React internal will convert key to string,
   * we need do this to avoid `checkStrictly` use number match
   */
  function keyListToString(keyList) {
    if (!keyList) return keyList;
    return keyList.map(function (key) {
      return String(key);
    });
  }
  
  var internalProcessProps = function internalProcessProps(props) {
    return props;
  };
  function convertDataToTree(treeData, processer) {
    if (!treeData) return [];
  
    var _ref3 = processer || {},
        _ref3$processProps = _ref3.processProps,
        processProps = _ref3$processProps === undefined ? internalProcessProps : _ref3$processProps;
  
    var list = Array.isArray(treeData) ? treeData : [treeData];
    return list.map(function (_ref4) {
      var children = _ref4.children,
          props = (0, _objectWithoutProperties3['default'])(_ref4, ['children']);
  
      var childrenNodes = convertDataToTree(children, processer);
  
      return _react2['default'].createElement(
        _TreeNode2['default'],
        processProps(props),
        childrenNodes
      );
    });
  }
  
  // TODO: ========================= NEW LOGIC =========================
  /**
   * Calculate treeNodes entities. `processTreeEntity` is used for `rc-tree-select`
   * @param treeNodes
   * @param processTreeEntity  User can customize the entity
   */
  function convertTreeToEntities(treeNodes) {
    var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
        initWrapper = _ref5.initWrapper,
        processEntity = _ref5.processEntity,
        onProcessFinished = _ref5.onProcessFinished;
  
    var posEntities = {};
    var keyEntities = {};
    var wrapper = {
      posEntities: posEntities,
      keyEntities: keyEntities
    };
  
    if (initWrapper) {
      wrapper = initWrapper(wrapper) || wrapper;
    }
  
    traverseTreeNodes(treeNodes, function (item) {
      var node = item.node,
          index = item.index,
          pos = item.pos,
          key = item.key,
          parentPos = item.parentPos;
  
      var entity = { node: node, index: index, key: key, pos: pos };
  
      posEntities[pos] = entity;
      keyEntities[key] = entity;
  
      // Fill children
      entity.parent = posEntities[parentPos];
      if (entity.parent) {
        entity.parent.children = entity.parent.children || [];
        entity.parent.children.push(entity);
      }
  
      if (processEntity) {
        processEntity(entity, wrapper);
      }
    });
  
    if (onProcessFinished) {
      onProcessFinished(wrapper);
    }
  
    return wrapper;
  }
  
  /**
   * Parse `checkedKeys` to { checkedKeys, halfCheckedKeys } style
   */
  function parseCheckedKeys(keys) {
    if (!keys) {
      return null;
    }
  
    // Convert keys to object format
    var keyProps = void 0;
    if (Array.isArray(keys)) {
      // [Legacy] Follow the api doc
      keyProps = {
        checkedKeys: keys,
        halfCheckedKeys: undefined
      };
    } else if (typeof keys === 'object') {
      keyProps = {
        checkedKeys: keys.checked || undefined,
        halfCheckedKeys: keys.halfChecked || undefined
      };
    } else {
      (0, _warning2['default'])(false, '`checkedKeys` is not an array or an object');
      return null;
    }
  
    keyProps.checkedKeys = keyListToString(keyProps.checkedKeys);
    keyProps.halfCheckedKeys = keyListToString(keyProps.halfCheckedKeys);
  
    return keyProps;
  }
  
  /**
   * Conduct check state by the keyList. It will conduct up & from the provided key.
   * If the conduct path reach the disabled or already checked / unchecked node will stop conduct.
   * @param keyList       list of keys
   * @param isCheck       is check the node or not
   * @param keyEntities   parsed by `convertTreeToEntities` function in Tree
   * @param checkStatus   Can pass current checked status for process (usually for uncheck operation)
   * @returns {{checkedKeys: [], halfCheckedKeys: []}}
   */
  function conductCheck(keyList, isCheck, keyEntities) {
    var checkStatus = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
  
    var checkedKeys = {};
    var halfCheckedKeys = {}; // Record the key has some child checked (include child half checked)
  
    (checkStatus.checkedKeys || []).forEach(function (key) {
      checkedKeys[key] = true;
    });
  
    (checkStatus.halfCheckedKeys || []).forEach(function (key) {
      halfCheckedKeys[key] = true;
    });
  
    // Conduct up
    function conductUp(key) {
      if (checkedKeys[key] === isCheck) return;
  
      var entity = keyEntities[key];
      if (!entity) return;
  
      var children = entity.children,
          parent = entity.parent,
          node = entity.node;
  
  
      if (isCheckDisabled(node)) return;
  
      // Check child node checked status
      var everyChildChecked = true;
      var someChildChecked = false; // Child checked or half checked
  
      (children || []).filter(function (child) {
        return !isCheckDisabled(child.node);
      }).forEach(function (_ref6) {
        var childKey = _ref6.key;
  
        var childChecked = checkedKeys[childKey];
        var childHalfChecked = halfCheckedKeys[childKey];
  
        if (childChecked || childHalfChecked) someChildChecked = true;
        if (!childChecked) everyChildChecked = false;
      });
  
      // Update checked status
      if (isCheck) {
        checkedKeys[key] = everyChildChecked;
      } else {
        checkedKeys[key] = false;
      }
      halfCheckedKeys[key] = someChildChecked;
  
      if (parent) {
        conductUp(parent.key);
      }
    }
  
    // Conduct down
    function conductDown(key) {
      if (checkedKeys[key] === isCheck) return;
  
      var entity = keyEntities[key];
      if (!entity) return;
  
      var children = entity.children,
          node = entity.node;
  
  
      if (isCheckDisabled(node)) return;
  
      checkedKeys[key] = isCheck;
  
      (children || []).forEach(function (child) {
        conductDown(child.key);
      });
    }
  
    function conduct(key) {
      var entity = keyEntities[key];
  
      if (!entity) {
        (0, _warning2['default'])(false, '\'' + key + '\' does not exist in the tree.');
        return;
      }
  
      var children = entity.children,
          parent = entity.parent,
          node = entity.node;
  
      checkedKeys[key] = isCheck;
  
      if (isCheckDisabled(node)) return;
  
      // Conduct down
      (children || []).filter(function (child) {
        return !isCheckDisabled(child.node);
      }).forEach(function (child) {
        conductDown(child.key);
      });
  
      // Conduct up
      if (parent) {
        conductUp(parent.key);
      }
    }
  
    (keyList || []).forEach(function (key) {
      conduct(key);
    });
  
    var checkedKeyList = [];
    var halfCheckedKeyList = [];
  
    // Fill checked list
    Object.keys(checkedKeys).forEach(function (key) {
      if (checkedKeys[key]) {
        checkedKeyList.push(key);
      }
    });
  
    // Fill half checked list
    Object.keys(halfCheckedKeys).forEach(function (key) {
      if (!checkedKeys[key] && halfCheckedKeys[key]) {
        halfCheckedKeyList.push(key);
      }
    });
  
    return {
      checkedKeys: checkedKeyList,
      halfCheckedKeys: halfCheckedKeyList
    };
  }
  
  /**
   * If user use `autoExpandParent` we should get the list of parent node
   * @param keyList
   * @param keyEntities
   */
  function conductExpandParent(keyList, keyEntities) {
    var expandedKeys = {};
  
    function conductUp(key) {
      if (expandedKeys[key]) return;
  
      var entity = keyEntities[key];
      if (!entity) return;
  
      var parent = entity.parent,
          node = entity.node;
  
  
      if (isCheckDisabled(node)) return;
  
      expandedKeys[key] = true;
  
      if (parent) {
        conductUp(parent.key);
      }
    }
  
    (keyList || []).forEach(function (key) {
      conductUp(key);
    });
  
    return Object.keys(expandedKeys);
  }