| /** |
| * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> |
| * Build: `lodash modularize exports="node" -o ./compat/` |
| * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> |
| * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> |
| * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors |
| * Available under MIT license <http://lodash.com/license> |
| */ |
| var forEach = require('../collections/forEach'), |
| forOwn = require('../objects/forOwn'), |
| isArray = require('../objects/isArray'), |
| isPlainObject = require('../objects/isPlainObject'); |
| |
| /** |
| * The base implementation of `_.merge` without argument juggling or support |
| * for `thisArg` binding. |
| * |
| * @private |
| * @param {Object} object The destination object. |
| * @param {Object} source The source object. |
| * @param {Function} [callback] The function to customize merging properties. |
| * @param {Array} [stackA=[]] Tracks traversed source objects. |
| * @param {Array} [stackB=[]] Associates values with source counterparts. |
| */ |
| function baseMerge(object, source, callback, stackA, stackB) { |
| (isArray(source) ? forEach : forOwn)(source, function(source, key) { |
| var found, |
| isArr, |
| result = source, |
| value = object[key]; |
| |
| if (source && ((isArr = isArray(source)) || isPlainObject(source))) { |
| // avoid merging previously merged cyclic sources |
| var stackLength = stackA.length; |
| while (stackLength--) { |
| if ((found = stackA[stackLength] == source)) { |
| value = stackB[stackLength]; |
| break; |
| } |
| } |
| if (!found) { |
| var isShallow; |
| if (callback) { |
| result = callback(value, source); |
| if ((isShallow = typeof result != 'undefined')) { |
| value = result; |
| } |
| } |
| if (!isShallow) { |
| value = isArr |
| ? (isArray(value) ? value : []) |
| : (isPlainObject(value) ? value : {}); |
| } |
| // add `source` and associated `value` to the stack of traversed objects |
| stackA.push(source); |
| stackB.push(value); |
| |
| // recursively merge objects and arrays (susceptible to call stack limits) |
| if (!isShallow) { |
| baseMerge(value, source, callback, stackA, stackB); |
| } |
| } |
| } |
| else { |
| if (callback) { |
| result = callback(value, source); |
| if (typeof result == 'undefined') { |
| result = source; |
| } |
| } |
| if (typeof result != 'undefined') { |
| value = result; |
| } |
| } |
| object[key] = value; |
| }); |
| } |
| |
| module.exports = baseMerge; |