function cloner(deep, item) {
  if (!item || typeof item !== 'object' || item instanceof Error || item instanceof _monkey.MonkeyDefinition || item instanceof _monkey.Monkey || 'ArrayBuffer' in global && item instanceof ArrayBuffer) return item; // Array

  if (_type["default"].array(item)) {
    if (deep) {
      var a = new Array(item.length);

      for (var i = 0, l = item.length; i < l; i++) {
        a[i] = cloner(true, item[i]);
      }

      return a;
    }

    return slice(item);
  } // Date


  if (item instanceof Date) return new Date(item.getTime()); // RegExp

  if (item instanceof RegExp) return cloneRegexp(item); // Object

  if (_type["default"].object(item)) {
    var o = {}; // NOTE: could be possible to erase computed properties through `null`.

    var props = Object.getOwnPropertyNames(item);

    for (var _i = 0, _l = props.length; _i < _l; _i++) {
      var name = props[_i];
      var k = Object.getOwnPropertyDescriptor(item, name);

      if (k.enumerable === true) {
        if (k.get && k.get.isLazyGetter) {
          Object.defineProperty(o, name, {
            get: k.get,
            enumerable: true,
            configurable: true
          });
        } else {
          o[name] = deep ? cloner(true, item[name]) : item[name];
        }
      } else if (k.enumerable === false) {
        Object.defineProperty(o, name, {
          value: deep ? cloner(true, k.value) : k.value,
          enumerable: false,
          writable: true,
          configurable: true
        });
      }
    }

    return o;
  }

  return item;
}
Function cloning the given variable.

@todo: implement a faster way to clone an array.

@param  {boolean} deep - Should we deep clone the variable.
@param  {mixed}   item - The variable to clone
@return {mixed}        - The cloned variable.