<commit_before>app.directive('component', function($compile, $document, WHITE_BOARD_PROPERTIES, WhiteBoardService,
                                    COMPONENT_PROPERTIES) {
    return {
        restrict: 'EA',
        replace: true,
        templateUrl: 'app/directive/core/component/componentTemplate.html',
        link: function(scope, element, attrs) {

            scope.$watch('component.type', function(componentType) {
                $(element).find('.component').html($compile('<' + componentType + '></' + componentType + '>')(scope));
            });

            /* Drag and drop, resize */

            var wasSelected = false;

            scope.isSelected = function() {

                if (WhiteBoardService.getSelectedComponent() == scope.componentKey) {

                    wasSelected = true;
                    return true;

                } else {

                    if (wasSelected) {
                        scope.isEditMode = false;
                        scope.component.selectedBy = false;
                        wasSelected = false;
                    }

                    return false;
                }
            };

            var startX, startY, startWidth, startHeight, startPageX, startPageY;

            scope.onMouseDownOnElement = function (event) {

                if (!scope.isControlModeEnabled)
                    return;

                startX = event.pageX - scope.component.x;
                startY = event.pageY - scope.component.y;

                startWidth = scope.component.width;
                startHeight = scope.component.height;

                startPageX = event.pageX;
                startPageY = event.pageY;

                var isResizing = false;

                if ($(event.target).hasClass("resizer")) {

                    event.preventDefault();
                    event.stopPropagation();

                    if ($(event.target).hasClass("resizer-width"))
                        scope.isResizingWidth = true;

                    if ($(event.target).hasClass("resizer-height"))
                        scope.isResizingHeight = true;

                    isResizing = true;
                }

                if (!scope.isEditMode) {

                    WhiteBoardService.setSelectedComponent(scope.componentKey);
                    scope.component.selectedBy = scope.currentUserKey;

                    element[0].focus();

                    if (!isResizing) {

                        event.preventDefault();
                        event.stopPropagation();

                        scope.isDragging = true;
                    }
                }

                $document.on('mousemove', onMouseMove);
                $document.on('mouseup', onMouseUp);
            };

            var onMouseMove = function(event) {

                var shouldApply = false;

                if (scope.isDragging) {
                    shouldApply = onMouseDrag(event);
                } else {

                    if (scope.isResizingWidth) {
                        shouldApply = onMouseResizeWidth(event);
                    }

                    if (scope.isResizingHeight) {
                        shouldApply = onMouseResizeHeight(event) || shouldApply;
                    }
                }

                if (shouldApply) {
                    scope.$apply();
                }
            };

            var onMouseResizeWidth = function (event) {

                var width = startWidth + (event.pageX - startPageX);

                if (Math.abs(scope.component.width - width) >= WHITE_BOARD_PROPERTIES.gridWidth) {

                    width = width - width % WHITE_BOARD_PROPERTIES.gridWidth;

                    if (width > COMPONENT_PROPERTIES.minWidth)
                        scope.component.width = width;
                    else
                        scope.component.width = COMPONENT_PROPERTIES.minWidth;

                    return true;
                }

                return false;
            };

            var onMouseResizeHeight = function (event) {

                var height = startHeight + (event.pageY - startPageY);

                if (Math.abs(scope.component.height - height) >= WHITE_BOARD_PROPERTIES.gridWidth) {

                    height = height - height % WHITE_BOARD_PROPERTIES.gridWidth;

                    if (height > COMPONENT_PROPERTIES.minHeight)
                        scope.component.height = height;
                    else
                        scope.component.height = COMPONENT_PROPERTIES.minHeight;

                    return true;
                }

                return false;
            };

            var onMouseDrag = function (event) {

                var y = event.pageY - startY;
                var x = event.pageX - startX;
<commit_msg>Feature: drag component to the limit of the white board to make it scroll<commit_after>app.directive('component', function($compile, $document, WHITE_BOARD_PROPERTIES, WhiteBoardService,
                                    COMPONENT_PROPERTIES, $timeout) {
    return {
        restrict: 'EA',
        replace: true,
        templateUrl: 'app/directive/core/component/componentTemplate.html',
        link: function(scope, element, attrs) {

            scope.$watch('component.type', function(componentType) {
                $(element).find('.component').html($compile('<' + componentType + '></' + componentType + '>')(scope));
            });

            /* Drag and drop, resize */

            var wasSelected = false;

            scope.isSelected = function() {

                if (WhiteBoardService.getSelectedComponent() == scope.componentKey) {

                    wasSelected = true;
                    return true;

                } else {

                    if (wasSelected) {
                        scope.isEditMode = false;
                        scope.component.selectedBy = false;
                        wasSelected = false;
                    }

                    return false;
                }
            };

            var startX, startY, startWidth, startHeight, startPageX, startPageY;

            scope.onMouseDownOnElement = function (event) {

                if (!scope.isControlModeEnabled)
                    return;

                startX = event.pageX - scope.component.x;
                startY = event.pageY - scope.component.y;

                startWidth = scope.component.width;
                startHeight = scope.component.height;

                startPageX = event.pageX;
                startPageY = event.pageY;

                var isResizing = false;

                if ($(event.target).hasClass("resizer")) {

                    event.preventDefault();
                    event.stopPropagation();

                    if ($(event.target).hasClass("resizer-width"))
                        scope.isResizingWidth = true;

                    if ($(event.target).hasClass("resizer-height"))
                        scope.isResizingHeight = true;

                    isResizing = true;
                }

                if (!scope.isEditMode) {

                    WhiteBoardService.setSelectedComponent(scope.componentKey);
                    scope.component.selectedBy = scope.currentUserKey;

                    element[0].focus();

                    if (!isResizing) {

                        event.preventDefault();
                        event.stopPropagation();

                        scope.isDragging = true;
                    }
                }

                $document.on('mousemove', onMouseMove);
                $document.on('mouseup', onMouseUp);
            };

            var onMouseMove = function(event) {

                var shouldApply = false;

                if (scope.isDragging) {
                    shouldApply = onMouseDrag(event);
                } else {

                    if (scope.isResizingWidth) {
                        shouldApply = onMouseResizeWidth(event);
                    }

                    if (scope.isResizingHeight) {
                        shouldApply = onMouseResizeHeight(event) || shouldApply;
                    }
                }

                if (shouldApply) {
                    scope.$apply();
                }
            };

            var onMouseResizeWidth = function (event) {

                var width = startWidth + (event.pageX - startPageX);

                if (Math.abs(scope.component.width - width) >= WHITE_BOARD_PROPERTIES.gridWidth) {

                    width = width - width % WHITE_BOARD_PROPERTIES.gridWidth;

                    if (width > COMPONENT_PROPERTIES.minWidth)
                        scope.component.width = width;
                    else
                        scope.component.width = COMPONENT_PROPERTIES.minWidth;

                    return true;
                }

                return false;
            };

            var onMouseResizeHeight = function (event) {

                var height = startHeight + (event.pageY - startPageY);

                if (Math.abs(scope.component.height - height) >= WHITE_BOARD_PROPERTIES.gridWidth) {

                    height = height - height % WHITE_BOARD_PROPERTIES.gridWidth;

                    if (height > COMPONENT_PROPERTIES.minHeight)
                        scope.component.height = height;
                    else
                        scope.component.height = COMPONENT_PROPERTIES.minHeight;

                    return true;
                }

                return false;
            };

            var lastTimeoutScrollLeft = false, lastTimeoutScrollTop = false;

            var scrollLeft = function(negativeScroll) {

                scope.component.x = negativeScroll ? scope.component.x - 50 : scope.component.x + 50;

                if (scope.component.x < 0) {
                    scope.component.x = 0;
                    return;
                }

                $("body").scrollLeft(negativeScroll ? $("body").scrollLeft() - 50 : $("body").scrollLeft() + 50);

                lastTimeoutScrollLeft = $timeout(function () {
                    if (scope.isDragging) {
                        scrollLeft(negativeScroll);
                    }
                }, 100);
            };

            var scrollTop = function(negativeScroll) {

                scope.component.y = negativeScroll ? scope.component.y - 50 : scope.component.y + 50;

                if (scope.component.y < 0) {
                    scope.component.y = 0;
                    return;
                }

                $("body").scrollTop(negativeScroll ? $("body").scrollTop() - 50 : $("body").scrollTop() + 50);

                lastTimeoutScrollTop = $timeout(function () {
                    if (scope.isDragging) {
                        scrollTop(negativeScroll);
                    }
                }, 100);
            };

            var clearScrollTimeouts = function() {

                if (lastTimeoutScrollLeft) {
                    $timeout.cancel(lastTimeoutScrollLeft);
                }

                if (lastTimeoutScrollTop) {
                    $timeout.cancel(lastTimeoutScrollTop);
                }
            };

            var onMouseDrag = function (event) {

                clearScrollTimeouts();

                if  ((event.clientX + 50) >= $(window).width()) {

                    scrollLeft(false);

                } else if ((event.clientX - 50) <= 0) {

                    scrollLeft(true);
                }

                if  ((event.clientY + 50) >= $(window).height()) {

                    scrollTop(false);

                } else if ((event.clientY - 50) <= 0) {

                    scrollTop(true);
                }

                var y = event.pageY - startY;
                var x = event.pageX - startX;

{'fraction_non_alphanumeric': 0.09440972808647188, 'fraction_numerical': 0.003208917412599223, 'mean_word_length': 1.184249354481741, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3830143', 'n_tokens_mistral': 3014, 'n_tokens_neox': 2667, 'n_words': 509}