<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//      JointJS.
//      (c) 2011-2013 client IO


if (typeof exports === 'object') {

    var joint = {
        util: require('./core').util,
        dia: {
            Link: require('./joint.dia.link').Link
        }
    };
    var Backbone = require('backbone');
    var _ = require('lodash');
}


// joint.dia.Cell base model.
// --------------------------

joint.dia.Cell = Backbone.Model.extend({

    // This is the same as Backbone.Model with the only difference that is uses _.merge
    // instead of just _.extend. The reason is that we want to mixin attributes set in upper classes.
    constructor: function(attributes, options) {

        var defaults;
        var attrs = attributes || {};
        this.cid = _.uniqueId('c');
        this.attributes = {};
        if (options && options.collection) this.collection = options.collection;
        if (options && options.parse) attrs = this.parse(attrs, options) || {};
        if (defaults = _.result(this, 'defaults')) {
            //<custom code>
            // Replaced the call to _.defaults with _.merge.
            attrs = _.merge({}, defaults, attrs);
            //</custom code>
        }
        this.set(attrs, options);
        this.changed = {};
        this.initialize.apply(this, arguments);
    },

    toJSON: function() {

        var defaultAttrs = this.constructor.prototype.defaults.attrs || {};
        var attrs = this.attributes.attrs;
        var finalAttrs = {};

        // Loop through all the attributes and
        // omit the default attributes as they are implicitly reconstructable by the cell 'type'.
        _.each(attrs, function(attr, selector) {

            var defaultAttr = defaultAttrs[selector];

            _.each(attr, function(value, name) {
                
                // attr is mainly flat though it might have one more level (consider the `style` attribute).
                // Check if the `value` is object and if yes, go one level deep.
                if (_.isObject(value) && !_.isArray(value)) {
                    
                    _.each(value, function(value2, name2) {

                        if (!defaultAttr || !defaultAttr[name] || !_.isEqual(defaultAttr[name][name2], value2)) {

                            finalAttrs[selector] = finalAttrs[selector] || {};
                            (finalAttrs[selector][name] || (finalAttrs[selector][name] = {}))[name2] = value2;
                        }
                    });

                } else if (!defaultAttr || !_.isEqual(defaultAttr[name], value)) {
                    // `value` is not an object, default attribute for such a selector does not exist
                    // or it is different than the attribute value set on the model.

                    finalAttrs[selector] = finalAttrs[selector] || {};
                    finalAttrs[selector][name] = value;
                }
            });
        });

        var attributes = _.cloneDeep(_.omit(this.attributes, 'attrs'));
        //var attributes = JSON.parse(JSON.stringify(_.omit(this.attributes, 'attrs')));
        attributes.attrs = finalAttrs;

        return attributes;
    },

    initialize: function(options) {

        if (!options || !options.id) {

            this.set('id', joint.util.uuid(), { silent: true });
        }
    },

    remove: function(options) {

	var collection = this.collection;

	if (collection) {
	    collection.trigger('batch:start');
	}

        // First, unembed this cell from its parent cell if there is one.
        var parentCellId = this.get('parent');
        if (parentCellId) {
            
            var parentCell = this.collection && this.collection.get(parentCellId);
            parentCell.unembed(this);
        }
        
        _.invoke(this.getEmbeddedCells(), 'remove', options);
        
        this.trigger('remove', this, this.collection, options);

	if (collection) {
	    collection.trigger('batch:stop');
	}
    },

    toFront: function() {

        if (this.collection) {

            this.set('z', (this.collection.last().get('z') || 0) + 1);
        }
    },
    
    toBack: function() {

        if (this.collection) {
            
            this.set('z', (this.collection.first().get('z') || 0) - 1);
        }
    },

    embed: function(cell) {
	
        if(this.get('parent') == cell.id) {
            
            throw new Error('Recursive embedding not allowed.');
			
        } else {
		
			this.trigger('batch:start');

			cell.set('parent', this.id);

			this.set('embeds', _.uniq((this.get('embeds') || []).concat([cell.id])));

			this.trigger('batch:stop');
		}
    },

    unembed: function(cell) {

	this.trigger('batch:start');

        var cellId = cell.id;
        cell.unset('parent');<commit_msg>Fixed issue where given two objects A and B. If A is embedded into B success. If B is embedded into A a too much recursion error occurs. Also fixed indentation from previous commit.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//      JointJS.
//      (c) 2011-2013 client IO


if (typeof exports === 'object') {

    var joint = {
        util: require('./core').util,
        dia: {
            Link: require('./joint.dia.link').Link
        }
    };
    var Backbone = require('backbone');
    var _ = require('lodash');
}


// joint.dia.Cell base model.
// --------------------------

joint.dia.Cell = Backbone.Model.extend({

    // This is the same as Backbone.Model with the only difference that is uses _.merge
    // instead of just _.extend. The reason is that we want to mixin attributes set in upper classes.
    constructor: function(attributes, options) {

        var defaults;
        var attrs = attributes || {};
        this.cid = _.uniqueId('c');
        this.attributes = {};
        if (options && options.collection) this.collection = options.collection;
        if (options && options.parse) attrs = this.parse(attrs, options) || {};
        if (defaults = _.result(this, 'defaults')) {
            //<custom code>
            // Replaced the call to _.defaults with _.merge.
            attrs = _.merge({}, defaults, attrs);
            //</custom code>
        }
        this.set(attrs, options);
        this.changed = {};
        this.initialize.apply(this, arguments);
    },

    toJSON: function() {

        var defaultAttrs = this.constructor.prototype.defaults.attrs || {};
        var attrs = this.attributes.attrs;
        var finalAttrs = {};

        // Loop through all the attributes and
        // omit the default attributes as they are implicitly reconstructable by the cell 'type'.
        _.each(attrs, function(attr, selector) {

            var defaultAttr = defaultAttrs[selector];

            _.each(attr, function(value, name) {
                
                // attr is mainly flat though it might have one more level (consider the `style` attribute).
                // Check if the `value` is object and if yes, go one level deep.
                if (_.isObject(value) && !_.isArray(value)) {
                    
                    _.each(value, function(value2, name2) {

                        if (!defaultAttr || !defaultAttr[name] || !_.isEqual(defaultAttr[name][name2], value2)) {

                            finalAttrs[selector] = finalAttrs[selector] || {};
                            (finalAttrs[selector][name] || (finalAttrs[selector][name] = {}))[name2] = value2;
                        }
                    });

                } else if (!defaultAttr || !_.isEqual(defaultAttr[name], value)) {
                    // `value` is not an object, default attribute for such a selector does not exist
                    // or it is different than the attribute value set on the model.

                    finalAttrs[selector] = finalAttrs[selector] || {};
                    finalAttrs[selector][name] = value;
                }
            });
        });

        var attributes = _.cloneDeep(_.omit(this.attributes, 'attrs'));
        //var attributes = JSON.parse(JSON.stringify(_.omit(this.attributes, 'attrs')));
        attributes.attrs = finalAttrs;

        return attributes;
    },

    initialize: function(options) {

        if (!options || !options.id) {

            this.set('id', joint.util.uuid(), { silent: true });
        }
    },

    remove: function(options) {

	var collection = this.collection;

	if (collection) {
	    collection.trigger('batch:start');
	}

        // First, unembed this cell from its parent cell if there is one.
        var parentCellId = this.get('parent');
        if (parentCellId) {
            
            var parentCell = this.collection && this.collection.get(parentCellId);
            parentCell.unembed(this);
        }
        
        _.invoke(this.getEmbeddedCells(), 'remove', options);
        
        this.trigger('remove', this, this.collection, options);

	if (collection) {
	    collection.trigger('batch:stop');
	}
    },

    toFront: function() {

        if (this.collection) {

            this.set('z', (this.collection.last().get('z') || 0) + 1);
        }
    },
    
    toBack: function() {

        if (this.collection) {
            
            this.set('z', (this.collection.first().get('z') || 0) - 1);
        }
    },

	embed: function(cell) {

		if(this.get('parent') == cell.id) {

			throw new Error('Recursive embedding not allowed.');

		} else {

			this.trigger('batch:start');

			cell.set('parent', this.id);

			this.set('embeds', _.uniq((this.get('embeds') || []).concat([cell.id])));

			this.trigger('batch:stop');
		}
	},

    unembed: function(cell) {

	this.trigger('batch:start');

        var cellId = cell.id;
        cell.unset('parent');
{'fraction_non_alphanumeric': 0.141735413974754, 'fraction_numerical': 0.004373322731338833, 'mean_word_length': 1.8955395683453238, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '1033331', 'n_tokens_mistral': 2866, 'n_tokens_neox': 2683, 'n_words': 748}