<commit_before>this.Backbone.Model = (function ( Model, _ ) {

  'use strict';


  function normalizeComputedProps( computedProps ) {
    var propSpec, action, prop, depends;
    var normalizedProps = {};

    if ( ! computedProps ) {
      return {};
    }

    for ( prop in computedProps ) {
      if ( computedProps.hasOwnProperty( prop ) ) {
        propSpec = computedProps[ prop ];

        if ( propSpec instanceof Function ) {
          action = propSpec;
          depends = [];
        } else {
          action = propSpec.action;
          depends = propSpec.depends || [];
        }

        normalizedProps[ prop ] = {
          action: action,
          depends: depends
        };
      }
    }

    return normalizedProps;
  }


  return Model.extend({

    /*
     * Instance methods
     */

    _computedProps: {},

    // Override Boostrap's default constructor, setting up listeners for dependencies.
    constructor: function () {
      var classProps = this._computedProps;
      var prop, propSpec, l;

      this._computedCache = {};
      this._computedProps = {};
      this._dependencyMap = {};

      for ( prop in classProps ) {
        if ( classProps.hasOwnProperty( prop ) ) {
          propSpec = classProps[ prop ];
          this.addProperty( prop, propSpec.depends, propSpec.action );
        }
      }

      return Model.apply( this, arguments );
    },

    /*
       .addProperty( name, [depends ,] action )

         name:    The name of the computed property.
         depends: List of properties the new property should
                  depend on.
         action:  A function for getting and setting the
                  computed property.

       Adds a new computed property to the model instance.
     */

    addProperty: function ( name, depends, action ) {
      if ( action === undefined ) {
        action = depends;
        depends = [];
      }

      var computedProps = this._computedProps;
      var dependencyMap = this._dependencyMap;

      computedProps[ name ] = action;

      _.map( depends, function ( dep ) {
        var dependents = dependencyMap[ dep ] || ( dependencyMap[ dep ] = [] );
        dependents.push( name );
      });

      return this;
    },

    get: _.wrap( Model.prototype.get, function ( get, attr ) {
      var computedProps = this._computedProps;
      var computedCache = this._computedCache;
      var action;

      if ( action = computedProps[ attr ] ) {
        var cached = computedCache[ attr ];
        if ( cached !== undefined ) {
          return cached;
        }
        var newValue = action.call( this );
        computedCache[ attr ] = newValue;
        return newValue;
      }

      return get.call( this, attr );
    }),

    set: _.wrap( Model.prototype.set, function ( set, attributes, value, options ) {
      var computedProps = this._computedProps;
      var computedCache = this._computedCache;
      var dependencyMap = this._dependencyMap;
      var key, newValue;

      if ( typeof attributes === 'string' ) {
        key = attributes;
        attributes = {};
        attributes[ key ] = value;
      } else {
        options = value;
      }

      attributes = _.chain( attributes )
        .keys()
        .reduce( function ( attrs, key ) {
          var group = attrs[ computedProps[ key ] ? 'computed' : 'regular' ];
          group[ key ] = attributes[ key ];
          return attrs;
        }, { computed: {}, regular: {} })
        .value();

      var changedAttrs = this.changedAttributes( attributes.regular ) || {};
      set.call( this, changedAttrs, options );

      var changedComputed = _.chain( changedAttrs )
        .keys()
        .map( function ( attr ) {
          return dependencyMap[ attr ];
        })
        .reduce( function ( dependents, newDependents ) {
          return _.union( dependents, newDependents || [] );
        }, [])
        .value();

      _.each( changedComputed, function ( attr ) {
        delete computedCache[ attr ];
      });

      _.each( attributes.computed, function ( value, attr ) {
        var cached = computedCache[ attr ];
        if ( ! cached || cached !== value ) {
          computedCache[ attr ] =
            computedProps[ attr ].call( this, value );
          changedComputed = _.union( changedComputed, [ attr ]);
        }
      }, this);

      _.each( changedComputed, function ( attr ) {
        if ( ! computedCache[ attr ] ) {
          computedCache[ attr ] = computedProps[ attr ].call( this );
        }
        this.trigger( 'change:' + attr, this, computedCache[ attr ]);
      }, this);

      return this;
    })

  }, {
<commit_msg>Add some comments<commit_after>this.Backbone.Model = (function ( Model, _ ) {

  'use strict';


  function normalizeComputedProps( computedProps ) {
    var propSpec, action, prop, depends;
    var normalizedProps = {};

    if ( ! computedProps ) {
      return {};
    }

    for ( prop in computedProps ) {
      if ( computedProps.hasOwnProperty( prop ) ) {
        propSpec = computedProps[ prop ];

        if ( propSpec instanceof Function ) {
          action = propSpec;
          depends = [];
        } else {
          action = propSpec.action;
          depends = propSpec.depends || [];
        }

        normalizedProps[ prop ] = {
          action: action,
          depends: depends
        };
      }
    }

    return normalizedProps;
  }


  return Model.extend({

    /*
     * Instance methods
     */

    _computedProps: {},

    // Override Boostrap's default constructor, setting up listeners for dependencies.
    constructor: function () {
      var classProps = this._computedProps;
      var prop, propSpec, l;

      this._computedCache = {};
      this._computedProps = {};
      this._dependencyMap = {};

      for ( prop in classProps ) {
        if ( classProps.hasOwnProperty( prop ) ) {
          propSpec = classProps[ prop ];
          this.addProperty( prop, propSpec.depends, propSpec.action );
        }
      }

      return Model.apply( this, arguments );
    },

    /*
       .addProperty( name, [depends ,] action )

         name:    The name of the computed property.
         depends: List of properties the new property should
                  depend on.
         action:  A function for getting and setting the
                  computed property.

       Adds a new computed property to the model instance.
     */

    addProperty: function ( name, depends, action ) {
      if ( action === undefined ) {
        action = depends;
        depends = [];
      }

      var computedProps = this._computedProps;
      var dependencyMap = this._dependencyMap;

      computedProps[ name ] = action;

      _.map( depends, function ( dep ) {
        var dependents = dependencyMap[ dep ] || ( dependencyMap[ dep ] = [] );
        dependents.push( name );
      });

      return this;
    },

    get: _.wrap( Model.prototype.get, function ( get, attr ) {
      var computedProps = this._computedProps;
      var computedCache = this._computedCache;
      var action;

      if ( action = computedProps[ attr ] ) {
        var cached = computedCache[ attr ];
        if ( cached !== undefined ) {
          return cached;
        }
        var newValue = action.call( this );
        computedCache[ attr ] = newValue;
        return newValue;
      }

      return get.call( this, attr );
    }),

    set: _.wrap( Model.prototype.set, function ( set, attributes, value, options ) {
      var computedProps = this._computedProps;
      var computedCache = this._computedCache;
      var dependencyMap = this._dependencyMap;
      var key, newValue;

      if ( typeof attributes === 'string' ) {
        key = attributes;
        attributes = {};
        attributes[ key ] = value;
      } else {
        options = value;
      }

      // Group computed and regular properties
      attributes = _.chain( attributes )
        .keys()
        .reduce( function ( attrs, key ) {
          var group = attrs[ computedProps[ key ] ? 'computed' : 'regular' ];
          group[ key ] = attributes[ key ];
          return attrs;
        }, { computed: {}, regular: {} })
        .value();

      var changedAttrs = this.changedAttributes( attributes.regular ) || {};
      set.call( this, changedAttrs, options );

      // Get all computed properties which have one or more changed dependencies
      var changedComputed = _.chain( changedAttrs )
        .keys()
        .map( function ( attr ) {
          return dependencyMap[ attr ];
        })
        .reduce( function ( dependents, newDependents ) {
          return _.union( dependents, newDependents || [] );
        }, [])
        .value();

      // Delete the cache of all changed properties
      _.each( changedComputed, function ( attr ) {
        delete computedCache[ attr ];
      });

      // Call setters of all computed properties
      _.each( attributes.computed, function ( value, attr ) {
        var cached = computedCache[ attr ];
        if ( ! cached || cached !== value ) {
          computedCache[ attr ] =
            computedProps[ attr ].call( this, value );
          changedComputed = _.union( changedComputed, [ attr ]);
        }
      }, this);

      // Populate the caches of all computed properties
      _.each( changedComputed, function ( attr ) {
        if ( ! computedCache[ attr ] ) {
          computedCache[ attr ] = computedProps[ attr ].call( this );
        }
        this.trigger( 'change:' + attr, this, computedCache[ attr ]);
      }, this);

      return this;
    })

  }, {

{'fraction_non_alphanumeric': 0.11256134488879607, 'fraction_numerical': 0.0, 'mean_word_length': 1.9006662628709874, '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': '4519984', 'n_tokens_mistral': 2563, 'n_tokens_neox': 2508, 'n_words': 728}