<commit_before>Backbone.Select = (function (Backbone, _) {
  var Select = {};

  // Select.One
  // ------------------
  // A single-select mixin for Backbone.Collection, allowing a single
  // model to be selected within a collection. Selection of another
  // model within the collection causes the previous model to be
  // deselected.

  Select.One = function(collection, models, options){
    this._pickyCid = _.uniqueId('singleSelect');
    this.collection = collection;
    this.trigger = trigger(collection);

    if (options && options.enableModelSharing) {

      // model-sharing mode
      _.each(models || [], function (model) {
        registerCollectionWithModel(model, this);
        if (model.selected) {
          if (this.selected) this.selected.deselect();
          this.selected = model;
        }
      }, this);

      this.collection.listenTo(this.collection, '_selected', this.select);
      this.collection.listenTo(this.collection, '_deselected', this.deselect);

      this.collection.listenTo(this.collection, 'reset', onResetSingleSelect);
      this.collection.listenTo(this.collection, 'add', onAdd);
      this.collection.listenTo(this.collection, 'remove', onRemove);

      // Mode flag, undocumented, but part of the API (monitored by tests). Can
      // be queried safely by other components. Use it read-only.
      this._modelSharingEnabled = true;

    }

  };

  _.extend(Select.One.prototype, {

    // Select a model, deselecting any previously
    // selected model
    select: function(model, options){
      var reselected = model && this.selected === model ? model : undefined;

      options || (options = {});
      options._processedBy || (options._processedBy = []);
      if (options._processedBy[this._pickyCid]) { return; }

      if (!reselected) {
        this.deselect(undefined, _.omit(options, "_silentLocally"));
        this.selected = model;
      }
      options._processedBy[this._pickyCid] = this;

      if (!options._processedBy[this.selected.cid]) this.selected.select(stripLocalOptions(options));

      if (!(options.silent || options._silentLocally)) {

        if (reselected) {
          if (!options._silentReselect) this.trigger("reselect:one", model, this, stripInternalOptions(options));
        } else {
          this.trigger("select:one", model, this, stripInternalOptions(options));
        }

      }
    },

    // Deselect a model, resulting in no model
    // being selected
    deselect: function(model, options){
      options || (options = {});
      if (!this.selected){ return; }

      model = model || this.selected;
      if (this.selected !== model){ return; }

      delete this.selected;
      if (!options._skipModelCall) model.deselect(stripLocalOptions(options));
      if (!(options.silent || options._silentLocally)) this.trigger("deselect:one", model, this, stripInternalOptions(options));
    },

    close: function () {
      unregisterCollectionWithModels(this);
      this.stopListening();
    }

  });

  // Select.Many
  // -----------------
  // A multi-select mixin for Backbone.Collection, allowing a collection to
  // have multiple items selected, including `selectAll` and `deselectAll`
  // capabilities.

  Select.Many = function (collection, models, options) {
    this._pickyCid = _.uniqueId('multiSelect');
    this.collection = collection;
    this.selected = {};
    this.trigger = trigger(collection);

    if (options && options.enableModelSharing) {

      // 'models' argument provided, model-sharing mode
      _.each(models || [], function (model) {
        registerCollectionWithModel(model, this);
        if (model.selected) this.selected[model.cid] = model;
      }, this);

      this.collection.listenTo(this.collection, '_selected', this.select);
      this.collection.listenTo(this.collection, '_deselected', this.deselect);

      this.collection.listenTo(this.collection, 'reset', onResetMultiSelect);
      this.collection.listenTo(this.collection, 'add', onAdd);
      this.collection.listenTo(this.collection, 'remove', onRemove);

      // Mode flag, undocumented, but part of the API (monitored by tests). Can
      // be queried safely by other components. Use it read-only.
      this._modelSharingEnabled = true;

    }

  };

  _.extend(Select.Many.prototype, {

    // Select a specified model, make sure the
    // model knows it's selected, and hold on to
    // the selected model.
    select: function (model, options) {
      var prevSelected = multiSelectionToArray(this.selected),
          reselected = this.selected[model.cid] ? [ model ] : [];

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      if (reselected.length && options._processedBy[this._pickyCid]) { return; }

      if (!reselected.length) {
        this.selected[model.cid] = model;
        this.selectedLength = _.size(this.selected);
      }
      options._processedBy[this._pickyCid] = this;

      if (!options._processedBy[model.cid]) model.select(stripLocalOptions(options));
      triggerMultiSelectEvents(this, prevSelected, options, reselected);
    },

    // Deselect a specified model, make sure the
    // model knows it has been deselected, and remove
    // the model from the selected list.
    deselect: function (model, options) {
      var prevSelected = multiSelectionToArray(this.selected);

      options || (options = {});
      if (!this.selected[model.cid]) { return; }

      delete this.selected[model.cid];
      this.selectedLength = _.size(this.selected);

      if (!options._skipModelCall) model.deselect(stripLocalOptions(options));
      triggerMultiSelectEvents(this, prevSelected, options);
    },

    // Select all models in this collection
    selectAll: function (options) {
      var prevSelected = multiSelectionToArray(this.selected),
          reselected = [];

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      this.selectedLength = 0;
      this.each(function (model) {
        this.selectedLength++;
        if (this.selected[model.cid]) reselected.push(model);
        this.select(model, _.extend({}, options, {_silentLocally: true}));
      }, this);
      options._processedBy[this._pickyCid] = this;

      triggerMultiSelectEvents(this, prevSelected, options, reselected);
    },

    // Deselect all models in this collection
    deselectAll: function (options) {
      var prevSelected;

      if (this.selectedLength === 0) { return; }
      prevSelected = multiSelectionToArray(this.selected);

      this.each(function (model) {
        if (model.selected) this.selectedLength--;
        this.deselect(model, _.extend({}, options, {_silentLocally: true}));
      }, this);

      this.selectedLength = 0;
      triggerMultiSelectEvents(this, prevSelected, options);
    },

    selectNone: function (options) {
      this.deselectAll(options);
    },

    // Toggle select all / none. If some are selected, it
    // will select all. If all are selected, it will select 
    // none. If none are selected, it will select all.
    toggleSelectAll: function (options) {
      if (this.selectedLength === this.length) {
        this.deselectAll(options);
      } else {
        this.selectAll(options);
      }
    },

    close: function () {
      unregisterCollectionWithModels(this);
      this.stopListening();
    }
  });

  // Select.Me
  // ----------------
  // A selectable mixin for Backbone.Model, allowing a model to be selected,
  // enabling it to work with Select.Many or on it's own

  Select.Me = function (model) {
    this.model = model;
    this.trigger = trigger(model);
  };

  _.extend(Select.Me.prototype, {

    // Select this model, and tell our
    // collection that we're selected
    select: function (options) {
      var reselected = this.selected;

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      if (options._processedBy[this.cid]) { return; }

      this.selected = true;
      options._processedBy[this.cid] = this;

      if (this._pickyCollections) {
        // Model-sharing mode: notify collections with an event
        this.trigger("_selected", this, stripLocalOptions(options));
      } else if (this.collection) {
        // Single collection only: no event listeners set up in collection, call
        // it directly
        if (!options._processedBy[this.collection._pickyCid]) this.collection.select(this, stripLocalOptions(options));
      }

      if (!(options.silent || options._silentLocally)) {
        if (reselected) {
          if (!options._silentReselect) this.trigger("reselected", this, stripInternalOptions(options));
        } else {
          this.trigger("selected", this, stripInternalOptions(options));
        }
      }
    },

    // Deselect this model, and tell our
    // collection that we're deselected
    deselect: function (options) {
      options || (options = {});
      if (!this.selected) { return; }

      this.selected = false;

      if (this._pickyCollections) {
        // Model-sharing mode: notify collections with an event
        this.trigger("_deselected", this, stripLocalOptions(options));
      } else if (this.collection) {
        // Single collection only: no event listeners set up in collection, call
        // it directly
        this.collection.deselect(this, stripLocalOptions(options));
      }

      if (!(options.silent || options._silentLocally)) this.trigger("deselected", this, stripInternalOptions(options));
    },

    // Change selected to the opposite of what
    // it currently is
    toggleSelected: function (options) {
      if (this.selected) {
        this.deselect(options);
      } else {
        this.select(options);
      }
    }
  });

  // Applying the mixin: class methods for setup
  Select.Me.applyTo = function (hostObject) {
    _.extend(hostObject, new Backbone.Select.Me(hostObject));
  };

  Select.One.applyTo = function (hostObject, models, options) {
    _.extend(hostObject, new Backbone.Select.One(hostObject, models, options));
  };

  Select.Many.applyTo = function (hostObject, models, options) {
    _.extend(hostObject, new Backbone.Select.Many(hostObject, models, options));
  };

  // Helper Methods
  // --------------

  // Trigger events from a multi-select collection based on the number of
  // selected items.
  var triggerMultiSelectEvents = function (collection, prevSelected, options, reselected) {
    function mapCidsToModels (cids, collection, previousSelection) {
      function mapper (cid) {
        // Find the model in the collection. If not found, it has been removed,
        // so get it from the array of previously selected models.
        return collection.get(cid) || previousSelection[cid];
      }
      return _.map(cids, mapper);
    }

    options || (options = {});
    if (options.silent || options._silentLocally) return;

    var selectedLength = collection.selectedLength,
        length = collection.length,
        prevSelectedCids = _.keys(prevSelected),
        selectedCids = _.keys(collection.selected),
        addedCids = _.difference( selectedCids, prevSelectedCids ),
        removedCids = _.difference( prevSelectedCids, selectedCids ),
        unchanged = (selectedLength === prevSelectedCids.length && addedCids.length === 0 && removedCids.length === 0),
        diff;
<commit_msg>Moved setup code to applyTo; removed this.model, this.collection self refs<commit_after>Backbone.Select = (function (Backbone, _) {
  var Select = {};

  // Select.One
  // ------------------
  // A single-select mixin for Backbone.Collection, allowing a single
  // model to be selected within a collection. Selection of another
  // model within the collection causes the previous model to be
  // deselected.

  Select.One = function(){};

  _.extend(Select.One.prototype, {

    // Select a model, deselecting any previously
    // selected model
    select: function(model, options){
      var reselected = model && this.selected === model ? model : undefined;

      options || (options = {});
      options._processedBy || (options._processedBy = []);
      if (options._processedBy[this._pickyCid]) { return; }

      if (!reselected) {
        this.deselect(undefined, _.omit(options, "_silentLocally"));
        this.selected = model;
      }
      options._processedBy[this._pickyCid] = this;

      if (!options._processedBy[this.selected.cid]) this.selected.select(stripLocalOptions(options));

      if (!(options.silent || options._silentLocally)) {

        if (reselected) {
          if (!options._silentReselect) this.trigger("reselect:one", model, this, stripInternalOptions(options));
        } else {
          this.trigger("select:one", model, this, stripInternalOptions(options));
        }

      }
    },

    // Deselect a model, resulting in no model
    // being selected
    deselect: function(model, options){
      options || (options = {});
      if (!this.selected){ return; }

      model = model || this.selected;
      if (this.selected !== model){ return; }

      delete this.selected;
      if (!options._skipModelCall) model.deselect(stripLocalOptions(options));
      if (!(options.silent || options._silentLocally)) this.trigger("deselect:one", model, this, stripInternalOptions(options));
    },

    close: function () {
      unregisterCollectionWithModels(this);
      this.stopListening();
    }

  });

  // Select.Many
  // -----------------
  // A multi-select mixin for Backbone.Collection, allowing a collection to
  // have multiple items selected, including `selectAll` and `deselectAll`
  // capabilities.

  Select.Many = function () {};

  _.extend(Select.Many.prototype, {

    // Select a specified model, make sure the
    // model knows it's selected, and hold on to
    // the selected model.
    select: function (model, options) {
      var prevSelected = multiSelectionToArray(this.selected),
          reselected = this.selected[model.cid] ? [ model ] : [];

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      if (reselected.length && options._processedBy[this._pickyCid]) { return; }

      if (!reselected.length) {
        this.selected[model.cid] = model;
        this.selectedLength = _.size(this.selected);
      }
      options._processedBy[this._pickyCid] = this;

      if (!options._processedBy[model.cid]) model.select(stripLocalOptions(options));
      triggerMultiSelectEvents(this, prevSelected, options, reselected);
    },

    // Deselect a specified model, make sure the
    // model knows it has been deselected, and remove
    // the model from the selected list.
    deselect: function (model, options) {
      var prevSelected = multiSelectionToArray(this.selected);

      options || (options = {});
      if (!this.selected[model.cid]) { return; }

      delete this.selected[model.cid];
      this.selectedLength = _.size(this.selected);

      if (!options._skipModelCall) model.deselect(stripLocalOptions(options));
      triggerMultiSelectEvents(this, prevSelected, options);
    },

    // Select all models in this collection
    selectAll: function (options) {
      var prevSelected = multiSelectionToArray(this.selected),
          reselected = [];

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      this.selectedLength = 0;
      this.each(function (model) {
        this.selectedLength++;
        if (this.selected[model.cid]) reselected.push(model);
        this.select(model, _.extend({}, options, {_silentLocally: true}));
      }, this);
      options._processedBy[this._pickyCid] = this;

      triggerMultiSelectEvents(this, prevSelected, options, reselected);
    },

    // Deselect all models in this collection
    deselectAll: function (options) {
      var prevSelected;

      if (this.selectedLength === 0) { return; }
      prevSelected = multiSelectionToArray(this.selected);

      this.each(function (model) {
        if (model.selected) this.selectedLength--;
        this.deselect(model, _.extend({}, options, {_silentLocally: true}));
      }, this);

      this.selectedLength = 0;
      triggerMultiSelectEvents(this, prevSelected, options);
    },

    selectNone: function (options) {
      this.deselectAll(options);
    },

    // Toggle select all / none. If some are selected, it
    // will select all. If all are selected, it will select 
    // none. If none are selected, it will select all.
    toggleSelectAll: function (options) {
      if (this.selectedLength === this.length) {
        this.deselectAll(options);
      } else {
        this.selectAll(options);
      }
    },

    close: function () {
      unregisterCollectionWithModels(this);
      this.stopListening();
    }
  });

  // Select.Me
  // ----------------
  // A selectable mixin for Backbone.Model, allowing a model to be selected,
  // enabling it to work with Select.One or Select.Many, or on it's own.

  Select.Me = function () {};

  _.extend(Select.Me.prototype, {

    // Select this model, and tell our
    // collection that we're selected
    select: function (options) {
      var reselected = this.selected;

      options || (options = {});
      options._processedBy || (options._processedBy = []);

      if (options._processedBy[this.cid]) { return; }

      this.selected = true;
      options._processedBy[this.cid] = this;

      if (this._pickyCollections) {
        // Model-sharing mode: notify collections with an event
        this.trigger("_selected", this, stripLocalOptions(options));
      } else if (this.collection) {
        // Single collection only: no event listeners set up in collection, call
        // it directly
        if (!options._processedBy[this.collection._pickyCid]) this.collection.select(this, stripLocalOptions(options));
      }

      if (!(options.silent || options._silentLocally)) {
        if (reselected) {
          if (!options._silentReselect) this.trigger("reselected", this, stripInternalOptions(options));
        } else {
          this.trigger("selected", this, stripInternalOptions(options));
        }
      }
    },

    // Deselect this model, and tell our
    // collection that we're deselected
    deselect: function (options) {
      options || (options = {});
      if (!this.selected) { return; }

      this.selected = false;

      if (this._pickyCollections) {
        // Model-sharing mode: notify collections with an event
        this.trigger("_deselected", this, stripLocalOptions(options));
      } else if (this.collection) {
        // Single collection only: no event listeners set up in collection, call
        // it directly
        this.collection.deselect(this, stripLocalOptions(options));
      }

      if (!(options.silent || options._silentLocally)) this.trigger("deselected", this, stripInternalOptions(options));
    },

    // Change selected to the opposite of what
    // it currently is
    toggleSelected: function (options) {
      if (this.selected) {
        this.deselect(options);
      } else {
        this.select(options);
      }
    }
  });

  // Applying the mixin: class methods for setup
  Select.Me.applyTo = function (hostObject) {
    _.extend(hostObject, new Backbone.Select.Me());
    hostObject.trigger = trigger(hostObject);
  };

  Select.One.applyTo = function (hostObject, models, options) {

    _.extend(hostObject, new Backbone.Select.One());

    hostObject._pickyCid = _.uniqueId('singleSelect');
    hostObject.trigger = trigger(hostObject);

    if (options && options.enableModelSharing) {

      // model-sharing mode
      _.each(models || [], function (model) {
        registerCollectionWithModel(model, hostObject);
        if (model.selected) {
          if (hostObject.selected) hostObject.selected.deselect();
          hostObject.selected = model;
        }
      });

      hostObject.listenTo(hostObject, '_selected', hostObject.select);
      hostObject.listenTo(hostObject, '_deselected', hostObject.deselect);

      hostObject.listenTo(hostObject, 'reset', onResetSingleSelect);
      hostObject.listenTo(hostObject, 'add', onAdd);
      hostObject.listenTo(hostObject, 'remove', onRemove);

      // Mode flag, undocumented, but part of the API (monitored by tests). Can
      // be queried safely by other components. Use it read-only.
      hostObject._modelSharingEnabled = true;

    }

  };

  Select.Many.applyTo = function (hostObject, models, options) {

    _.extend(hostObject, new Backbone.Select.Many());

    hostObject._pickyCid = _.uniqueId('multiSelect');
    hostObject.selected = {};
    hostObject.trigger = trigger(hostObject);

    if (options && options.enableModelSharing) {

      // model-sharing mode
      _.each(models || [], function (model) {
        registerCollectionWithModel(model, hostObject);
        if (model.selected) hostObject.selected[model.cid] = model;
      });

      hostObject.listenTo(hostObject, '_selected', hostObject.select);
      hostObject.listenTo(hostObject, '_deselected', hostObject.deselect);

      hostObject.listenTo(hostObject, 'reset', onResetMultiSelect);
      hostObject.listenTo(hostObject, 'add', onAdd);
      hostObject.listenTo(hostObject, 'remove', onRemove);

      // Mode flag, undocumented, but part of the API (monitored by tests). Can
      // be queried safely by other components. Use it read-only.
      hostObject._modelSharingEnabled = true;

    }

  };

  // Helper Methods
  // --------------

  // Trigger events from a multi-select collection based on the number of
  // selected items.
  var triggerMultiSelectEvents = function (collection, prevSelected, options, reselected) {
    function mapCidsToModels (cids, collection, previousSelection) {
      function mapper (cid) {
        // Find the model in the collection. If not found, it has been removed,
        // so get it from the array of previously selected models.
        return collection.get(cid) || previousSelection[cid];
      }
      return _.map(cids, mapper);
    }

    options || (options = {});
    if (options.silent || options._silentLocally) return;

    var selectedLength = collection.selectedLength,
        length = collection.length,
        prevSelectedCids = _.keys(prevSelected),
        selectedCids = _.keys(collection.selected),
        addedCids = _.difference( selectedCids, prevSelectedCids ),
        removedCids = _.difference( prevSelectedCids, selectedCids ),
        unchanged = (selectedLength === prevSelectedCids.length && addedCids.length === 0 && removedCids.length === 0),
        diff;

{'fraction_non_alphanumeric': 0.12876579203109814, 'fraction_numerical': 0.0004417351356126866, 'mean_word_length': 2.818994601889339, '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': '1513640', 'n_tokens_mistral': 6353, 'n_tokens_neox': 6138, 'n_words': 1574}