<commit_before>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([ 'module', 'angular' ], function (module, angular) {
            module.exports = factory(angular);
        });
    } else if (typeof module === 'object') {
        module.exports = factory(require('angular'));
    } else {
        if (!root.mp) {
            root.mp = {};
        }

        root.mp.autocomplete = factory(root.angular);
    }
}(this, function (angular) {
    'use strict';

    return angular.module('mp.autocomplete', []).directive('autocomplete', [ '$window', function ($window) {
        // Introduce custom elements for IE8
        $window.document.createElement('autocomplete');

        var tmpl = '' +
            '<div class="angular-autocomplete">' +
            '   <span ng-repeat="item in items">{{ item }}</span>' +
            '   <span ng-if="items.length == 0">{{ noResultsText }}</span>' +
            '</div>';

        return {
            restrict: 'AE',
            template: tmpl,
            replace: true,
            require: '?ngModel',
            scope: {
                dataSource: '@',
                template: '@',
                parser: '&',
                noResultsText: '@',
                debounce: '@'
            },

            link: function ($scope, $element, $attributes, ngModel) {
                // Init values.
                if (!!$scope.noResultsText) {
                    $scope.noResultsText = 'No results';
                }
                $scope.items = ['hello', 'world'];

                // Add the search handler.
            }
        };
    }]);
}));
<commit_msg>Update directive to be an attribute directive on an input field<commit_after>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([ 'module', 'angular' ], function (module, angular) {
            module.exports = factory(angular);
        });
    } else if (typeof module === 'object') {
        module.exports = factory(require('angular'));
    } else {
        if (!root.mp) {
            root.mp = {};
        }

        root.mp.autocomplete = factory(root.angular);
    }
}(this, function (angular) {
    'use strict';

    return angular.module('mp.autocomplete', []).directive('autocomplete', [
        '$window', '$q', '$compile', '$parse', '$timeout',
        function($window, $q, $compile, $parse, $timeout) {
            var TEMPLATE = '' +
                '<ul class="angular-autocomplete" ng-if="isOpen()">' +
                '   <li ng-repeat="match in matches" ' +
                '      ng-class="{ selected: selectedIndex == $index }" ' +
                '      ng-click="select($index)">{{ match }}</li>' +
                '</ul>';

            var HOT_KEYS = [9, 13, 27, 38, 40];

            return {
                restrict: 'A',
                require: 'ngModel',
                link: function (originalScope, $element, $attributes, ngModel) {
                    // model setter executed upon match selection
                    var $setModelValue = $parse($attributes.ngModel).assign;

                    // suggestion fetch function
                    var fetchSuggestions = originalScope.$eval($attributes.autocomplete);

                    // create a child scope for the directive so that we are not
                    // polluting original scope with matches, query etc.
                    var $scope = originalScope.$new();
                    originalScope.$on('$destroy', function () {
                        $scope.$destroy();
                    });

                    var resetMatches = function () {
                        $scope.matches = [];
                        $scope.selectedIndex = -1;
                    };

                    $scope.isOpen = function () {
                        return $scope.matches.length > 0;
                    };

                    $scope.select = function (selectedIndex) {
                        //called from within the $digest() cycle
                        $setModelValue(originalScope, $scope.matches[selectedIndex]);
                        resetMatches();

                        // @todo Notify observer of selection

                        //return focus to the input element if a match was selected via a mouse click event
                        // use timeout to avoid $rootScope:inprog error
                        $timeout(function () {
                            $element[0].focus();
                        }, 0, false);
                    };

                    $scope.selectNext = function () {
                        $scope.selectedIndex = ($scope.selectedIndex + 1) % $scope.matches.length;
                    };

                    $scope.selectPrev = function () {
                        $scope.selectedIndex = ($scope.selectedIndex > 0
                                                ? $scope.selectedIndex
                                                : $scope.matches.length) - 1;
                    };

                    // 0. Initialize to empty state
                    resetMatches();

                    // 1. Watch model for changes
                    ngModel.$parsers.unshift(function (inputValue) {
                        // @todo: add debouncing
                        // 2. Fetch suggestions
                        fetchSuggestions(inputValue).then(function (suggestions) {
                            // 3. Present suggestions
                            $scope.matches = suggestions;
                        });
                    });

                    // 4. Handle mouse selection or keypresses
                    $element.bind('keydown', function (evt) {
                        // we have matches and an "interesting" key was pressed
                        if ($scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
                            return;
                        }

                        // if there's nothing selected and enter/tab is hit, don't do anything
                        if ($scope.selectedIndex == -1 && (evt.which === 13 || evt.which === 9)) {
                            return;
                        }

                        evt.preventDefault();

                        $scope.$apply(function () {
                            if (evt.which === 40) { // Down Arrow
                                $scope.selectNext();
                            } else if (evt.which === 38) { // Up Arrow
                                $scope.selectPrev();
                            } else if (evt.which === 13 || evt.which === 9) { // Enter or Tab
                                $scope.select($scope.selectedIndex);
                            } else if (evt.which === 27) { // Esc
                                // 6. Handle cancelling of the dialog
                                resetMatches();
                                evt.stopPropagation();
                            }
                        });
                    }).bind('blur', function () {
                        // Close the autocomplete dialog when the element loses focus
                        $scope.$apply(function () {
                            resetMatches();
                        });
                    });

                    var $template = $compile(TEMPLATE)($scope);
                    $element.after($template);
                }
            };
        }
    ]);
}));
{'fraction_non_alphanumeric': 0.12392818863879958, 'fraction_numerical': 0.00522508038585209, 'mean_word_length': 1.1231513083048918, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '478130', 'n_tokens_mistral': 1816, 'n_tokens_neox': 1656, 'n_words': 421}