"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _react = _interopRequireWildcard(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _classnames = _interopRequireDefault(require("classnames"));

var _util = require("../../util");

var _treeNode = _interopRequireDefault(require("./tree-node"));

var _util2 = require("./util");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

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); }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }

function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }

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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

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; }

var bindCtx = _util.func.bindCtx,
    noop = _util.func.noop;
var getOffset = _util.dom.getOffset;
var pickOthers = _util.obj.pickOthers,
    isPlainObject = _util.obj.isPlainObject;
/**
 * Tree
 */

var Tree =
/*#__PURE__*/
function (_Component) {
  _inherits(Tree, _Component);

  function Tree(props) {
    var _this;

    _classCallCheck(this, Tree);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Tree).call(this, props));

    _this.updateCache(props);

    var _this$props = _this.props,
        focusable = _this$props.focusable,
        autoFocus = _this$props.autoFocus,
        focusedKey = _this$props.focusedKey;

    if (focusable) {
      _this.tabbableKey = _this.getFirstAvaliablelChildKey('0');
    }

    _this.indeterminateKeys = [];
    _this.state = {
      expandedKeys: _this.getExpandedKeys(props),
      selectedKeys: _this.getSelectedKeys(props),
      checkedKeys: _this.getCheckedKeys(props),
      focusedKey: 'focusedKey' in _this.props ? focusedKey : focusable && autoFocus ? _this.tabbableKey : null
    };
    bindCtx(_assertThisInitialized(_this), ['handleExpand', 'handleSelect', 'handleCheck', 'handleBlur']);
    return _this;
  }

  _createClass(Tree, [{
    key: "UNSAFE_componentWillReceiveProps",
    value: function UNSAFE_componentWillReceiveProps(nextProps) {
      this.updateCache(nextProps);
      var st = {};

      if ('expandedKeys' in nextProps) {
        st.expandedKeys = this.getExpandedKeys(nextProps, true);
      }

      if ('selectedKeys' in nextProps) {
        st.selectedKeys = this.getSelectedKeys(nextProps, true);
      }

      if ('checkedKeys' in nextProps) {
        st.checkedKeys = this.getCheckedKeys(nextProps, true);
      }

      this.indeterminateKeys = this.getIndeterminateKeys(st.checkedKeys || this.state.checkedKeys || []);

      if (Object.keys(st).length) {
        this.setState(st);
      }
    }
  }, {
    key: "updateCache",
    value: function updateCache(props) {
      var _this2 = this;

      this._k2n = {};
      this._p2n = {};

      if ('dataSource' in props) {
        var loop = function loop(data) {
          var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
          return data.forEach(function (item, index) {
            var pos = "".concat(prefix, "-").concat(index);
            var key = item.key;
            key = key || pos;

            var newItem = _objectSpread({}, item, {
              key: key,
              pos: pos
            });

            var children = item.children;

            if (children && children.length) {
              loop(children, pos);
            }

            _this2._k2n[key] = _this2._p2n[pos] = newItem;
          });
        };

        loop(props.dataSource);
      } else if ('children' in props) {
        var _loop = function _loop(children) {
          var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
          return _react.Children.map(children, function (node, index) {
            if (!_react["default"].isValidElement(node)) {
              return;
            }

            var pos = "".concat(prefix, "-").concat(index);
            var key = node.key;
            key = key || pos;

            var newItem = _objectSpread({}, node.props, {
              key: key,
              pos: pos
            });

            var children = node.props.children;

            if (children && _react.Children.count(children)) {
              newItem.children = _loop(children, pos);
            }

            _this2._k2n[key] = _this2._p2n[pos] = newItem;
            return newItem;
          });
        };

        _loop(props.children);
      }
    }
  }, {
    key: "setFocusKey",
    value: function setFocusKey() {
      var _this$state$selectedK = this.state.selectedKeys,
          selectedKeys = _this$state$selectedK === void 0 ? [] : _this$state$selectedK;
      this.setState({
        focusedKey: selectedKeys.length > 0 ? selectedKeys[0] : this.getFirstAvaliablelChildKey('0')
      });
    }
  }, {
    key: "getExpandedKeys",
    value: function getExpandedKeys(props, willReceiveProps) {
      var _this3 = this;

      var expandedKeys;

      if (!willReceiveProps && props.defaultExpandAll) {
        expandedKeys = Object.keys(this._k2n).filter(function (key) {
          var children = _this3._k2n[key].children;
          return children && children.length;
        });
      } else {
        expandedKeys = 'expandedKeys' in props ? props.expandedKeys : willReceiveProps ? [] : props.defaultExpandedKeys;
        expandedKeys = (0, _util2.normalizeToArray)(expandedKeys);

        if (props.autoExpandParent) {
          var newExpandedKeys = [];
          var expandedPoss = expandedKeys.reduce(function (ret, key) {
            var pos = _this3._k2n[key] && _this3._k2n[key].pos;

            if (pos) {
              ret.push(pos);
              newExpandedKeys.push(key);
            }

            return ret;
          }, []);
          expandedPoss.forEach(function (pos) {
            var nums = pos.split('-');

            if (nums.length === 2) {
              return;
            }

            for (var i = 1; i <= nums.length - 2; i++) {
              var ancestorPos = nums.slice(0, i + 1).join('-');
              var ancestorKey = _this3._p2n[ancestorPos].key;

              if (newExpandedKeys.indexOf(ancestorKey) === -1) {
                newExpandedKeys.push(ancestorKey);
              }
            }
          });
          return newExpandedKeys;
        }
      }

      return expandedKeys;
    }
  }, {
    key: "getAvailableKey",
    value: function getAvailableKey(pos, prev) {
      var _this4 = this;

      var ps = Object.keys(this._p2n).filter(function (p) {
        return _this4.isAvailablePos(pos, p);
      });

      if (ps.length > 1) {
        var index = ps.indexOf(pos);
        var targetIndex;

        if (prev) {
          targetIndex = index === 0 ? ps.length - 1 : index - 1;
        } else {
          targetIndex = index === ps.length - 1 ? 0 : index + 1;
        }

        return this._p2n[ps[targetIndex]].key;
      }

      return null;
    }
  }, {
    key: "getFirstAvaliablelChildKey",
    value: function getFirstAvaliablelChildKey(parentPos) {
      var _this5 = this;

      var pos = Object.keys(this._p2n).find(function (p) {
        return _this5.isAvailablePos("".concat(parentPos, "-0"), p);
      });
      return pos ? this._p2n[pos].key : null;
    }
  }, {
    key: "isAvailablePos",
    value: function isAvailablePos(refPos, targetPos) {
      var disabled = this._p2n[targetPos].disabled;
      return this.isSibling(refPos, targetPos) && !disabled;
    }
  }, {
    key: "isSibling",
    value: function isSibling(currentPos, targetPos) {
      var currentNums = currentPos.split('-').slice(0, -1);
      var targetNums = targetPos.split('-').slice(0, -1);
      return currentNums.length === targetNums.length && currentNums.every(function (num, index) {
        return num === targetNums[index];
      });
    }
  }, {
    key: "getParentKey",
    value: function getParentKey(pos) {
      return this._p2n[pos.slice(0, pos.length - 2)].key;
    }
  }, {
    key: "getSelectedKeys",
    value: function getSelectedKeys(props, willReceiveProps) {
      var _this6 = this;

      var selectedKeys = 'selectedKeys' in props ? props.selectedKeys : willReceiveProps ? [] : props.defaultSelectedKeys;
      selectedKeys = (0, _util2.normalizeToArray)(selectedKeys);
      var newSelectKeys = selectedKeys.filter(function (key) {
        return _this6._k2n[key];
      });
      return newSelectKeys;
    }
    /* istanbul ignore next */

  }, {
    key: "getCheckedKeys",
    value: function getCheckedKeys(props, willReceiveProps) {
      var _this7 = this;

      var checkedKeys = props.defaultCheckedKeys;

      if ('checkedKeys' in props) {
        checkedKeys = props.checkedKeys;
      } else if (willReceiveProps) {
        checkedKeys = [];
      }

      var checkStrictly = this.props.checkStrictly;

      if (checkStrictly) {
        if (isPlainObject(checkedKeys)) {
          var _checkedKeys = checkedKeys,
              checked = _checkedKeys.checked,
              indeterminate = _checkedKeys.indeterminate;
          checkedKeys = (0, _util2.normalizeToArray)(checked);
          this.indeterminateKeys = (0, _util2.normalizeToArray)(indeterminate);
        } else {
          checkedKeys = (0, _util2.normalizeToArray)(checkedKeys);
        }

        checkedKeys = checkedKeys.filter(function (key) {
          return !!_this7._k2n[key];
        });
      } else {
        checkedKeys = (0, _util2.getAllCheckedKeys)(checkedKeys, this._k2n, this._p2n);
        checkedKeys = checkedKeys.filter(function (key) {
          return !!_this7._k2n[key];
        });
        this.indeterminateKeys = this.getIndeterminateKeys(checkedKeys);
      }

      return checkedKeys;
    }
  }, {
    key: "processKey",
    value: function processKey(keys, key, add) {
      var index = keys.indexOf(key);

      if (add && index === -1) {
        keys.push(key);
      } else if (!add && index > -1) {
        keys.splice(index, 1);
      }

      return keys;
    }
    /* eslint-disable max-statements */

  }, {
    key: "handleItemKeyDown",
    value: function handleItemKeyDown(key, item, e) {
      if ([_util.KEYCODE.UP, _util.KEYCODE.DOWN, _util.KEYCODE.RIGHT, _util.KEYCODE.LEFT, _util.KEYCODE.ENTER, _util.KEYCODE.ESC, _util.KEYCODE.SPACE].indexOf(e.keyCode) > -1) {
        e.preventDefault();
        e.stopPropagation();
      }

      var focusedKey = this.state.focusedKey;
      var node = this._k2n[key];
      var pos = this._k2n[key].pos;
      var level = pos.split('-').length - 1;

      switch (e.keyCode) {
        case _util.KEYCODE.UP:
          {
            var avaliableKey = this.getAvailableKey(pos, true);

            if (avaliableKey) {
              focusedKey = avaliableKey;
            }

            break;
          }

        case _util.KEYCODE.DOWN:
          {
            var _avaliableKey = this.getAvailableKey(pos, false);

            if (_avaliableKey) {
              focusedKey = _avaliableKey;
            }

            break;
          }

        case _util.KEYCODE.RIGHT:
          {
            this.handleExpand(true, key, node);

            var _avaliableKey2 = this.getFirstAvaliablelChildKey(pos);

            if (_avaliableKey2) {
              focusedKey = _avaliableKey2;
            }

            break;
          }

        case _util.KEYCODE.LEFT:
        case _util.KEYCODE.ESC:
          {
            if (level === 1) {
              var _avaliableKey3 = this.getAvailableKey(pos, true);

              if (_avaliableKey3) {
                focusedKey = _avaliableKey3;
              }
            } else if (level > 1) {
              var parentKey = this.getParentKey(pos);
              this.handleExpand(false, parentKey, node);
              focusedKey = parentKey;
            }

            break;
          }

        case _util.KEYCODE.ENTER:
        case _util.KEYCODE.SPACE:
          {
            var checkable = item.props.checkable === true || this.props.checkable;
            var selectable = item.props.selectable === true || this.props.selectable;

            if (checkable) {
              this.handleCheck(!item.props.checked, key, node);
            } else if (selectable) {
              this.handleSelect(!item.props.selected, key, node, e);
            }

            break;
          }

        case _util.KEYCODE.TAB:
          focusedKey = null;
          break;

        default:
          break;
      }

      if (focusedKey !== this.state.focusedKey) {
        if (!('focusedKey' in this.props)) {
          this.setState({
            focusedKey: focusedKey
          });
        }
      }

      this.props.onItemKeyDown(focusedKey, item, e);
      this.props.onItemFocus(focusedKey, e);
    }
  }, {
    key: "handleBlur",
    value: function handleBlur(e) {
      this.setState({
        focusedKey: ''
      });
      this.props.onBlur && this.props.onBlur(e);
    }
  }, {
    key: "handleExpand",
    value: function handleExpand(expand, key, node) {
      var _this8 = this;

      var _this$props2 = this.props,
          onExpand = _this$props2.onExpand,
          loadData = _this$props2.loadData;
      var expandedKeys = this.state.expandedKeys; // 由于setState 是异步操作，所以去掉 [...this.state.expandedKeys]

      this.processKey(expandedKeys, key, expand);

      var setExpandedState = function setExpandedState() {
        if (!('expandedKeys' in _this8.props)) {
          _this8.setState({
            expandedKeys: expandedKeys
          });
        }

        onExpand(expandedKeys, {
          expanded: expand,
          node: node
        });
      };

      if (expand && loadData) {
        return loadData(node).then(setExpandedState);
      } else {
        setExpandedState();
      }
    }
  }, {
    key: "handleSelect",
    value: function handleSelect(select, key, node, e) {
      var _this$props3 = this.props,
          multiple = _this$props3.multiple,
          onSelect = _this$props3.onSelect;

      var selectedKeys = _toConsumableArray(this.state.selectedKeys);

      if (multiple) {
        this.processKey(selectedKeys, key, select);
      } else {
        selectedKeys = [key];
      }

      if (!('selectedKeys' in this.props)) {
        this.setState({
          selectedKeys: selectedKeys
        });
      }

      onSelect(selectedKeys, {
        selectedNodes: this.getNodes(selectedKeys),
        node: node,
        selected: select,
        event: e
      });
    } // eslint-disable-next-line max-statements

  }, {
    key: "handleCheck",
    value: function handleCheck(check, key, node) {
      var _this9 = this;

      var _this$props4 = this.props,
          checkStrictly = _this$props4.checkStrictly,
          checkedStrategy = _this$props4.checkedStrategy,
          onCheck = _this$props4.onCheck;

      var checkedKeys = _toConsumableArray(this.state.checkedKeys);

      if (checkStrictly) {
        this.processKey(checkedKeys, key, check);

        var _newCheckedKeys = isPlainObject(this.props.checkedKeys) ? {
          checked: checkedKeys,
          indeterminate: this.indeterminateKeys
        } : checkedKeys;

        onCheck(_newCheckedKeys, {
          checkedNodes: this.getNodes(checkedKeys),
          checkedNodesPositions: checkedKeys.map(function (key) {
            if (!_this9._k2n[key]) return null;
            var _this9$_k2n$key = _this9._k2n[key],
                node = _this9$_k2n$key.node,
                pos = _this9$_k2n$key.pos;
            return {
              node: node,
              pos: pos
            };
          }).filter(function (v) {
            return !!v;
          }),
          node: node,
          indeterminateKeys: this.indeterminateKeys,
          checked: check
        });
        return;
      }

      var pos = this._k2n[key].pos;
      var ps = Object.keys(this._p2n);
      ps.forEach(function (p) {
        if ((0, _util2.isDescendantOrSelf)(pos, p)) {
          _this9.processKey(checkedKeys, _this9._p2n[p].key, check);
        }
      });
      var currentPos = pos;
      var nums = pos.split('-');

      for (var i = nums.length; i > 2; i--) {
        var parentCheck = true;
        var parentPos = nums.slice(0, i - 1).join('-');
        var parentKey = this._p2n[parentPos].key;
        var parentChecked = checkedKeys.indexOf(parentKey) > -1;

        if (!check && !parentChecked) {
          break;
        }

        for (var j = 0; j < ps.length; j++) {
          var p = ps[j];

          if ((0, _util2.isSiblingOrSelf)(currentPos, p)) {
            var k = this._p2n[p].key;

            if (checkedKeys.indexOf(k) === -1) {
              parentCheck = false;
              break;
            }
          }
        }

        this.processKey(checkedKeys, parentKey, parentCheck);
        currentPos = parentPos;
      }

      var indeterminateKeys = this.getIndeterminateKeys(checkedKeys);

      if (!('checkedKeys' in this.props)) {
        this.setState({
          checkedKeys: checkedKeys
        });
        this.indeterminateKeys = indeterminateKeys;
      }

      var newCheckedKeys;

      switch (checkedStrategy) {
        case 'parent':
          newCheckedKeys = (0, _util2.filterChildKey)(checkedKeys, this._k2n);
          break;

        case 'child':
          newCheckedKeys = (0, _util2.filterParentKey)(checkedKeys, this._k2n);
          break;

        default:
          newCheckedKeys = checkedKeys;
          break;
      }

      onCheck(newCheckedKeys, {
        checkedNodes: this.getNodes(newCheckedKeys),
        checkedNodesPositions: newCheckedKeys.map(function (key) {
          if (!_this9._k2n[key]) return null;
          var _this9$_k2n$key2 = _this9._k2n[key],
              node = _this9$_k2n$key2.node,
              pos = _this9$_k2n$key2.pos;
          return {
            node: node,
            pos: pos
          };
        }).filter(function (v) {
          return !!v;
        }),
        node: node,
        indeterminateKeys: indeterminateKeys,
        checked: check
      });
    }
    /* eslint-enable */

  }, {
    key: "getNodeProps",
    value: function getNodeProps(key) {
      var prefix = this.props.prefix;
      var _this$state = this.state,
          expandedKeys = _this$state.expandedKeys,
          selectedKeys = _this$state.selectedKeys,
          checkedKeys = _this$state.checkedKeys,
          dragOverNodeKey = _this$state.dragOverNodeKey;
      var pos = this._k2n[key].pos;
      return {
        prefix: prefix,
        root: this,
        eventKey: key,
        pos: pos,
        expanded: expandedKeys.indexOf(key) > -1,
        selected: selectedKeys.indexOf(key) > -1,
        checked: checkedKeys.indexOf(key) > -1,
        indeterminate: this.indeterminateKeys.indexOf(key) > -1,
        dragOver: dragOverNodeKey === key && this.dropPosition === 0,
        dragOverGapTop: dragOverNodeKey === key && this.dropPosition === -1,
        dragOverGapBottom: dragOverNodeKey === key && this.dropPosition === 1
      };
    }
  }, {
    key: "getParentNode",
    value: function getParentNode(pos) {
      var parentPos = pos.split('-').slice(0, -1).join('-');

      if (parentPos.length === 1) {
        return null;
      }

      return this._p2n[parentPos].node;
    }
  }, {
    key: "getNodes",
    value: function getNodes(keys) {
      var _this10 = this;

      return keys.map(function (key) {
        return _this10._k2n[key] && _this10._k2n[key].node;
      }).filter(function (v) {
        return !!v;
      });
    }
  }, {
    key: "getIndeterminateKeys",
    value: function getIndeterminateKeys(checkedKeys) {
      var _this11 = this;

      var indeterminateKeys = [];
      var poss = (0, _util2.filterChildKey)(checkedKeys.filter(function (key) {
        return !!_this11._k2n[key];
      }), this._k2n).map(function (key) {
        return _this11._k2n[key].pos;
      });
      poss.forEach(function (pos) {
        var nums = pos.split('-');

        for (var i = nums.length; i > 2; i--) {
          var parentPos = nums.slice(0, i - 1).join('-');
          var parentKey = _this11._p2n[parentPos].key;

          if (indeterminateKeys.indexOf(parentKey) === -1) {
            indeterminateKeys.push(parentKey);
          }
        }
      });
      return indeterminateKeys;
    }
  }, {
    key: "handleDragStart",
    value: function handleDragStart(e, node) {
      var _this12 = this;

      var dragNodeKey = node.props.eventKey;
      this.dragNode = node;
      this.dragNodesKeys = Object.keys(this._k2n).filter(function (k) {
        return (0, _util2.isDescendantOrSelf)(_this12._k2n[dragNodeKey].pos, _this12._k2n[k].pos);
      });
      var expandedKeys = this.processKey(_toConsumableArray(this.state.expandedKeys), dragNodeKey, false);
      this.setState({
        expandedKeys: expandedKeys
      });
      this.props.onDragStart({
        event: e,
        node: node,
        expandedKeys: expandedKeys
      });
    }
  }, {
    key: "handleDragEnter",
    value: function handleDragEnter(e, node) {
      var dragOverNodeKey = node.props.eventKey;
      this.dropPosition = this.getDropPosition(e, node);

      if (this.dragNode && this.dragNode.props.eventKey === dragOverNodeKey && this.dropPosition === 0) {
        this.setState({
          dragOverNodeKey: null
        });
        return;
      }

      var expandedKeys = this.processKey(_toConsumableArray(this.state.expandedKeys), dragOverNodeKey, true);
      this.setState({
        dragOverNodeKey: dragOverNodeKey,
        expandedKeys: expandedKeys
      });
      this.props.onDragEnter({
        event: e,
        node: node,
        expandedKeys: expandedKeys
      });
    }
  }, {
    key: "getDropPosition",
    value: function getDropPosition(e, node) {
      var labelWrapperNode = node.refs.labelWrapper;
      var offsetTop = getOffset(labelWrapperNode).top;
      var offsetHeight = labelWrapperNode.offsetHeight;
      var pageY = e.pageY;
      var gapHeight = 2;

      if (pageY > offsetTop + offsetHeight - gapHeight) {
        return 1;
      }

      if (pageY < offsetTop + gapHeight) {
        return -1;
      }

      return 0;
    }
  }, {
    key: "handleDragOver",
    value: function handleDragOver(e, node) {
      this.props.onDragOver({
        event: e,
        node: node
      });
    }
  }, {
    key: "handleDragLeave",
    value: function handleDragLeave(e, node) {
      this.props.onDragLeave({
        event: e,
        node: node
      });
    }
  }, {
    key: "handleDragEnd",
    value: function handleDragEnd(e, node) {
      this.setState({
        dragOverNodeKey: null
      });
      this.props.onDragEnd({
        event: e,
        node: node
      });
    }
  }, {
    key: "handleDrop",
    value: function handleDrop(e, node) {
      if (this.dragNode && (0, _util2.isDescendantOrSelf)(this._k2n[this.dragNode.props.eventKey].pos, this._k2n[node.props.eventKey].pos)) {
        return;
      }

      this.setState({
        dragOverNodeKey: null
      });
      var params = this.generateDropParams(node);
      this.props.onDrop(_objectSpread({
        event: e
      }, params));
    }
  }, {
    key: "canDrop",
    value: function canDrop(node) {
      var params = this.generateDropParams(node);
      return this.props.canDrop(params);
    }
  }, {
    key: "generateDropParams",
    value: function generateDropParams(node) {
      return {
        dragNode: this.dragNode,
        dragNodesKeys: _toConsumableArray(this.dragNodesKeys),
        node: node,
        dropPosition: this.dropPosition
      };
    }
  }, {
    key: "filterTreeNode",
    value: function filterTreeNode(node) {
      return this.props.filterTreeNode.call(this, node);
    }
  }, {
    key: "renderByDataSource",
    value: function renderByDataSource() {
      var _this13 = this;

      var rtl = this.props.rtl;

      var loop = function loop(data) {
        var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
        return data.map(function (item, index) {
          var pos = "".concat(prefix, "-").concat(index);

          var _item$key = item.key,
              key = _item$key === void 0 ? pos : _item$key,
              children = item.children,
              others = _objectWithoutProperties(item, ["key", "children"]);

          var props = _objectSpread({}, others, {}, _this13.getNodeProps("".concat(key)), {
            _key: key
          });

          if (children && children.length) {
            props.children = loop(children, pos);
          }

          var node = _react["default"].createElement(_treeNode["default"], _extends({
            rtl: rtl,
            key: key,
            size: data.length
          }, props));

          _this13._k2n[key].node = node;
          return node;
        });
      };

      return loop(this.props.dataSource);
    }
  }, {
    key: "renderByChildren",
    value: function renderByChildren() {
      var _this14 = this;

      var rtl = this.props.rtl;

      var loop = function loop(children) {
        var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
        return _react.Children.map(children, function (child, index) {
          if (!_react["default"].isValidElement(child)) {
            return;
          }

          var pos = "".concat(prefix, "-").concat(index);
          var key = child.key || pos;

          var props = _this14.getNodeProps("".concat(key));

          if (child.props.children) {
            props.children = loop(child.props.children, pos);
          }

          props._key = key;
          props.rtl = rtl;
          props.size = _react.Children.count(children);
          var node = (0, _react.cloneElement)(child, props);
          _this14._k2n[key].node = node;
          return node;
        });
      };

      return loop(this.props.children);
    }
  }, {
    key: "render",
    value: function render() {
      var _cx;

      var _this$props5 = this.props,
          prefix = _this$props5.prefix,
          rtl = _this$props5.rtl,
          className = _this$props5.className,
          dataSource = _this$props5.dataSource,
          showLine = _this$props5.showLine,
          isNodeBlock = _this$props5.isNodeBlock,
          isLabelBlock = _this$props5.isLabelBlock,
          multiple = _this$props5.multiple;
      var others = pickOthers(Object.keys(Tree.propTypes), this.props);

      if (rtl) {
        others.dir = 'rtl';
      }

      var newClassName = (0, _classnames["default"])((_cx = {}, _defineProperty(_cx, "".concat(prefix, "tree"), true), _defineProperty(_cx, "".concat(prefix, "label-block"), isLabelBlock), _defineProperty(_cx, "".concat(prefix, "node-block"), isNodeBlock), _defineProperty(_cx, "".concat(prefix, "node-indent"), !isNodeBlock), _defineProperty(_cx, "".concat(prefix, "show-line"), !isNodeBlock && showLine), _defineProperty(_cx, className, !!className), _cx));
      return _react["default"].createElement("ul", _extends({
        role: "tree",
        "aria-multiselectable": multiple,
        onBlur: this.handleBlur,
        className: newClassName
      }, others), dataSource ? this.renderByDataSource() : this.renderByChildren());
    }
  }]);

  return Tree;
}(_react.Component);

exports["default"] = Tree;

_defineProperty(Tree, "propTypes", {
  prefix: _propTypes["default"].string,
  rtl: _propTypes["default"].bool,
  pure: _propTypes["default"].bool,
  className: _propTypes["default"].string,

  /**
   * 树节点
   */
  children: _propTypes["default"].node,

  /**
   * 数据源，该属性优先级高于 children
   */
  dataSource: _propTypes["default"].array,

  /**
   * 是否显示树的线
   */
  showLine: _propTypes["default"].bool,

  /**
   * 是否支持选中节点
   */
  selectable: _propTypes["default"].bool,

  /**
   * （用于受控）当前选中节点 key 的数组
   */
  selectedKeys: _propTypes["default"].arrayOf(_propTypes["default"].string),

  /**
   * （用于非受控）默认选中节点 key 的数组
   */
  defaultSelectedKeys: _propTypes["default"].arrayOf(_propTypes["default"].string),

  /**
   * 选中或取消选中节点时触发的回调函数
   * @param {Array} selectedKeys 选中节点key的数组
   * @param {Object} extra 额外参数
   * @param {Array} extra.selectedNodes 选中节点的数组
   * @param {Object} extra.node 当前操作的节点
   * @param {Boolean} extra.selected 当前操作是否是选中
   */
  onSelect: _propTypes["default"].func,

  /**
   * 是否支持多选
   */
  multiple: _propTypes["default"].bool,

  /**
   * 是否支持勾选节点的复选框
   */
  checkable: _propTypes["default"].bool,

  /**
   * （用于受控）当前勾选复选框节点 key 的数组或 `{checked: Array, indeterminate: Array}` 的对象
   */
  checkedKeys: _propTypes["default"].oneOfType([_propTypes["default"].arrayOf(_propTypes["default"].string), _propTypes["default"].object]),

  /**
   * （用于非受控）默认勾选复选框节点 key 的数组
   */
  defaultCheckedKeys: _propTypes["default"].arrayOf(_propTypes["default"].string),

  /**
   * 勾选节点复选框是否完全受控（父子节点选中状态不再关联）
   */
  checkStrictly: _propTypes["default"].bool,

  /**
   * 定义选中时回填的方式
   * @enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点
   */
  checkedStrategy: _propTypes["default"].oneOf(['all', 'parent', 'child']),

  /**
   * 勾选或取消勾选复选框时触发的回调函数
   * @param {Array} checkedKeys 勾选复选框节点key的数组
   * @param {Object} extra 额外参数
   * @param {Array} extra.checkedNodes 勾选复选框节点的数组
   * @param {Array} extra.checkedNodesPositions 包含有勾选复选框节点和其位置的对象的数组
   * @param {Array} extra.indeterminateKeys 半选复选框节点 key 的数组
   * @param {Object} extra.node 当前操作的节点
   * @param {Boolean} extra.checked 当前操作是否是勾选
   */
  onCheck: _propTypes["default"].func,

  /**
   * （用于受控）当前展开的节点 key 的数组
   */
  expandedKeys: _propTypes["default"].arrayOf(_propTypes["default"].string),

  /**
   * （用于非受控）默认展开的节点 key 的数组
   */
  defaultExpandedKeys: _propTypes["default"].arrayOf(_propTypes["default"].string),

  /**
   * 是否默认展开所有节点
   */
  defaultExpandAll: _propTypes["default"].bool,

  /**
   * 是否自动展开父节点
   */
  autoExpandParent: _propTypes["default"].bool,

  /**
   * 展开或收起节点时触发的回调函数
   * @param {Array} expandedKeys 展开的节点key的数组
   * @param {Object} extra 额外参数
   * @param {Object} extra.node 当前操作的节点
   * @param {Boolean} extra.expanded 当前操作是否是展开
   */
  onExpand: _propTypes["default"].func,

  /**
   * 是否支持编辑节点内容
   */
  editable: _propTypes["default"].bool,

  /**
   * 编辑节点内容完成时触发的回调函数
   * @param {String} key 编辑节点的 key
   * @param {String} label 编辑节点完成时节点的文本
   * @param {Object} node 当前编辑的节点
   */
  onEditFinish: _propTypes["default"].func,

  /**
   * 是否支持拖拽节点
   */
  draggable: _propTypes["default"].bool,

  /**
   * 开始拖拽节点时触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 拖拽的节点
   */
  onDragStart: _propTypes["default"].func,

  /**
   * 拖拽节点进入目标节点时触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 目标节点
   * @param {Array} info.expandedKeys 当前展开的节点key的数组
   */
  onDragEnter: _propTypes["default"].func,

  /**
   * 拖拽节点在目标节点上移动的时候触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 目标节点
   */
  onDragOver: _propTypes["default"].func,

  /**
   * 拖拽节点离开目标节点时触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 目标节点
   */
  onDragLeave: _propTypes["default"].func,

  /**
   * 拖拽节点拖拽结束时触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 目标节点
   */
  onDragEnd: _propTypes["default"].func,

  /**
   * 拖拽节点放入目标节点内或前后触发的回调函数
   * @param {Object} info 拖拽信息
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 目标节点
   * @param {Object} info.dragNode 拖拽的节点
   * @param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组
   * @param {Number} info.dropPosition 放置位置，-1代表当前节点前，0代表当前节点里，1代表当前节点后
   */
  onDrop: _propTypes["default"].func,

  /**
   * 节点是否可被作为拖拽的目标节点
   * @param {Object} info 拖拽信息
   * @param {Object} info.node 目标节点
   * @param {Object} info.dragNode 拖拽的节点
   * @param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组
   * @param {Number} info.dropPosition 放置位置，-1代表当前节点前，0代表当前节点里，1代表当前节点后
   * @return {Boolean} 是否可以被当作目标节点
   */
  canDrop: _propTypes["default"].func,

  /**
   * 异步加载数据的函数
   * @param {Object} node 被点击展开的节点
   */
  loadData: _propTypes["default"].func,

  /**
   * 按需筛选高亮节点
   * @param {Object} node 待筛选的节点
   * @return {Boolean} 是否被筛选中
   */
  filterTreeNode: _propTypes["default"].func,

  /**
   * 右键点击节点时触发的回调函数
   * @param {Object} info 信息对象
   * @param {Object} info.event 事件对象
   * @param {Object} info.node 点击的节点
   */
  onRightClick: _propTypes["default"].func,

  /**
   * 设置节点是否占满剩余空间，一般用于统一在各节点右侧添加元素(借助 flex 实现，暂时只支持 ie10+)
   */
  isLabelBlock: _propTypes["default"].bool,

  /**
   * 设置节点是否占满一行
   */
  isNodeBlock: _propTypes["default"].oneOfType([_propTypes["default"].bool, _propTypes["default"].object]),

  /**
   * 是否开启展开收起动画
   */
  animation: _propTypes["default"].bool,

  /**
   * 当前获得焦点的子菜单或菜单项 key 值
   */
  focusedKey: _propTypes["default"].string,
  focusable: _propTypes["default"].bool,
  autoFocus: _propTypes["default"].bool,
  onItemFocus: _propTypes["default"].func,
  onBlur: _propTypes["default"].func,
  onItemKeyDown: _propTypes["default"].func
});

_defineProperty(Tree, "defaultProps", {
  prefix: 'next-',
  rtl: false,
  pure: false,
  showLine: false,
  selectable: true,
  editable: false,
  multiple: false,
  checkable: false,
  checkStrictly: false,
  checkedStrategy: 'all',
  draggable: false,
  autoExpandParent: true,
  defaultExpandAll: false,
  defaultExpandedKeys: [],
  defaultCheckedKeys: [],
  defaultSelectedKeys: [],
  onExpand: noop,
  onCheck: noop,
  onSelect: noop,
  onDragStart: noop,
  onDragEnter: noop,
  onDragOver: noop,
  onDragLeave: noop,
  onDragEnd: noop,
  onDrop: noop,
  canDrop: function canDrop() {
    return true;
  },
  onEditFinish: noop,
  onRightClick: noop,
  isLabelBlock: false,
  isNodeBlock: false,
  animation: true,
  focusable: true,
  autoFocus: false,
  onItemFocus: noop,
  onItemKeyDown: noop
});