function looseEqual(a, b) {
  if (a === b) {
    return true;
  }

  var aValidType = isDate(a);
  var bValidType = isDate(b);

  if (aValidType || bValidType) {
    return aValidType && bValidType ? a.getTime() === b.getTime() : false;
  }

  aValidType = isArray(a);
  bValidType = isArray(b);

  if (aValidType || bValidType) {
    return aValidType && bValidType ? a.length === b.length && a.every(function (e, i) {
      return looseEqual(e, b[i]);
    }) : false;
  }

  aValidType = isObject(a);
  bValidType = isObject(b);

  if (aValidType || bValidType) {
    /* istanbul ignore if: this if will probably never be called */
    if (!aValidType || !bValidType) {
      return false;
    }

    var aKeysCount = keys(a).length;
    var bKeysCount = keys(b).length;

    if (aKeysCount !== bKeysCount) {
      return false;
    }

    for (var key in a) {
      var aHasKey = a.hasOwnProperty(key);
      var bHasKey = b.hasOwnProperty(key);

      if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) {
        return false;
      }
    }
  }

  return String(a) === String(b);
}
/**
 * Check if two values are loosely equal - that is,
 * if they are plain objects, do they have the same shape?
 * Returns boolean true or false
 */
Check if two values are loosely equal - that is,
if they are plain objects, do they have the same shape.
Returns boolean true or false
Check if two values are loosely equal - that is if they are plain objects do they have the same shape . Returns boolean true or false
function looseEqual(a, b) {
  if (a === b) {
    return true;
  }
  var aValidType = isDate(a);
  var bValidType = isDate(b);
  if (aValidType || bValidType) {
    return aValidType && bValidType ? a.getTime() === b.getTime() : false;
  }
  aValidType = isArray(a);
  bValidType = isArray(b);
  if (aValidType || bValidType) {
    return aValidType && bValidType ? a.length === b.length && a.every(function (e, i) {
      return looseEqual(e, b[i]);
    }) : false;
  }
  aValidType = isObject(a);
  bValidType = isObject(b);
  if (aValidType || bValidType) {
    if (!aValidType || !bValidType) {
      return false;
    }
    var aKeysCount = keys(a).length;
    var bKeysCount = keys(b).length;
    if (aKeysCount !== bKeysCount) {
      return false;
    }
    for (var key in a) {
      var aHasKey = a.hasOwnProperty(key);
      var bHasKey = b.hasOwnProperty(key);
      if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) {
        return false;
      }
    }
  }
  return String(a) === String(b);
}
function looseEqual ( a , b ) { if ( a === b ) { return true ; } var aValidType = isDate ( a ) ; var bValidType = isDate ( b ) ; if ( aValidType || bValidType ) { return aValidType && bValidType ? a . getTime ( ) === b . getTime ( ) : false ; } aValidType = isArray ( a ) ; bValidType = isArray ( b ) ; if ( aValidType || bValidType ) { return aValidType && bValidType ? a . length === b . length && a . every ( function ( e , i ) { return looseEqual ( e , b [ i ] ) ; } ) : false ; } aValidType = isObject ( a ) ; bValidType = isObject ( b ) ; if ( aValidType || bValidType ) { if ( ! aValidType || ! bValidType ) { return false ; } var aKeysCount = keys ( a ) . length ; var bKeysCount = keys ( b ) . length ; if ( aKeysCount !== bKeysCount ) { return false ; } for ( var key in a ) { var aHasKey = a . hasOwnProperty ( key ) ; var bHasKey = b . hasOwnProperty ( key ) ; if ( aHasKey && ! bHasKey || ! aHasKey && bHasKey || ! looseEqual ( a [ key ] , b [ key ] ) ) { return false ; } } } return String ( a ) === String ( b ) ; }
Check if two values are loosely equal - that is,
 if they are plain objects, do they have the same shape?
Check if two values are loosely equal - that is if they are plain objects do they have the same shape?
/* istanbul ignore if: this if will probably never be called */