'use strict'; var eq = require('./eq') , isPlainObject = require('./is-plain-object') , value = require('./valid-value') , isArray = Array.isArray, keys = Object.keys , propertyIsEnumerable = Object.prototype.propertyIsEnumerable , eqArr, eqVal, eqObj; eqArr = function (a, b, recMap) { var i, l = a.length; if (l !== b.length) return false; for (i = 0; i < l; ++i) { if (a.hasOwnProperty(i) !== b.hasOwnProperty(i)) return false; if (!eqVal(a[i], b[i], recMap)) return false; } return true; }; eqObj = function (a, b, recMap) { var k1 = keys(a), k2 = keys(b); if (k1.length !== k2.length) return false; return k1.every(function (key) { if (!propertyIsEnumerable.call(b, key)) return false; return eqVal(a[key], b[key], recMap); }); }; eqVal = function (a, b, recMap) { var i, eqX, c1, c2; if (eq(a, b)) return true; if (isPlainObject(a)) { if (!isPlainObject(b)) return false; eqX = eqObj; } else if (isArray(a) && isArray(b)) { eqX = eqArr; } else { return false; } c1 = recMap[0]; c2 = recMap[1]; i = c1.indexOf(a); if (i !== -1) { if (c2[i].indexOf(b) !== -1) return true; } else { i = c1.push(a) - 1; c2[i] = []; } c2[i].push(b); return eqX(a, b, recMap); }; module.exports = function (a, b) { if (eq(value(a), value(b))) return true; return eqVal(Object(a), Object(b), [[], []]); };