<commit_before>/**
 * Created by Danny on 24/12/13.
 */
var datamagic = datamagic || {};

datamagic.Binder = function(){
    // Private members
    this.payload = {};
    this.callBack = {};
    this.viewModel = {};
    this.exclusions = [];
};

datamagic.Binder.prototype = function(){
    var attach = function(viewModel, exclusions, callBack){
        this.viewModel = viewModel;
        this.callBack = callBack;
        this.exclusions = exclusions;

        attachExtenders.call(this, viewModel, exclusions);
    };

    var attachExtenders = function(obj, exclusions){
        var target = obj.extend ? obj() : obj;
        exclusions = exclusions || [];

        if(Object.prototype.toString.call( target ) === '[object Array]'){
            for(var i = 0; i < target.length; i++) {
                doAttachment.call(this, prop, target[i]);
                attachExtenders.call(this,target[i], exclusions);
            }
        }

        for(var prop in target){
            if(isKnockoutArray(target[prop])){
                doAttachment.call(this, prop, target[prop]);
                attachExtenders.call(this,target[prop](), exclusions);
                //attachExtenders.call(this,target[prop]);
            }else{
                if(shouldTrack.call(this, prop, target)){
                    doAttachment.call(this, prop, target[prop]);
                }else{
                    if (this.exclusions.indexOf(prop) < 0) {
                        this.exclusions.push(prop);
                    }
                }
            }
        }
    };

    var shouldTrack = function(prop, target){
        if(!isExcludedProperty.call(this, prop)){
            if(target[prop].extend) return true;
        }
        return false;
    };

    var isExcludedProperty = function(prop){
        return ko.utils.arrayFirst(this.exclusions, function(item){
            return item === prop;
        }) ? true : false;
    };

    var doAttachment = function(propertyName, observable){
        if(observable.extend){
            var options = {
                name : propertyName,
                payload : this.payload,
                callBack : this.callBack,
                viewModel : this.viewModel,
                hydratePayload : hydratePayload,
                cleanPayload : cleanPayload,
                exclusions : this.exclusions
            };
            //observable = observable.extend({logChange : options });
            observable.extend({logChange : options });
        }
    };

    ko.extenders.logChange = function(target, options){
        if(isKnockoutArray(target)){
            target.subscribe(function(changes){

                for(var i = 0; i < changes.length; i++){
                    if(changes[i].status === "added") {
                        if(target()[changes[i].index].extend) attachExtenders.call(this, target()[changes[i].index], options.exclusions);
                    }
                }

//                if(rebind){
//                    // Seems a bit excessive - could cause a performance issue here
//                    // TODO: Work out how to bind to changes in the new object
//                    attach(options.viewModel, options.exclusions,options.callBack);
//                }

                options.hydratePayload(options);
            }, null, "arrayChange");
        }else{
            target.subscribe(function(newValue){
                options.hydratePayload(options);
            });
        }
    };



    var hydratePayload = function(options){
        options.payload = ko.toJS(options.viewModel);
        if(options.exclusions && options.exclusions.length > 0) options.cleanPayload(options);
        if(options.payload) options.callBack(options.payload);
    };

    var cleanPayload = function(options){<commit_msg>Fixed complex object in array bug<commit_after>/**
 * Created by Danny on 24/12/13.
 */
var datamagic = datamagic || {};

datamagic.Binder = function(){
    // Private members
    this.payload = {};
    this.callBack = {};
    this.viewModel = {};
    this.exclusions = [];
};

datamagic.Binder.prototype = function(){
    var attach = function(viewModel, exclusions, callBack){
        this.viewModel = viewModel;
        this.callBack = callBack;
        this.exclusions = exclusions;

        attachExtenders.call(this, viewModel, exclusions);
    };

    var attachExtenders = function(obj, exclusions){
        var target = obj.extend ? obj() : obj;
        exclusions = exclusions || [];

        if(Object.prototype.toString.call( target ) === '[object Array]'){
            for(var i = 0; i < target.length; i++) {
                doAttachment.call(this, prop, target[i]);
                attachExtenders.call(this,target[i], exclusions);
            }
        }

        for(var prop in target){
            if(isKnockoutArray(target[prop])){
                doAttachment.call(this, prop, target[prop]);
                attachExtenders.call(this,target[prop](), exclusions);
                //attachExtenders.call(this,target[prop]);
            }else{
                if(shouldTrack.call(this, prop, target)){
                    doAttachment.call(this, prop, target[prop]);
                }else{
                    if (this.exclusions.indexOf(prop) < 0) {
                        this.exclusions.push(prop);
                    }
                }
            }
        }
    };

    var shouldTrack = function(prop, target){
        if(!isExcludedProperty.call(this, prop)){
            if(target[prop].extend) return true;
        }
        return false;
    };

    var isExcludedProperty = function(prop){
        return ko.utils.arrayFirst(this.exclusions, function(item){
            return item === prop;
        }) ? true : false;
    };

    var doAttachment = function(propertyName, observable){
        if(observable.extend){
            var options = {
                name : propertyName,
                payload : this.payload,
                callBack : this.callBack,
                viewModel : this.viewModel,
                hydratePayload : hydratePayload,
                cleanPayload : cleanPayload,
                exclusions : this.exclusions
            };
            //observable = observable.extend({logChange : options });
            if(observable.isChangeLogged === undefined) observable.extend({logChange : options });
            observable.isChangeLogged = true;
        }
    };

    ko.extenders.logChange = function(target, options){

        if(isKnockoutArray(target)){
            target.subscribe(function(changes){

                var rebind = false;

                for(var i = 0; i < changes.length; i++){
                    if(changes[i].status === "added") {
                        rebind = true;
                        break;
                    }
                }

                if(rebind){
//                    // Seems a bit excessive - could cause a performance issue here
//                    // TODO: Work out how to bind to changes in the new object
                    attach(options.viewModel, options.exclusions,options.callBack);
                }

                options.hydratePayload(options);
            }, null, "arrayChange");
        }else{
            target.subscribe(function(newValue){
                options.hydratePayload(options);
            });
        }
    };



    var hydratePayload = function(options){
        options.payload = ko.toJS(options.viewModel);
        if(options.exclusions && options.exclusions.length > 0) options.cleanPayload(options);
        if(options.payload) options.callBack(options.payload);
    };

    var cleanPayload = function(options){
{'fraction_non_alphanumeric': 0.11948865118705974, 'fraction_numerical': 0.0026089225150013043, 'mean_word_length': 1.7178305565402339, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, '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': '6944074', 'n_tokens_mistral': 2102, 'n_tokens_neox': 1948, 'n_words': 394}