Name: js-handler/node_modules/nodeunit/node_modules/tap/node_modules/deep-equal/index.js 
1:
var pSlice = Array.prototype.slice;
2:
var Object_keys = typeof Object.keys === 'function'
3:
    ? Object.keys
4:
    : function (obj) {
5:
        var keys = [];
6:
        for (var key in obj) keys.push(key);
7:
        return keys;
8:
    }
9:
;
10:
 
11:
var deepEqual = module.exports = function (actual, expected) {
12:
  // 7.1. All identical values are equivalent, as determined by ===.
13:
  if (actual === expected) {
14:
    return true;
15:
 
16:
  } else if (actual instanceof Date && expected instanceof Date) {
17:
    return actual.getTime() === expected.getTime();
18:
 
19:
  // 7.3. Other pairs that do not both pass typeof value == 'object',
20:
  // equivalence is determined by ==.
21:
  } else if (typeof actual != 'object' && typeof expected != 'object') {
22:
    return actual == expected;
23:
 
24:
  // 7.4. For all other Object pairs, including Array objects, equivalence is
25:
  // determined by having the same number of owned properties (as verified
26:
  // with Object.prototype.hasOwnProperty.call), the same set of keys
27:
  // (although not necessarily the same order), equivalent values for every
28:
  // corresponding key, and an identical 'prototype' property. Note: this
29:
  // accounts for both named and indexed properties on Arrays.
30:
  } else {
31:
    return objEquiv(actual, expected);
32:
  }
33:
}
34:
 
35:
function isUndefinedOrNull(value) {
36:
  return value === null || value === undefined;
37:
}
38:
 
39:
function isArguments(object) {
40:
  return Object.prototype.toString.call(object) == '[object Arguments]';
41:
}
42:
 
43:
function objEquiv(a, b) {
44:
  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
45:
    return false;
46:
  // an identical 'prototype' property.
47:
  if (a.prototype !== b.prototype) return false;
48:
  //~~~I've managed to break Object.keys through screwy arguments passing.
49:
  //   Converting to array solves the problem.
50:
  if (isArguments(a)) {
51:
    if (!isArguments(b)) {
52:
      return false;
53:
    }
54:
    a = pSlice.call(a);
55:
    b = pSlice.call(b);
56:
    return deepEqual(a, b);
57:
  }
58:
  try {
59:
    var ka = Object_keys(a),
60:
        kb = Object_keys(b),
61:
        key, i;
62:
  } catch (e) {//happens when one is a string literal and the other isn't
63:
    return false;
64:
  }
65:
  // having the same number of owned properties (keys incorporates
66:
  // hasOwnProperty)
67:
  if (ka.length != kb.length)
68:
    return false;
69:
  //the same set of keys (although not necessarily the same order),
70:
  ka.sort();
71:
  kb.sort();
72:
  //~~~cheap key test
73:
  for (i = ka.length - 1; i >= 0; i--) {
74:
    if (ka[i] != kb[i])
75:
      return false;
76:
  }
77:
  //equivalent values for every corresponding key, and
78:
  //~~~possibly expensive deep test
79:
  for (i = ka.length - 1; i >= 0; i--) {
80:
    key = ka[i];
81:
    if (!deepEqual(a[key], b[key])) return false;
82:
  }
83:
  return true;
84:
}