"use strict";
/**
 * This method is like `merge` except that it accepts customizer which is
 * invoked to produce the merged values of the destination and source properties.
 * If customizer returns undefined, merging is handled by the method instead.
 * Drop-in replacement for lodash/mergeWith.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = mergeWith;
const tslib_1 = require("tslib");
const isPlainObject_1 = tslib_1.__importDefault(require("./isPlainObject"));
function baseMergeWith(target, source, customizer) {
    if (source == null) {
        return target;
    }
    const keys = Object.keys(source);
    for (const key of keys) {
        const srcValue = source[key];
        const tgtValue = target[key];
        const customResult = customizer(tgtValue, srcValue, key, target, source);
        if (customResult !== undefined) {
            target[key] = customResult;
        }
        else if (Array.isArray(srcValue)) {
            if (!Array.isArray(tgtValue)) {
                target[key] = [];
            }
            baseMergeWith(target[key], srcValue, customizer);
        }
        else if ((0, isPlainObject_1.default)(srcValue)) {
            if (!(0, isPlainObject_1.default)(tgtValue)) {
                target[key] = {};
            }
            baseMergeWith(target[key], srcValue, customizer);
        }
        else if (srcValue !== undefined) {
            target[key] = srcValue;
        }
    }
    return target;
}
function mergeWith(target, ...args) {
    // The last argument is the customizer function
    const customizer = args[args.length - 1];
    const sources = args.slice(0, -1);
    for (const source of sources) {
        baseMergeWith(target, source, customizer);
    }
    return target;
}
