<commit_before>/*jslint    browser:    true,
            indent:     4,
            confusion:  true */
/*global    jQuery, ich */

/**
 * jQuery Custom Autocomplete 0.1
 *
 * Copyright (c) 2011, <NAME>
 * All rights reserved.
 *
 * Licensed under the New BSD License
 * See: http://www.opensource.org/licenses/bsd-license.php
 */
(function ($) {

    'use strict';

    // Add cache to avoid repeated duplicate Ajax calls
    var cache = {};

    $.fn.customAutocomplete = function (opts) {
        var options = $.extend({}, $.fn.customAutocomplete.defaults, opts),
            keycodes = $.fn.customAutocomplete.keycodes,
            context = $(this),
            textbox = context.find(options.textbox),
            formActions = context.find(options.formActions),
            suggestionList = context.find(options.suggestionList),
            inputList = context.find(options.inputList),
            newInputList = context.find(options.newInputList),
            inputs = inputList.add(newInputList).find(options.inputs),
            newInputTextbox = newInputList.find(options.newInputTextbox),
            expiredList = context.find(options.expiredList),
            placeholder = textbox.attr('placeholder'),
            url = options.url,
            prefix = options.prefix,
            newInputCounter = 1,
            newSuggestions,
            filteredSuggestions,
            typedText,

            // Removes (faked) placeholder text from textbox
            removeFakePlaceholder = function () {
                if (textbox.val().indexOf(placeholder) !== -1) {
                    textbox.val(null);
                }
                textbox.removeClass('placeholder');
            },

            // Checks if any inputs have changed from original-state,
            // showing form-actions and adding ``.expired`` if any inputs have changed.
            updateFormActions = function () {
                if (inputs.filter(function () { return $(this).data('state') === 'changed'; }).length) {
                    expiredList.addClass('expired');
                    if (options.hideFormActions) {
                        formActions.fadeIn('fast');
                    }
                } else {
                    expiredList.removeClass('expired');
                    if (options.hideFormActions) {
                        formActions.fadeOut('fast');
                    }
                }

                if (options.noInputsNote) {
                    var noInputsNote = ich.autocomplete_no_inputs();
                    inputList.add(newInputList).each(function () {
                        if ($(this).find(options.inputs).length) {
                            $(this).find('.none').remove();
                        } else {
                            if ($(this).children('ul').length) {
                                $(this).children('ul').append(noInputsNote);
                            } else {
                                $(this).append(noInputsNote);
                            }
                        }
                    });
                }
            },

            // Used if there are specific restrictions on new inputs
            passRestrictedNewInputs = function (thisGroup, newInputName) {
                // If the group already has selected inputs...
                if (thisGroup.find(options.inputs + ':checked').length) {
                    // ...and if *all* of the selected inputs begin with "^" and ends with "$"...
                    if (thisGroup.find(options.inputs + '[value^="^"][value$="$"]:checked').length === thisGroup.find(options.inputs + ':checked').length
                            // ...and if the typed-text hasn't already been selected as an input, and if the typed-text begins with "^" and ends with "$"...
                            && !(thisGroup.find(options.inputs + '[value="' + newInputName.toString().toLowerCase() + '"]:checked').length)
                            && newInputName.indexOf('^') === 0
                            && newInputName.lastIndexOf('$') === newInputName.length - 1) {
                        // ...then append the new suggestion to the suggestion-list.
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            },

            // Filter autocomplete suggestions, returning those that aren't duplicates.
            filterSuggestions = function () {
                filteredSuggestions = newSuggestions.filter(function () {
                    var thisSuggestionID = $(this).find('a').data('id'),
                        thisSuggestionName = $(this).find('a').data('name'),
                        thisSuggestionType = $(this).find('a').data('type');
                    if (thisSuggestionName && !options.caseSensitive) { thisSuggestionName = thisSuggestionName.toString().toLowerCase(); }
                    if ($(this).find('a').hasClass('new')) {
                        if (inputs.filter('[id^="id-' + prefix + '-' + thisSuggestionType + '-"]:checked').filter(function () { return $(this).siblings('label').text() === thisSuggestionName; }).length
                                || inputs.filter('[id^="id-' + prefix + '-new' + thisSuggestionType + '-"]:checked').filter(function () { return $(this).siblings('label').text() === thisSuggestionName; }).length
                                || newSuggestions.find('a:not(.new)').filter(function () { return $(this).data('name') === thisSuggestionName && $(this).data('type') === thisSuggestionType; }).length) {
                            return false;
                        } else {
                            return true;
                        }
                    } else {
                        if (inputs.filter('[id^="id-' + prefix + '-' + thisSuggestionType + '-"][value="' + thisSuggestionID + '"]:checked').length) {
                            return false;
                        } else {
                            return true;
                        }
                    }
                });
            },

            // Create list of autocomplete suggestions from Ajax response or existing list of inputs
            updateSuggestions = function (data, cached) {
                if (!data && !options.ajax) {
                    var suggestions;
                    if (options.caseSensitive) {
                        suggestions = inputList.find(options.inputs).not(':disabled').parent('li').filter(function () {
                            return $(this).children('label').text().indexOf(typedText) !== -1;
                        });
                    } else {
                        suggestions = inputList.find(options.inputs).not(':disabled').parent('li').filter(function () {
                            return $(this).children('label').text().toLowerCase().indexOf(typedText.toLowerCase()) !== -1;
                        });
                    }
                    data = {};
                    data.suggestions = [];
                    suggestions.each(function () {
                        var typedIndex,
                            thisSuggestion = {};
                        if (options.caseSensitive) {
                            typedIndex = $(this).children('label').text().indexOf(typedText);
                        } else {
                            typedIndex = $(this).children('label').text().toLowerCase().indexOf(typedText.toLowerCase());
                        }
                        thisSuggestion.typedText = typedText;
                        thisSuggestion.name = $(this).children('label').text();
                        thisSuggestion.preText = $(this).children('label').text().substring(0, typedIndex);
                        thisSuggestion.postText = $(this).children('label').text().substring(typedIndex + typedText.length);
                        thisSuggestion.id = $(this).children('input').attr('value');
                        if (options.multipleCategories) {
                            thisSuggestion.type = $(this).children('input').data('name');
                            if ($(this).closest(options.inputList).find('.category-title').length) {
                                thisSuggestion.displayType = $(this).closest(options.inputList).find('.category-title').text();
                            }
                        }
                        data.suggestions.push(thisSuggestion);
                    });
                }

                if (options.allowNew && !cached) {
                    if (!(options.restrictAllowNew && textbox.data('allow-new') !== true)) {
                        newInputList.each(function () {
                            var thisSuggestion = {};
                            thisSuggestion.typedText = typedText;
                            thisSuggestion.name = typedText;
                            thisSuggestion.id = typedText;
                            thisSuggestion.newSuggestion = true;
                            if (options.multipleCategories) {
                                thisSuggestion.type = $(this).data('name');
                                if ($(this).find('.category-title').length) {
                                    thisSuggestion.displayType = $(this).find('.category-title').text();
                                }
                            } else {
                                thisSuggestion.type = options.inputType;
                            }

                            if (options.restrictNewInputs) {
                                if (passRestrictedNewInputs($(this), typedText)) {
                                    data.suggestions.unshift(thisSuggestion);
                                }
                            } else {
                                data.suggestions.unshift(thisSuggestion);
                            }
                        });
                    }
                }

                newSuggestions = ich.autocomplete_suggestion(data);
                filterSuggestions();
                suggestionList.html(filteredSuggestions);

                // Show suggestion list if it contains suggestions; otherwise, hide it.
                if (suggestionList.find('li').length) {
                    suggestionList.show();
                } else {
                    suggestionList.hide();
                }

                // Adds ".selected" to first autocomplete suggestion.
                if (!(suggestionList.find('.selected').length)) {
                    suggestionList.find('li:first-child a').addClass('selected');
                }
            };

        suggestionList.hide();

        if (options.hideFormActions) {
            formActions.hide();
        }

        if (options.fakePlaceholder) {
            textbox.addClass('placeholder');
        }

        if (!options.multipleCategories && options.newInputList === null) {
            newInputList = context.find(options.inputList);
            newInputTextbox = newInputList.find(options.newInputTextbox);
            options.newInputList = options.inputList;
        }

        if (!expiredList.length) {
            expiredList = $(options.expiredList);
        }

        // Set data-originallyChecked on each input to store original state
        inputs.each(function () {
            $(this).data('originallyChecked', $(this).is(':checked'));
        });

        // Reset button sets each input to its original state, hides form-actions
        // and suggestion-list, and returns focus to the textbox.
        formActions.find(options.reset).click(function (e) {
            e.preventDefault();
            if (options.hideFormActions) {
                formActions.fadeOut('fast');
            }
            expiredList.removeClass('expired');
            inputs.each(function () {
                $(this).removeData('state');
                $(this).prop('checked', $(this).data('originallyChecked')).change();
            });
            textbox.focus();
            suggestionList.hide();
        });

        // Selecting/unselecting an input returns focus to textbox, hides
        // suggestion-list, sets data-state "changed" if input has changed from
        // original state, and shows/hides form-actions as appropriate.
        if (options.inputsNeverRemoved) {
            inputList.add(newInputList).on('change', options.inputs, function () {
                if ($(this).data('originallyChecked') !== $(this).is(':checked')) {
                    $(this).data('state', 'changed');
                } else {
                    $(this).removeData('state');
                }
                textbox.focus();
                suggestionList.hide();
                updateFormActions();
            });
        }

        // If there are any new inputs already selected, prevent a new input from being selected
        // unless it and all new inputs begin with ^ and end with $.
        if (options.restrictNewInputs && options.inputsNeverRemoved) {
            newInputList.on('click', options.inputs + ':not(:checked) + label', function (e) {
                var thisGroup = $(this).closest(options.newInputList),
                    thisInputName = $(this).text();
                if (!passRestrictedNewInputs(thisGroup, thisInputName)) {
                    textbox.focus();
                    e.preventDefault();
                }
            });
        }

        textbox
            .keyup(function (e) {
                // Updates suggestion-list if typed-text has changed
                var updateSuggestionList = function () {
                    if (textbox.val() !== typedText && textbox.val() !== placeholder) {
                        typedText = textbox.val();
                        if (typedText.length) {
                            if (options.ajax) {
                                if (cache[typedText]) {
                                    updateSuggestions(cache[typedText], true);
                                } else {
                                    $.get(options.url, {text: typedText}, function (response) {
                                        cache[typedText] = response;
                                        updateSuggestions(response, false);
                                    });
                                }
                            } else {
                                updateSuggestions();
                            }<commit_msg>jquery.custom-autocomplete text cannot contain only spaces.<commit_after>/*jslint    browser:    true,
            indent:     4,
            confusion:  true */
/*global    jQuery, ich */

/**
 * jQuery Custom Autocomplete 0.1
 *
 * Copyright (c) 2011, <NAME>
 * All rights reserved.
 *
 * Licensed under the New BSD License
 * See: http://www.opensource.org/licenses/bsd-license.php
 */
(function ($) {

    'use strict';

    // Add cache to avoid repeated duplicate Ajax calls
    var cache = {};

    $.fn.customAutocomplete = function (opts) {
        var options = $.extend({}, $.fn.customAutocomplete.defaults, opts),
            keycodes = $.fn.customAutocomplete.keycodes,
            context = $(this),
            textbox = context.find(options.textbox),
            formActions = context.find(options.formActions),
            suggestionList = context.find(options.suggestionList),
            inputList = context.find(options.inputList),
            newInputList = context.find(options.newInputList),
            inputs = inputList.add(newInputList).find(options.inputs),
            newInputTextbox = newInputList.find(options.newInputTextbox),
            expiredList = context.find(options.expiredList),
            placeholder = textbox.attr('placeholder'),
            url = options.url,
            prefix = options.prefix,
            newInputCounter = 1,
            newSuggestions,
            filteredSuggestions,
            typedText,

            // Removes (faked) placeholder text from textbox
            removeFakePlaceholder = function () {
                if (textbox.val().indexOf(placeholder) !== -1) {
                    textbox.val(null);
                }
                textbox.removeClass('placeholder');
            },

            // Checks if any inputs have changed from original-state,
            // showing form-actions and adding ``.expired`` if any inputs have changed.
            updateFormActions = function () {
                if (inputs.filter(function () { return $(this).data('state') === 'changed'; }).length) {
                    expiredList.addClass('expired');
                    if (options.hideFormActions) {
                        formActions.fadeIn('fast');
                    }
                } else {
                    expiredList.removeClass('expired');
                    if (options.hideFormActions) {
                        formActions.fadeOut('fast');
                    }
                }

                if (options.noInputsNote) {
                    var noInputsNote = ich.autocomplete_no_inputs();
                    inputList.add(newInputList).each(function () {
                        if ($(this).find(options.inputs).length) {
                            $(this).find('.none').remove();
                        } else {
                            if ($(this).children('ul').length) {
                                $(this).children('ul').append(noInputsNote);
                            } else {
                                $(this).append(noInputsNote);
                            }
                        }
                    });
                }
            },

            // Used if there are specific restrictions on new inputs
            passRestrictedNewInputs = function (thisGroup, newInputName) {
                // If the group already has selected inputs...
                if (thisGroup.find(options.inputs + ':checked').length) {
                    // ...and if *all* of the selected inputs begin with "^" and ends with "$"...
                    if (thisGroup.find(options.inputs + '[value^="^"][value$="$"]:checked').length === thisGroup.find(options.inputs + ':checked').length
                            // ...and if the typed-text hasn't already been selected as an input, and if the typed-text begins with "^" and ends with "$"...
                            && !(thisGroup.find(options.inputs + '[value="' + newInputName.toString().toLowerCase() + '"]:checked').length)
                            && newInputName.indexOf('^') === 0
                            && newInputName.lastIndexOf('$') === newInputName.length - 1) {
                        // ...then append the new suggestion to the suggestion-list.
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            },

            // Filter autocomplete suggestions, returning those that aren't duplicates.
            filterSuggestions = function () {
                filteredSuggestions = newSuggestions.filter(function () {
                    var thisSuggestionID = $(this).find('a').data('id'),
                        thisSuggestionName = $(this).find('a').data('name'),
                        thisSuggestionType = $(this).find('a').data('type');
                    if (thisSuggestionName && !options.caseSensitive) { thisSuggestionName = thisSuggestionName.toString().toLowerCase(); }
                    if ($(this).find('a').hasClass('new')) {
                        if (inputs.filter('[id^="id-' + prefix + '-' + thisSuggestionType + '-"]:checked').filter(function () { return $(this).siblings('label').text() === thisSuggestionName; }).length
                                || inputs.filter('[id^="id-' + prefix + '-new' + thisSuggestionType + '-"]:checked').filter(function () { return $(this).siblings('label').text() === thisSuggestionName; }).length
                                || newSuggestions.find('a:not(.new)').filter(function () { return $(this).data('name') === thisSuggestionName && $(this).data('type') === thisSuggestionType; }).length) {
                            return false;
                        } else {
                            return true;
                        }
                    } else {
                        if (inputs.filter('[id^="id-' + prefix + '-' + thisSuggestionType + '-"][value="' + thisSuggestionID + '"]:checked').length) {
                            return false;
                        } else {
                            return true;
                        }
                    }
                });
            },

            // Create list of autocomplete suggestions from Ajax response or existing list of inputs
            updateSuggestions = function (data, cached) {
                if (!data && !options.ajax) {
                    var suggestions;
                    if (options.caseSensitive) {
                        suggestions = inputList.find(options.inputs).not(':disabled').parent('li').filter(function () {
                            return $(this).children('label').text().indexOf(typedText) !== -1;
                        });
                    } else {
                        suggestions = inputList.find(options.inputs).not(':disabled').parent('li').filter(function () {
                            return $(this).children('label').text().toLowerCase().indexOf(typedText.toLowerCase()) !== -1;
                        });
                    }
                    data = {};
                    data.suggestions = [];
                    suggestions.each(function () {
                        var typedIndex,
                            thisSuggestion = {};
                        if (options.caseSensitive) {
                            typedIndex = $(this).children('label').text().indexOf(typedText);
                        } else {
                            typedIndex = $(this).children('label').text().toLowerCase().indexOf(typedText.toLowerCase());
                        }
                        thisSuggestion.typedText = typedText;
                        thisSuggestion.name = $(this).children('label').text();
                        thisSuggestion.preText = $(this).children('label').text().substring(0, typedIndex);
                        thisSuggestion.postText = $(this).children('label').text().substring(typedIndex + typedText.length);
                        thisSuggestion.id = $(this).children('input').attr('value');
                        if (options.multipleCategories) {
                            thisSuggestion.type = $(this).children('input').data('name');
                            if ($(this).closest(options.inputList).find('.category-title').length) {
                                thisSuggestion.displayType = $(this).closest(options.inputList).find('.category-title').text();
                            }
                        }
                        data.suggestions.push(thisSuggestion);
                    });
                }

                if (options.allowNew && !cached) {
                    if (!(options.restrictAllowNew && textbox.data('allow-new') !== true)) {
                        newInputList.each(function () {
                            var thisSuggestion = {};
                            thisSuggestion.typedText = typedText;
                            thisSuggestion.name = typedText;
                            thisSuggestion.id = typedText;
                            thisSuggestion.newSuggestion = true;
                            if (options.multipleCategories) {
                                thisSuggestion.type = $(this).data('name');
                                if ($(this).find('.category-title').length) {
                                    thisSuggestion.displayType = $(this).find('.category-title').text();
                                }
                            } else {
                                thisSuggestion.type = options.inputType;
                            }

                            if (options.restrictNewInputs) {
                                if (passRestrictedNewInputs($(this), typedText)) {
                                    data.suggestions.unshift(thisSuggestion);
                                }
                            } else {
                                data.suggestions.unshift(thisSuggestion);
                            }
                        });
                    }
                }

                newSuggestions = ich.autocomplete_suggestion(data);
                filterSuggestions();
                suggestionList.html(filteredSuggestions);

                // Show suggestion list if it contains suggestions; otherwise, hide it.
                if (suggestionList.find('li').length) {
                    suggestionList.show();
                } else {
                    suggestionList.hide();
                }

                // Adds ".selected" to first autocomplete suggestion.
                if (!(suggestionList.find('.selected').length)) {
                    suggestionList.find('li:first-child a').addClass('selected');
                }
            };

        suggestionList.hide();

        if (options.hideFormActions) {
            formActions.hide();
        }

        if (options.fakePlaceholder) {
            textbox.addClass('placeholder');
        }

        if (!options.multipleCategories && options.newInputList === null) {
            newInputList = context.find(options.inputList);
            newInputTextbox = newInputList.find(options.newInputTextbox);
            options.newInputList = options.inputList;
        }

        if (!expiredList.length) {
            expiredList = $(options.expiredList);
        }

        // Set data-originallyChecked on each input to store original state
        inputs.each(function () {
            $(this).data('originallyChecked', $(this).is(':checked'));
        });

        // Reset button sets each input to its original state, hides form-actions
        // and suggestion-list, and returns focus to the textbox.
        formActions.find(options.reset).click(function (e) {
            e.preventDefault();
            if (options.hideFormActions) {
                formActions.fadeOut('fast');
            }
            expiredList.removeClass('expired');
            inputs.each(function () {
                $(this).removeData('state');
                $(this).prop('checked', $(this).data('originallyChecked')).change();
            });
            textbox.focus();
            suggestionList.hide();
        });

        // Selecting/unselecting an input returns focus to textbox, hides
        // suggestion-list, sets data-state "changed" if input has changed from
        // original state, and shows/hides form-actions as appropriate.
        if (options.inputsNeverRemoved) {
            inputList.add(newInputList).on('change', options.inputs, function () {
                if ($(this).data('originallyChecked') !== $(this).is(':checked')) {
                    $(this).data('state', 'changed');
                } else {
                    $(this).removeData('state');
                }
                textbox.focus();
                suggestionList.hide();
                updateFormActions();
            });
        }

        // If there are any new inputs already selected, prevent a new input from being selected
        // unless it and all new inputs begin with ^ and end with $.
        if (options.restrictNewInputs && options.inputsNeverRemoved) {
            newInputList.on('click', options.inputs + ':not(:checked) + label', function (e) {
                var thisGroup = $(this).closest(options.newInputList),
                    thisInputName = $(this).text();
                if (!passRestrictedNewInputs(thisGroup, thisInputName)) {
                    textbox.focus();
                    e.preventDefault();
                }
            });
        }

        textbox
            .keyup(function (e) {
                // Updates suggestion-list if typed-text has changed
                var updateSuggestionList = function () {
                    if (textbox.val() !== typedText && textbox.val() !== placeholder) {
                        typedText = textbox.val();
                        if (typedText.length && typedText.trim() !== '') {
                            if (options.ajax) {
                                if (cache[typedText]) {
                                    updateSuggestions(cache[typedText], true);
                                } else {
                                    $.get(options.url, {text: typedText}, function (response) {
                                        cache[typedText] = response;
                                        updateSuggestions(response, false);
                                    });
                                }
                            } else {
                                updateSuggestions();
                            }
{'fraction_non_alphanumeric': 0.12153503512078122, 'fraction_numerical': 0.0009593969504882645, 'mean_word_length': 1.309749920861032, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1444884', 'n_tokens_mistral': 6905, 'n_tokens_neox': 6440, 'n_words': 1249}