<commit_before>define(function(require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');
	

	var PixiView       = require('common/pixi/view');
	var Colors         = require('common/colors/colors');
	var PiecewiseCurve = require('common/math/piecewise-curve');
	var Rectangle      = require('common/math/rectangle');

	var Constants      = require('constants');

	var defaultMovementConstraintBounds = new Rectangle(
		Number.NEGATIVE_INFINITY,
		Number.NEGATIVE_INFINITY,
		Number.POSITIVE_INFINITY,
		Number.POSITIVE_INFINITY
	);

	/**
	 * A view that represents an element model
	 */
	var ElementView = PixiView.extend({

		events: {
			'touchstart      .displayObject': 'dragStart',
			'mousedown       .displayObject': 'dragStart',
			'touchmove       .displayObject': 'drag',
			'mousemove       .displayObject': 'drag',
			'touchend        .displayObject': 'dragEnd',
			'mouseup         .displayObject': 'dragEnd',
			'touchendoutside .displayObject': 'dragEnd',
			'mouseupoutside  .displayObject': 'dragEnd',
		},

		/**
		 *
		 */
		initialize: function(options) {
			this.mvt = options.mvt;

			this.movable = options.movable || false;
			this.movementConstraintBounds = options.movementConstraintBounds || defaultMovementConstraintBounds;

			this.fillColor = options.fillColor;
			this.fillAlpha = options.fillAlpha !== undefined ? options.fillAlpha : 1;
			this.lineWidth = options.lineWidth !== undefined ? options.lineWidth : 3;
			this.lineColor = options.lineColor || '#444444';
			this.lineJoin  = options.lineJoin  || 'round';
			this.textColor = options.textColor || '#000000';
			this.textFont  = options.textFont  || ElementView.TEXT_FONT;
			this.labelText = options.labelText || '';

			if (this.fillColor === undefined)
				this.fillColor = 0x000000;
			else if (_.isString(this.fillColor))
				this.fillColor =  Colors.parseHex(options.fillColor);

			// To give some feedback on the cursor
			if (this.movable)
				this.displayObject.buttonMode = true;

			this._dragBounds = new Rectangle();
		},

		calculateDragBounds: function(dx, dy) {
			var bounds = this.displayObject.getBounds();
			return this._dragBounds.set(
				bounds.x + dx,
				bounds.y + dy,
				bounds.width,
				bounds.height
			);
		},

		dragStart: function(data) {
			this.dragXOffset = data.getLocalPosition(this.displayObject).x;
			this.dragYOffset = data.getLocalPosition(this.displayObject).y;
			this.dragging = true;
			this.model.set('userControlled', true);
		},

		drag: function(data) {
			if (this.dragging) {
				var dx = data.global.x - this.displayObject.x - this.dragXOffset;
				var dy = data.global.y - this.displayObject.y - this.dragYOffset;
				
				var newBounds = this.calculateDragBounds(dx, dy);
				var constraintBounds = this.movementConstraintBounds;

				console.log(dx + ', ' + dy);

				if (!constraintBounds.contains(newBounds)) {
					var overflowLeft   = constraintBounds.left() - newBounds.left();
					var overflowRight  = newBounds.right() - constraintBounds.right();
					var overflowTop    = constraintBounds.bottom() - newBounds.bottom();
					var overflowBottom = newBounds.top() - constraintBounds.top();

					// Backtrack if we need to
					if (overflowLeft > 0)
						dx += overflowLeft;
					else if (overflowRight > 0)
						dx -= overflowRight;

					if (overflowTop > 0)
						dy += overflowTop;
					else if (overflowBottom > 0)
						dy -= overflowBottom;
				}

				dx = this.mvt.viewToModelDeltaX(dx);
				dy = this.mvt.viewToModelDeltaY(dy);

				this.model.translate(dx, dy);

				this.dragX = data.global.x;
				this.dragY = data.global.y;
			}
		},

		dragEnd: function(data) {<commit_msg>PIXI canvases don't listen to drag events after the pointer moves outside the canvas :(<commit_after>define(function(require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');
	

	var PixiView       = require('common/pixi/view');
	var Colors         = require('common/colors/colors');
	var PiecewiseCurve = require('common/math/piecewise-curve');
	var Rectangle      = require('common/math/rectangle');

	var Constants      = require('constants');

	var defaultMovementConstraintBounds = new Rectangle(
		Number.NEGATIVE_INFINITY,
		Number.NEGATIVE_INFINITY,
		Number.POSITIVE_INFINITY,
		Number.POSITIVE_INFINITY
	);

	/**
	 * A view that represents an element model
	 */
	var ElementView = PixiView.extend({

		events: {
			'touchstart      .displayObject': 'dragStart',
			'mousedown       .displayObject': 'dragStart',
			'touchmove       .displayObject': 'drag',
			'mousemove       .displayObject': 'drag',
			'touchend        .displayObject': 'dragEnd',
			'mouseup         .displayObject': 'dragEnd',
			'touchendoutside .displayObject': 'dragEnd',
			'mouseupoutside  .displayObject': 'dragEnd',
		},

		/**
		 *
		 */
		initialize: function(options) {
			this.mvt = options.mvt;

			this.movable = options.movable || false;
			this.movementConstraintBounds = options.movementConstraintBounds || defaultMovementConstraintBounds;

			this.fillColor = options.fillColor;
			this.fillAlpha = options.fillAlpha !== undefined ? options.fillAlpha : 1;
			this.lineWidth = options.lineWidth !== undefined ? options.lineWidth : 3;
			this.lineColor = options.lineColor || '#444444';
			this.lineJoin  = options.lineJoin  || 'round';
			this.textColor = options.textColor || '#000000';
			this.textFont  = options.textFont  || ElementView.TEXT_FONT;
			this.labelText = options.labelText || '';

			if (this.fillColor === undefined)
				this.fillColor = 0x000000;
			else if (_.isString(this.fillColor))
				this.fillColor =  Colors.parseHex(options.fillColor);

			// To give some feedback on the cursor
			if (this.movable)
				this.displayObject.buttonMode = true;

			this._dragBounds = new Rectangle();
			this._dragOffset = new PIXI.Point();
		},

		calculateDragBounds: function(dx, dy) {
			var bounds = this.displayObject.getBounds();
			return this._dragBounds.set(
				bounds.x + dx,
				bounds.y + dy,
				bounds.width,
				bounds.height
			);
		},

		dragStart: function(data) {
			this.dragOffset = data.getLocalPosition(this.displayObject, this._dragOffset);
			this.dragging = true;
			this.model.set('userControlled', true);
		},

		drag: function(data) {
			if (this.dragging) {
				var dx = data.global.x - this.displayObject.x - this.dragOffset.x;
				var dy = data.global.y - this.displayObject.y - this.dragOffset.y;
				
				var newBounds = this.calculateDragBounds(dx, dy);
				var constraintBounds = this.movementConstraintBounds;

				if (!constraintBounds.contains(newBounds)) {
					var overflowLeft   = constraintBounds.left() - newBounds.left();
					var overflowRight  = newBounds.right() - constraintBounds.right();
					var overflowTop    = constraintBounds.bottom() - newBounds.bottom();
					var overflowBottom = newBounds.top() - constraintBounds.top();

					// Backtrack if we need to
					if (overflowLeft > 0)
						dx += overflowLeft;
					else if (overflowRight > 0)
						dx -= overflowRight;

					if (overflowTop > 0)
						dy += overflowTop;
					else if (overflowBottom > 0)
						dy -= overflowBottom;
				}

				dx = this.mvt.viewToModelDeltaX(dx);
				dy = this.mvt.viewToModelDeltaY(dy);

				this.model.translate(dx, dy);

				this.dragX = data.global.x;
				this.dragY = data.global.y;
			}
		},

		dragEnd: function(data) {
{'fraction_non_alphanumeric': 0.12922868741542626, 'fraction_numerical': 0.006765899864682003, 'mean_word_length': 3.240390131956397, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '7143072', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2292, 'n_words': 474}