<commit_before>
dop.util.path = function (source, callback, destiny, mutator) {

    var hasCallback = typeof callback == 'function',
        hasDestiny = dop.util.isObject(destiny);

    dop.util.pathRecursive(
        source, 
        destiny, 
        callback, 
        [], 
        [],
        hasCallback,
        hasDestiny,
        mutator
   );

    return destiny;
};

dop.util.pathRecursive = function (source, destiny, callback, circular, path, hasCallback, hasDestiny, mutator) {

    var prop, value, typeofValue, skip;

    for (prop in source) {

        skip = false;
        value = source[prop];

        if (hasCallback) {
            // path.push(prop);
            // skip = callback(source, prop, value, destiny, path.slice(0), this);
            skip = callback(source, prop, value, destiny, this);
        }

        if (skip !== true) {

            typeofValue = dop.util.typeof(value);

            if (hasDestiny)
                mutator(destiny, prop, value, typeofValue);

            // Objects or arrays
            if ((typeofValue=='object' || typeofValue=='array') && value!==source && circular.indexOf(value)==-1) {
                circular.push(value);
                dop.util.pathRecursive(value, destiny[prop], callback, circular, path, hasCallback, hasDestiny, mutator);
            }


            // if (hasCallback)
                // path.pop();
        }
    }
};<commit_msg>Improving merge/path algorithm to allow custom mutators callbacks<commit_after>
dop.util.path = function (source, callback, destiny, mutator) {
    var hasCallback = typeof callback == 'function',
        hasDestiny = dop.util.isObject(destiny);
    dop.util.pathRecursive(source, callback, destiny, mutator, [], [], hasCallback, hasDestiny);
    return destiny;
};

dop.util.pathRecursive = function (source, callback, destiny, mutator, circular, path, hasCallback, hasDestiny) {

    var prop, value, typeofValue, skip;

    for (prop in source) {

        skip = false;
        value = source[prop];

        if (hasCallback) {
            // path.push(prop);
            // skip = callback(source, prop, value, destiny, path.slice(0), this);
            skip = callback(source, prop, value, destiny, this);
        }

        if (skip !== true) {

            typeofValue = dop.util.typeof(value);

            if (hasDestiny)
                mutator(destiny, prop, value, typeofValue);

            // Objects or arrays
            if ((typeofValue=='object' || typeofValue=='array') && value!==source && circular.indexOf(value)==-1) {
                circular.push(value);
                dop.util.pathRecursive(value, callback, destiny[prop], mutator, circular, path, hasCallback, hasDestiny);
            }


            // if (hasCallback)
                // path.pop();
        }
    }
};
{'fraction_non_alphanumeric': 0.13085106382978723, 'fraction_numerical': 0.0014184397163120568, 'mean_word_length': 2.0830601092896175, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6296486', 'n_tokens_mistral': 829, 'n_tokens_neox': 781, 'n_words': 192}