00001 var assignMergeValue = require('./_assignMergeValue'),
00002 cloneBuffer = require('./_cloneBuffer'),
00003 cloneTypedArray = require('./_cloneTypedArray'),
00004 copyArray = require('./_copyArray'),
00005 initCloneObject = require('./_initCloneObject'),
00006 isArguments = require('./isArguments'),
00007 isArray = require('./isArray'),
00008 isArrayLikeObject = require('./isArrayLikeObject'),
00009 isBuffer = require('./isBuffer'),
00010 isFunction = require('./isFunction'),
00011 isObject = require('./isObject'),
00012 isPlainObject = require('./isPlainObject'),
00013 isTypedArray = require('./isTypedArray'),
00014 toPlainObject = require('./toPlainObject');
00015
00031 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
00032 var objValue = object[key],
00033 srcValue = source[key],
00034 stacked = stack.get(srcValue);
00035
00036 if (stacked) {
00037 assignMergeValue(object, key, stacked);
00038 return;
00039 }
00040 var newValue = customizer
00041 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
00042 : undefined;
00043
00044 var isCommon = newValue === undefined;
00045
00046 if (isCommon) {
00047 var isArr = isArray(srcValue),
00048 isBuff = !isArr && isBuffer(srcValue),
00049 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
00050
00051 newValue = srcValue;
00052 if (isArr || isBuff || isTyped) {
00053 if (isArray(objValue)) {
00054 newValue = objValue;
00055 }
00056 else if (isArrayLikeObject(objValue)) {
00057 newValue = copyArray(objValue);
00058 }
00059 else if (isBuff) {
00060 isCommon = false;
00061 newValue = cloneBuffer(srcValue, true);
00062 }
00063 else if (isTyped) {
00064 isCommon = false;
00065 newValue = cloneTypedArray(srcValue, true);
00066 }
00067 else {
00068 newValue = [];
00069 }
00070 }
00071 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
00072 newValue = objValue;
00073 if (isArguments(objValue)) {
00074 newValue = toPlainObject(objValue);
00075 }
00076 else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
00077 newValue = initCloneObject(srcValue);
00078 }
00079 }
00080 else {
00081 isCommon = false;
00082 }
00083 }
00084 if (isCommon) {
00085
00086 stack.set(srcValue, newValue);
00087 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
00088 stack['delete'](srcValue);
00089 }
00090 assignMergeValue(object, key, newValue);
00091 }
00092
00093 module.exports = baseMergeDeep;