text: 'use strict';
  
  var Stack = require('./Stack');
  var equalArrays = require('./equalArrays');
  var equalByTag = require('./equalByTag');
  var equalObjects = require('./equalObjects');
  var getTag = require('./getTag');
  var isArray = require('../isArray');
  var isBuffer = require('../isBuffer');
  var isTypedArray = require('../isTypedArray');
  
  /** Used to compose bitmasks for value comparisons. */
  var COMPARE_PARTIAL_FLAG = 1;
  
  /** `Object#toString` result references. */
  var argsTag = '[object Arguments]';
  var arrayTag = '[object Array]';
  var objectTag = '[object Object]';
  
  /** Used for built-in method references. */
  var objectProto = Object.prototype;
  
  /** Used to check objects for own properties. */
  var hasOwnProperty = objectProto.hasOwnProperty;
  
  /**
   * A specialized version of `baseIsEqual` for arrays and objects which performs
   * deep comparisons and tracks traversed objects enabling objects with circular
   * references to be compared.
   *
   * @private
   * @param {Object} object The object to compare.
   * @param {Object} other The other object to compare.
   * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
   * @param {Function} customizer The function to customize comparisons.
   * @param {Function} equalFunc The function to determine equivalents of values.
   * @param {Object} [stack] Tracks traversed `object` and `other` objects.
   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
   */
  function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
      var objIsArr = isArray(object);
      var othIsArr = isArray(other);
      var objTag = objIsArr ? arrayTag : getTag(object);
      var othTag = othIsArr ? arrayTag : getTag(other);
  
      objTag = objTag == argsTag ? objectTag : objTag;
      othTag = othTag == argsTag ? objectTag : othTag;
  
      var objIsObj = objTag == objectTag;
      var othIsObj = othTag == objectTag;
      var isSameTag = objTag == othTag;
  
      if (isSameTag && isBuffer(object)) {
          if (!isBuffer(other)) {
              return false;
          }
          objIsArr = true;
          objIsObj = false;
      }
      if (isSameTag && !objIsObj) {
          stack || (stack = new Stack());
          return (objIsArr || isTypedArray(object))
              ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
              : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
      }
      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
          var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__');
          var othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
  
          if (objIsWrapped || othIsWrapped) {
              var objUnwrapped = objIsWrapped ? object.value() : object;
              var othUnwrapped = othIsWrapped ? other.value() : other;
  
              stack || (stack = new Stack());
              return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
          }
      }
      if (!isSameTag) {
          return false;
      }
      stack || (stack = new Stack());
      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  }
  
  module.exports = baseIsEqualDeep;
  