<commit_before>/*
 * Copyright 2017 Micro Focus International plc.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'underscore',
    'jquery',
    'd3',
    'find/app/util/global-key-listener',
    'find/idol/app/model/answer-bank/idol-answered-questions-collection',
    'find/idol/app/model/entitysearch/entity-search-collection',
    'find/app/page/search/template-helpers/pretty-print-number-helper',
    'text!find/templates/app/page/loading-spinner.html',
    'i18n!find/nls/bundle'
], function(_, $, d3, globalKeyListener, AnsweredQuestionsCollection, EntitySearchCollection, prettyPrintNumberHelper, loadingSpinnerTemplate, i18n) {
    'use strict';

    const loadingHtml = _.template(loadingSpinnerTemplate)({i18n: i18n, large: false});

    function SelectionEntitySearch(options) {
        const documentRenderer = options.documentRenderer;
        const answerServer = options.answerServer;
        // You can control which elements the popup will appear on by adjusting this selector.
        const selector = options.selector || '.main-results-container,.parametric-value-element,.dt-bootstrap,.trending-chart,.sunburst,.entity-topic-map,.leaflet-popup-content,.document-detail-tabs-content,.entity-search-messages';
        const debounceMillis = options.debounceMillis || 250;
        // The length of time you have to hover over the text in the topic map before we automatically entity-search it.
        const hoverDelay = options.hoverDelay || 1000;
        let element = options.element || document.body;

        const entityModels = new EntitySearchCollection();
        let lastQueryText, lastFetch;

        function loadModel(text, bounds) {
            if (lastFetch && lastQueryText !== text) {
                lastFetch.abort();
            }

            lastQueryText = text;

            const $hover = $('<div class="selection-entity first-appearance">');
            $hover.one('mouseover', function(){
                $hover.removeClass('first-appearance');
            })

            updateIndicator($hover, loadingHtml, bounds, null);

            lastFetch = entityModels.fetch({
                data: { text: text }
            }).done(function(){
                if (text === lastQueryText && entityModels.length) {
                    const result = entityModels.first();
                    const html = documentRenderer.renderEntity(result);

                    $hover.addClass('first-appearance').one('mouseover', function(){
                        $hover.removeClass('first-appearance');
                    })

                    updateIndicator($hover, html, bounds, result.get('title'));
                }
                else {
                    clearIndicator($hover)
                }
            }).fail(function(){
                clearIndicator($hover);
            })
        }

        function clearIndicator($hover) {
            $hover.remove();
        }

        function clearAllIndicators() {
            // We have to clear all selections which were triggered by other selections
            $('.selection-entity').remove();
        }

        function clearClickedIndicator(e) {
            const $closest = $(e.currentTarget).closest('.selection-entity');

            $closest.remove();
        }

        function updateIndicator($hover, html, bounds, context){
            const top = bounds.bottom + 10;
            const left = bounds.left;

            let dragLastX, dragLastY, dragX, dragY, dragging = false;

            function moveElement(evt) {
                if (!dragging) {
                    $hover.addClass('selection-entity-drag');

                    const offset = $hover.offset();
                    dragX = offset.left;
                    dragY = offset.top;
                    dragLastX = evt.pageX;
                    dragLastY = evt.pageY;
                    $hover.css({
                        bottom: 'auto',
                        right: 'auto'
                    })
                }

                dragging = true;

                dragX += evt.pageX - dragLastX;
                dragY += evt.pageY - dragLastY;
                dragLastX = evt.pageX;
                dragLastY = evt.pageY;

                $hover.addClass('selection-entity-drag')
                    .css({
                        left: dragX,
                        top: dragY
                    });
            }

            function onMouseUp() {
                dragging = false;
                $(document)
                    .off('mousemove', moveElement)
                    .off('mouseup', onMouseUp)
            }

            $hover.css({
                top: top,
                left: left
            }).html(html).appendTo(element).on('mousedown', function(evt){
                if ($(evt.target).closest('.entity-search-controls,.entity-search-messages').length) {
                    // Prevent drag start if they're trying to select text in the conversation history.
                    return
                }

                dragLastX = evt.screenX;
                dragLastY = evt.screenY;
                $(document)
                    .on('mousemove', moveElement)
                    .on('mouseup', onMouseUp);
            });

            function reposition(){
                if ($hover.hasClass('selection-entity-drag')) {
                    return;
                }

                if ($hover.height() + top > window.innerHeight) {
                    // If the popup goes below the page, show it above the selection instead of below,<commit_msg>(DEMOS-72, CORE-4439) Fix issue where a load spinner which extended off the bottom of the page wouldn't be replaced with the entity search results under certain conditions (both top and bottom are set, such that the element becomes zero-height).<commit_after>/*
 * Copyright 2017 Micro Focus International plc.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'underscore',
    'jquery',
    'd3',
    'find/app/util/global-key-listener',
    'find/idol/app/model/answer-bank/idol-answered-questions-collection',
    'find/idol/app/model/entitysearch/entity-search-collection',
    'find/app/page/search/template-helpers/pretty-print-number-helper',
    'text!find/templates/app/page/loading-spinner.html',
    'i18n!find/nls/bundle'
], function(_, $, d3, globalKeyListener, AnsweredQuestionsCollection, EntitySearchCollection, prettyPrintNumberHelper, loadingSpinnerTemplate, i18n) {
    'use strict';

    const loadingHtml = _.template(loadingSpinnerTemplate)({i18n: i18n, large: false});

    function SelectionEntitySearch(options) {
        const documentRenderer = options.documentRenderer;
        const answerServer = options.answerServer;
        // You can control which elements the popup will appear on by adjusting this selector.
        const selector = options.selector || '.main-results-container,.parametric-value-element,.dt-bootstrap,.trending-chart,.sunburst,.entity-topic-map,.leaflet-popup-content,.document-detail-tabs-content,.entity-search-messages';
        const debounceMillis = options.debounceMillis || 250;
        // The length of time you have to hover over the text in the topic map before we automatically entity-search it.
        const hoverDelay = options.hoverDelay || 1000;
        let element = options.element || document.body;

        const entityModels = new EntitySearchCollection();
        let lastQueryText, lastFetch;

        function loadModel(text, bounds) {
            if (lastFetch && lastQueryText !== text) {
                lastFetch.abort();
            }

            lastQueryText = text;

            const $hover = $('<div class="selection-entity first-appearance">');
            $hover.one('mouseover', function(){
                $hover.removeClass('first-appearance');
            })

            updateIndicator($hover, loadingHtml, bounds, null);

            lastFetch = entityModels.fetch({
                data: { text: text }
            }).done(function(){
                if (text === lastQueryText && entityModels.length) {
                    const result = entityModels.first();
                    const html = documentRenderer.renderEntity(result);

                    $hover.addClass('first-appearance').one('mouseover', function(){
                        $hover.removeClass('first-appearance');
                    })

                    updateIndicator($hover, html, bounds, result.get('title'));
                }
                else {
                    clearIndicator($hover)
                }
            }).fail(function(){
                clearIndicator($hover);
            })
        }

        function clearIndicator($hover) {
            $hover.remove();
        }

        function clearAllIndicators() {
            // We have to clear all selections which were triggered by other selections
            $('.selection-entity').remove();
        }

        function clearClickedIndicator(e) {
            const $closest = $(e.currentTarget).closest('.selection-entity');

            $closest.remove();
        }

        function updateIndicator($hover, html, bounds, context){
            const top = bounds.bottom + 10;
            const left = bounds.left;

            let dragLastX, dragLastY, dragX, dragY, dragging = false;

            function moveElement(evt) {
                if (!dragging) {
                    $hover.addClass('selection-entity-drag');

                    const offset = $hover.offset();
                    dragX = offset.left;
                    dragY = offset.top;
                    dragLastX = evt.pageX;
                    dragLastY = evt.pageY;
                    $hover.css({
                        bottom: 'auto',
                        right: 'auto'
                    })
                }

                dragging = true;

                dragX += evt.pageX - dragLastX;
                dragY += evt.pageY - dragLastY;
                dragLastX = evt.pageX;
                dragLastY = evt.pageY;

                $hover.addClass('selection-entity-drag')
                    .css({
                        left: dragX,
                        top: dragY
                    });
            }

            function onMouseUp() {
                dragging = false;
                $(document)
                    .off('mousemove', moveElement)
                    .off('mouseup', onMouseUp)
            }

            $hover.css({
                top: top,
                left: left,
                // we have to explicitly clear bottom and right in case we're updating a load spinner which now
                //   contains new content, and it previously had bottom/right set to fit it in the screen.
                bottom: 'auto',
                right: 'auto'
            }).html(html).appendTo(element).on('mousedown', function(evt){
                if ($(evt.target).closest('.entity-search-controls,.entity-search-messages').length) {
                    // Prevent drag start if they're trying to select text in the conversation history.
                    return
                }

                dragLastX = evt.screenX;
                dragLastY = evt.screenY;
                $(document)
                    .on('mousemove', moveElement)
                    .on('mouseup', onMouseUp);
            });

            function reposition(){
                if ($hover.hasClass('selection-entity-drag')) {
                    return;
                }

                if ($hover.height() + top > window.innerHeight) {
                    // If the popup goes below the page, show it above the selection instead of below,
{'fraction_non_alphanumeric': 0.10700389105058365, 'fraction_numerical': 0.004398578920656403, 'mean_word_length': 1.6408309135581862, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '4157858', 'n_tokens_mistral': 3009, 'n_tokens_neox': 2805, 'n_words': 699}