<commit_before>(function($, window) {
  'use strict';

  var POSITIONED = ['fixed', 'relative', 'absolute'];
  var WINDOW_EVENTS = 'mousewheel resize';

  var $window = $(window);

  var ScrollWatch = function(el, options) {
    _.bindAll(this, 'handleScroll', 'onScroll');

    this.$el = $(el);
    this.el = this.$el[0];

    this.options = _.defaults(options || {}, {
      watchOn: window
    });

    this.$watchOn = $(this.options.watchOn);
    this._prepareContainer();
    this.inViewport = false;
    this.callbacks = { "scrollin": $.Callbacks(), "scrollout": $.Callbacks(), "scroll": $.Callbacks() };
    this.listen();
  };

  ScrollWatch.prototype = {

    _prepareContainer: function() {
      if (this.$watchOn[0] === window) {
        return; // no prep needed for window
      }

      var positioning = this.$watchOn.css('position');
      var isPositioned = _.contains(POSITIONED, positioning);

      if (!isPositioned) {
        this.$watchOn.css('position', 'relative');
      }
    },

    listen: function() {
      this.$watchOn.on('scroll', this.onScroll);
      $window.on(WINDOW_EVENTS, this.onScroll);
    },

    destroy: function() {
      this.$watchOn.off('scroll', this.onScroll);
      $window.off(WINDOW_EVENTS, this.onScroll);
      this.$el.data('scrollWatch', null);
    },

    on: function(event, options, callback, thisArg) {
      if (_.isFunction(options)) {
        thisArg = callback;
        callback = options;
        options = {};
      }

      options = _.extend({}, this.options, options);
      callback = _.bind(callback, thisArg || this.$el);

      // delay handler
      if (options.delay) {
        callback = this._createDelayedCallback(event, callback, options);
      }

      this.callbacks[event].add(callback);
      this.$watchOn.scroll();
      return this;
    },

    _createDelayedCallback: function(event, cb, options) {
      return function() {
        var args = arguments;
        _.delay(function() {
          cb.apply(this, args);
        }, options.delay);
      };
    },

    handleScroll: function() {
      var lastVisibility = this.visibility;
      var visibility = this.isInViewport();
      var currentOffset = this.$watchOn.scrollTop();

      if (this.lastOffset === false) {
        this.direction = false;
      } else {
        this.direction = (currentOffset > this.lastOffset) ? 'down' : 'up';
      }

      this.lastOffset = currentOffset;
      this.visibility = visibility;

      if (!this.inViewport && visibility === 1) {
        this.inViewport = true;
        this.trigger('scrollin');
      } else if (this.inViewport && visibility === 0) {
        this.inViewport = false;

        if (this.dfd) {
          this.dfd.done(_.bind(this.trigger, this, 'scrollout'));
        } else {
          this.trigger('scrollout');
        }
      }

      // prevent firing multiple `scroll` events when the visibility is the same
      if (visibility !== lastVisibility) {
        this.trigger('scroll');
      }

      return this;
    },

    onScroll: function(event) {
      if (this.running) {
        return;
      }

      this.running = true;
      this.originalEvent = event;
      this.handleScroll();
      this.running = false;
    },

    trigger: function(event) {
      if (event !== 'scroll' && event === this.lastTriggered) {<commit_msg>Force option for handleScroll<commit_after>(function($, window) {
  'use strict';

  var POSITIONED = ['fixed', 'relative', 'absolute'];
  var WINDOW_EVENTS = 'mousewheel resize';

  var $window = $(window);

  var ScrollWatch = function(el, options) {
    _.bindAll(this, 'handleScroll', 'onScroll');

    this.$el = $(el);
    this.el = this.$el[0];

    this.options = _.defaults(options || {}, {
      watchOn: window
    });

    this.$watchOn = $(this.options.watchOn);
    this._prepareContainer();
    this.inViewport = false;
    this.callbacks = { "scrollin": $.Callbacks(), "scrollout": $.Callbacks(), "scroll": $.Callbacks() };
    this.listen();
  };

  ScrollWatch.prototype = {

    _prepareContainer: function() {
      if (this.$watchOn[0] === window) {
        return; // no prep needed for window
      }

      var positioning = this.$watchOn.css('position');
      var isPositioned = _.contains(POSITIONED, positioning);

      if (!isPositioned) {
        this.$watchOn.css('position', 'relative');
      }
    },

    listen: function() {
      this.$watchOn.on('scroll', this.onScroll);
      $window.on(WINDOW_EVENTS, this.onScroll);
    },

    destroy: function() {
      this.$watchOn.off('scroll', this.onScroll);
      $window.off(WINDOW_EVENTS, this.onScroll);
      this.$el.data('scrollWatch', null);
    },

    on: function(event, options, callback, thisArg) {
      if (_.isFunction(options)) {
        thisArg = callback;
        callback = options;
        options = {};
      }

      options = _.extend({}, this.options, options);
      callback = _.bind(callback, thisArg || this.$el);

      // delay handler
      if (options.delay) {
        callback = this._createDelayedCallback(event, callback, options);
      }

      this.callbacks[event].add(callback);
      this.$watchOn.scroll();
      return this;
    },

    _createDelayedCallback: function(event, cb, options) {
      return function() {
        var args = arguments;
        _.delay(function() {
          cb.apply(this, args);
        }, options.delay);
      };
    },

    // Force=true circumvents our logic that prevents multiple `scroll` events
    // when the visibility is the same
    handleScroll: function(force) {
      var lastVisibility = this.visibility;
      var visibility = this.isInViewport();
      var currentOffset = this.$watchOn.scrollTop();

      if (this.lastOffset === false) {
        this.direction = false;
      } else {
        this.direction = (currentOffset > this.lastOffset) ? 'down' : 'up';
      }

      this.lastOffset = currentOffset;
      this.visibility = visibility;

      if (!this.inViewport && visibility === 1) {
        this.inViewport = true;
        this.trigger('scrollin');
      } else if (this.inViewport && visibility === 0) {
        this.inViewport = false;

        if (this.dfd) {
          this.dfd.done(_.bind(this.trigger, this, 'scrollout'));
        } else {
          this.trigger('scrollout');
        }
      }

      // prevent firing multiple `scroll` events when the visibility is the same
      if (visibility !== lastVisibility || force) {
        this.trigger('scroll');
      }

      return this;
    },

    onScroll: function(event) {
      if (this.running) {
        return;
      }

      this.running = true;
      this.originalEvent = event;
      this.handleScroll();
      this.running = false;
    },

    trigger: function(event) {
      if (event !== 'scroll' && event === this.lastTriggered) {
{'fraction_non_alphanumeric': 0.150686933645133, 'fraction_numerical': 0.001169248757673195, 'mean_word_length': 2.3826000988630747, 'pattern_counts': {'":': 6, '<': 3, '<?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': '891749', 'n_tokens_mistral': 2058, 'n_tokens_neox': 1982, 'n_words': 437}