<commit_before><?php echo $this->element('EventReports/markdownViewerHelpModal') ?>

<div id="mardown-viewer-toolbar" class="btn-toolbar">
    <div class="btn-group">
        <button type="button" class="btn" data-togglemode="editor" onclick="setMode('editor')">
            <i class="<?= $this->FontAwesome->getClass('edit') ?> fa-edit"></i>
            <?= __('Edit') ?>
        </button>
        <button type="button" class="btn" data-togglemode="splitscreen" onclick="setMode('splitscreen')">
            <i class="<?= $this->FontAwesome->getClass('columns') ?> fa-columns"></i>
            <?= __('Split Screen') ?>
        </button>
        <button type="button" class="btn btn-inverse" data-togglemode="viewer" onclick="setMode('viewer')">
            <i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i>
            <?= __('Markdown') ?>
        </button>
        <button type="button" class="btn" data-togglemode="raw" onclick="setMode('raw')">
            <i class="<?= $this->FontAwesome->getClass('code') ?> fa-code"></i>
            <?= __('Raw') ?>
        </button>
    </div>
    <div class="btn-group">
        <button id="saveMarkdownButton" type="button" class="btn btn-primary" onclick="saveMarkdown()">
            <i class="<?= $this->FontAwesome->getClass('save') ?> fa-save"></i>
            <?= __('Save') ?>
        </button>
        <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            <li class="dropdown-submenu">
                <a tabindex="-1" href="#">
                    <span class="icon"><i class="<?= $this->FontAwesome->getClass('download') ?> fa-download"></i></span>
                    <?= __('Downloads') ?>
                </a>
                <ul class="dropdown-menu">
                    <li><a tabindex="-1" href="#" onclick="downloadMarkdown('pdf')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('file-pdf') ?> fa-file-pdf"></i></span>
                        <?= __('Download PDF (via print)') ?>
                    </a></li>
                    <li><a tabindex="-1" href="#" onclick="downloadMarkdown('text')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i></span>
                        <?= __('Download Markdown') ?>
                    </a></li>
                    <li><a tabindex="-1" href="#" title="<?= __('Replace custom syntax by a valid one') ?>" onclick="downloadMarkdown('text-gfm')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i></span>
                        <?= __('Download GFM simplified format') ?>
                    </a></li>
                </ul>
            </li>
        </ul>
    </div>
    <button type="button" class="btn btn-primary" onclick="showHelp()">
        <i class="<?= $this->FontAwesome->getClass('question-circle') ?> fa-question-circle"></i>
        <?= __('Help') ?>
    </button>
</div>

<div class="raw-container">
    <pre id="raw"><?php echo h($markdown) ?></pre>
</div>
<div class="split-container">
    <div id="editor-container">
        <div id="editor-subcontainer">
            <div id="top-bar" class="editor-action-bar">
                <span class="<?= $this->FontAwesome->getClass('bold') ?> useCursorPointer icon" onclick="replacementAction('bold')"></span>
                <span class="<?= $this->FontAwesome->getClass('italic') ?> useCursorPointer icon" onclick="replacementAction('italic')"></span>
                <span class="<?= $this->FontAwesome->getClass('heading') ?> useCursorPointer icon" onclick="replacementAction('heading')"></span>
                <span class="<?= $this->FontAwesome->getClass('strikethrough') ?> useCursorPointer icon" onclick="replacementAction('strikethrough')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('list-ul') ?> useCursorPointer icon" onclick="replacementAction('list-ul')"></span>
                <span class="<?= $this->FontAwesome->getClass('list-ol') ?> useCursorPointer icon" onclick="replacementAction('list-ol')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('quote-left') ?> useCursorPointer icon" onclick="replacementAction('quote')"></span>
                <span class="<?= $this->FontAwesome->getClass('code') ?> useCursorPointer icon" onclick="replacementAction('code')"></span>
                <span class="<?= $this->FontAwesome->getClass('table') ?> useCursorPointer icon" onclick="replacementAction('table')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('cube') ?> useCursorPointer icon" onclick="replacementAction('attribute')"></span>
                <span class="<?= $this->FontAwesome->getClass('cubes') ?> useCursorPointer icon" onclick="replacementAction('object')"></span>
            </div>
            <textarea id="editor"></textarea>
            <div id="bottom-bar" class="editor-action-bar">
                <span id="lastModifiedField">
                    <?= isset($lastModified) ? h($lastModified) : '' ?>
                </span>
                <span>
                </span>
            </div>
        </div>
        <div id="resizable-handle" class="ui-resizable-handle ui-resizable-e"></div>
    </div>
    <div id="viewer-container">
        <div id="viewer"></div>
    </div>
</div>

<?php
    echo $this->element('genericElements/assetLoader', array(
        'js' => array(
            'doT',
            'markdown-it',
            'highlight.min',
            'FileSaver',
            'codemirror/codemirror',
            'codemirror/modes/markdown',
            'codemirror/addons/simplescrollbars',
            'codemirror/addons/show-hint',
        ),
        'css' => array(
            'highlight.min',
            'codemirror',
            'codemirror/simplescrollbars',
            'codemirror/show-hint',
        )
    ));

    // - Add help
    // - Add toggle button for autocomplete
    // - Add last modified timestamp & time since last edit
    // - Add Picker for elements [correlation/eventGraph picture/tags/galaxyMatrix]
?>
<script>
    'use strict';
    var md, cm;
    var originalRaw = <?= json_encode(is_array($markdown) ? $markdown : array($markdown), JSON_HEX_TAG); ?>[0];
    var proxyMISPElements = <?= json_encode(is_array($proxyMISPElements) ? $proxyMISPElements : array($proxyMISPElements), JSON_HEX_TAG); ?>;
    var MISPElementValues = [], MISPElementTypes = [], MISPElementIDs = []
    var modelName = '<?= h($modelName) ?>';
    var mardownModelFieldName = '<?= h($mardownModelFieldName) ?>';
    var debounceDelay = 50;
    var renderTimer, scrollTimer;
    var scrollMap;
    var $splitContainer, $editorContainer, $rawContainer, $viewerContainer, $resizableHandle
    var $editor, $viewer, $raw
    var $saveMarkdownButton, $mardownViewerToolbar
    var loadingSpanAnimation = '<span id="loadingSpan" class="fa fa-spin fa-spinner" style="margin-left: 5px;"></span>';
    var dotTemplateAttribute = doT.template("<span class=\"misp-element-wrapper attribute\" data-scope=\"{{=it.scope}}\" data-elementid=\"{{=it.elementid}}\"><span class=\"bold\">{{=it.type}}<span class=\"blue\"> {{=it.value}}</span></span></span>");
    var dotTemplateObject = doT.template("<span class=\"misp-element-wrapper object\" data-scope=\"{{=it.scope}}\" data-elementid=\"{{=it.elementid}}\"><span class=\"bold\">{{=it.type}}<span class=\"\"> {{=it.value}}</span></span></span>");
    var dotTemplateInvalid = doT.template("<span class=\"misp-element-wrapper invalid\"><span class=\"bold red\">{{=it.scope}}<span class=\"blue\"> ({{=it.id}})</span></span></span>");

    var contentChanged = false
    var defaultMode = 'viewer'
    var currentMode
    var splitEdit = true
    var noEditorScroll = false // Necessary as onscroll cannot be unbound from CM
    $(document).ready(function() {
        $splitContainer = $('.split-container')
        $editorContainer = $('#editor-container')
        $viewerContainer = $('#viewer-container')
        $rawContainer = $('div.raw-container')
        $resizableHandle = $('#resizable-handle')
        $editor = $('#editor')
        $viewer = $('#viewer')
        $raw = $('#raw')
        $mardownViewerToolbar = $('#mardown-viewer-toolbar')
        $saveMarkdownButton = $('#saveMarkdownButton')

        initMarkdownIt()
        initCodeMirror()
        setMode(defaultMode)
        setEditorData(originalRaw);

        $editorContainer.resizable({
            handles: {
                e: $resizableHandle
            },
            grid: 50,
            minWidth: 300,
            maxWidth: window.innerWidth -220 - 300,
            stop: function() {
                cm.refresh()
                scrollMap = null;
            },
            helper: 'ui-resizable-helper'
        })
        renderMarkdown()

        $editorContainer.on('touchstart mouseover', function () {
            noEditorScroll = false
            $viewerContainer.off('scroll');
            cm.on('scroll', function(event) {
                if (!noEditorScroll) {
                    doScroll(syncResultScroll)
                }
            });
        });

        $viewerContainer.on('touchstart mouseover', function () {
            noEditorScroll = true
            $viewerContainer.on('scroll', function() {
                doScroll(syncSrcScroll)
            });
        });

        buildMISPElementHints()
    })

    function initMarkdownIt() {
        var mdOptions = {
            highlight: function (str, lang) {
                if (lang && hljs.getLanguage(lang)) {
                    try {
                        return hljs.highlight(lang, str, true).value;
                    } catch (__) {}
                }
                return ''; // use external default escaping
            }
        }
        md = window.markdownit('default', mdOptions);
        md.disable([ 'link', 'image' ])
        md.renderer.rules.table_open = function () {
            return '<table class="table table-striped">\n';
        };
        md.renderer.rules.paragraph_open = injectLineNumbers;
        md.renderer.rules.heading_open = injectLineNumbers;
        md.renderer.rules.MISPElement = MISPElementRenderer;
        md.inline.ruler.push('MISP_element_rule', MISPElementRule);
    }

    function initCodeMirror() {
        var cmOptions = {
            mode: 'markdown',
            theme:'default',
            lineNumbers: true,
            indentUnit: 4,
            showCursorWhenSelecting: true,
            lineWrapping: true,
            scrollbarStyle: 'overlay',
            extraKeys: {
                "Esc": function(cm) {
                    console.log('<esc>')
                },
                "Ctrl-Space": "autocomplete",
                "Ctrl-B": function() { replacementAction('bold') },
                "Ctrl-I": function() { replacementAction('italic') },
                "Ctrl-M": function() { replacementAction('element') },
            },
            hintOptions: {
                hint: hintMISPElements,
                completeSingle: false
            },
        }
        cm = CodeMirror.fromTextArea($editor[0], cmOptions);
        cm.on('changes', function() {
            doRender();
        })
        cm.on("keyup", function (cm, event) {
            if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/
                event.keyCode != 13) {        /*Enter - do not open autocomplete list just after item has been selected in it*/ 
                cm.showHint()
            }
        });
    }

    function hintMISPElements(cm, options) {
        var authorizedMISPElements = ['attribute', 'object']
        var reMISPElement = RegExp('@\\[(?<scope>' + authorizedMISPElements.join('|') + ')\\]\\((?<elementid>[^\\)]+)\\)');
        var reExtendedWord = /\S/
        var scope, elementID, element
        var cursor = cm.getCursor()
        var line = cm.getLine(cursor.line)
        var start = cursor.ch
        var end = cursor.ch
        while (start && reExtendedWord.test(line.charAt(start - 1))) --start
        while (end < line.length && reExtendedWord.test(line.charAt(end))) ++end
        var word = line.slice(start, end).toLowerCase()
        
        var res = reMISPElement.exec(word)
        if (res !== null) {
            scope = res.groups.scope
            elementID = res.groups.elementid
            element = proxyMISPElements[scope][elementID]
            var hintList = []
            if (element !== undefined) {
                hintList.push(
                    {
                        text: '@[' + scope + '](' + element.id + ')',
                        render: function(elem, self, data) {
                            var hintElement = renderHintElement(scope, element)
                            $(elem).append(hintElement)<commit_msg>chg: [markdownViewer] Checkbox for autocomplete while typing<commit_after><?php echo $this->element('EventReports/markdownViewerHelpModal') ?>

<div id="mardown-viewer-toolbar" class="btn-toolbar">
    <div class="btn-group">
        <button type="button" class="btn" data-togglemode="editor" onclick="setMode('editor')">
            <i class="<?= $this->FontAwesome->getClass('edit') ?> fa-edit"></i>
            <?= __('Edit') ?>
        </button>
        <button type="button" class="btn" data-togglemode="splitscreen" onclick="setMode('splitscreen')">
            <i class="<?= $this->FontAwesome->getClass('columns') ?> fa-columns"></i>
            <?= __('Split Screen') ?>
        </button>
        <button type="button" class="btn btn-inverse" data-togglemode="viewer" onclick="setMode('viewer')">
            <i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i>
            <?= __('Markdown') ?>
        </button>
        <button type="button" class="btn" data-togglemode="raw" onclick="setMode('raw')">
            <i class="<?= $this->FontAwesome->getClass('code') ?> fa-code"></i>
            <?= __('Raw') ?>
        </button>
    </div>
    <div class="btn-group">
        <button id="saveMarkdownButton" type="button" class="btn btn-primary" onclick="saveMarkdown()">
            <i class="<?= $this->FontAwesome->getClass('save') ?> fa-save"></i>
            <?= __('Save') ?>
        </button>
        <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            <li class="dropdown-submenu">
                <a tabindex="-1" href="#">
                    <span class="icon"><i class="<?= $this->FontAwesome->getClass('download') ?> fa-download"></i></span>
                    <?= __('Downloads') ?>
                </a>
                <ul class="dropdown-menu">
                    <li><a tabindex="-1" href="#" onclick="downloadMarkdown('pdf')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('file-pdf') ?> fa-file-pdf"></i></span>
                        <?= __('Download PDF (via print)') ?>
                    </a></li>
                    <li><a tabindex="-1" href="#" onclick="downloadMarkdown('text')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i></span>
                        <?= __('Download Markdown') ?>
                    </a></li>
                    <li><a tabindex="-1" href="#" title="<?= __('Replace custom syntax by a valid one') ?>" onclick="downloadMarkdown('text-gfm')">
                        <span class="icon"><i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i></span>
                        <?= __('Download GFM simplified format') ?>
                    </a></li>
                </ul>
            </li>
        </ul>
    </div>
    <button type="button" class="btn btn-primary" onclick="showHelp()">
        <i class="<?= $this->FontAwesome->getClass('question-circle') ?> fa-question-circle"></i>
        <?= __('Help') ?>
    </button>
</div>

<div class="raw-container">
    <pre id="raw"><?php echo h($markdown) ?></pre>
</div>
<div class="split-container">
    <div id="editor-container">
        <div id="editor-subcontainer">
            <div id="top-bar" class="editor-action-bar">
                <span class="<?= $this->FontAwesome->getClass('bold') ?> useCursorPointer icon" onclick="replacementAction('bold')"></span>
                <span class="<?= $this->FontAwesome->getClass('italic') ?> useCursorPointer icon" onclick="replacementAction('italic')"></span>
                <span class="<?= $this->FontAwesome->getClass('heading') ?> useCursorPointer icon" onclick="replacementAction('heading')"></span>
                <span class="<?= $this->FontAwesome->getClass('strikethrough') ?> useCursorPointer icon" onclick="replacementAction('strikethrough')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('list-ul') ?> useCursorPointer icon" onclick="replacementAction('list-ul')"></span>
                <span class="<?= $this->FontAwesome->getClass('list-ol') ?> useCursorPointer icon" onclick="replacementAction('list-ol')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('quote-left') ?> useCursorPointer icon" onclick="replacementAction('quote')"></span>
                <span class="<?= $this->FontAwesome->getClass('code') ?> useCursorPointer icon" onclick="replacementAction('code')"></span>
                <span class="<?= $this->FontAwesome->getClass('table') ?> useCursorPointer icon" onclick="replacementAction('table')"></span>
                <i class="top-bar-separator"></i>
                <span class="<?= $this->FontAwesome->getClass('cube') ?> useCursorPointer icon" onclick="replacementAction('attribute')"></span>
                <span class="<?= $this->FontAwesome->getClass('cubes') ?> useCursorPointer icon" onclick="replacementAction('object')"></span>
            </div>
            <textarea id="editor"></textarea>
            <div id="bottom-bar" class="editor-action-bar">
                <span id="lastModifiedField">
                    <?= isset($lastModified) ? h($lastModified) : '' ?>
                </span>
                <span>
                    <span title="<?= __('Toggle autocompletion while typing'); ?>">
                        <input type="checkbox" id="autocompletionCB" style="margin: 0 2px 0 0" checked="checked"></input>
                        <span class="<?= $this->FontAwesome->getClass('magic') ?> useCursorPointer icon" onclick="$autocompletionCB[0].checked = !$autocompletionCB[0].checked"></span>
                    </span>
                </span>
            </div>
        </div>
        <div id="resizable-handle" class="ui-resizable-handle ui-resizable-e"></div>
    </div>
    <div id="viewer-container">
        <div id="viewer"></div>
    </div>
</div>

<?php
    echo $this->element('genericElements/assetLoader', array(
        'js' => array(
            'doT',
            'markdown-it',
            'highlight.min',
            'FileSaver',
            'codemirror/codemirror',
            'codemirror/modes/markdown',
            'codemirror/addons/simplescrollbars',
            'codemirror/addons/show-hint',
        ),
        'css' => array(
            'highlight.min',
            'codemirror',
            'codemirror/simplescrollbars',
            'codemirror/show-hint',
        )
    ));

    // - Add last modified timestamp & time since last edit
    // - Add Picker for elements [correlation/eventGraph picture/tags/galaxyMatrix]
    // - Add popover for MISP Element
    // - Add support of picture (attachment) in the markdown
?>
<script>
    'use strict';
    var md, cm;
    var originalRaw = <?= json_encode(is_array($markdown) ? $markdown : array($markdown), JSON_HEX_TAG); ?>[0];
    var proxyMISPElements = <?= json_encode(is_array($proxyMISPElements) ? $proxyMISPElements : array($proxyMISPElements), JSON_HEX_TAG); ?>;
    var MISPElementValues = [], MISPElementTypes = [], MISPElementIDs = []
    var modelName = '<?= h($modelName) ?>';
    var mardownModelFieldName = '<?= h($mardownModelFieldName) ?>';
    var debounceDelay = 50;
    var renderTimer, scrollTimer;
    var scrollMap;
    var $splitContainer, $editorContainer, $rawContainer, $viewerContainer, $resizableHandle, $autocompletionCB
    var $editor, $viewer, $raw
    var $saveMarkdownButton, $mardownViewerToolbar
    var loadingSpanAnimation = '<span id="loadingSpan" class="fa fa-spin fa-spinner" style="margin-left: 5px;"></span>';
    var dotTemplateAttribute = doT.template("<span class=\"misp-element-wrapper attribute\" data-scope=\"{{=it.scope}}\" data-elementid=\"{{=it.elementid}}\"><span class=\"bold\">{{=it.type}}<span class=\"blue\"> {{=it.value}}</span></span></span>");
    var dotTemplateObject = doT.template("<span class=\"misp-element-wrapper object\" data-scope=\"{{=it.scope}}\" data-elementid=\"{{=it.elementid}}\"><span class=\"bold\">{{=it.type}}<span class=\"\"> {{=it.value}}</span></span></span>");
    var dotTemplateInvalid = doT.template("<span class=\"misp-element-wrapper invalid\"><span class=\"bold red\">{{=it.scope}}<span class=\"blue\"> ({{=it.id}})</span></span></span>");

    var contentChanged = false
    var defaultMode = 'viewer'
    var currentMode
    var splitEdit = true
    var noEditorScroll = false // Necessary as onscroll cannot be unbound from CM
    $(document).ready(function() {
        $splitContainer = $('.split-container')
        $editorContainer = $('#editor-container')
        $viewerContainer = $('#viewer-container')
        $rawContainer = $('div.raw-container')
        $resizableHandle = $('#resizable-handle')
        $editor = $('#editor')
        $viewer = $('#viewer')
        $raw = $('#raw')
        $mardownViewerToolbar = $('#mardown-viewer-toolbar')
        $saveMarkdownButton = $('#saveMarkdownButton')
        $autocompletionCB = $('#autocompletionCB')

        initMarkdownIt()
        initCodeMirror()
        setMode(defaultMode)
        setEditorData(originalRaw);

        $editorContainer.resizable({
            handles: {
                e: $resizableHandle
            },
            grid: 50,
            minWidth: 300,
            maxWidth: window.innerWidth -220 - 300,
            stop: function() {
                cm.refresh()
                scrollMap = null;
            },
            helper: 'ui-resizable-helper'
        })
        renderMarkdown()

        $editorContainer.on('touchstart mouseover', function () {
            noEditorScroll = false
            $viewerContainer.off('scroll');
            cm.on('scroll', function(event) {
                if (!noEditorScroll) {
                    doScroll(syncResultScroll)
                }
            });
        });

        $viewerContainer.on('touchstart mouseover', function () {
            noEditorScroll = true
            $viewerContainer.on('scroll', function() {
                doScroll(syncSrcScroll)
            });
        });

        buildMISPElementHints()
    })

    function initMarkdownIt() {
        var mdOptions = {
            highlight: function (str, lang) {
                if (lang && hljs.getLanguage(lang)) {
                    try {
                        return hljs.highlight(lang, str, true).value;
                    } catch (__) {}
                }
                return ''; // use external default escaping
            }
        }
        md = window.markdownit('default', mdOptions);
        md.disable([ 'link', 'image' ])
        md.renderer.rules.table_open = function () {
            return '<table class="table table-striped">\n';
        };
        md.renderer.rules.paragraph_open = injectLineNumbers;
        md.renderer.rules.heading_open = injectLineNumbers;
        md.renderer.rules.MISPElement = MISPElementRenderer;
        md.inline.ruler.push('MISP_element_rule', MISPElementRule);
    }

    function initCodeMirror() {
        var cmOptions = {
            mode: 'markdown',
            theme:'default',
            lineNumbers: true,
            indentUnit: 4,
            showCursorWhenSelecting: true,
            lineWrapping: true,
            scrollbarStyle: 'overlay',
            extraKeys: {
                "Esc": function(cm) {
                    console.log('<esc>')
                },
                "Ctrl-Space": "autocomplete",
                "Ctrl-B": function() { replacementAction('bold') },
                "Ctrl-I": function() { replacementAction('italic') },
                "Ctrl-M": function() { replacementAction('element') },
            },
            hintOptions: {
                hint: hintMISPElements,
                completeSingle: false
            },
        }
        cm = CodeMirror.fromTextArea($editor[0], cmOptions);
        cm.on('changes', function() {
            doRender();
        })
        cm.on("keyup", function (cm, event) {
            if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/
                event.keyCode != 13 &&        /*Enter - do not open autocomplete list just after item has been selected in it*/ 
                $autocompletionCB.prop('checked')) {
                cm.showHint()
            }
        });
    }

    function hintMISPElements(cm, options) {
        var authorizedMISPElements = ['attribute', 'object']
        var reMISPElement = RegExp('@\\[(?<scope>' + authorizedMISPElements.join('|') + ')\\]\\((?<elementid>[^\\)]+)\\)');
        var reExtendedWord = /\S/
        var scope, elementID, element
        var cursor = cm.getCursor()
        var line = cm.getLine(cursor.line)
        var start = cursor.ch
        var end = cursor.ch
        while (start && reExtendedWord.test(line.charAt(start - 1))) --start
        while (end < line.length && reExtendedWord.test(line.charAt(end))) ++end
        var word = line.slice(start, end).toLowerCase()
        
        var res = reMISPElement.exec(word)
        if (res !== null) {
            scope = res.groups.scope
            elementID = res.groups.elementid
            element = proxyMISPElements[scope][elementID]
            var hintList = []
            if (element !== undefined) {
                hintList.push(
                    {
                        text: '@[' + scope + '](' + element.id + ')',
                        render: function(elem, self, data) {
                            var hintElement = renderHintElement(scope, element)
                            $(elem).append(hintElement)
{'fraction_non_alphanumeric': 0.17221251440681118, 'fraction_numerical': 0.0020076588467115293, 'mean_word_length': 2.2117014925373133, 'pattern_counts': {'":': 10, '<': 391, '<?xml version=': 0, '>': 483, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1363619', 'n_tokens_mistral': 7719, 'n_tokens_neox': 7482, 'n_words': 1394}