/**
 * Function removes the spacing between tab navigation and document tool bar
 *
 * @param {type} Y
 * @return {undefined}
 */
function adjustPdfannotatorNavbar(Y) {
    let navbar = document.getElementsByClassName('nav');
    for (let i = 0; i < navbar.length; i++) {
        (function (innerI) {
            tab = navbar[innerI];
            tab.classList.add('pdfannotatornavbar');
        })(i);
    }
}

//The MIT License (MIT)
//
//Copyright (c) 2016 Instructure, Inc. (https://github.com/instructure/pdf-annotate.js/blob/master/docs/index.js, 1.3.2018)
//modified      2018 RWTH Aachen, Rabea de Groot, Anna Heynkes and Friederike Schwager (see README.md)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
//
//R: The first parameter has to be Y, because it is a default YUI-object, because moodle gives this object first.
function startIndex(
    Y,
    _cm,
    _documentObject,
    _contextId,
    _userid,
    _capabilities,
    _toolbarSettings,
    _page = 1,
    _annoid = null,
    _commid = null,
    _editorSettings
) {
    // 3. parameter war mal _fileid

    // Require amd modules.
    require(['jquery', 'core/templates', 'core/notification', 'mod_pdfannotator/jspdf', 'core/fragment'], function (
        $,
        templates,
        notification,
        jsPDF,
        Fragment
    ) {
        var currentAnnotations = [];
        (function (modules) {
            // webpackBootstrap
            // The module cache
            var installedModules = {};

            // The require function
            function __webpack_require__(moduleId) {
                // Check if module is in cache
                if (installedModules[moduleId]) return installedModules[moduleId].exports;

                // Create a new module (and put it into the cache)
                var module = (installedModules[moduleId] = {
                    exports: {},
                    id: moduleId,
                    loaded: false,
                });

                // Execute the module function
                modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

                // Flag the module as loaded
                module.loaded = true;

                // Return the exports of the module
                return module.exports;
            }

            // expose the modules object (__webpack_modules__)
            __webpack_require__.m = modules;

            // expose the module cache
            __webpack_require__.c = installedModules;

            // __webpack_public_path__
            __webpack_require__.p = '';

            // Load entry module and return exports
            return __webpack_require__(0);
        })([
            /* 0 */
            function (module, exports, __webpack_require__) {
                'use strict';

                var _slicedToArray = (function () {
                    function sliceIterator(arr, i) {
                        var _arr = [];
                        var _n = true;
                        var _d = false;
                        var _e = undefined;
                        try {
                            for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
                                _arr.push(_s.value);
                                if (i && _arr.length === i) break;
                            }
                        } catch (err) {
                            _d = true;
                            _e = err;
                        } finally {
                            try {
                                if (!_n && _i['return']) _i['return']();
                            } finally {
                                if (_d) throw _e;
                            }
                        }
                        return _arr;
                    }
                    return function (arr, i) {
                        if (Array.isArray(arr)) {
                            return arr;
                        } else if (Symbol.iterator in Object(arr)) {
                            return sliceIterator(arr, i);
                        } else {
                            throw new TypeError('Invalid attempt to destructure non-iterable instance');
                        }
                    };
                })();

                var _twitterText = __webpack_require__(1);

                var _twitterText2 = _interopRequireDefault(_twitterText);

                var _ = __webpack_require__(2);

                var _2 = _interopRequireDefault(_);

                var _initColorPicker = __webpack_require__(4);

                var _initColorPicker2 = _interopRequireDefault(_initColorPicker);

                function _interopRequireDefault(obj) {
                    return obj && obj.__esModule ? obj : { default: obj };
                }

                var UI = _2.default.UI;
                var documentId = _documentObject.annotatorid; // The id of the pdfannotator.

                var PAGE_HEIGHT = void 0;
                var RENDER_OPTIONS = {
                    documentId: _documentObject.annotatorid, // The id of the pdfannotator.
                    documentPath: _documentObject.fullurl, // The path to pdf.
                    pdfDocument: null,
                    scale: parseFloat(localStorage.getItem(documentId + '/scale'), 10) || 1.0,
                    rotate: parseInt(localStorage.getItem(documentId + '/rotate'), 10) || 0,
                };

                /* *********************** eigener Store Adapter!! **********************************/
                let MyStoreAdapter = new _2.default.StoreAdapter({
                    /**
                     * This function get all annotations of a specific document on a specific page.
                     * @param {type} documentId of the pdfannotator
                     * @param {type} pageNumber, of which you want to have the annotations
                     * @returns {unresolved} array of annotation objects
                     */
                    getAnnotations(documentId, pageNumber) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                page_Number: pageNumber,
                                action: 'read',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    /**
                     * Method selects an annotation by id and returns it to JavaScript for shifting
                     *
                     * @param {type} documentId
                     * @param {type} annotationId
                     * @return {unresolved} annotation object
                     */
                    getAnnotation(documentId, annotationId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationId: annotationId,
                                action: 'readsingle',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    /**
                     * This function sends the annotation to save in database
                     * @param {type} documentId
                     * @param {type} pageNumber
                     * @param {type} annotation
                     * @returns {annotation object} The annotation object with the right id. In case of error an error object returns
                     */
                    addAnnotation(documentId, pageNumber, annotation) {
                        var tmp = annotation;
                        tmp.newAnno = true;
                        currentAnnotations[pageNumber].push(tmp);
                        annotation = JSON.stringify(annotation);
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                page_Number: pageNumber,
                                annotation: annotation,
                                action: 'create',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);

                            if (data.status === 'success') {
                                var index = currentAnnotations[pageNumber].indexOf(tmp);
                                currentAnnotations[pageNumber][index] = data;
                                return data;
                            } else if (data.status === 'error') {
                                notification.addNotification({
                                    message: data.reason,
                                    type: 'error',
                                });
                                if (data.log) {
                                    console.error(data.log);
                                }
                            }
                            return { status: 'error' };
                        });
                    },

                    /**
                     * Method passes the edited annotation object along with its old id on to action.php for updating/saving
                     *
                     * @param {type} documentid
                     * @param {type} annotationId
                     * @param {type} annotation
                     * @return {unresolved}
                     */
                    editAnnotation(documentid, page, annotationId, annotationJS) {
                        var annotation = JSON.stringify(annotationJS);
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentid,
                                annotationId: annotationId,
                                annotation: annotation,
                                action: 'update',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);
                            if (data.status == 'error') {
                                console.error(M.util.get_string('error:editAnnotation', 'pdfannotator'));
                                return false;
                            }
                            for (var anno in currentAnnotations[page]) {
                                if (currentAnnotations[page][anno].uuid == annotationId) {
                                    currentAnnotations[page][anno] = annotationJS.annotation;
                                    break;
                                }
                            }
                            return data;
                        });
                    },
                    /**
                     * This function sends the delete instruction to the server and notifies the user, if the deletion was successful
                     * @param {type} documentId
                     * @param {type} annotation
                     * @returns {unresolved} the status success or error
                     */
                    deleteAnnotation(documentId, annotation, deletionInfo = true) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotation: annotation,
                                cmid: _cm.id,
                                action: 'delete',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);
                            if (data.status === 'success') {
                                if (deletionInfo) {
                                    notification.addNotification({
                                        message: M.util.get_string('annotationDeleted', 'pdfannotator'),
                                        type: 'success',
                                    });
                                    setTimeoutNotification();
                                }
                                var node = document.querySelector(
                                    '[data-pdf-annotate-id="' + data.deleteannotation + '"]'
                                );
                                if (node) {
                                    node.parentNode.removeChild(node);
                                    document.querySelector('.comment-list-container').innerHTML = '';
                                    document.querySelector('.comment-list-form').setAttribute('style', 'display:none');
                                    UI.renderQuestions(documentId, $('#currentPage').val());
                                }
                            } else if (data.status === 'error') {
                                notification.addNotification({
                                    message: M.util.get_string('deletionForbidden', 'pdfannotator') + data.reason,
                                    type: 'error',
                                });
                            }

                            return data;
                        });
                    },
                    /**
                     *
                     * @param {type} documentId
                     * @param {type} annotationId
                     * @param {type} content
                     * @param {type} visibility
                     * @param {type} isquestion
                     * @returns {unresolved}
                     */
                    addComment(documentId, annotationId, content, visibility = 'public', isquestion = 0) {
                        var pdfannotator_addcomment_editoritemid = document.querySelectorAll(
                            '.pdfannotator_addcomment_editoritemid'
                        )[0].value;
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationId: annotationId,
                                content: content,
                                visibility: visibility,
                                action: 'addComment',
                                isquestion: isquestion,
                                cmid: _cm.id,
                                pdfannotator_addcomment_editoritemid: pdfannotator_addcomment_editoritemid,
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = data.substring(data.indexOf('{'), data.length);
                            //TODO compare to data before data.substring
                            data = JSON.parse(data);
                            if (data.status === 'success') {
                                return data;
                            } else if (data.status == -1) {
                                notification.alert(
                                    M.util.get_string('error', 'pdfannotator'),
                                    M.util.get_string('missingAnnotation', 'pdfannotator'),
                                    'ok'
                                );
                                return false;
                            } else {
                                notification.addNotification({
                                    message: M.util.get_string('error:addComment', 'pdfannotator'),
                                    type: 'error',
                                });
                                return false;
                            }
                        });
                    },

                    /**
                     * Updates db after a comment has been edited
                     *
                     * @param {type} documentId
                     * @param {type} commentId
                     * @param {type} content
                     * @returns {unresolved}
                     */
                    editComment(documentId, commentId, content, editForm) {
                        var pdfannotator_editcomment_editoritemid = editForm.querySelectorAll(
                            '.pdfannotator_editcomment_editoritemid'
                        )[0].value;
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                commentId: commentId,
                                content: content,
                                action: 'editComment',
                                pdfannotator_editcomment_editoritemid: pdfannotator_editcomment_editoritemid,
                                cmid: _cm.id,
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    deleteComment(documentId, commentId, action) {
                        if (action) {
                            // Report comment to manager

                            return $.ajax({
                                type: 'POST',
                                url: 'action.php',
                                data: {
                                    documentId: documentId,
                                    commentId: commentId,
                                    action: 'reportComment',
                                    sesskey: M.cfg.sesskey,
                                },
                            }).then(function () {
                                alert('Comment has been reported');
                            });
                        } else {
                            // Delete comment if authorised to do so
                            return $.ajax({
                                type: 'POST',
                                url: 'action.php',
                                data: {
                                    documentId: documentId,
                                    commentId: commentId,
                                    cmid: _cm.id,
                                    action: 'deleteComment',
                                    sesskey: M.cfg.sesskey,
                                },
                            }).then(function (data) {
                                data = JSON.parse(data);
                                if (data.status === 'success') {
                                    // remove comment from DOM
                                    var child = document.getElementById('comment_' + commentId);
                                    if (child !== null) {
                                        if (data.wasanswered) {
                                            $('#comment_' + commentId + ' .chat-message-text p').html(
                                                '<em>' + M.util.get_string('deletedComment', 'pdfannotator') + '</em>'
                                            );
                                            $('#comment_' + commentId + ' .chat-message-meta .time').remove();
                                            $('#comment_' + commentId + ' .chat-message-meta .user').remove();
                                            $('#comment_' + commentId + ' .countVotes').remove();
                                            $('#comment_' + commentId + ' .comment-like-a')
                                                .attr('disabled', 'disabled')
                                                .css('visibility', 'hidden');
                                            $('#comment_' + commentId + ' .edited').remove();
                                            if (data.isquestion == 0) {
                                                $('#comment_' + commentId + ' .dropdown').remove();
                                            } else {
                                                $(
                                                    '#comment_' +
                                                        commentId +
                                                        ' .chat-message-meta .dropdown .comment-report-button'
                                                ).remove();
                                                $(
                                                    '#comment_' +
                                                        commentId +
                                                        ' .chat-message-meta .dropdown .comment-delete-a'
                                                ).remove();
                                                $(
                                                    '#comment_' +
                                                        commentId +
                                                        ' .chat-message-meta .dropdown .comment-edit-a'
                                                ).remove();
                                                $(
                                                    '#comment_' +
                                                        commentId +
                                                        ' .chat-message-meta .dropdown .comment-forward-a'
                                                ).remove();
                                                $(
                                                    '#comment_' +
                                                        commentId +
                                                        ' .chat-message-meta .dropdown #hidebutton' +
                                                        commentId
                                                ).remove();
                                            }
                                        } else {
                                            var parent = child.parentNode;
                                            parent.removeChild(child);
                                        }
                                    }

                                    notification.addNotification({
                                        message: M.util.get_string('commentDeleted', 'pdfannotator'),
                                        type: 'success',
                                    });
                                    setTimeoutNotification();

                                    // If the predecessor comment was marked as deleted, remove it from DOM as well
                                    // (This is currently irrelevant, because we jump back to overview after deletion, but I'd prefer to stay in the thread.)
                                    data.followups.forEach(function (element) {
                                        var id = 'comment_' + element;
                                        var child = document.getElementById(id);
                                        var parent = child.parentNode;
                                        parent.removeChild(child);
                                    });
                                    // If the annotation is deleted as well, remove it from the pdf.
                                    if (data.deleteannotation !== 0) {
                                        var node = document.querySelector(
                                            '[data-pdf-annotate-id="' + data.deleteannotation + '"]'
                                        );
                                        node.parentNode.removeChild(node);
                                        document.querySelector('.comment-list-container').innerHTML = '';
                                        document
                                            .querySelector('.comment-list-form')
                                            .setAttribute('style', 'display:none');
                                        UI.renderQuestions(documentId, $('#currentPage').val());
                                    }
                                } else {
                                    notification.addNotification({
                                        message: M.util.get_string('deletionForbidden', 'pdfannotator'),
                                        type: 'error',
                                    });
                                }
                                return data;
                            });
                        }
                    },
                    /**
                     * Hide a comment from participants' view / display as deleted to anyone
                     * but the manager/teacher/editing teacher
                     *
                     * @param {type} documentId
                     * @param {type} commentId
                     * @param string action
                     * @returns {unresolved}
                     */
                    hideComment(documentId, commentId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                commentId: commentId,
                                cmid: _cm.id,
                                action: 'hideComment',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);
                            if (data.status === 'success') {
                                $('#comment_' + commentId).addClass('dimmed_text'); // render chat box in grey.
                                $('#chatmessage' + commentId).append(
                                    "<br><span id='taghidden" +
                                        commentId +
                                        "' class='tag tag-info'>" +
                                        M.util.get_string('hiddenforparticipants', 'pdfannotator') +
                                        '</span>'
                                );
                                let comment = document.getElementById('comment_' + commentId);
                                //renderMathJax(comment);
                                notification.addNotification({
                                    message: M.util.get_string('successfullyHidden', 'pdfannotator'),
                                    type: 'success',
                                });
                                setTimeoutNotification();
                            } else {
                                notification.addNotification({
                                    message: M.util.get_string('error:hideComment', 'pdfannotator'),
                                    type: 'error',
                                });
                            }
                        });
                    },
                    /**
                     *
                     * @param {type} documentId
                     * @param {type} commentId
                     * @returns {unresolved}
                     */
                    redisplayComment(documentId, commentId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                commentId: commentId,
                                cmid: _cm.id,
                                action: 'redisplayComment',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);
                            if (data.status === 'success') {
                                $('#comment_' + commentId).removeClass('dimmed_text'); // render chat box in grey.
                                $('#taghidden' + commentId).remove();
                                let comment = document.getElementById('comment_' + commentId);
                                //renderMathJax(comment);
                                notification.addNotification({
                                    message: M.util.get_string('successfullyRedisplayed', 'pdfannotator'),
                                    type: 'success',
                                });
                                setTimeoutNotification();
                            } else {
                                notification.addNotification({
                                    message: M.util.get_string('error:redisplayComment', 'pdfannotator'),
                                    type: 'error',
                                });
                            }
                        });
                    },
                    /**
                     * Method collects all comments of one annotation
                     *
                     * @param {type} documentId
                     * @param {type} annotationId
                     * @return {unresolved}
                     */
                    getComments(documentId, annotationId) {
                        if (annotationId === undefined) {
                            annotationId = 0;
                        }
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationId: annotationId,
                                action: 'getComments',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    /**
                     * This function collects all Questions (Annotations with min. one comment)
                     * @param {type} documentId
                     * @param {type} pageNumber
                     * @returns {unresolved} array of comments objects (only questions) with an additional attribute 'answercount'
                     */
                    getQuestions(documentId, pageNumber, pattern) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                page_Number: pageNumber,
                                action: 'getQuestions',
                                pattern: pattern,
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    /**
                     * Get all information about an annotation. This function only retrieves information about annotations of types 'drawing' and 'textbox'.
                     * @param {type} documentId
                     * @param {type} commentId
                     * @returns {unresolved}
                     */
                    getInformation(documentId, annotationId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationId: annotationId,
                                action: 'getInformation',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },
                    /**
                     * inserts a vote into the database
                     * @param {type} documentId
                     * @param {type} commentId
                     * @returns {unresolved}
                     */
                    voteComment(documentId, commentId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                commentid: commentId,
                                action: 'voteComment',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    subscribeQuestion(documentId, annotationId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationid: annotationId,
                                action: 'subscribeQuestion',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    unsubscribeQuestion(documentId, annotationId) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                annotationid: annotationId,
                                action: 'unsubscribeQuestion',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            return JSON.parse(data);
                        });
                    },

                    markSolved(documentId, comment) {
                        return $.ajax({
                            type: 'POST',
                            url: 'action.php',
                            data: {
                                documentId: documentId,
                                commentid: comment.uuid,
                                action: 'markSolved',
                                sesskey: M.cfg.sesskey,
                            },
                        }).then(function (data) {
                            data = JSON.parse(data);
                            if (data.status === 'success') {
                                let i = $('#comment_' + comment.uuid + ' .comment-solve-a i');
                                let span = $('#comment_' + comment.uuid + ' .comment-solve-a span.menu-action-text');
                                let img = $('#comment_' + comment.uuid + ' .comment-solve-a img');

                                comment.solved = !comment.solved;
                                if (comment.isquestion) {
                                    if (comment.solved) {
                                        $('#comment_' + comment.uuid + ' .solved').append(
                                            '<i class="icon fa fa-lock fa-fw solvedquestionicon" title="' +
                                                M.util.get_string('questionSolved', 'pdfannotator') +
                                                '"></i>'
                                        );
                                        span.text(M.util.get_string('markUnsolved', 'pdfannotator'));
                                    } else {
                                        $('#comment_' + comment.uuid + ' .solved').empty();
                                        span.text(M.util.get_string('markSolved', 'pdfannotator'));
                                    }
                                    i.toggleClass('fa-lock');
                                    i.toggleClass('fa-unlock');
                                } else {
                                    // comment is answer
                                    if (comment.solved) {
                                        $('#comment_' + comment.uuid + ' .solved').append(
                                            '<i class="icon fa fa-check fa-fw correctanswericon" title="' +
                                                M.util.get_string('questionSolved', 'pdfannotator') +
                                                '"></i>'
                                        );
                                        span.text(M.util.get_string('removeCorrect', 'pdfannotator'));
                                        img.attr('src', M.util.image_url('i/completion-manual-n', 'core'));
                                    } else {
                                        $('#comment_' + comment.uuid + ' .solved').empty();
                                        span.text(M.util.get_string('markCorrect', 'pdfannotator'));
                                        img.attr('src', M.util.image_url('i/completion-manual-enabled', 'core'));
                                    }
                                    $('#comment_' + comment.uuid).toggleClass('correct');
                                }
                            } else {
                                let message = comment.isquestion
                                    ? M.util.get_string('error:closequestion', 'pdfannotator')
                                    : M.util.get_string('error:markcorrectanswer', 'pdfannotator');
                                notification.addNotification({
                                    message: message,
                                    type: 'info',
                                });
                            }
                        });
                    },

                    getCommentsToPrint(documentId, getUrl = false) {
                        if (!getUrl) {
                            return $.ajax({
                                type: 'POST',
                                url: 'action.php', //?XDEBUG_SESSION_START=netbeans-xdebug",
                                data: {
                                    documentId: documentId,
                                    action: 'getCommentsToPrint',
                                    sesskey: M.cfg.sesskey,
                                },
                            })
                                .then(function (data) {
                                    return JSON.parse(data);
                                })
                                .catch(function (err) {
                                    notification.addNotification({
                                        message: M.util.get_string('error:printcommentsdata', 'pdfannotator'),
                                        type: 'error',
                                    });
                                });
                        }
                    },
                });

                /* ************** END Store Adapter!! **********************************/

                _2.default.setStoreAdapter(MyStoreAdapter);
                pdfjsLib.GlobalWorkerOptions.workerSrc = 'shared/pdf.worker.js?ver=00002';
                // Render stuff
                var NUM_PAGES = 0;
                var oldPageNumber;

                /**
                 * This function determines which page the user should see after the scroll event
                 * @param {type} e
                 * @returns {void}
                 */
                function handleScroll(e) {
                    var height = document.getElementById('viewer').clientHeight;
                    var visiblePageNum = Math.round((((e.target.scrollTop * 100) / height) * NUM_PAGES) / 100) + 1;

                    var visiblePage = document.querySelector(
                        '.page[data-page-number="' + visiblePageNum + '"][data-loaded="false"]'
                    );
                    var visiblePageAfter = document.querySelector(
                        '.page[data-page-number="' + (visiblePageNum + 1) + '"][data-loaded="false"]'
                    );
                    var visiblePageBefore = document.querySelector(
                        '.page[data-page-number="' + (visiblePageNum - 1) + '"][data-loaded="false"]'
                    );

                    if (visiblePage) {
                        setTimeout(function () {
                            UI.renderPage(visiblePageNum, RENDER_OPTIONS);
                            if (visiblePageAfter) UI.renderPage(visiblePageNum + 1, RENDER_OPTIONS);
                            if (visiblePageBefore) UI.renderPage(visiblePageNum - 1, RENDER_OPTIONS);
                        });
                    } else {
                        // Anyway if the other pages are not loaded, they should be loaded.
                        if (visiblePageAfter) UI.renderPage(visiblePageNum + 1, RENDER_OPTIONS);
                        if (visiblePageBefore) UI.renderPage(visiblePageNum - 1, RENDER_OPTIONS);
                    }
                    if (
                        visiblePageNum !== oldPageNumber &&
                        $('.comment-list-form')[0].style.display === 'none' &&
                        document.querySelector('.comment-list-container p') === null
                    ) {
                        UI.renderQuestions(documentId, visiblePageNum);
                    }
                    document.getElementById('currentPage').value = visiblePageNum;
                    oldPageNumber = visiblePageNum;
                }

                // Add EventListener to GUI-Elements.
                // Add scroll event to dynamically load the single pages of the pdf.
                var scrollTimer = null;
                document.getElementById('content-wrapper').addEventListener('scroll', function (e) {
                    if (scrollTimer) {
                        clearTimeout(scrollTimer);
                    }
                    scrollTimer = setTimeout(handleScroll, 500, e);
                });

                // Add click event to cancel-Button of commentswrapper to close the comments view and load the questions of this page.
                document.getElementById('commentCancel').addEventListener('click', function (e) {
                    var visiblePageNum = document.getElementById('currentPage').value;
                    document.querySelector('.comment-list-form').setAttribute('style', 'display:none');
                    document.getElementById('commentSubmit').value = M.util.get_string('answerButton', 'pdfannotator');
                    document.getElementById('id_pdfannotator_content').value = '';
                    var editorComment = document.querySelectorAll('#id_pdfannotator_contenteditable')[0].childNodes;
                    if (editorComment) {
                        editorComment.forEach((comment) => {
                            comment.remove();
                        });
                    }
                    document.querySelector('.comment-list-container').innerHTML = '';
                    // Disable and then enable to delete overlay and directly add the function to create an overlay.
                    UI.disableEdit();
                    UI.enableEdit();
                    UI.renderQuestions(documentId, visiblePageNum);
                });

                // 'Overview' tab receives a dropdown navigation menu.
                addDropdownNavigation(null, _capabilities, _cm.id);

                // Initialise the print option for printing the document or its discussions.
                (function () {
                    if (_toolbarSettings.useprint || _capabilities.useprint) {
                        $('#pdfannotator_print_button').click(function () {
                            openDocumentCallback();
                            setTimeout(function () {
                                // Activate cursor icon ('hand') again.
                                document.getElementById('pdfannotator_cursor').click();
                            }, 2000); // Wait 2 seconds to prevent race condition.
                        });

                        function openDocumentCallback() {
                            var url = document.getElementById('myprinturl').innerHTML;
                            location.href = url;
                        }
                    }

                    if (_toolbarSettings.useprintcomments || _capabilities.useprintcomments) {
                        const toggleDropdown = document.getElementById('printAnnotationsOptions');
                        const dropdown = document.getElementById('printAnnotationsOptionsContent');

                        toggleDropdown.addEventListener('click', function () {
                            dropdown.classList.toggle('hidden');
                        });

                        document.addEventListener('click', function (e) {
                            if (!toggleDropdown.contains(e.target) && !dropdown.contains(e.target) && !dropdown.classList.contains('hidden')) {
                                dropdown.classList.add('hidden');
                                document.getElementById('pdfannotator_cursor').click();
                            }
                        });
                        
                        document.getElementById('pdfannotator_printannotations_button').addEventListener('click', function () {
                            openCommentsCallback();
                            setTimeout(function () {
                                // See above.
                                document.getElementById('pdfannotator_cursor').click();
                            }, 2000); // See above.
                        }); // end of click event handler

                        document.getElementById('pdfannotator_printannotations_buttonCSV').addEventListener('click', function () {
                            saveCommentsAsCSV();
                            setTimeout(function () {
                                document.getElementById('pdfannotator_cursor').click();
                            }, 2000);
                        });

                        /**
                         * Goes through all comments in the document, formats them into a CSV file
                         * CSV file format: id, page, author, text, lastEdited, list of answerIds
                         * Then downloads the file with name <documentname>_comments.csv
                         *
                         * @returns {undefined}
                         */
                        function saveCommentsAsCSV() {
                            _2.default
                                .getStoreAdapter()
                                .getCommentsToPrint(RENDER_OPTIONS.documentId)
                                .then(function (data) {
                                    if (data.status === 'success') {
                                        let doc = [];

                                        // Get data to process.
                                        let newdata = data['newdata'];
                                        let title = newdata['documentname'];
                                        newdata = newdata['posts'];
                                        const headers = 'id,page,author,text,lastEdited,answerIds';
                                        doc.push(headers);

                                        if (newdata === null) {
                                            newdata = 0;
                                        }

                                        for (let i = 0; i < newdata.length; i++) {
                                            (function (innerI) {
                                                let postString = '';
                                                const post = newdata[innerI];
                                                const id = post['id'];
                                                const question = sanatizeString(post['rawAnsweredquestion']);
                                                const author = post['author'];
                                                const timeasked = post['timemodified'];
                                                const page = post['page'];

                                                const answerIds = [];
                                                const answerStrings = [];
                                                const answers = post['answers'];
                                                let answer;

                                                for (let z = 0; z < answers.length; z++) {
                                                    (function (innerZ) {
                                                        answer = answers[innerZ];
                                                        answerIds.push(parseInt(answer['id']));
                                                        const answerText = sanatizeString(answer['rawAnswer']);
                                                        const answerString = `\n${answer['id']},${page},"${answer['author']}","${answerText}","${answer['timemodified']}","[]"`;
                                                        answerStrings.push(answerString);
                                                    })(z);
                                                }
                                                postString = `\n${id},${page},"${author}","${question}","${timeasked}","${JSON.stringify(answerIds)}"`;
                                                doc.push(postString);
                                                answerStrings.forEach(elem => doc.push(elem));
                                            })(i);
                                        }
                                        // Create new Blob with doc here
                                        const printTitle = title + '_' + M.util.get_string('comments', 'pdfannotator') + '.csv';
                                        const file = new Blob(doc, { type: '.csv'});
                                        const url = URL.createObjectURL(file);
                                        downloadURL(url, printTitle);
                                        
                                        /**
                                         * Triggers the download of a file from a given URL with the specified filename.
                                         * Creates an invisible <a> element, sets its href to the provided Blob or data URL.
                                         * Simulates a click to download the file. Then element is removed from DOM and URL revoked
                                         *
                                         * @param {string} url - Blob URL or data URL representing the file to be downloaded.
                                         * @param {string} title - Desired filename for the downloaded file.
                                         * @returns {undefined}
                                         */
                                        function downloadURL(url, title){
                                            const elem = document.createElement('a');
                                            elem.hidden = true;
                                            elem.href = url;
                                            elem.download = title;
                                            document.body.appendChild(elem);
                                            elem.click();
                        
                                            // Clean up
                                            URL.revokeObjectURL(url);
                                            document.body.removeChild(elem);
                                        }

                                        /**
                                         * Prepares user comments for export as a CSV.
                                         * Cleans up an HTML string by removing newlines, escaping double quotes and stripping out all HTML tags.
                                         * 
                                         * @param {string} text - a string subContent of the post
                                         * @returns {string} the same string suited for .csv files
                                         */
                                        function sanatizeString(text){
                                            // Remove all HTML-Tags except img
                                            const div = document.createElement('div');
                                            div.innerHTML = text;
                                            const walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
                                            let result = '';

                                            while(walker.nextNode()) {
                                                const node = walker.currentNode;

                                                if(node.nodeType === Node.TEXT_NODE) {
                                                    const parentTag = node.parentNode?.tagName?.toLowerCase();
                                                    if (parentTag !== 'a') {
                                                        result += node.textContent;
                                                    }
                                                } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'img') {
                                                    result += node.outerHTML;
                                                } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'a') {
                                                    const linkText = node.textContent || '';
                                                    const href = node.getAttribute('href') || '';
                                                    result += linkText + ' [URL: ' + href + ']';
                                                }
                                            }

                                            // In the comments linebreaks are represented by <br \>-Tags. Sometimes there is an additional \n
                                            // We remove all \n that already exist.
                                            result = result.replace(/\n/g, '');
                                            // Escape doublequotes
                                            result = result.replaceAll(/"/g, '""');

                                            return result;
                                        }
                                    } else if (data.status === 'empty') {
                                        notification.addNotification({
                                            message: M.util.get_string('infonocomments', 'pdfannotator'),
                                            type: 'info',
                                        });
                                    } else if (data.status === 'error') {
                                        notification.addNotification({
                                            message: M.util.get_string('error:printcomments', 'pdfannotator'),
                                            type: 'error',
                                        });
                                    }
                                });
                        } // End of function saveCommentsAsCSV

                        function openCommentsCallback() {
                            _2.default
                                .getStoreAdapter()
                                .getCommentsToPrint(RENDER_OPTIONS.documentId)
                                .then(function (data) {
                                    if (data.status === 'success') {
                                        // Get annotation type images.
                                        var mypin =
                                            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAgCAYAAAD5VeO1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAISSURBVEhL7ZTvS1NRGMf9i/pHeln/QC/LfshqZG+E0LJSUkhsYW5zuiYYrGzDbOgYmxKz3Svmr93ubZutlKYoZIzS+Oa5PIwdz7n3HoWIoA98X+x5zvOBu/OjBX+Q/3Ipf1/+rX4AvbRjZ3f/B1W9cZXnrW34IgVcDmm4M2nauTaio/2Zbve8cJSH0hY6JlYQfftVmu5JA2PZMq2WI5XPGzXcjC1Lpc3pemlg5v0mTYlI5ddHNalMlrYRDQeHv2iSR5BXat/RGV8XJLfjhp3j9QcJE3mzRtM8gnx8roShzGdOcDGoo+V8yM6FwALXC+e2EEgZNM0jyINpE4F0lROce5hryM/ez3A9loHX6zTNI8iza1u4l7C44cGZTzjjT9jpf1Pher1TJcRyH2maR5CzzWkd5j/dLb6IjvrPQ5rmEeSMp7Mf0D9dlsqaMzhbRV9ylaZEpHKGf0zDcPaLVMrCNrIt/I5Wy3GUszfkksvfczVcwOZenVbLcZQzxufL6E2agnggVTk6IUVa5YyrnMEeruPy1uACdd3xlM8Va+h8UWyIe5IWXhWq1HXHU864Mao35L6IRlVvlOSRjGVfJHZ6Hk3Jb6MMJTk7Of7oEjqerx09bPtU9UZJzvBHF3ElVKBfaijLb8UW7ZwEZfnd+DLao+qbyVCWP54uoi/h/I7IUJbH8xt4kvK+lc0oy0/DvyoHfgN0wePwx9o1ZAAAAABJRU5ErkJggg==';
                                        var myhighlight =
                                            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAdCAYAAABbjRdIAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAS1SURBVEhLfVbfcxRFEO7dvducSMVLIGVUKgEjSCGlhVW+UMWL5Yt/nVW++OijpahPgFaBhJRFISCiBAwJEsLJRSNJiEHOY7M//L7umdvNnUlf9fVs78z3TffMTk/w8XftIo5CqUNrtUDqIWwUSC0UiWAjPMNIGARQEYGlKaBSFJKjkcNmsFmeS4ZGmouksFt4TlPYLJcEGnxy6Y9iqB6BDERKCiIlM9IIDFQSBY4IhjxKWDjCDH9UkqQkIZlqrvb5ViZhrCRGFDMyhBRDh9AeUmt+2gZso24+Wj5X35sGOt5wygDIE9ZcCo3ULNPKAexMbRCEJMgArRJWnyt9dVwfHi15QMYHpE1n4TpDywgHdTe/H6ftCi55wppbE24MC9k6+QFxLZLYReCj8up9fK/9KiQ9LG4w4JNHI+tXnR2spZPr4dpQbhxNC6z32Tr5Pjb+/3BDz8qc0mGzcjNTEANmP+5CKsW3bTwnZf19ZqhGwvFuR3uyHqmqJ+Y3ZiS7iZLiTyMmAcf34RoZOoX64GcJdTOrEuVZJjPffCmt+3fN0SclYSDt3271CIir+MrjnXhQdk0ZicNtEd35+QfZ+9KITEwddZ5BYX8OaS/OOZwqrik6oeFmhj76ssIjf7Yfyl/tlrzz3inn2VlWHj2QeKhhOA7X4/PIc0eQpUzPQH3WsdLtPJPZ69/LiZPvS60em3MXWVq4LZNvHFMcYlSPOI3BnFXFn5ObVy/JoSPHZXT/y86zs2ysP5bOs6dy4ODhQUz8GERFShLK4vysbKw9llcnp5xnd7l/95auaRhFzrMdbzuZO8p5mlOao2OSbiUyffYLmZ/9EeViy70ZlO6/HV1XplDH8494FQlZIpQDijKktYk+yujYuK4Tt/3C7Z9k+szn0lqc13f98gBrNX7goDRe2KPjiUM8QpkWErIW+Zd0WjG0DpTh5qg1IJz9L1dnZObbr2R1Zdl57Rvk9zd19O0BDD95PoNse/HLvWVPCL+Xftl8siZXLp6RG5cvSOefTY1273BThkf26bgqjmEZaYgi2nP4l6lXVNnNjXVHMSjLrUWZPnda15NREcOPrRJpGzaszqAksZKeJIlukp2EUTdH9sv4a5My9sqETo7j7Gpg2iOFBl/fXC8arFcsK9BqWQ/yVCLJ5OmTVZnDccWUUbhpXn/zuH5/9bihKSJgopMEIW48CfQ5Ljtmc+niDhKcvrGGCw9JXPHDQapksK1fr8nKwwWZAOihI2/J8tI9Wbp3R949+YF+5MiMEvlsWEYsOpKQ3MgyXHhwu/rs2qqSWVQksbqUdv6W+StnpcBNyUdz4tSHujsDt2m4hzRNtCAhae9G5a5wjEoJQRYyz35WZRoK+X3ueo+I0nhxWOI9TfQRHehVI0CKEpcyqicinscmT/Dp5ZXC3x+0wnqL2bOu+TqnlQCHnMbEUwjR2EdbbgLgKTAvpxohiWFtErg3cga2i8oOGjbzrG1cMKFdjSSTLnxs0+oz/RoV+9k4i87hVfBDC7kk6Vcl1DQZaDWFfrfxvV+bfu2Rom/w0flHSKNLHXJm1wKzetdHyrTKMoUsFawXTvwxxB2p36tuFKwP2roXYH3GkjSX/wAPXk0w5HWeHQAAAABJRU5ErkJggg==';
                                        var mystrikeout =
                                            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAdCAIAAADU74AfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASsSURBVEhLjZb5T1pLGIbn//+lSZOm16JtjFetRa3AZRMFqqjIJjsoLoiHfTmAoIDY9hmGEmpvTM2EjN+873O+2b5zxNv94j/e8tJhdfmktnba+BJqbkeapljrv0Tbnmw7Ux1XuuPKdPcyXX7pEyHOKBqU6HHhhQAHmnjvLX88qq3465+Dza1IyxTTrYmOM93dy957Lnrfcr2Dy/7hZd93JX/pEyHOKBqU6HHhhQAHmlg6rCjc9lnLHG/bUx3S8V708B9d9/03D4H8Q/D2UTX6RIgzigYlelx4FRSaWD6uSVykZYm3HanOfvb+INc7vu6f5h/ChcczbRArDuOlYaIkf+kTIc4oGpToceGFAAeaWD2tk7Y5rjPgPr/n4Sc3D6HCY1QbJEvDdGWUrT6d16aNPhHijKJBiR4XXghwoImNYGMnqtuTMjuGmVT4bkA66crTRX181RzftJ5v9WmjT4Q4o2hQoseFFwIcaGIr0mTj2EeWnGciYoLkctkYg7hrfy92ftBKXflLI0KcUTQo0ePCCwEONLETbZEz28d6MxGejJREChMWoD8bcUbRoESPCy8EONCEJa6zZRwLFpvVYTo8/xWcagqKEj0uvBDgQBO2RJulVQmy5KwRk3odpxoalOhxqTThQBOkyiqwwBwLHshctN9x/mh2w7htWFxcXd+wOt2hxKXJ6lRDKNHjwgsBDjSxm+6QMEc3Xhxma0/53xP0HocNBoP/LFNojfL1R18wvrT0kYgaRYkeF14IcKAJV6bD9nMf2DimUNCfZ7jrSg+zxbE3i9CSV2Wg0NW/6HHhhQAHmmA5ubNyEcvDXGPM4ZiZI+mbhYUF47ZpFlHN6T7M3jZUHz0uvBDgQJsnjl4QSQcif6BnQRq4C01X/V/E0f8RS8Mcs54jau1ndkNBPUdB/p0NzRp6XGq7p0RKnlpHzio3lwMxbyCX5ZV/FRR6PFecH6Whx4V3uo7sDBWUEsIRpa5kqk/c3BeH8brat7u8bJHiOj0+TR+rIZToceGVhzzXgyYoyFQ6SlPkbpAqj7gG80v5ekOJHhdeCHCgCa43lYMlkBOfHEmVy9//4cILAQ40YY7pu+lp4eFR7BrnK//H3F80ebZbkys4SVCVHzjQBAXd9qs4cu659qnKFLqyun5V6b9guX1B8vpqsaNBiR4XXghwoAljuEn55TUkC9pk7hJaHrGDG5tfLY59FkujdThM3+mbbS6ILl8YDUr0uPBCgANNrAcagFXRZWkpIYFb+XrhYpkcHsw7Vle21KMi5OpD90n0g8Gw9mUrrkkNSvS4VLmFA02snNR451LQrUn5XmaYNeYohAsD27eQ4yC0709umu2bJvsnTua60eYNRAp9RtGgVDi8EOBAE5+OqqunDWO4paC7ma7nXL5a1euQm0DdP6Np8pc+EeKMokGJXuEgwIEmPhyUeSWuBaZQkqfG8YLn4VQnssDMVqpGnwhxRtGgRK9wEOBAE+/cpUU+UY5rPEF+ovAdENPZNflZkelSlll1/KrRJ0KcUTQo0ePCCwEONPHGpb3zlGCTMKvA0honXFOUbwK+WOTXD7moRp8IcUbRoESPCy8EOG9c2k8N39Uo7RdC/gAAAABJRU5ErkJggg==';
                                        var myarea =
                                            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAdCAYAAAC5UQwxAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB5SURBVEhLY/hPZzBwFr76+P3/1cfvaYJBZsMA3MKw3v3/GULm0wSDzIYBFAsd67djdSElGGQmTguRJagF0M0dtZBiMGohlEc9MGohlEc9MGohlEc9MGohlEc9MGohlEc9gNdCurdpYK0samOsFtK9XUovQGcL//8HABAZtWaLsIHAAAAAAElFTkSuQmCC';

                                        // Create pdf.
                                        var doc = new jsPDF({ filters: ['ASCIIHexEncode'] });

                                        // Set a font compatible with Greek. It is a base64-encoded string of a .ttf file
                                        var NotoSans =
                                            ' ';

                                        doc.addFileToVFS('NotoSans.ttf', NotoSans);
                                        doc.addFont('NotoSans.ttf', 'NotoSans', 'normal');
                                        doc.setFont('NotoSans'); // set font

                                        var count = 15; // initial header space
                                        const contentRightMargin = 35;
                                        const contentLeftMargin = 15;
                                        const contentTopBottomMargin = 27;
                                        const a4height = 280; // in mm.
                                        const a4width = 210; // in mm.

                                        // Get data to process.
                                        var data = data['newdata'];
                                        var title = data['documentname'];
                                        data = data['posts'];

                                        // Print title.
                                        doc.setFontSize(16);
                                        doc.setTextColor(0, 84, 159);
                                        doc.text(35, count, title);

                                        doc.setTextColor(0, 0, 51);
                                        doc.setFontSize(10);

                                        if (data === null) {
                                            doc.text(
                                                35,
                                                27,
                                                M.util.get_string('emptypdf', 'pdfannotator') + ' ' + page
                                            );
                                            data = 0;
                                        }

                                        var count = 27;
                                        var page = '0';

                                        for (var i = 0; i < data.length; i++) {
                                            (function (innerI) {
                                                var post = data[innerI];
                                                // Add page number each time it changes.
                                                if (page !== post['page']) {
                                                    page = post['page'];
                                                    doc.setFont(undefined, 'bold');
                                                    doc.setTextColor(0, 84, 159);
                                                    if (count >= a4height) {
                                                        doc.addPage();
                                                        count = contentTopBottomMargin;
                                                    }
                                                    doc.text(
                                                        15,
                                                        count,
                                                        M.util.get_string('page', 'pdfannotator') + ' ' + page
                                                    );
                                                    doc.setFont(undefined, 'normal');
                                                    count += 5;
                                                }
                                                // Add icon to each question depending on its annotation type and increment count by 5 or 7.
                                                addIcon(post['annotationtypeid']);

                                                // Add question in RWTH dark blue.
                                                var question = post['answeredquestion'];
                                                var author = post['author'];
                                                var timeasked = post['timemodified'];
                                                doc.setTextColor(0, 84, 159);
                                                breakLines(author, timeasked, question);
                                                // Add answers to the question in black (extremely dark blue which looks better).
                                                doc.setTextColor(0, 0, 51);
                                                var answers = post['answers'];
                                                var answer;
                                                for (var z = 0; z < answers.length; z++) {
                                                    (function (innerZ) {
                                                        answer = answers[innerZ];
                                                        count += 5;
                                                        breakLines(
                                                            answer['author'],
                                                            answer['timemodified'],
                                                            answer['answer']
                                                        );
                                                    })(z);
                                                }
                                            })(i);
                                            count += 10;
                                        }
                                        var printtitle = title + '_' + M.util.get_string('comments', 'pdfannotator');
                                        doc.save(printtitle + '.pdf');
                                        /**
                                         * Take a user's post (i.e. an individual question or answer), determine whether
                                         * it contains latex formulae images or not and place its text and/or images on the pdf
                                         */
                                        function breakLines(
                                            author = null,
                                            timemodified = null,
                                            post,
                                            characters = 130
                                        ) {
                                            // 1. print the author right away
                                            printAuthor(author, timemodified);
                                            post.forEach(function (subContent) {
                                                // Answer contains text only or any object such as array.
                                                if (typeof subContent === 'string') {
                                                    printTextblock(author, timemodified, subContent, characters);
                                                } else if (typeof subContent === 'object') {
                                                    printItem(subContent);
                                                }
                                            });
                                        }
                                        /**
                                         * Take a text block, split it into pieces no larger than 130 characters
                                         * and print one piece per line
                                         */
                                        function printTextblock(
                                            author = null,
                                            timemodified = null,
                                            text,
                                            characters = 130
                                        ) {
                                            // In the comments linebreaks are represented by <br \>-Tags. Sometimes there is an additional \n
                                            // jsPDF needs \n-linebreaks so we replace <br \> with \n. But first we remove all \n that already exist.
                                            text = text.replace(/\n/g, '');
                                            text = text.replace(/<br \/>/g, '\n');
                                            // Remove all other HTML-Tags.
                                            text = $('<div>').html(text).text();

                                            var stringarray = doc.splitTextToSize(text, characters);
                                            var textbit;
                                            for (var j = 0; j < stringarray.length; j++) {
                                                //doc.setFont('NotoSans');
                                                doc.setFont(undefined, 'normal');
                                                textbit = stringarray[j];
                                                if (count >= a4height) {
                                                    doc.addPage();
                                                    count = contentTopBottomMargin;
                                                }
                                                doc.text(contentRightMargin, count, textbit);
                                                count += 5;
                                            }
                                        }
                                        function printItem(item, index) {
                                            if (typeof item === 'object') {
                                                //item.includes('data:image/png;base64,')) {
                                                if (item['mathform']) {
                                                    printMathFrom(item);
                                                } else if (item['image']) {
                                                    printImage(item);
                                                }
                                            } else if (typeof item === 'string') {
                                                printTextblock(null, null, item);
                                            } else {
                                                console.error(M.util.get_string('error:printlatex', 'pdfannotator'));
                                                notification.addNotification({
                                                    message: M.util.get_string('error:printlatex', 'pdfannotator'),
                                                    type: 'error',
                                                });
                                            }
                                        }
                                        function printImage(data) {
                                            var url;
                                            var image;

                                            if (data['image'] !== 'error') {
                                                image = data['image'];
                                                var height = data['imageheight'] * 0.264583333333334; // Convert pixel into mm.
                                                // Reduce height and witdh if its size more than a4height.
                                                while (height > a4height - 2 * contentTopBottomMargin) {
                                                    height = height - height * 0.1;
                                                }
                                                var width = data['imagewidth'] * 0.264583333333334;
                                                while (width > a4width - (contentLeftMargin + contentRightMargin)) {
                                                    width = width - width * 0.1;
                                                }
                                                if (count + height >= a4height) {
                                                    doc.addPage();
                                                    count = contentTopBottomMargin;
                                                }
                                                doc.addImage(
                                                    image,
                                                    data['format'],
                                                    contentRightMargin,
                                                    count,
                                                    width,
                                                    height
                                                ); // image data, format, offset to the left, offset to the top, width, height
                                                count += 5 + height;
                                            } else {
                                                let item = `<p>${data['message']}</p>`;
                                                printTextblock(null, null, item);
                                            }
                                        }
                                        /**
                                         * Take an image, calculate its height in millimeters and print it on the pdf
                                         */
                                        function printMathFrom(data) {
                                            var img = data['mathform'];
                                            var height = data['mathformheight'] * 0.264583333333334; // Convert pixel into mm.
                                            if (count + height >= a4height) {
                                                doc.addPage();
                                                count = contentTopBottomMargin;
                                            }
                                            doc.addImage(img, data['format'], contentRightMargin, count, 0, 0); // image data, format, offset to the left, offset to the top, width, height
                                            count += 5 + height;
                                        }
                                        /**
                                         * Print the author in bold
                                         * @param {type} author
                                         * @returns {undefined}
                                         */
                                        function printAuthor(author, timemodified = null) {
                                            doc.setFont(undefined, 'bold');
                                            if (timemodified !== null) {
                                                doc.text(120, count, timemodified);
                                            }
                                            if (author.length > 37) {
                                                count += 5;
                                            }
                                            doc.text(contentRightMargin, count, author);
                                            doc.setFont(undefined, 'normal');
                                            count += 5;
                                        }
                                        /**
                                         * Place an icon before each question, depending on the question's type of annotation
                                         * Increment the height variable so that the next line does not overlap with the currnet one
                                         */
                                        function addIcon(annotationtype) {
                                            if (count >= a4height) {
                                                doc.addPage();
                                                count = contentTopBottomMargin;
                                            }
                                            var height = 5;
                                            switch (annotationtype) {
                                                case '1':
                                                    doc.addImage(myarea, 'PNG', 15, count, 5, 5);
                                                    break;
                                                case '3':
                                                    doc.addImage(myhighlight, 'PNG', 15, count, 5, 5);
                                                    break;
                                                case '4':
                                                    doc.addImage(mypin, 'PNG', 15, count, 5, 7);
                                                    height = 7;
                                                    break;
                                                case '5':
                                                    doc.addImage(mystrikeout, 'PNG', 15, count, 5, 5);
                                                    break;
                                                default:
                                                    doc.addImage(mypin, 'PNG', 15, count, 5, 7);
                                                    height = 7;
                                            }
                                            count += height;
                                        }
                                    } else if (data.status === 'empty') {
                                        notification.addNotification({
                                            message: M.util.get_string('infonocomments', 'pdfannotator'),
                                            type: 'info',
                                        });
                                    } else if (data.status === 'error') {
                                        notification.addNotification({
                                            message: M.util.get_string('error:printcomments', 'pdfannotator'),
                                            type: 'error',
                                        });
                                    }
                                });
                        } // end of function openCommentsCallback
                    }
                })();

                /**
                 * First function to render the pdf document. Renders only the first page
                 * and triggers the function to sync the annotations.
                 * @returns {undefined}
                 */
                function render() {
                    return pdfjsLib
                        .getDocument(RENDER_OPTIONS.documentPath)
                        .promise.then(
                            function fulfilled(pdf) {
                                RENDER_OPTIONS.pdfDocument = pdf;
                                pdf.getPage(1).then(function (result) {
                                    let rotate = result._pageInfo.rotate;
                                    RENDER_OPTIONS.rotate =
                                        parseInt(localStorage.getItem(documentId + '/rotate'), 10) || rotate;

                                    var viewer = document.getElementById('viewer');
                                    viewer.innerHTML = '';
                                    NUM_PAGES = pdf._pdfInfo.numPages;
                                    for (var i = 0; i < NUM_PAGES; i++) {
                                        var page = UI.createPage(i + 1);
                                        viewer.appendChild(page);
                                    }
                                    return UI.renderPage(_page, RENDER_OPTIONS, true).then(function (_ref) {
                                        var _ref2 = _slicedToArray(_ref, 2);

                                        var pdfPage = _ref2[0];
                                        var annotations = _ref2[1];
                                        var viewport = pdfPage.getViewport({
                                            scale: RENDER_OPTIONS.scale,
                                            rotation: RENDER_OPTIONS.rotate,
                                        });
                                        PAGE_HEIGHT = viewport.height;

                                        //Set the right page height to every nonseen page to calculate the current seen page better during scrolling
                                        document.querySelectorAll('#viewer .page').forEach(function (elem) {
                                            elem.style.height = PAGE_HEIGHT + 'px';
                                        });

                                        if (!$('.path-mod-pdfannotator').first().hasClass('fullscreenWrapper')) {
                                            var pageheight100 = pdfPage.getViewport({
                                                scale: 1,
                                                rotation: 0,
                                            }).height;
                                            $('#body-wrapper').css('height', pageheight100 + 40);
                                        }
                                        document.getElementById('currentPage').value = _page;
                                        document.getElementById('currentPage').max = NUM_PAGES;
                                        document.getElementById('sumPages').innerHTML = NUM_PAGES;

                                        //pick annotation, if the annotation id has been passed
                                        if (_annoid !== null) {
                                            UI.pickAnnotation(_page, _annoid, _commid);
                                        } else {
                                            UI.renderAllQuestions(documentId, _page);
                                        }

                                        setTimeout(UI.loadNewAnnotations, 5000);
                                    });
                                });
                            },
                            function rejected(err) {
                                let child = document.createElement('div');
                                child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
                                document.getElementById('viewer').appendChild(child);
                            }
                        )
                        .catch(function (err) {
                            let child = document.createElement('div');
                            child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
                            document.getElementById('viewer').appendChild(child);
                        });
                }

                render();

                //initialize button allQuestions
                (function () {
                    document.querySelector('#allQuestions').addEventListener('click', function () {
                        UI.renderAllQuestions(documentId);
                    });
                })();

                //initialize button questionsOnThisPage
                (function () {
                    document.querySelector('#questionsOnThisPage').addEventListener('click', function () {
                        var pageNumber = document.getElementById('currentPage').value;
                        UI.renderQuestions(documentId, pageNumber, 1);
                    });
                })();

                /**
                 * Initialize buttons comment-visibility
                 * @returns {undefined}
                 */
                (function () {
                    const visibilityButtons = document.querySelectorAll('.comment-visibility-button');
                    const clearActiveAttribute = (nodes) => {
                        nodes.forEach(btn => {btn.setAttribute('data-active', false)});
                    };
                    visibilityButtons.forEach(btn => {
                        btn.addEventListener('click', function () {
                            if(btn.getAttribute('data-active') === 'false'){
                                clearActiveAttribute(visibilityButtons);
                                btn.setAttribute('data-active', true);
                                const pageNumber = document.getElementById('currentPage').value;
                                UI.renderQuestions(documentId, pageNumber, 1);
                            }
                        });
                    });
                })();

                /**
                 * Function for a fixed toolbar, when scrolliing down. But only as long as the document is visible.
                 * @returns {undefined}
                 */
                (function () {
                    var top =
                        $('#pdftoolbar').offset().top -
                        parseFloat($('#pdftoolbar').css('marginTop').replace(/auto/, 0));
                    var width = $('#pdftoolbar').width();
                    var fixedTop = 0; // Height of moodle-navbar.
                    if ($('.fixed-top').length > 0) {
                        fixedTop = $('.fixed-top').outerHeight();
                    } else if ($('.navbar-static-top').length > 0) {
                        fixedTop = $('.navbar-static-top').outerHeight();
                    }
                    var toolbarHeight = $('#pdftoolbar').outerHeight();
                    var contentTop = $('#content-wrapper').offset().top;

                    var oldTop = $('#pdftoolbar').css('top');
                    var contentHeight = $('#content-wrapper').height();
                    var bottom = contentTop + contentHeight - fixedTop - toolbarHeight;

                    $(window).scroll(function (event) {
                        var y = $(this).scrollTop();

                        // Calculate again in case contentHeight was 1 (because content wasn't loaded yet?)
                        contentHeight = $('#content-wrapper').height();
                        bottom = contentTop + contentHeight - fixedTop - toolbarHeight;
                        var notifications = $('#user-notifications').children();

                        if (y >= top + 1 - fixedTop && y < bottom - 50 && !notifications) {
                            $('#pdftoolbar').addClass('fixtool');
                            $('#pdftoolbar').width(width);
                            document.getElementById('pdftoolbar').style.top = fixedTop + 'px';
                        } else {
                            $('#pdftoolbar').removeClass('fixtool');
                            document.getElementById('pdftoolbar').style.top = oldTop;
                        }
                    });

                    // adjust width of toolbar
                    $(window).resize(function () {
                        width = $('#pdftoolbar').parent().width();
                        $('#pdftoolbar').width(width);
                    });
                })();

                //initialize searchForm
                (function () {
                    // hide form and show/hide it after click on the search icon
                    $('#searchForm').hide();
                    $('#searchButton').click(function (e) {
                        $('#searchForm').toggle();
                        $('#searchPattern').val('');
                        $('#searchClear').hide();
                        $('#searchPattern').focus();
                    });
                    // Search if the user typed
                    $('#searchPattern').keyup(function (e) {
                        if ($('#searchPattern').val().length > 0) {
                            $('#searchClear').show();
                        } else {
                            $('#searchClear').hide();
                        }
                        let pageNumber = document.getElementById('currentPage').value;
                        UI.renderQuestions(documentId, pageNumber, 1);
                    });

                    //Clear-Button
                    $('#searchForm').submit(function (e) {
                        $('#searchPattern').val('');
                        $('#searchClear').hide();
                        let pageNumber = document.getElementById('currentPage').value;
                        UI.renderQuestions(documentId, pageNumber, 1);
                        return false;
                    });
                })();

                if (_toolbarSettings.use_studenttextbox === '1' || _capabilities.usetextbox) {
                    // initialize the textbox
                    (function () {
                        var textSize = void 0;
                        var textColor = void 0;

                        function initText() {
                            var size = document.querySelector('.toolbar .text-size');
                            [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 96].forEach(function (s) {
                                size.appendChild(new Option(s, s));
                            });

                            setText(
                                localStorage.getItem(RENDER_OPTIONS.documentId + '/text/size') || 10,
                                localStorage.getItem(RENDER_OPTIONS.documentId + '/text/color') || '#000000'
                            );

                            (0, _initColorPicker2.default)(
                                document.querySelector('.text-color'),
                                textColor,
                                function (value) {
                                    setText(textSize, value);
                                }
                            );
                        }

                        function setText(size, color) {
                            var modified = false;

                            if (textSize !== size) {
                                modified = true;
                                textSize = size;
                                localStorage.setItem(RENDER_OPTIONS.documentId + '/text/size', textSize);
                                document.querySelector('.toolbar .text-size').value = textSize;
                            }

                            if (textColor !== color) {
                                modified = true;
                                textColor = color;
                                localStorage.setItem(RENDER_OPTIONS.documentId + '/text/color', textColor);

                                var selected = document.querySelector('.toolbar .text-color.color-selected');
                                if (selected) {
                                    selected.classList.remove('color-selected');
                                    selected.removeAttribute('aria-selected');
                                }

                                selected = document.querySelector('.toolbar .text-color[data-color="' + color + '"]');
                                if (selected) {
                                    selected.classList.add('color-selected');
                                    selected.setAttribute('aria-selected', true);
                                }
                            }

                            if (modified) {
                                UI.setText(textSize, textColor);
                            }
                        }

                        function handleTextSizeChange(e) {
                            setText(e.target.value, textColor);
                            document.querySelector('#pdftoolbar button.text').click(); // Select text.
                        }

                        document.querySelector('.toolbar .text-size').addEventListener('change', handleTextSizeChange);

                        initText();
                    })(); // Initialize textbox end.
                }

                if (_toolbarSettings.use_studentdrawing === '1' || _capabilities.usedrawing) {
                    // Initialize pen.
                    (function () {
                        var penSize = void 0;
                        var penColor = void 0;

                        function initPen() {
                            var size = document.querySelector('.toolbar .pen-size');
                            for (var i = 0; i < 20; i++) {
                                size.appendChild(new Option(i + 1, i + 1));
                            }

                            setPen(
                                localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/size') || 1,
                                localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/color') || '#000000'
                            );

                            (0, _initColorPicker2.default)(
                                document.querySelector('.pen-color'),
                                penColor,
                                function (value) {
                                    setPen(penSize, value);
                                }
                            );
                        }

                        function setPen(size, color) {
                            var modified = false;

                            if (penSize !== size) {
                                modified = true;
                                penSize = size;
                                localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/size', penSize);
                                document.querySelector('.toolbar .pen-size').value = penSize;
                            }

                            if (penColor !== color) {
                                modified = true;
                                penColor = color;
                                localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/color', penColor);

                                var selected = document.querySelector('.toolbar .pen-color.color-selected');
                                if (selected) {
                                    selected.classList.remove('color-selected');
                                    selected.removeAttribute('aria-selected');
                                }

                                selected = document.querySelector('.toolbar .pen-color[data-color="' + color + '"]');
                                if (selected) {
                                    selected.classList.add('color-selected');
                                    selected.setAttribute('aria-selected', true);
                                }
                            }

                            if (modified) {
                                UI.setPen(penSize, penColor);
                            }
                        }

                        function handlePenSizeChange(e) {
                            setPen(e.target.value, penColor);
                            document.querySelector('#pdftoolbar button.pen').click(); // Select pen.
                        }

                        document.querySelector('.toolbar .pen-size').addEventListener('change', handlePenSizeChange);

                        initPen();
                    })(); // End initialize pen.
                }
                // Toolbar buttons (defined in index.mustache) are given event listeners:
                (function () {
                    //Cursor should always be default selected
                    var tooltype = 'cursor';
                    if (tooltype) {
                        setActiveToolbarItem(
                            tooltype,
                            document.querySelector('.toolbar button[data-tooltype=' + tooltype + ']')
                        );
                    }

                    function setActiveToolbarItem(type, button) {
                        var active = document.querySelector('.toolbar button.active');
                        if (active) {
                            active.classList.remove('active');

                            switch (tooltype) {
                                case 'cursor':
                                    UI.disableEdit();
                                    break;
                                case 'draw':
                                    UI.disablePen();
                                    break;
                                case 'text':
                                    UI.disableText();
                                    break;
                                case 'point':
                                    UI.disablePoint();
                                    break;
                                case 'area':
                                case 'highlight':
                                case 'strikeout':
                                    UI.disableRect();
                                    break;
                            }
                        }

                        if (button) {
                            button.classList.add('active');
                        }
                        if (tooltype !== type) {
                            localStorage.setItem(RENDER_OPTIONS.documentId + '/tooltype', type);
                        }
                        tooltype = type;

                        switch (type) {
                            case 'cursor':
                                UI.enableEdit();
                                break;
                            case 'draw':
                                UI.enablePen();
                                break;
                            case 'text':
                                UI.enableText();
                                break;
                            case 'point':
                                UI.enablePoint();
                                break;
                            case 'area':
                            case 'highlight':
                            case 'strikeout':
                                UI.enableRect(type);
                                break;
                        }
                    }

                    function handleToolbarClick(e) {
                        var target = e.target;
                        //The content of some buttons are img-tags.
                        //Then the nodeName of the clicked target will be IMG, but we need the outer button element
                        if (
                            (target.nodeName === 'IMG' || target.nodeName === 'I') &&
                            target.parentElement.nodeName === 'BUTTON'
                        ) {
                            target = e.target.parentElement;
                        }
                        if (target.nodeName === 'BUTTON') {
                            //Only setActiveToolbarItem if the button is not disabled! (It is disables, if the annotations are hidden)
                            if (!target.disabled) {
                                setActiveToolbarItem(target.getAttribute('data-tooltype'), target);
                            }
                        }
                        //clear right side (comment-wrapper), if there are comments of an annotation
                        var form = document.querySelector('.comment-list-form');
                        if (form.style.display !== 'none') {
                            form.style.display = 'none';
                            document.querySelector('.comment-list-container').innerHTML = '';
                        }
                    }
                    document.querySelector('.toolbar').addEventListener('click', handleToolbarClick);
                })(); //end Toolbar buttons

                // Scale

                (function () {
                    function setScaleRotate(scale, rotate) {
                        scale = parseFloat(scale, 10);
                        rotate = parseInt(rotate, 10);

                        if (RENDER_OPTIONS.scale !== scale || RENDER_OPTIONS.rotate !== rotate) {
                            RENDER_OPTIONS.scale = scale;
                            RENDER_OPTIONS.rotate = rotate;

                            localStorage.setItem(RENDER_OPTIONS.documentId + '/scale', RENDER_OPTIONS.scale);
                            localStorage.setItem(RENDER_OPTIONS.documentId + '/rotate', RENDER_OPTIONS.rotate % 360);
                            _page = parseInt(document.getElementById('currentPage').value);

                            let pagecontainer = document.getElementById('pageContainer' + _page);
                            let loader = document.createElement('div');
                            loader.id = 'loader';

                            document.body.appendChild(loader);
                            render().then(function () {
                                $('#content-wrapper').scrollTop(
                                    document.getElementById('pageContainer' + _page).offsetTop
                                );
                                document.body.removeChild(loader);
                            });
                        }
                    }

                    function handleScaleChange(e) {
                        setScaleRotate(e.target.value, RENDER_OPTIONS.rotate);
                    }

                    function handleRotateCWClick() {
                        setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate + 90);
                    }

                    function handleRotateCCWClick() {
                        setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate - 90);
                    }

                    document.querySelector('.toolbar select.scale').value = RENDER_OPTIONS.scale;

                    // Add eventHandlers to select and +/- Button for scaling
                    $('.toolbar select.scale').change(handleScaleChange);

                    let options = document.querySelector('.toolbar select.scale').options.length;
                    document.querySelector('.toolbar #scalePlus').addEventListener('click', function () {
                        handleScaleButton(1);
                    });
                    document.querySelector('.toolbar #scaleMinus').addEventListener('click', function () {
                        handleScaleButton(-1);
                    });

                    function handleScaleButton(value) {
                        let index = document.querySelector('.toolbar select.scale').selectedIndex + value;
                        if (index >= 0 && index < options) {
                            document.querySelector('.toolbar select.scale').selectedIndex = index;
                        }
                        $('.toolbar select.scale').change();
                        setTimeout(function () {
                            document.getElementById('pdfannotator_cursor').click();
                        }, 100);
                    }
                })(); //end scale rotate

                // Hide/Show annotations Button
                (function () {
                    //hide is 'block' for display annotations and 'none' for hide annotations
                    var hide = localStorage.getItem(RENDER_OPTIONS.documentId + '/hide') || 'block';

                    function handleHideClick(e) {
                        toggleHide(e);

                        for (var i = 0; i < NUM_PAGES; i++) {
                            document.querySelector(
                                'div#pageContainer' + (i + 1) + ' svg.annotationLayer'
                            ).style.display = hide;
                        }
                    }

                    function toggleHide(e) {
                        let img;
                        let a;
                        if (e.target.tagName === 'A') {
                            a = e.target;
                            img = e.target.childNodes[0];
                        } else {
                            img = e.target;
                            a = img.parentNode;
                        }
                        hide = hide === 'block' ? 'none' : 'block';
                        img.src =
                            img.src.indexOf('accessibility_checker') !== -1
                                ? M.util.image_url(
                                      '/i/hide'
                                  ) /*'/moodle/theme/image.php/clean/core/1504678549/i/hide' */
                                : M.util.image_url('/e/accessibility_checker'); // '/moodle/theme/image.php/clean/core/1504678549/e/accessibility_checker';
                        if (hide === 'block') {
                            document.querySelectorAll('.toolbar button[data-tooltype]').forEach(function (elem) {
                                elem.disabled = false;
                            });
                            img.alt = M.util.get_string('hideAnnotations', 'pdfannotator');
                            img.title = M.util.get_string('hideAnnotations', 'pdfannotator');
                            a.title = M.util.get_string('hideAnnotations', 'pdfannotator');
                        } else {
                            document.querySelectorAll('.toolbar button[data-tooltype]').forEach(function (elem) {
                                elem.disabled = true;
                            });
                            img.alt = M.util.get_string('showAnnotations', 'pdfannotator');
                            img.title = M.util.get_string('showAnnotations', 'pdfannotator');
                            a.title = M.util.get_string('showAnnotations', 'pdfannotator');
                        }
                    }
                    document.querySelector('a.hideComments').addEventListener('click', handleHideClick);
                })(); //end hide/show annotations button

                // Jump to Page
                (function () {
                    var currentPageInput = $('#currentPage');
                    var oldPage = currentPageInput.val();

                    function jumpToPage() {
                        var numPages = parseInt($('#sumPages').html(), 10);
                        var newPage = parseInt(currentPageInput.val(), 10);

                        var inputValid = false;
                        if (Number.isInteger(newPage)) {
                            if (newPage >= 1 && newPage <= numPages) {
                                inputValid = true;
                            }
                        }

                        if (!inputValid) {
                            currentPageInput.val(oldPage);
                            return;
                        }

                        oldPage = newPage;
                        $('#content-wrapper').scrollTop(document.getElementById('pageContainer' + newPage).offsetTop);
                    }

                    // Add eventListener for inputfield and buttons
                    currentPageInput.change(jumpToPage);

                    $('#nextPage').click(function () {
                        currentPageInput.val(parseInt(currentPageInput.val(), 10) + 1);
                        currentPageInput.change();
                        setTimeout(function () {
                            document.getElementById('pdfannotator_cursor').click();
                        }, 100);
                    });
                    $('#prevPage').click(function () {
                        currentPageInput.val(parseInt(currentPageInput.val(), 10) - 1);
                        currentPageInput.change();
                        setTimeout(function () {
                            document.getElementById('pdfannotator_cursor').click();
                        }, 100);
                    });
                })();

                // Make toolbar responsive: Elements that can't be displayed in one row, are in a dropdown.
                (function () {
                    // Set width as attribute because width of elements in dropdown is 0 if dropdown is collapsed.
                    $('#toolbarContent')
                        .children()
                        .each(function () {
                            $(this).attr('visibleWidth', $(this).outerWidth());
                        });

                    function responsiveToolbar() {
                        let changed = false;
                        do {
                            changed = false;
                            let lastElement = $('#toolbarContent').children(':not(.pdf-annotator-hidden)').last(); // Last visible element in toolbar.
                            let firstDropdownElement = $('#toolbar-dropdown-content').children().first(); // First element in dropdown.
                            let firstWidth = parseInt(firstDropdownElement.attr('visibleWidth')); // Width of first element in dropdown.
                            // If lastElem is displayed in a second row because screen isn't wide enough.
                            if (lastElement.offset().top > $('#toolbarContent').offset().top + 10) {
                                // Move last element (not dropdown-button) into dropdown and display button.
                                let toolbarElements = $('#toolbarContent').children(':not(#toolbar-dropdown-button)');
                                if (toolbarElements.length > 0) {
                                    lastElement = toolbarElements.last();
                                    $('#toolbar-dropdown-content').prepend(lastElement);
                                    $('#toolbar-dropdown-button').removeClass('pdf-annotator-hidden');
                                    changed = true;
                                }
                                // If there is enough space to display the next hidden element.
                            } else if (
                                firstDropdownElement.length !== 0 &&
                                lastElement.offset().left + lastElement.outerWidth() + firstWidth + 20 <
                                    $('#toolbarContent').offset().left + $('#toolbarContent').width()
                            ) {
                                firstDropdownElement.insertBefore('#toolbar-dropdown-button'); // Move element from dropdown to toolbar.
                                // Hide button if all elements are shown.
                                if ($('#toolbar-dropdown-content').children().length === 0) {
                                    $('#toolbar-dropdown-button').addClass('pdf-annotator-hidden');
                                }
                                changed = true;
                            }
                        } while (changed);
                    }
                    responsiveToolbar();
                    $(window).resize(responsiveToolbar);
                    $('#toolbar-dropdown-button').click(function () {
                        setTimeout(function () {
                            document.getElementById('pdfannotator_cursor').click();
                        }, 100);
                    });
                })();

                // Comment annotations.
                (function (window, document) {
                    var commentList = document.querySelector('#comment-wrapper .comment-list-container'); // to be found in index.php
                    var commentForm = document.querySelector('#comment-wrapper .comment-list-form'); // to be found in index.php

                    // Function checks whether the target annotation type allows comments.
                    function supportsComments(target) {
                        var type = target.getAttribute('data-pdf-annotate-type');
                        return ['point', 'highlight', 'area', 'strikeout'].indexOf(type) > -1;
                    }

                    /*
                     * Function inserts a comment into the HTML DOM for display.
                     * A comment consists of its content as well as a delete button, wrapped up in a shared div.
                     *
                     * @return {Element}
                     */
                    function insertComments(comments, markCommentid = undefined) {
                        if (!comments) {
                            return false;
                        }
                        if (!comments.comments) {
                            comments = { comments: [comments] };
                        }

                        (function (templates, data) {
                            if (data.comments[0] !== false) {
                                templates
                                    .render('mod_pdfannotator/comment', data)
                                    .then(function (html, js) {
                                        if (data.comments.length === 1 && !data.comments[0].isquestion) {
                                            $('.comment-list-container').append(html);
                                        } else {
                                            templates.replaceNodeContents('.comment-list-container', html, js);
                                        }
                                    })
                                    .then(function () {
                                        data.comments.forEach(function (comment) {
                                            createVoteHandler(comment);
                                            createEditFormHandler(comment);
                                            createSubscriptionHandler(comment);
                                            createHideHandler(comment);
                                            createDeleteHandler(comment);
                                            createSolvedHandler(comment);
                                            let pattern = $('#searchPattern').val();
                                            if (
                                                pattern !== '' &&
                                                comment.content.search(new RegExp(pattern, 'i')) !== -1
                                            ) {
                                                $('#comment_' + comment.uuid).addClass('mark');
                                            }

                                            let selector = '#comment_' + comment.uuid + ' .chat-message-text p';
                                            let element = document.querySelector(selector);
                                            //renderMathJax(element);
                                        });

                                        //if the target has the attribute markCommentid a specific comment should be marked with an red border.
                                        //after 3 sec the border should disappear.
                                        if (markCommentid !== undefined && markCommentid !== null) {
                                            $('#comment_' + markCommentid).addClass('mark');
                                            markCommentid = undefined;
                                            setTimeout(function () {
                                                if (document.querySelector('#comment_' + markCommentid)) {
                                                    document.querySelector('#comment_' + markCommentid).style.border =
                                                        'none';
                                                }
                                            }, 3000);
                                        }
                                    })
                                    .catch(notification.exception);
                            }
                        })(templates, comments);
                        return true;
                    }

                    function createSolvedHandler(comment) {
                        var button = $('#comment_' + comment.uuid + ' .comment-solve-a');
                        var i = $('#comment_' + comment.uuid + ' .comment-solve-a i');
                        var span = $('#comment_' + comment.uuid + ' .comment-solve-a span.menu-action-text');
                        var img = $('#comment_' + comment.uuid + ' .comment-solve-a img');
                        button.click(function (e) {
                            _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, comment);
                        });
                    }

                    function createSubscriptionHandler(comment) {
                        var button = $('#comment_' + comment.uuid + ' .comment-subscribe-a');
                        var i = $('#comment_' + comment.uuid + ' .comment-subscribe-a i');
                        var span = $('#comment_' + comment.uuid + ' .comment-subscribe-a span.menu-action-text');
                        button.click(function (e) {
                            if (comment.issubscribed) {
                                _2.default
                                    .getStoreAdapter()
                                    .unsubscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
                                    .then(function (data) {
                                        if (data.status === 'success') {
                                            notification.addNotification({
                                                message: M.util.get_string('successfullyUnsubscribed', 'pdfannotator'),
                                                type: 'success',
                                            });
                                            setTimeoutNotification();
                                        } else if (data.status == 'error') {
                                            notification.addNotification({
                                                message: M.util.get_string('error:unsubscribe', 'pdfannotator'),
                                                type: 'error',
                                            });
                                            console.error(M.util.get_string('error:unsubscribe', 'pdfannotator'));
                                        }
                                        span.text(M.util.get_string('subscribeQuestion', 'pdfannotator'));
                                    });
                            } else {
                                _2.default
                                    .getStoreAdapter()
                                    .subscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
                                    .then(function (data) {
                                        if (data.status === 'success') {
                                            notification.addNotification({
                                                message: M.util.get_string('successfullySubscribednotify', 'pdfannotator'),
                                                type: 'success',
                                            });
                                            setTimeoutNotification();
                                        } else if (data.status == 'error') {
                                            notification.addNotification({
                                                message: M.util.get_string('error:subscribe', 'pdfannotator'),
                                                type: 'error',
                                            });
                                            console.error(M.util.get_string('error:subscribe', 'pdfannotator'));
                                        }
                                        span.text(M.util.get_string('unsubscribeQuestion', 'pdfannotator'));
                                    });
                            }
                            comment.issubscribed = !comment.issubscribed;
                            i.toggleClass('fa-bell');
                            i.toggleClass('fa-bell-slash');
                        });
                    }

                    function createVoteHandler(comment) {
                        // Create an element for click.
                        var likeButton = $('#comment_' + comment.uuid + ' .comment-like-a');
                        if (comment.isdeleted == 1 || !comment.usevotes) {
                            likeButton.attr('disabled', 'disabled');
                            likeButton.css('visibility', 'hidden');
                        } else if (comment.userid == _userid || comment.isvoted) {
                            likeButton.attr('disabled', 'disabled');
                        }

                        likeButton.click(function (e) {
                            _2.default
                                .getStoreAdapter()
                                .voteComment(RENDER_OPTIONS.documentId, comment.uuid)
                                .then(function (data) {
                                    if (data.status == 'error') {
                                        notification.addNotification({
                                            message: M.util.get_string('error:voteComment', 'pdfannotator'),
                                            type: 'error',
                                        });
                                        console.error(M.util.get_string('error:voteComment', 'pdfannotator'));
                                    } else {
                                        // Update number of votes and disable button.
                                        var voteDiv = document.querySelector(
                                            'div#comment_' + comment.uuid + ' div.wrappervotessolved'
                                        );
                                        var button = voteDiv.querySelector('button');
                                        var img = button.querySelector('i');
                                        var div = voteDiv.querySelector('.countVotes');

                                        button.disabled = true;
                                        div.innerHTML = data.numberVotes;
                                        if (comment.isquestion == 1) {
                                            button.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //button
                                            img.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
                                            img.alt = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
                                            div.title =
                                                data.numberVotes +
                                                ' ' +
                                                M.util.get_string('likeCountQuestion', 'pdfannotator');
                                        } else {
                                            button.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator');
                                            img.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
                                            img.alt = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
                                            div.title =
                                                data.numberVotes +
                                                ' ' +
                                                M.util.get_string('likeCountAnswer', 'pdfannotator');
                                        }
                                    }
                                });
                        });
                    }

                    /**
                     * Function enables managers to hide a comment from participants
                     * or to display it to participants once more.
                     *
                     * @param {type} comment
                     * @returns {undefined}
                     */
                    function createHideHandler(comment) {
                        var button = $('#hideButton' + comment.uuid);

                        button.click(function (e) {
                            var icon = button.children().first();
                            var menutext = button.children().last();
                            if (comment.ishidden) {
                                _2.default.getStoreAdapter().redisplayComment(RENDER_OPTIONS.documentId, comment.uuid);
                                menutext.html(M.util.get_string('markhidden', 'pdfannotator'));
                            } else {
                                _2.default.getStoreAdapter().hideComment(RENDER_OPTIONS.documentId, comment.uuid);
                                menutext.html(M.util.get_string('removehidden', 'pdfannotator'));
                            }
                            comment.ishidden = !comment.ishidden;
                            icon.toggleClass('fa-eye');
                            icon.toggleClass('fa-eye-slash');
                        });
                    }

                    /**
                     * Function handles opening/closing and submitting the edit comment form.
                     * @param {type} comment
                     * @returns {undefined}
                     */
                    function createEditFormHandler(comment) {
                        // Create an element for click.
                        var editButton = $('#editButton' + comment.uuid);
                        // Add an event handler to the click element that opens a textarea and fills it with the current comment.
                        editButton.click(function (e) {
                            UI.loadEditor('edit', comment.uuid, handleClickIfEditorExists);
                            function handleClickIfEditorExists() {
                                // Add an event handler to the form for submitting any changes to the database.
                                let editForm = document.getElementById(`edit${comment.uuid}`);
                                editForm.onsubmit = function (e) {
                                    let editTextarea = document.getElementById(`editarea${comment.uuid}`);
                                    let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
                                    let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);

                                    let newContent = editTextarea.value.trim(); // If atto editor is used.
                                    var iframe = document.getElementById('myarea_ifr'); // If tinymce editor is used.
                                    if (iframe) {
                                        let editorArea = iframe.contentWindow.document.getElementById('tinymce');
                                        newContent = editorArea.innerHTML;
                                    }
                                    if (newContent.length === 0) {
                                        // Should be more than one character, otherwise it should not be saved.
                                        notification.addNotification({
                                            message: M.util.get_string('min0Chars', 'pdfannotator'),
                                            type: 'error',
                                        });
                                    } else if (newContent === comment.displaycontent) {
                                        // No changes.
                                        editForm.style.display = 'none';
                                        chatMessage.innerHTML = comment.displaycontent;
                                        //renderMathJax(chatMessage);
                                    } else {
                                        // Save changes.
                                        _2.default
                                            .getStoreAdapter()
                                            .editComment(documentId, comment.uuid, newContent, editForm)
                                            .then(function (data) {
                                                if (data.status === 'success') {
                                                    editForm.style.display = 'none';
                                                    $(`edit_comment_editor_wrapper_${comment.uuid}`).remove();
                                                    if (data.modifiedby) {
                                                        $('#comment_' + comment.uuid + ' .edited').html(
                                                            M.util.get_string('editedComment', 'pdfannotator') +
                                                                ' ' +
                                                                data.timemodified +
                                                                ' ' +
                                                                M.util.get_string('modifiedby', 'pdfannotator') +
                                                                ' ' +
                                                                data.modifiedby
                                                        );
                                                    } else {
                                                        $('#comment_' + comment.uuid + ' .edited').html(
                                                            M.util.get_string('editedComment', 'pdfannotator') +
                                                                ' ' +
                                                                data.timemodified
                                                        );
                                                    }
                                                    newContent = data.newContent;
                                                    chatMessage.innerHTML = newContent;
                                                    comment.content = newContent;
                                                    comment.displaycontent = newContent;
                                                    editTextarea = newContent;
                                                    //renderMathJax(chatMessage);
                                                    notification.addNotification({
                                                        message: M.util.get_string(
                                                            'successfullyEdited',
                                                            'pdfannotator'
                                                        ),
                                                        type: 'success',
                                                    });
                                                    setTimeoutNotification();
                                                } else {
                                                    notification.addNotification({
                                                        message: M.util.get_string('error:editComment', 'pdfannotator'),
                                                        type: 'error',
                                                    });
                                                }
                                            });
                                    }
                                    setTimeout(function () {
                                        let notificationpanel = document.getElementById('user-notifications');
                                        while (notificationpanel.hasChildNodes()) {
                                            notificationpanel.removeChild(notificationpanel.firstChild);
                                        }
                                    }, 4000);

                                    return false; // Prevents normal POST and page reload in favour of an asynchronous load.
                                };

                                let cancelBtn = $('#comment_' + comment.uuid + ' #commentCancel');
                                cancelBtn.click(function (e) {
                                    let editTextarea = document.getElementById(`editarea${comment.uuid}`);
                                    let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
                                    let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);
                                    editForm.style.display = 'none';
                                    editTextarea.innerHTML = '';
                                    editTextarea.innerHTML = comment.displaycontent;
                                    if (editAreaEditable) {
                                        // Only exists for atto editor, not tinymce.
                                        editAreaEditable.innerHTML = '';
                                        editAreaEditable.innerHTML = comment.displaycontent;
                                    }
                                    chatMessage.innerHTML = comment.displaycontent;
                                    //renderMathJax(chatMessage);
                                });
                            }
                        });
                    }

                    /**
                     * This function creates an Node-Element for deleting the comment.
                     * @param {type} comment The comment-object for which the deletebutton is.
                     * @returns {Element|startIndex.indexstartIndex#L#26.indexstartIndex#L#26#L#72.indexstartIndex#L#26#L#72#L#743.createDeleteButton.deleteSpan}
                     */
                    function createDeleteHandler(comment) {
                        var button = $('#comment_' + comment.uuid + ' .comment-delete-a');
                        button.click(function (e) {
                            var confirmDelete = '';
                            if (comment.isquestion == 1) {
                                if (_capabilities.deleteany) {
                                    confirmDelete = M.util.get_string('deletingQuestion_manager', 'pdfannotator');
                                } else {
                                    confirmDelete = M.util.get_string('deletingQuestion_student', 'pdfannotator');
                                }
                            } else {
                                confirmDelete = M.util.get_string('deletingComment', 'pdfannotator');
                            }
                            var deleteCallback = function () {
                                dialogCallbackForDelete.call(this, comment);
                            };
                            notification.confirm(
                                M.util.get_string('deletingCommentTitle', 'pdfannotator'),
                                confirmDelete,
                                M.util.get_string('yesButton', 'pdfannotator'),
                                M.util.get_string('cancelButton', 'pdfannotator'),
                                deleteCallback,
                                null
                            );
                        });

                        function dialogCallbackForDelete(args = comment) {
                            if (args.type === 'textbox' || args.type === 'drawing') {
                                _2.default
                                    .getStoreAdapter()
                                    .deleteAnnotation(documentId, args.annotation)
                                    .then(
                                        function (data) {
                                            if (data.status === 'success') {
                                                var node = document.querySelector(
                                                    '[data-pdf-annotate-id="' + args.annotation + '"]'
                                                );
                                                var visiblePageNum =
                                                    node.parentNode.getAttribute('data-pdf-annotate-page');
                                                node.parentNode.removeChild(node);
                                                // Not possible to enter new comments.
                                                document.querySelector('.comment-list-container').innerHTML = '';
                                                document
                                                    .querySelector('.comment-list-form')
                                                    .setAttribute('style', 'display:none');
                                                UI.renderQuestions(documentId, visiblePageNum);
                                            }
                                        },
                                        function (err) {
                                            notification.addNotification({
                                                message: M.util.get_string('error:deleteAnnotation', 'pdfannotator'),
                                                type: 'error',
                                            });
                                            console.error(M.util.get_string('error:deleteAnnotation', 'pdfannotator'));
                                        }
                                    );
                            } else {
                                _2.default
                                    .getStoreAdapter()
                                    .deleteComment(RENDER_OPTIONS.documentId, args.uuid)
                                    .then(function (data) {
                                        // If comment was answered so that it is not completly deleted but displayed as deleted.
                                        // If question: Close   If answer: Remove marking as correct
                                        if (
                                            data.wasanswered &&
                                            ((comment.isquestion && !comment.solved) ||
                                                (!comment.isquestion && comment.solved))
                                        ) {
                                            _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, args);
                                        }
                                    });
                            }
                        }
                    }

                    /**
                     * This function is called, when an annotation is clicked. The corresponding comments are rendered and a form to submit a comment.
                     * @param {type} target
                     * @returns {undefined}
                     */
                    function handleAnnotationClick(target) {
                        if (supportsComments(target)) {
                            (function () {
                                var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
                                var annotationId = target.getAttribute('data-pdf-annotate-id');

                                _2.default
                                    .getStoreAdapter()
                                    .getComments(documentId, annotationId)
                                    .then(function (comments) {
                                        var title;
                                        if (comments.comments[0].visibility == 'protected') {
                                            title = M.util.get_string('protected_comments', 'pdfannotator');
                                            $('#protectedDiv').hide();
                                            $('#anonymousDiv').hide();
                                            $('#privateDiv').hide();
                                            $('#id_pdfannotator_contenteditable').attr(
                                                'placeholder',
                                                M.util.get_string('add_protected_comment', 'pdfannotator')
                                            );
                                        } else if (comments.comments[0].visibility == 'private') {
                                            title = M.util.get_string('private_comments', 'pdfannotator');
                                            $('#privateDiv').hide();
                                            $('#protectedDiv').hide();
                                            $('#anonymousDiv').hide();
                                            $('#id_pdfannotator_contenteditable').attr(
                                                'placeholder',
                                                M.util.get_string('add_private_comment', 'pdfannotator')
                                            );
                                        } else {
                                            title = M.util.get_string('public_comments', 'pdfannotator');
                                            $('#privateDiv').hide();
                                            $('#protectedDiv').hide();
                                            $('#anonymousDiv').show();
                                            $('#id_pdfannotator_contenteditable').attr(
                                                'placeholder',
                                                M.util.get_string('addAComment', 'pdfannotator')
                                            );
                                        }

                                        $('#comment-wrapper h4')[0].innerHTML = title;
                                        commentList.innerHTML = '';
                                        commentForm.style.display = 'inherit';

                                        var button1 = document.getElementById('allQuestions'); // to be found in index template
                                        button1.style.display = 'inline';
                                        var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
                                        button2.style.display = 'inline';

                                        commentForm.onsubmit = function (e) {
                                            document.querySelector('#commentSubmit').disabled = true;
                                            var commentVisibility = read_visibility_of_checkbox();
                                            var isquestion = 0; // this is a normal comment, so it is not a question
                                            var textarea = document.getElementById('id_pdfannotator_content');
                                            var commentContentElements = textarea.value.trim();
                                            if (commentContentElements.length === 0) {
                                                //should be more than one character, otherwise it should not be saved.
                                                notification.addNotification({
                                                    message: M.util.get_string('min0Chars', 'pdfannotator'),
                                                    type: 'error',
                                                });
                                                document.querySelector('#commentSubmit').disabled = false;
                                                return false;
                                            }

                                            _2.default
                                                .getStoreAdapter()
                                                .addComment(
                                                    documentId,
                                                    annotationId,
                                                    commentContentElements,
                                                    commentVisibility,
                                                    isquestion
                                                )
                                                .then(function (response) {
                                                    var fn = (response) => insertComments(response);
                                                    UI.loadEditor('add', 0, fn, response);
                                                })
                                                .then(function (success) {
                                                    if (!success) {
                                                        return false;
                                                    }
                                                    document.querySelector('#commentSubmit').disabled = false;
                                                })
                                                .catch(function (err) {
                                                    notification.addNotification({
                                                        message: M.util.get_string('error:addComment', 'pdfannotator'),
                                                        type: 'error',
                                                    });
                                                    console.error(
                                                        M.util.get_string('error:addComment', 'pdfannotator')
                                                    );
                                                });

                                            return false; // Prevents page reload via POST to enable asynchronous loading
                                        };

                                        var params = { comments: comments, markCommentid: target.markCommentid };
                                        var fn = (params) => {
                                            var comments = params.comments;
                                            var markCommentid = params.markCommentid;
                                            //render comments
                                            insertComments(comments, markCommentid);
                                        };
                                        UI.loadEditor('add', 0, fn, params);
                                    })
                                    .catch(function (err) {
                                        commentList.innerHTML = '';
                                        commentForm.style.display = 'none';
                                        commentForm.onsubmit = null;

                                        insertComments({
                                            content: M.util.get_string('error:getComments', 'pdfannotator'),
                                        });

                                        notification.addNotification({
                                            message: M.util.get_string('error:getComments', 'pdfannotator'),
                                            type: 'error',
                                        });
                                    });
                            })();
                        } else {
                            // Drawing or textbox
                            (function () {
                                var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
                                var annotationId = target.getAttribute('data-pdf-annotate-id');

                                _2.default
                                    .getStoreAdapter()
                                    .getInformation(documentId, annotationId)
                                    .then(function (annotation) {
                                        UI.hideLoader();
                                        commentList.innerHTML = '';
                                        commentForm.style.display = 'none';
                                        commentForm.onsubmit = null;

                                        var button1 = document.getElementById('allQuestions'); // to be found in index template
                                        button1.style.display = 'inline';
                                        var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
                                        button2.style.display = 'inline';

                                        //render comments
                                        insertComments(annotation);
                                    })
                                    .catch(function (err) {
                                        commentList.innerHTML = '';
                                        commentForm.style.display = 'none';
                                        commentForm.onsubmit = null;

                                        insertComments({
                                            content: M.util.get_string('error:getComments', 'pdfannotator'),
                                        });

                                        notification.addNotification({
                                            message: M.util.get_string('error:getComments', 'pdfannotator'),
                                            type: 'error',
                                        });
                                    });
                            })();
                        }
                    }

                    function handleAnnotationBlur(target) {
                        if (supportsComments(target)) {
                            commentList.innerHTML = '';
                            commentForm.style.display = 'none';
                            commentForm.onsubmit = null;
                        }
                        var visiblePageNum = document.getElementById('currentPage').value;
                        UI.renderQuestions(documentId, visiblePageNum);
                    }

                    UI.addEventListener('annotation:click', handleAnnotationClick);
                    UI.addEventListener('annotation:blur', handleAnnotationBlur);
                })(window, document); //end comment annotation.
            },
            /* 1 */
            function (module, exports, __webpack_require__) {
                var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
                (function () {
                    if (typeof twttr === 'undefined' || twttr === null) {
                        var twttr = {};
                    }

                    twttr.txt = {};
                    twttr.txt.regexen = {};

                    var HTML_ENTITIES = {
                        '&': '&amp;',
                        '>': '&gt;',
                        '<': '&lt;',
                        '"': '&quot;',
                        "'": '&#39;',
                    };

                    // HTML escaping
                    twttr.txt.htmlEscape = function (text) {
                        return (
                            text &&
                            text.replace(/[&"'><]/g, function (character) {
                                return HTML_ENTITIES[character];
                            })
                        );
                    };

                    // Builds a RegExp
                    function regexSupplant(regex, flags) {
                        flags = flags || '';
                        if (typeof regex !== 'string') {
                            if (regex.global && flags.indexOf('g') < 0) {
                                flags += 'g';
                            }
                            if (regex.ignoreCase && flags.indexOf('i') < 0) {
                                flags += 'i';
                            }
                            if (regex.multiline && flags.indexOf('m') < 0) {
                                flags += 'm';
                            }

                            regex = regex.source;
                        }

                        return new RegExp(
                            regex.replace(/#\{(\w+)\}/g, function (match, name) {
                                var newRegex = twttr.txt.regexen[name] || '';
                                if (typeof newRegex !== 'string') {
                                    newRegex = newRegex.source;
                                }
                                return newRegex;
                            }),
                            flags
                        );
                    }

                    twttr.txt.regexSupplant = regexSupplant;

                    // simple string interpolation
                    function stringSupplant(str, values) {
                        return str.replace(/#\{(\w+)\}/g, function (match, name) {
                            return values[name] || '';
                        });
                    }

                    twttr.txt.stringSupplant = stringSupplant;

                    twttr.txt.regexen.spaces_group =
                        /\x09-\x0D\x20\x85\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000/;
                    twttr.txt.regexen.spaces = regexSupplant(/[#{spaces_group}]/);
                    twttr.txt.regexen.invalid_chars_group = /\uFFFE\uFEFF\uFFFF\u202A-\u202E/;
                    twttr.txt.regexen.invalid_chars = regexSupplant(/[#{invalid_chars_group}]/);
                    twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/;
                    twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/gm;
                    twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/gm;

                    twttr.txt.regexen.latinAccentChars =
                        /\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u024F\u0253\u0254\u0256\u0257\u0259\u025B\u0263\u0268\u026F\u0272\u0289\u028B\u02BB\u0300-\u036F\u1E00-\u1EFF/;

                    // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{L}\p{M}
                    twttr.txt.regexen.bmpLetterAndMarks =
                        /A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u052f\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07ca-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0-\u08b2\u08e4-\u0963\u0971-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09f0\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a70-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0c00-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c81-\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0cf1\u0cf2\u0d01-\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u103f\u1050-\u108f\u109a-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16f1-\u16f8\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u180b-\u180d\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191e\u1920-\u192b\u1930-\u193b\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f\u1aa7\u1ab0-\u1abe\u1b00-\u1b4b\u1b6b-\u1b73\u1b80-\u1baf\u1bba-\u1bf3\u1c00-\u1c37\u1c4d-\u1c4f\u1c5a-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1cf8\u1cf9\u1d00-\u1df5\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u20d0-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2183\u2184\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005\u3006\u302a-\u302f\u3031-\u3035\u303b\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua672\ua674-\ua67d\ua67f-\ua69d\ua69f-\ua6e5\ua6f0\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua827\ua840-\ua873\ua880-\ua8c4\ua8e0-\ua8f7\ua8fb\ua90a-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf\ua9e0-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa36\uaa40-\uaa4d\uaa60-\uaa76\uaa7a-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabea\uabec\uabed\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf870-\uf87f\uf882\uf884-\uf89f\uf8b8\uf8c1-\uf8d6\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe2d\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc/;
                    twttr.txt.regexen.astralLetterAndMarks =
                        /\ud800[\udc00-\udc0b\udc0d-\udc26\udc28-\udc3a\udc3c\udc3d\udc3f-\udc4d\udc50-\udc5d\udc80-\udcfa\uddfd\ude80-\ude9c\udea0-\uded0\udee0\udf00-\udf1f\udf30-\udf40\udf42-\udf49\udf50-\udf7a\udf80-\udf9d\udfa0-\udfc3\udfc8-\udfcf]|\ud801[\udc00-\udc9d\udd00-\udd27\udd30-\udd63\ude00-\udf36\udf40-\udf55\udf60-\udf67]|\ud802[\udc00-\udc05\udc08\udc0a-\udc35\udc37\udc38\udc3c\udc3f-\udc55\udc60-\udc76\udc80-\udc9e\udd00-\udd15\udd20-\udd39\udd80-\uddb7\uddbe\uddbf\ude00-\ude03\ude05\ude06\ude0c-\ude13\ude15-\ude17\ude19-\ude33\ude38-\ude3a\ude3f\ude60-\ude7c\ude80-\ude9c\udec0-\udec7\udec9-\udee6\udf00-\udf35\udf40-\udf55\udf60-\udf72\udf80-\udf91]|\ud803[\udc00-\udc48]|\ud804[\udc00-\udc46\udc7f-\udcba\udcd0-\udce8\udd00-\udd34\udd50-\udd73\udd76\udd80-\uddc4\uddda\ude00-\ude11\ude13-\ude37\udeb0-\udeea\udf01-\udf03\udf05-\udf0c\udf0f\udf10\udf13-\udf28\udf2a-\udf30\udf32\udf33\udf35-\udf39\udf3c-\udf44\udf47\udf48\udf4b-\udf4d\udf57\udf5d-\udf63\udf66-\udf6c\udf70-\udf74]|\ud805[\udc80-\udcc5\udcc7\udd80-\uddb5\uddb8-\uddc0\ude00-\ude40\ude44\ude80-\udeb7]|\ud806[\udca0-\udcdf\udcff\udec0-\udef8]|\ud808[\udc00-\udf98]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud81a[\udc00-\ude38\ude40-\ude5e\uded0-\udeed\udef0-\udef4\udf00-\udf36\udf40-\udf43\udf63-\udf77\udf7d-\udf8f]|\ud81b[\udf00-\udf44\udf50-\udf7e\udf8f-\udf9f]|\ud82c[\udc00\udc01]|\ud82f[\udc00-\udc6a\udc70-\udc7c\udc80-\udc88\udc90-\udc99\udc9d\udc9e]|\ud834[\udd65-\udd69\udd6d-\udd72\udd7b-\udd82\udd85-\udd8b\uddaa-\uddad\ude42-\ude44]|\ud835[\udc00-\udc54\udc56-\udc9c\udc9e\udc9f\udca2\udca5\udca6\udca9-\udcac\udcae-\udcb9\udcbb\udcbd-\udcc3\udcc5-\udd05\udd07-\udd0a\udd0d-\udd14\udd16-\udd1c\udd1e-\udd39\udd3b-\udd3e\udd40-\udd44\udd46\udd4a-\udd50\udd52-\udea5\udea8-\udec0\udec2-\udeda\udedc-\udefa\udefc-\udf14\udf16-\udf34\udf36-\udf4e\udf50-\udf6e\udf70-\udf88\udf8a-\udfa8\udfaa-\udfc2\udfc4-\udfcb]|\ud83a[\udc00-\udcc4\udcd0-\udcd6]|\ud83b[\ude00-\ude03\ude05-\ude1f\ude21\ude22\ude24\ude27\ude29-\ude32\ude34-\ude37\ude39\ude3b\ude42\ude47\ude49\ude4b\ude4d-\ude4f\ude51\ude52\ude54\ude57\ude59\ude5b\ude5d\ude5f\ude61\ude62\ude64\ude67-\ude6a\ude6c-\ude72\ude74-\ude77\ude79-\ude7c\ude7e\ude80-\ude89\ude8b-\ude9b\udea1-\udea3\udea5-\udea9\udeab-\udebb]|\ud840[\udc00-\udfff]|\ud841[\udc00-\udfff]|\ud842[\udc00-\udfff]|\ud843[\udc00-\udfff]|\ud844[\udc00-\udfff]|\ud845[\udc00-\udfff]|\ud846[\udc00-\udfff]|\ud847[\udc00-\udfff]|\ud848[\udc00-\udfff]|\ud849[\udc00-\udfff]|\ud84a[\udc00-\udfff]|\ud84b[\udc00-\udfff]|\ud84c[\udc00-\udfff]|\ud84d[\udc00-\udfff]|\ud84e[\udc00-\udfff]|\ud84f[\udc00-\udfff]|\ud850[\udc00-\udfff]|\ud851[\udc00-\udfff]|\ud852[\udc00-\udfff]|\ud853[\udc00-\udfff]|\ud854[\udc00-\udfff]|\ud855[\udc00-\udfff]|\ud856[\udc00-\udfff]|\ud857[\udc00-\udfff]|\ud858[\udc00-\udfff]|\ud859[\udc00-\udfff]|\ud85a[\udc00-\udfff]|\ud85b[\udc00-\udfff]|\ud85c[\udc00-\udfff]|\ud85d[\udc00-\udfff]|\ud85e[\udc00-\udfff]|\ud85f[\udc00-\udfff]|\ud860[\udc00-\udfff]|\ud861[\udc00-\udfff]|\ud862[\udc00-\udfff]|\ud863[\udc00-\udfff]|\ud864[\udc00-\udfff]|\ud865[\udc00-\udfff]|\ud866[\udc00-\udfff]|\ud867[\udc00-\udfff]|\ud868[\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|\ud86a[\udc00-\udfff]|\ud86b[\udc00-\udfff]|\ud86c[\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud87e[\udc00-\ude1d]|\udb40[\udd00-\uddef]/;

                    // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{Nd}
                    twttr.txt.regexen.bmpNumerals =
                        /0-9\u0660-\u0669\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0de6-\u0def\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\ua9f0-\ua9f9\uaa50-\uaa59\uabf0-\uabf9\uff10-\uff19/;
                    twttr.txt.regexen.astralNumerals =
                        /\ud801[\udca0-\udca9]|\ud804[\udc66-\udc6f\udcf0-\udcf9\udd36-\udd3f\uddd0-\uddd9\udef0-\udef9]|\ud805[\udcd0-\udcd9\ude50-\ude59\udec0-\udec9]|\ud806[\udce0-\udce9]|\ud81a[\ude60-\ude69\udf50-\udf59]|\ud835[\udfce-\udfff]/;

                    twttr.txt.regexen.hashtagSpecialChars =
                        /_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\xb7/;

                    // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
                    twttr.txt.regexen.hashSigns = /[#＃]/;
                    twttr.txt.regexen.hashtagAlpha = regexSupplant(
                        /(?:[#{bmpLetterAndMarks}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}))/
                    );
                    twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(
                        /(?:[#{bmpLetterAndMarks}#{bmpNumerals}#{hashtagSpecialChars}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}|#{astralNumerals}))/
                    );
                    twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
                    twttr.txt.regexen.codePoint = /(?:[^\uD800-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])/;
                    twttr.txt.regexen.hashtagBoundary = regexSupplant(
                        /(?:^|$|(?!#{hashtagAlphaNumeric}|&)#{codePoint})/
                    );
                    twttr.txt.regexen.validHashtag = regexSupplant(
                        /(#{hashtagBoundary})(#{hashSigns})(?!\uFE0F|\u20E3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi
                    );

                    // Mention related regex collection
                    twttr.txt.regexen.validMentionPrecedingChars =
                        /(?:^|[^a-zA-Z0-9_!#$%&*@＠]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
                    twttr.txt.regexen.atSigns = /[@＠]/;
                    twttr.txt.regexen.validMentionOrList = regexSupplant(
                        '(#{validMentionPrecedingChars})' + // $1: Preceding character
                            '(#{atSigns})' + // $2: At mark
                            '([a-zA-Z0-9_]{1,20})' + // $3: Screen name
                            '(/[a-zA-Z][a-zA-Z0-9_-]{0,24})?', // $4: List (optional)
                        'g'
                    );
                    twttr.txt.regexen.validReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/);
                    twttr.txt.regexen.endMentionMatch = regexSupplant(/^(?:#{atSigns}|[#{latinAccentChars}]|:\/\/)/);

                    // URL related regex collection
                    twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(
                        /(?:[^A-Za-z0-9@＠$#＃#{invalid_chars_group}]|^)/
                    );
                    twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/;
                    twttr.txt.regexen.invalidDomainChars = stringSupplant(
                        '#{punct}#{spaces_group}#{invalid_chars_group}',
                        twttr.txt.regexen
                    );
                    twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
                    twttr.txt.regexen.validSubdomain = regexSupplant(
                        /(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/
                    );
                    twttr.txt.regexen.validDomainName = regexSupplant(
                        /(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/
                    );
                    twttr.txt.regexen.validGTLD = regexSupplant(
                        RegExp(
                            '(?:(?:' +
                                '삼성|닷컴|닷넷|香格里拉|餐厅|食品|飞利浦|電訊盈科|集团|购物|谷歌|诺基亚|联通|网络|网站|网店|网址|组织机构|移动|珠宝|点看|游戏|淡马锡|机构|書籍|时尚|新闻|政府|政务|' +
                                '手表|手机|我爱你|慈善|微博|广东|工行|家電|娱乐|大拿|在线|嘉里大酒店|嘉里|商标|商店|商城|公益|公司|八卦|健康|信息|佛山|企业|中文网|中信|世界|ポイント|ファッション|' +
                                'セール|ストア|コム|グーグル|クラウド|みんな|คอม|संगठन|नेट|कॉम|همراه|موقع|موبايلي|كوم|شبكة|بيتك|بازار|العليان|' +
                                'ارامكو|ابوظبي|קום|сайт|рус|орг|онлайн|москва|ком|дети|zuerich|zone|zippo|zip|zero|zara|zappos|' +
                                'yun|youtube|you|yokohama|yoga|yodobashi|yandex|yamaxun|yahoo|yachts|xyz|xxx|xperia|xin|xihuan|' +
                                'xfinity|xerox|xbox|wtf|wtc|world|works|work|woodside|wolterskluwer|wme|wine|windows|win|' +
                                'williamhill|wiki|wien|whoswho|weir|weibo|wedding|wed|website|weber|webcam|weatherchannel|' +
                                'weather|watches|watch|warman|wanggou|wang|walter|wales|vuelos|voyage|voto|voting|vote|' +
                                'volkswagen|vodka|vlaanderen|viva|vistaprint|vista|vision|virgin|vip|vin|villas|viking|vig|video|' +
                                'viajes|vet|versicherung|vermögensberatung|vermögensberater|verisign|ventures|vegas|vana|' +
                                'vacations|ups|uol|uno|university|unicom|ubs|tvs|tushu|tunes|tui|tube|trv|trust|' +
                                'travelersinsurance|travelers|travelchannel|travel|training|trading|trade|toys|toyota|town|tours|' +
                                'total|toshiba|toray|top|tools|tokyo|today|tmall|tirol|tires|tips|tiffany|tienda|tickets|theatre|' +
                                'theater|thd|teva|tennis|temasek|telefonica|telecity|tel|technology|tech|team|tdk|tci|taxi|tax|' +
                                'tattoo|tatar|tatamotors|taobao|talk|taipei|tab|systems|symantec|sydney|swiss|swatch|suzuki|' +
                                'surgery|surf|support|supply|supplies|sucks|style|study|studio|stream|store|storage|stockholm|' +
                                'stcgroup|stc|statoil|statefarm|statebank|starhub|star|stada|srl|spreadbetting|spot|spiegel|' +
                                'space|soy|sony|song|solutions|solar|sohu|software|softbank|social|soccer|sncf|smile|skype|sky|' +
                                'skin|ski|site|singles|sina|silk|shriram|show|shouji|shopping|shop|shoes|shiksha|shia|shell|shaw|' +
                                'sharp|shangrila|sfr|sexy|sex|sew|seven|services|sener|select|seek|security|seat|scot|scor|' +
                                'science|schwarz|schule|school|scholarships|schmidt|schaeffler|scb|sca|sbs|sbi|saxo|save|sas|' +
                                'sarl|sapo|sap|sanofi|sandvikcoromant|sandvik|samsung|salon|sale|sakura|safety|safe|saarland|' +
                                'ryukyu|rwe|run|ruhr|rsvp|room|rodeo|rocks|rocher|rip|rio|ricoh|richardli|rich|rexroth|reviews|' +
                                'review|restaurant|rest|republican|report|repair|rentals|rent|ren|reit|reisen|reise|rehab|' +
                                'redumbrella|redstone|red|recipes|realty|realtor|realestate|read|racing|quest|quebec|qpon|pwc|' +
                                'pub|protection|property|properties|promo|progressive|prof|productions|prod|pro|prime|press|' +
                                'praxi|post|porn|politie|poker|pohl|pnc|plus|plumbing|playstation|play|place|pizza|pioneer|pink|' +
                                'ping|pin|pid|pictures|pictet|pics|piaget|physio|photos|photography|photo|philips|pharmacy|pet|' +
                                'pccw|passagens|party|parts|partners|pars|paris|panerai|pamperedchef|page|ovh|ott|otsuka|osaka|' +
                                'origins|orientexpress|organic|org|orange|oracle|ooo|online|onl|ong|one|omega|ollo|olayangroup|' +
                                'olayan|okinawa|office|obi|nyc|ntt|nrw|nra|nowtv|nowruz|now|norton|northwesternmutual|nokia|' +
                                'nissay|nissan|ninja|nikon|nico|nhk|ngo|nfl|nexus|nextdirect|next|news|new|neustar|network|' +
                                'netflix|netbank|net|nec|navy|natura|name|nagoya|nadex|mutuelle|mutual|museum|mtr|mtpc|mtn|' +
                                'movistar|movie|mov|motorcycles|moscow|mortgage|mormon|montblanc|money|monash|mom|moi|moe|moda|' +
                                'mobily|mobi|mma|mls|mlb|mitsubishi|mit|mini|mil|microsoft|miami|metlife|meo|menu|men|memorial|' +
                                'meme|melbourne|meet|media|med|mba|mattel|marriott|markets|marketing|market|mango|management|man|' +
                                'makeup|maison|maif|madrid|luxury|luxe|lupin|ltda|ltd|love|lotto|lotte|london|lol|locus|locker|' +
                                'loans|loan|lixil|living|live|lipsy|link|linde|lincoln|limo|limited|like|lighting|lifestyle|' +
                                'lifeinsurance|life|lidl|liaison|lgbt|lexus|lego|legal|leclerc|lease|lds|lawyer|law|latrobe|lat|' +
                                'lasalle|lanxess|landrover|land|lancaster|lamer|lamborghini|lacaixa|kyoto|kuokgroup|kred|krd|kpn|' +
                                'kpmg|kosher|komatsu|koeln|kiwi|kitchen|kindle|kinder|kim|kia|kfh|kerryproperties|kerrylogistics|' +
                                'kerryhotels|kddi|kaufen|juegos|jprs|jpmorgan|joy|jot|joburg|jobs|jnj|jmp|jll|jlc|jewelry|jetzt|' +
                                'jcp|jcb|java|jaguar|iwc|itv|itau|istanbul|ist|ismaili|iselect|irish|ipiranga|investments|' +
                                'international|int|insure|insurance|institute|ink|ing|info|infiniti|industries|immobilien|immo|' +
                                'imdb|imamat|ikano|iinet|ifm|icu|ice|icbc|ibm|hyundai|htc|hsbc|how|house|hotmail|hoteles|hosting|' +
                                'host|horse|honda|homes|homedepot|holiday|holdings|hockey|hkt|hiv|hitachi|hisamitsu|hiphop|hgtv|' +
                                'hermes|here|helsinki|help|healthcare|health|hdfcbank|haus|hangout|hamburg|guru|guitars|guide|' +
                                'guge|gucci|guardian|group|gripe|green|gratis|graphics|grainger|gov|got|gop|google|goog|goodyear|' +
                                'goo|golf|goldpoint|gold|godaddy|gmx|gmo|gmbh|gmail|globo|global|gle|glass|giving|gives|gifts|' +
                                'gift|ggee|genting|gent|gea|gdn|gbiz|garden|games|game|gallup|gallo|gallery|gal|fyi|futbol|' +
                                'furniture|fund|fujitsu|ftr|frontier|frontdoor|frogans|frl|fresenius|fox|foundation|forum|' +
                                'forsale|forex|ford|football|foodnetwork|foo|fly|flsmidth|flowers|florist|flir|flights|flickr|' +
                                'fitness|fit|fishing|fish|firmdale|firestone|fire|financial|finance|final|film|ferrero|feedback|' +
                                'fedex|fast|fashion|farmers|farm|fans|fan|family|faith|fairwinds|fail|fage|extraspace|express|' +
                                'exposed|expert|exchange|everbank|events|eus|eurovision|estate|esq|erni|ericsson|equipment|epson|' +
                                'epost|enterprises|engineering|engineer|energy|emerck|email|education|edu|edeka|eat|earth|dvag|' +
                                'durban|dupont|dunlop|dubai|dtv|drive|download|dot|doosan|domains|doha|dog|docs|dnp|discount|' +
                                'directory|direct|digital|diet|diamonds|dhl|dev|design|desi|dentist|dental|democrat|delta|' +
                                'deloitte|dell|delivery|degree|deals|dealer|deal|dds|dclk|day|datsun|dating|date|dance|dad|dabur|' +
                                'cyou|cymru|cuisinella|csc|cruises|crs|crown|cricket|creditunion|creditcard|credit|courses|' +
                                'coupons|coupon|country|corsica|coop|cool|cookingchannel|cooking|contractors|contact|consulting|' +
                                'construction|condos|comsec|computer|compare|company|community|commbank|comcast|com|cologne|' +
                                'college|coffee|codes|coach|clubmed|club|cloud|clothing|clinique|clinic|click|cleaning|claims|' +
                                'cityeats|city|citic|cisco|circle|cipriani|church|chrome|christmas|chloe|chintai|cheap|chat|' +
                                'chase|channel|chanel|cfd|cfa|cern|ceo|center|ceb|cbre|cbn|cba|catering|cat|casino|cash|casa|' +
                                'cartier|cars|careers|career|care|cards|caravan|car|capital|capetown|canon|cancerresearch|camp|' +
                                'camera|cam|call|cal|cafe|cab|bzh|buzz|buy|business|builders|build|bugatti|budapest|brussels|' +
                                'brother|broker|broadway|bridgestone|bradesco|boutique|bot|bostik|bosch|boots|book|boo|bond|bom|' +
                                'boehringer|boats|bnpparibas|bnl|bmw|bms|blue|bloomberg|blog|blanco|blackfriday|black|biz|bio|' +
                                'bingo|bing|bike|bid|bible|bharti|bet|best|berlin|bentley|beer|beats|bcn|bcg|bbva|bbc|bayern|' +
                                'bauhaus|bargains|barefoot|barclays|barclaycard|barcelona|bar|bank|band|baidu|baby|azure|axa|aws|' +
                                'avianca|autos|auto|author|audio|audible|audi|auction|attorney|associates|asia|arte|art|arpa|' +
                                'army|archi|aramco|aquarelle|apple|app|apartments|anz|anquan|android|analytics|amsterdam|amica|' +
                                'alstom|alsace|ally|allfinanz|alipay|alibaba|akdn|airtel|airforce|airbus|aig|agency|agakhan|afl|' +
                                'aetna|aero|aeg|adult|ads|adac|actor|active|aco|accountants|accountant|accenture|academy|' +
                                'abudhabi|abogado|able|abbvie|abbott|abb|aarp|aaa|onion' +
                                ')(?=[^0-9a-zA-Z@]|$))'
                        )
                    );
                    twttr.txt.regexen.validCCTLD = regexSupplant(
                        RegExp(
                            '(?:(?:' +
                                '한국|香港|澳門|新加坡|台灣|台湾|中國|中国|გე|ไทย|ලංකා|ഭാരതം|ಭಾರತ|భారత్|சிங்கப்பூர்|இலங்கை|இந்தியா|ଭାରତ|ભારત|ਭਾਰਤ|' +
                                'ভাৰত|ভারত|বাংলা|भारत|پاکستان|مليسيا|مصر|قطر|فلسطين|عمان|عراق|سورية|سودان|تونس|بھارت|ایران|' +
                                'امارات|المغرب|السعودية|الجزائر|الاردن|հայ|қаз|укр|срб|рф|мон|мкд|ею|бел|бг|ελ|zw|zm|za|yt|ye|ws|' +
                                'wf|vu|vn|vi|vg|ve|vc|va|uz|uy|us|um|uk|ug|ua|tz|tw|tv|tt|tr|tp|to|tn|tm|tl|tk|tj|th|tg|tf|td|tc|' +
                                'sz|sy|sx|sv|su|st|ss|sr|so|sn|sm|sl|sk|sj|si|sh|sg|se|sd|sc|sb|sa|rw|ru|rs|ro|re|qa|py|pw|pt|ps|' +
                                'pr|pn|pm|pl|pk|ph|pg|pf|pe|pa|om|nz|nu|nr|np|no|nl|ni|ng|nf|ne|nc|na|mz|my|mx|mw|mv|mu|mt|ms|mr|' +
                                'mq|mp|mo|mn|mm|ml|mk|mh|mg|mf|me|md|mc|ma|ly|lv|lu|lt|ls|lr|lk|li|lc|lb|la|kz|ky|kw|kr|kp|kn|km|' +
                                'ki|kh|kg|ke|jp|jo|jm|je|it|is|ir|iq|io|in|im|il|ie|id|hu|ht|hr|hn|hm|hk|gy|gw|gu|gt|gs|gr|gq|gp|' +
                                'gn|gm|gl|gi|gh|gg|gf|ge|gd|gb|ga|fr|fo|fm|fk|fj|fi|eu|et|es|er|eh|eg|ee|ec|dz|do|dm|dk|dj|de|cz|' +
                                'cy|cx|cw|cv|cu|cr|co|cn|cm|cl|ck|ci|ch|cg|cf|cd|cc|ca|bz|by|bw|bv|bt|bs|br|bq|bo|bn|bm|bl|bj|bi|' +
                                'bh|bg|bf|be|bd|bb|ba|az|ax|aw|au|at|as|ar|aq|ao|an|am|al|ai|ag|af|ae|ad|ac' +
                                ')(?=[^0-9a-zA-Z@]|$))'
                        )
                    );
                    twttr.txt.regexen.validPunycode = /(?:xn--[0-9a-z]+)/;
                    twttr.txt.regexen.validSpecialCCTLD = /(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))/;
                    twttr.txt.regexen.validDomain = regexSupplant(
                        /(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/
                    );
                    twttr.txt.regexen.validAsciiDomain = regexSupplant(
                        /(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi
                    );
                    twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
                    twttr.txt.regexen.validSpecialShortDomain = regexSupplant(
                        /^#{validDomainName}#{validSpecialCCTLD}$/i
                    );
                    twttr.txt.regexen.validPortNumber = /[0-9]+/;
                    twttr.txt.regexen.cyrillicLettersAndMarks = /\u0400-\u04FF/;
                    twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(
                        /[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|&#{latinAccentChars}]/i
                    );
                    // Allow URL paths to contain up to two nested levels of balanced parens
                    //  1. Used in Wikipedia URLs like /Primer_(film)
                    //  2. Used in IIS sessions like /S(dfd346)/
                    //  3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
                    twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
                        '\\(' +
                            '(?:' +
                            '#{validGeneralUrlPathChars}+' +
                            '|' +
                            // allow one nested level of balanced parentheses
                            '(?:' +
                            '#{validGeneralUrlPathChars}*' +
                            '\\(' +
                            '#{validGeneralUrlPathChars}+' +
                            '\\)' +
                            '#{validGeneralUrlPathChars}*' +
                            ')' +
                            ')' +
                            '\\)',
                        'i'
                    );
                    // Valid end-of-path chracters (so /foo. does not gobble the period).
                    // 1. Allow =&# for empty URL parameters and other URL-join artifacts
                    twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(
                        /[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i
                    );
                    // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
                    twttr.txt.regexen.validUrlPath = regexSupplant(
                        '(?:' +
                            '(?:' +
                            '#{validGeneralUrlPathChars}*' +
                            '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' +
                            '#{validUrlPathEndingChars}' +
                            ')|(?:@#{validGeneralUrlPathChars}+/)' +
                            ')',
                        'i'
                    );

                    twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!?\*'@\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i;
                    twttr.txt.regexen.validUrlQueryEndingChars = /[a-z0-9_&=#\/]/i;
                    twttr.txt.regexen.extractUrl = regexSupplant(
                        '(' + // $1 total match
                            '(#{validUrlPrecedingChars})' + // $2 Preceeding chracter
                            '(' + // $3 URL
                            '(https?:\\/\\/)?' + // $4 Protocol (optional)
                            '(#{validDomain})' + // $5 Domain(s)
                            '(?::(#{validPortNumber}))?' + // $6 Port number (optional)
                            '(\\/#{validUrlPath}*)?' + // $7 URL Path
                            '(\\?#{validUrlQueryChars}*#{validUrlQueryEndingChars})?' + // $8 Query String
                            ')' +
                            ')',
                        'gi'
                    );

                    twttr.txt.regexen.validTcoUrl = /^https?:\/\/t\.co\/[a-z0-9]+/i;
                    twttr.txt.regexen.urlHasProtocol = /^https?:\/\//i;
                    twttr.txt.regexen.urlHasHttps = /^https:\/\//i;

                    // cashtag related regex
                    twttr.txt.regexen.cashtag = /[a-z]{1,6}(?:[._][a-z]{1,2})?/i;
                    twttr.txt.regexen.validCashtag = regexSupplant(
                        '(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])',
                        'gi'
                    );

                    // These URL validation pattern strings are based on the ABNF from RFC 3986
                    twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
                    twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
                    twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
                    twttr.txt.regexen.validateUrlPchar = regexSupplant(
                        '(?:' +
                            '#{validateUrlUnreserved}|' +
                            '#{validateUrlPctEncoded}|' +
                            '#{validateUrlSubDelims}|' +
                            '[:|@]' +
                            ')',
                        'i'
                    );

                    twttr.txt.regexen.validateUrlScheme = /(?:[a-z][a-z0-9+\-.]*)/i;
                    twttr.txt.regexen.validateUrlUserinfo = regexSupplant(
                        '(?:' +
                            '#{validateUrlUnreserved}|' +
                            '#{validateUrlPctEncoded}|' +
                            '#{validateUrlSubDelims}|' +
                            ':' +
                            ')*',
                        'i'
                    );

                    twttr.txt.regexen.validateUrlDecOctet =
                        /(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9]{2})|(?:2[0-4][0-9])|(?:25[0-5]))/i;
                    twttr.txt.regexen.validateUrlIpv4 = regexSupplant(
                        /(?:#{validateUrlDecOctet}(?:\.#{validateUrlDecOctet}){3})/i
                    );

                    // Punting on real IPv6 validation for now
                    twttr.txt.regexen.validateUrlIpv6 = /(?:\[[a-f0-9:\.]+\])/i;

                    // Also punting on IPvFuture for now
                    twttr.txt.regexen.validateUrlIp = regexSupplant(
                        '(?:' + '#{validateUrlIpv4}|' + '#{validateUrlIpv6}' + ')',
                        'i'
                    );

                    // This is more strict than the rfc specifies
                    twttr.txt.regexen.validateUrlSubDomainSegment = /(?:[a-z0-9](?:[a-z0-9_\-]*[a-z0-9])?)/i;
                    twttr.txt.regexen.validateUrlDomainSegment = /(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)/i;
                    twttr.txt.regexen.validateUrlDomainTld = /(?:[a-z](?:[a-z0-9\-]*[a-z0-9])?)/i;
                    twttr.txt.regexen.validateUrlDomain = regexSupplant(
                        /(?:(?:#{validateUrlSubDomainSegment]}\.)*(?:#{validateUrlDomainSegment]}\.)#{validateUrlDomainTld})/i
                    );

                    twttr.txt.regexen.validateUrlHost = regexSupplant(
                        '(?:' + '#{validateUrlIp}|' + '#{validateUrlDomain}' + ')',
                        'i'
                    );

                    // Unencoded internationalized domains - this doesn't check for invalid UTF-8 sequences
                    twttr.txt.regexen.validateUrlUnicodeSubDomainSegment =
                        /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9_\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
                    twttr.txt.regexen.validateUrlUnicodeDomainSegment =
                        /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
                    twttr.txt.regexen.validateUrlUnicodeDomainTld =
                        /(?:(?:[a-z]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
                    twttr.txt.regexen.validateUrlUnicodeDomain = regexSupplant(
                        /(?:(?:#{validateUrlUnicodeSubDomainSegment}\.)*(?:#{validateUrlUnicodeDomainSegment}\.)#{validateUrlUnicodeDomainTld})/i
                    );

                    twttr.txt.regexen.validateUrlUnicodeHost = regexSupplant(
                        '(?:' + '#{validateUrlIp}|' + '#{validateUrlUnicodeDomain}' + ')',
                        'i'
                    );

                    twttr.txt.regexen.validateUrlPort = /[0-9]{1,5}/;

                    twttr.txt.regexen.validateUrlUnicodeAuthority = regexSupplant(
                        '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
                            '(#{validateUrlUnicodeHost})' + // $2 host
                            '(?::(#{validateUrlPort}))?', //$3 port
                        'i'
                    );

                    twttr.txt.regexen.validateUrlAuthority = regexSupplant(
                        '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
                            '(#{validateUrlHost})' + // $2 host
                            '(?::(#{validateUrlPort}))?', // $3 port
                        'i'
                    );

                    twttr.txt.regexen.validateUrlPath = regexSupplant(/(\/#{validateUrlPchar}*)*/i);
                    twttr.txt.regexen.validateUrlQuery = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);
                    twttr.txt.regexen.validateUrlFragment = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);

                    // Modified version of RFC 3986 Appendix B
                    twttr.txt.regexen.validateUrlUnencoded = regexSupplant(
                        '^' + // Full URL
                            '(?:' +
                            '([^:/?#]+):\\/\\/' + // $1 Scheme
                            ')?' +
                            '([^/?#]*)' + // $2 Authority
                            '([^?#]*)' + // $3 Path
                            '(?:' +
                            '\\?([^#]*)' + // $4 Query
                            ')?' +
                            '(?:' +
                            '#(.*)' + // $5 Fragment
                            ')?$',
                        'i'
                    );

                    // Default CSS class for auto-linked lists (along with the url class)
                    var DEFAULT_LIST_CLASS = 'tweet-url list-slug';
                    // Default CSS class for auto-linked usernames (along with the url class)
                    var DEFAULT_USERNAME_CLASS = 'tweet-url username';
                    // Default CSS class for auto-linked hashtags (along with the url class)
                    var DEFAULT_HASHTAG_CLASS = 'tweet-url hashtag';
                    // Default CSS class for auto-linked cashtags (along with the url class)
                    var DEFAULT_CASHTAG_CLASS = 'tweet-url cashtag';
                    // Options which should not be passed as HTML attributes
                    var OPTIONS_NOT_ATTRIBUTES = {
                        urlClass: true,
                        listClass: true,
                        usernameClass: true,
                        hashtagClass: true,
                        cashtagClass: true,
                        usernameUrlBase: true,
                        listUrlBase: true,
                        hashtagUrlBase: true,
                        cashtagUrlBase: true,
                        usernameUrlBlock: true,
                        listUrlBlock: true,
                        hashtagUrlBlock: true,
                        linkUrlBlock: true,
                        usernameIncludeSymbol: true,
                        suppressLists: true,
                        suppressNoFollow: true,
                        targetBlank: true,
                        suppressDataScreenName: true,
                        urlEntities: true,
                        symbolTag: true,
                        textWithSymbolTag: true,
                        urlTarget: true,
                        invisibleTagAttrs: true,
                        linkAttributeBlock: true,
                        linkTextBlock: true,
                        htmlEscapeNonEntities: true,
                    };

                    var BOOLEAN_ATTRIBUTES = { disabled: true, readonly: true, multiple: true, checked: true };

                    // Simple object cloning function for simple objects
                    function clone(o) {
                        var r = {};
                        for (var k in o) {
                            if (o.hasOwnProperty(k)) {
                                r[k] = o[k];
                            }
                        }

                        return r;
                    }

                    twttr.txt.tagAttrs = function (attributes) {
                        var htmlAttrs = '';
                        for (var k in attributes) {
                            var v = attributes[k];
                            if (BOOLEAN_ATTRIBUTES[k]) {
                                v = v ? k : null;
                            }
                            if (v == null) continue;
                            htmlAttrs +=
                                ' ' + twttr.txt.htmlEscape(k) + '="' + twttr.txt.htmlEscape(v.toString()) + '"';
                        }
                        return htmlAttrs;
                    };

                    twttr.txt.linkToText = function (entity, text, attributes, options) {
                        if (!options.suppressNoFollow) {
                            attributes.rel = 'nofollow';
                        }
                        // if linkAttributeBlock is specified, call it to modify the attributes
                        if (options.linkAttributeBlock) {
                            options.linkAttributeBlock(entity, attributes);
                        }
                        // if linkTextBlock is specified, call it to get a new/modified link text
                        if (options.linkTextBlock) {
                            text = options.linkTextBlock(entity, text);
                        }
                        var d = {
                            text: text,
                            attr: twttr.txt.tagAttrs(attributes),
                        };
                        return stringSupplant('<a#{attr}>#{text}</a>', d);
                    };

                    twttr.txt.linkToTextWithSymbol = function (entity, symbol, text, attributes, options) {
                        var taggedSymbol = options.symbolTag
                            ? '<' + options.symbolTag + '>' + symbol + '</' + options.symbolTag + '>'
                            : symbol;
                        text = twttr.txt.htmlEscape(text);
                        var taggedText = options.textWithSymbolTag
                            ? '<' + options.textWithSymbolTag + '>' + text + '</' + options.textWithSymbolTag + '>'
                            : text;

                        if (options.usernameIncludeSymbol || !symbol.match(twttr.txt.regexen.atSigns)) {
                            return twttr.txt.linkToText(entity, taggedSymbol + taggedText, attributes, options);
                        } else {
                            return taggedSymbol + twttr.txt.linkToText(entity, taggedText, attributes, options);
                        }
                    };

                    twttr.txt.linkToHashtag = function (entity, text, options) {
                        var hash = text.substring(entity.indices[0], entity.indices[0] + 1);
                        var hashtag = twttr.txt.htmlEscape(entity.hashtag);
                        var attrs = clone(options.htmlAttrs || {});
                        attrs.href = options.hashtagUrlBase + hashtag;
                        attrs.title = '#' + hashtag;
                        attrs['class'] = options.hashtagClass;
                        if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)) {
                            attrs['class'] += ' rtl';
                        }
                        if (options.targetBlank) {
                            attrs.target = '_blank';
                        }

                        return twttr.txt.linkToTextWithSymbol(entity, hash, hashtag, attrs, options);
                    };

                    twttr.txt.linkToCashtag = function (entity, text, options) {
                        var cashtag = twttr.txt.htmlEscape(entity.cashtag);
                        var attrs = clone(options.htmlAttrs || {});
                        attrs.href = options.cashtagUrlBase + cashtag;
                        attrs.title = '$' + cashtag;
                        attrs['class'] = options.cashtagClass;
                        if (options.targetBlank) {
                            attrs.target = '_blank';
                        }

                        return twttr.txt.linkToTextWithSymbol(entity, '$', cashtag, attrs, options);
                    };

                    twttr.txt.linkToMentionAndList = function (entity, text, options) {
                        var at = text.substring(entity.indices[0], entity.indices[0] + 1);
                        var user = twttr.txt.htmlEscape(entity.screenName);
                        var slashListname = twttr.txt.htmlEscape(entity.listSlug);
                        var isList = entity.listSlug && !options.suppressLists;
                        var attrs = clone(options.htmlAttrs || {});
                        attrs['class'] = isList ? options.listClass : options.usernameClass;
                        attrs.href = isList
                            ? options.listUrlBase + user + slashListname
                            : options.usernameUrlBase + user;
                        if (!isList && !options.suppressDataScreenName) {
                            attrs['data-screen-name'] = user;
                        }
                        if (options.targetBlank) {
                            attrs.target = '_blank';
                        }

                        return twttr.txt.linkToTextWithSymbol(
                            entity,
                            at,
                            isList ? user + slashListname : user,
                            attrs,
                            options
                        );
                    };

                    twttr.txt.linkToUrl = function (entity, text, options) {
                        var url = entity.url;
                        var displayUrl = url;
                        var linkText = twttr.txt.htmlEscape(displayUrl);

                        // If the caller passed a urlEntities object (provided by a Twitter API
                        // response with include_entities=true), we use that to render the display_url
                        // for each URL instead of it's underlying t.co URL.
                        var urlEntity = (options.urlEntities && options.urlEntities[url]) || entity;
                        if (urlEntity.display_url) {
                            linkText = twttr.txt.linkTextWithEntity(urlEntity, options);
                        }

                        var attrs = clone(options.htmlAttrs || {});

                        if (!url.match(twttr.txt.regexen.urlHasProtocol)) {
                            url = 'http://' + url;
                        }
                        attrs.href = url;

                        if (options.targetBlank) {
                            attrs.target = '_blank';
                        }

                        // set class only if urlClass is specified.
                        if (options.urlClass) {
                            attrs['class'] = options.urlClass;
                        }

                        // set target only if urlTarget is specified.
                        if (options.urlTarget) {
                            attrs.target = options.urlTarget;
                        }

                        if (!options.title && urlEntity.display_url) {
                            attrs.title = urlEntity.expanded_url;
                        }

                        return twttr.txt.linkToText(entity, linkText, attrs, options);
                    };

                    twttr.txt.linkTextWithEntity = function (entity, options) {
                        var displayUrl = entity.display_url;
                        var expandedUrl = entity.expanded_url;

                        // Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
                        // should contain the full original URL (expanded_url), not the display URL.
                        //
                        // Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
                        // font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
                        // Elements with font-size:0 get copied even though they are not visible.
                        // Note that display:none doesn't work here. Elements with display:none don't get copied.
                        //
                        // Additionally, we want to *display* ellipses, but we don't want them copied.  To make this happen we
                        // wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
                        // everything with the tco-ellipsis class.
                        //
                        // Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/#!/username/status/1234/photo/1
                        // For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
                        // For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.

                        var displayUrlSansEllipses = displayUrl.replace(/…/g, ''); // We have to disregard ellipses for matching
                        // Note: we currently only support eliding parts of the URL at the beginning or the end.
                        // Eventually we may want to elide parts of the URL in the *middle*.  If so, this code will
                        // become more complicated.  We will probably want to create a regexp out of display URL,
                        // replacing every ellipsis with a ".*".
                        if (expandedUrl.indexOf(displayUrlSansEllipses) != -1) {
                            var displayUrlIndex = expandedUrl.indexOf(displayUrlSansEllipses);
                            var v = {
                                displayUrlSansEllipses: displayUrlSansEllipses,
                                // Portion of expandedUrl that precedes the displayUrl substring
                                beforeDisplayUrl: expandedUrl.substr(0, displayUrlIndex),
                                // Portion of expandedUrl that comes after displayUrl
                                afterDisplayUrl: expandedUrl.substr(displayUrlIndex + displayUrlSansEllipses.length),
                                precedingEllipsis: displayUrl.match(/^…/) ? '…' : '',
                                followingEllipsis: displayUrl.match(/…$/) ? '…' : '',
                            };
                            for (var k in v) {
                                if (v.hasOwnProperty(k)) {
                                    v[k] = twttr.txt.htmlEscape(v[k]);
                                }
                            }
                            // As an example: The user tweets "hi http://longdomainname.com/foo"
                            // This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
                            // This will get rendered as:
                            // <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
                            //   …
                            //   <!-- There's a chance the onCopy event handler might not fire. In case that happens,
                            //        we include an &nbsp; here so that the … doesn't bump up against the URL and ruin it.
                            //        The &nbsp; is inside the tco-ellipsis span so that when the onCopy handler *does*
                            //        fire, it doesn't get copied.  Otherwise the copied text would have two spaces in a row,
                            //        e.g. "hi  http://longdomainname.com/foo".
                            //   <span style='font-size:0'>&nbsp;</span>
                            // </span>
                            // <span style='font-size:0'>  <!-- This stuff should get copied but not displayed -->
                            //   http://longdomai
                            // </span>
                            // <span class='js-display-url'> <!-- This stuff should get displayed *and* copied -->
                            //   nname.com/foo
                            // </span>
                            // <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
                            //   <span style='font-size:0'>&nbsp;</span>
                            //   …
                            // </span>
                            v['invisible'] = options.invisibleTagAttrs;
                            return stringSupplant(
                                "<span class='tco-ellipsis'>#{precedingEllipsis}<span #{invisible}>&nbsp;</span></span><span #{invisible}>#{beforeDisplayUrl}</span><span class='js-display-url'>#{displayUrlSansEllipses}</span><span #{invisible}>#{afterDisplayUrl}</span><span class='tco-ellipsis'><span #{invisible}>&nbsp;</span>#{followingEllipsis}</span>",
                                v
                            );
                        }
                        return displayUrl;
                    };

                    twttr.txt.autoLinkEntities = function (text, entities, options) {
                        options = clone(options || {});

                        options.hashtagClass = options.hashtagClass || DEFAULT_HASHTAG_CLASS;
                        options.hashtagUrlBase = options.hashtagUrlBase || 'https://twitter.com/#!/search?q=%23';
                        options.cashtagClass = options.cashtagClass || DEFAULT_CASHTAG_CLASS;
                        options.cashtagUrlBase = options.cashtagUrlBase || 'https://twitter.com/#!/search?q=%24';
                        options.listClass = options.listClass || DEFAULT_LIST_CLASS;
                        options.usernameClass = options.usernameClass || DEFAULT_USERNAME_CLASS;
                        options.usernameUrlBase = options.usernameUrlBase || 'https://twitter.com/';
                        options.listUrlBase = options.listUrlBase || 'https://twitter.com/';
                        options.htmlAttrs = twttr.txt.extractHtmlAttrsFromOptions(options);
                        options.invisibleTagAttrs =
                            options.invisibleTagAttrs || "style='position:absolute;left:-9999px;'";

                        // remap url entities to hash
                        var urlEntities, i, len;
                        if (options.urlEntities) {
                            urlEntities = {};
                            for (i = 0, len = options.urlEntities.length; i < len; i++) {
                                urlEntities[options.urlEntities[i].url] = options.urlEntities[i];
                            }
                            options.urlEntities = urlEntities;
                        }

                        var result = '';
                        var beginIndex = 0;

                        // sort entities by start index
                        entities.sort(function (a, b) {
                            return a.indices[0] - b.indices[0];
                        });

                        var nonEntity = options.htmlEscapeNonEntities
                            ? twttr.txt.htmlEscape
                            : function (text) {
                                  return text;
                              };

                        for (var i = 0; i < entities.length; i++) {
                            var entity = entities[i];
                            result += nonEntity(text.substring(beginIndex, entity.indices[0]));

                            if (entity.url) {
                                result += twttr.txt.linkToUrl(entity, text, options);
                            } else if (entity.hashtag) {
                                result += text; //twttr.txt.linkToHashtag(entity, text, options);
                            } else if (entity.screenName) {
                                result += text; //twttr.txt.linkToMentionAndList(entity, text, options);
                            } else if (entity.cashtag) {
                                result += text; //twttr.txt.linkToCashtag(entity, text, options);
                            }
                            beginIndex = entity.indices[1];
                        }
                        result += nonEntity(text.substring(beginIndex, text.length));
                        return result;
                    };

                    twttr.txt.autoLinkWithJSON = function (text, json, options) {
                        // map JSON entity to twitter-text entity
                        if (json.user_mentions) {
                            for (var i = 0; i < json.user_mentions.length; i++) {
                                // this is a @mention
                                json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
                            }
                        }

                        if (json.hashtags) {
                            for (var i = 0; i < json.hashtags.length; i++) {
                                // this is a #hashtag
                                json.hashtags[i].hashtag = json.hashtags[i].text;
                            }
                        }

                        if (json.symbols) {
                            for (var i = 0; i < json.symbols.length; i++) {
                                // this is a $CASH tag
                                json.symbols[i].cashtag = json.symbols[i].text;
                            }
                        }

                        // concatenate all entities
                        var entities = [];
                        for (var key in json) {
                            entities = entities.concat(json[key]);
                        }

                        // modify indices to UTF-16
                        twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);

                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.extractHtmlAttrsFromOptions = function (options) {
                        var htmlAttrs = {};
                        for (var k in options) {
                            var v = options[k];
                            if (OPTIONS_NOT_ATTRIBUTES[k]) continue;
                            if (BOOLEAN_ATTRIBUTES[k]) {
                                v = v ? k : null;
                            }
                            if (v == null) continue;
                            htmlAttrs[k] = v;
                        }
                        return htmlAttrs;
                    };

                    twttr.txt.autoLink = function (text, options) {
                        var entities = twttr.txt.extractEntitiesWithIndices(text, {
                            extractUrlsWithoutProtocol: false,
                        });
                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.autoLinkUsernamesOrLists = function (text, options) {
                        var entities = twttr.txt.extractMentionsOrListsWithIndices(text);
                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.autoLinkHashtags = function (text, options) {
                        var entities = twttr.txt.extractHashtagsWithIndices(text);
                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.autoLinkCashtags = function (text, options) {
                        var entities = twttr.txt.extractCashtagsWithIndices(text);
                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.autoLinkUrlsCustom = function (text, options) {
                        var entities = twttr.txt.extractUrlsWithIndices(text, {
                            extractUrlsWithoutProtocol: false,
                        });
                        return twttr.txt.autoLinkEntities(text, entities, options);
                    };

                    twttr.txt.removeOverlappingEntities = function (entities) {
                        entities.sort(function (a, b) {
                            return a.indices[0] - b.indices[0];
                        });

                        var prev = entities[0];
                        for (var i = 1; i < entities.length; i++) {
                            if (prev.indices[1] > entities[i].indices[0]) {
                                entities.splice(i, 1);
                                i--;
                            } else {
                                prev = entities[i];
                            }
                        }
                    };

                    twttr.txt.extractEntitiesWithIndices = function (text, options) {
                        var entities = twttr.txt
                            .extractUrlsWithIndices(text, options)
                            .concat(twttr.txt.extractMentionsOrListsWithIndices(text))
                            .concat(twttr.txt.extractHashtagsWithIndices(text, { checkUrlOverlap: false }))
                            .concat(twttr.txt.extractCashtagsWithIndices(text));

                        if (entities.length == 0) {
                            return [];
                        }

                        twttr.txt.removeOverlappingEntities(entities);
                        return entities;
                    };

                    twttr.txt.extractMentions = function (text) {
                        var screenNamesOnly = [],
                            screenNamesWithIndices = twttr.txt.extractMentionsWithIndices(text);

                        for (var i = 0; i < screenNamesWithIndices.length; i++) {
                            var screenName = screenNamesWithIndices[i].screenName;
                            screenNamesOnly.push(screenName);
                        }

                        return screenNamesOnly;
                    };

                    twttr.txt.extractMentionsWithIndices = function (text) {
                        var mentions = [],
                            mentionOrList,
                            mentionsOrLists = twttr.txt.extractMentionsOrListsWithIndices(text);

                        for (var i = 0; i < mentionsOrLists.length; i++) {
                            mentionOrList = mentionsOrLists[i];
                            if (mentionOrList.listSlug == '') {
                                mentions.push({
                                    screenName: mentionOrList.screenName,
                                    indices: mentionOrList.indices,
                                });
                            }
                        }

                        return mentions;
                    };

                    /**
                     * Extract list or user mentions.
                     * (Presence of listSlug indicates a list)
                     */
                    twttr.txt.extractMentionsOrListsWithIndices = function (text) {
                        if (!text || !text.match(twttr.txt.regexen.atSigns)) {
                            return [];
                        }

                        var possibleNames = [],
                            slashListname;

                        text.replace(
                            twttr.txt.regexen.validMentionOrList,
                            function (match, before, atSign, screenName, slashListname, offset, chunk) {
                                var after = chunk.slice(offset + match.length);
                                if (!after.match(twttr.txt.regexen.endMentionMatch)) {
                                    slashListname = slashListname || '';
                                    var startPosition = offset + before.length;
                                    var endPosition = startPosition + screenName.length + slashListname.length + 1;
                                    possibleNames.push({
                                        screenName: screenName,
                                        listSlug: slashListname,
                                        indices: [startPosition, endPosition],
                                    });
                                }
                            }
                        );

                        return possibleNames;
                    };

                    twttr.txt.extractReplies = function (text) {
                        if (!text) {
                            return null;
                        }

                        var possibleScreenName = text.match(twttr.txt.regexen.validReply);
                        if (!possibleScreenName || RegExp.rightContext.match(twttr.txt.regexen.endMentionMatch)) {
                            return null;
                        }

                        return possibleScreenName[1];
                    };

                    twttr.txt.extractUrls = function (text, options) {
                        var urlsOnly = [],
                            urlsWithIndices = twttr.txt.extractUrlsWithIndices(text, options);

                        for (var i = 0; i < urlsWithIndices.length; i++) {
                            urlsOnly.push(urlsWithIndices[i].url);
                        }

                        return urlsOnly;
                    };

                    twttr.txt.extractUrlsWithIndices = function (text, options) {
                        if (!options) {
                            options = { extractUrlsWithoutProtocol: true };
                        }
                        if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
                            return [];
                        }

                        var urls = [];

                        while (twttr.txt.regexen.extractUrl.exec(text)) {
                            var before = RegExp.$2,
                                url = RegExp.$3,
                                protocol = RegExp.$4,
                                domain = RegExp.$5,
                                path = RegExp.$7;
                            var endPosition = twttr.txt.regexen.extractUrl.lastIndex,
                                startPosition = endPosition - url.length;

                            // if protocol is missing and domain contains non-ASCII characters,
                            // extract ASCII-only domains.
                            if (!protocol) {
                                if (
                                    !options.extractUrlsWithoutProtocol ||
                                    before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)
                                ) {
                                    continue;
                                }
                                var lastUrl = null,
                                    asciiEndPosition = 0;
                                domain.replace(twttr.txt.regexen.validAsciiDomain, function (asciiDomain) {
                                    var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
                                    asciiEndPosition = asciiStartPosition + asciiDomain.length;
                                    lastUrl = {
                                        url: asciiDomain,
                                        indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition],
                                    };
                                    if (
                                        path ||
                                        asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain) ||
                                        !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)
                                    ) {
                                        urls.push(lastUrl);
                                    }
                                });

                                // no ASCII-only domain found. Skip the entire URL.
                                if (lastUrl == null) {
                                    continue;
                                }

                                // lastUrl only contains domain. Need to add path and query if they exist.
                                if (path) {
                                    lastUrl.url = url.replace(domain, lastUrl.url);
                                    lastUrl.indices[1] = endPosition;
                                }
                            } else {
                                // In the case of t.co URLs, don't allow additional path characters.
                                if (url.match(twttr.txt.regexen.validTcoUrl)) {
                                    url = RegExp.lastMatch;
                                    endPosition = startPosition + url.length;
                                }
                                urls.push({
                                    url: url,
                                    indices: [startPosition, endPosition],
                                });
                            }
                        }

                        return urls;
                    };

                    twttr.txt.extractHashtags = function (text) {
                        var hashtagsOnly = [],
                            hashtagsWithIndices = twttr.txt.extractHashtagsWithIndices(text);

                        for (var i = 0; i < hashtagsWithIndices.length; i++) {
                            hashtagsOnly.push(hashtagsWithIndices[i].hashtag);
                        }

                        return hashtagsOnly;
                    };

                    twttr.txt.extractHashtagsWithIndices = function (text, options) {
                        if (!options) {
                            options = { checkUrlOverlap: true };
                        }

                        if (!text || !text.match(twttr.txt.regexen.hashSigns)) {
                            return [];
                        }

                        var tags = [];

                        text.replace(
                            twttr.txt.regexen.validHashtag,
                            function (match, before, hash, hashText, offset, chunk) {
                                var after = chunk.slice(offset + match.length);
                                if (after.match(twttr.txt.regexen.endHashtagMatch)) return;
                                var startPosition = offset + before.length;
                                var endPosition = startPosition + hashText.length + 1;
                                tags.push({
                                    hashtag: hashText,
                                    indices: [startPosition, endPosition],
                                });
                            }
                        );

                        if (options.checkUrlOverlap) {
                            // also extract URL entities
                            var urls = twttr.txt.extractUrlsWithIndices(text);
                            if (urls.length > 0) {
                                var entities = tags.concat(urls);
                                // remove overlap
                                twttr.txt.removeOverlappingEntities(entities);
                                // only push back hashtags
                                tags = [];
                                for (var i = 0; i < entities.length; i++) {
                                    if (entities[i].hashtag) {
                                        tags.push(entities[i]);
                                    }
                                }
                            }
                        }

                        return tags;
                    };

                    twttr.txt.extractCashtags = function (text) {
                        var cashtagsOnly = [],
                            cashtagsWithIndices = twttr.txt.extractCashtagsWithIndices(text);

                        for (var i = 0; i < cashtagsWithIndices.length; i++) {
                            cashtagsOnly.push(cashtagsWithIndices[i].cashtag);
                        }

                        return cashtagsOnly;
                    };

                    twttr.txt.extractCashtagsWithIndices = function (text) {
                        if (!text || text.indexOf('$') == -1) {
                            return [];
                        }

                        var tags = [];

                        text.replace(
                            twttr.txt.regexen.validCashtag,
                            function (match, before, dollar, cashtag, offset, chunk) {
                                var startPosition = offset + before.length;
                                var endPosition = startPosition + cashtag.length + 1;
                                tags.push({
                                    cashtag: cashtag,
                                    indices: [startPosition, endPosition],
                                });
                            }
                        );

                        return tags;
                    };

                    twttr.txt.modifyIndicesFromUnicodeToUTF16 = function (text, entities) {
                        twttr.txt.convertUnicodeIndices(text, entities, false);
                    };

                    twttr.txt.modifyIndicesFromUTF16ToUnicode = function (text, entities) {
                        twttr.txt.convertUnicodeIndices(text, entities, true);
                    };

                    twttr.txt.getUnicodeTextLength = function (text) {
                        return text.replace(twttr.txt.regexen.non_bmp_code_pairs, ' ').length;
                    };

                    twttr.txt.convertUnicodeIndices = function (text, entities, indicesInUTF16) {
                        if (entities.length == 0) {
                            return;
                        }

                        var charIndex = 0;
                        var codePointIndex = 0;

                        // sort entities by start index
                        entities.sort(function (a, b) {
                            return a.indices[0] - b.indices[0];
                        });
                        var entityIndex = 0;
                        var entity = entities[0];

                        while (charIndex < text.length) {
                            if (entity.indices[0] == (indicesInUTF16 ? charIndex : codePointIndex)) {
                                var len = entity.indices[1] - entity.indices[0];
                                entity.indices[0] = indicesInUTF16 ? codePointIndex : charIndex;
                                entity.indices[1] = entity.indices[0] + len;

                                entityIndex++;
                                if (entityIndex == entities.length) {
                                    // no more entity
                                    break;
                                }
                                entity = entities[entityIndex];
                            }

                            var c = text.charCodeAt(charIndex);
                            if (0xd800 <= c && c <= 0xdbff && charIndex < text.length - 1) {
                                // Found high surrogate char
                                c = text.charCodeAt(charIndex + 1);
                                if (0xdc00 <= c && c <= 0xdfff) {
                                    // Found surrogate pair
                                    charIndex++;
                                }
                            }
                            codePointIndex++;
                            charIndex++;
                        }
                    };

                    // this essentially does text.split(/<|>/)
                    // except that won't work in IE, where empty strings are ommitted
                    // so "<>".split(/<|>/) => [] in IE, but is ["", "", ""] in all others
                    // but "<<".split("<") => ["", "", ""]
                    twttr.txt.splitTags = function (text) {
                        var firstSplits = text.split('<'),
                            secondSplits,
                            allSplits = [],
                            split;

                        for (var i = 0; i < firstSplits.length; i += 1) {
                            split = firstSplits[i];
                            if (!split) {
                                allSplits.push('');
                            } else {
                                secondSplits = split.split('>');
                                for (var j = 0; j < secondSplits.length; j += 1) {
                                    allSplits.push(secondSplits[j]);
                                }
                            }
                        }

                        return allSplits;
                    };

                    twttr.txt.hitHighlight = function (text, hits, options) {
                        var defaultHighlightTag = 'em';

                        hits = hits || [];
                        options = options || {};

                        if (hits.length === 0) {
                            return text;
                        }

                        var tagName = options.tag || defaultHighlightTag,
                            tags = ['<' + tagName + '>', '</' + tagName + '>'],
                            chunks = twttr.txt.splitTags(text),
                            i,
                            j,
                            result = '',
                            chunkIndex = 0,
                            chunk = chunks[0],
                            prevChunksLen = 0,
                            chunkCursor = 0,
                            startInChunk = false,
                            chunkChars = chunk,
                            flatHits = [],
                            index,
                            hit,
                            tag,
                            placed,
                            hitSpot;

                        for (i = 0; i < hits.length; i += 1) {
                            for (j = 0; j < hits[i].length; j += 1) {
                                flatHits.push(hits[i][j]);
                            }
                        }

                        for (index = 0; index < flatHits.length; index += 1) {
                            hit = flatHits[index];
                            tag = tags[index % 2];
                            placed = false;

                            while (chunk != null && hit >= prevChunksLen + chunk.length) {
                                result += chunkChars.slice(chunkCursor);
                                if (startInChunk && hit === prevChunksLen + chunkChars.length) {
                                    result += tag;
                                    placed = true;
                                }

                                if (chunks[chunkIndex + 1]) {
                                    result += '<' + chunks[chunkIndex + 1] + '>';
                                }

                                prevChunksLen += chunkChars.length;
                                chunkCursor = 0;
                                chunkIndex += 2;
                                chunk = chunks[chunkIndex];
                                chunkChars = chunk;
                                startInChunk = false;
                            }

                            if (!placed && chunk != null) {
                                hitSpot = hit - prevChunksLen;
                                result += chunkChars.slice(chunkCursor, hitSpot) + tag;
                                chunkCursor = hitSpot;
                                if (index % 2 === 0) {
                                    startInChunk = true;
                                } else {
                                    startInChunk = false;
                                }
                            } else if (!placed) {
                                placed = true;
                                result += tag;
                            }
                        }

                        if (chunk != null) {
                            if (chunkCursor < chunkChars.length) {
                                result += chunkChars.slice(chunkCursor);
                            }
                            for (index = chunkIndex + 1; index < chunks.length; index += 1) {
                                result += index % 2 === 0 ? chunks[index] : '<' + chunks[index] + '>';
                            }
                        }

                        return result;
                    };

                    var MAX_LENGTH = 140;

                    // Returns the length of Tweet text with consideration to t.co URL replacement
                    // and chars outside the basic multilingual plane that use 2 UTF16 code points
                    twttr.txt.getTweetLength = function (text, options) {
                        if (!options) {
                            options = {
                                // These come from https://api.twitter.com/1/help/configuration.json
                                // described by https://dev.twitter.com/docs/api/1/get/help/configuration
                                short_url_length: 23,
                                short_url_length_https: 23,
                            };
                        }
                        var textLength = twttr.txt.getUnicodeTextLength(text),
                            urlsWithIndices = twttr.txt.extractUrlsWithIndices(text);
                        twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);

                        for (var i = 0; i < urlsWithIndices.length; i++) {
                            // Subtract the length of the original URL
                            textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];

                            // Add 23 characters for URL starting with https://
                            // http:// URLs still use https://t.co so they are 23 characters as well
                            if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
                                textLength += options.short_url_length_https;
                            } else {
                                textLength += options.short_url_length;
                            }
                        }

                        return textLength;
                    };

                    // Check the text for any reason that it may not be valid as a Tweet. This is meant as a pre-validation
                    // before posting to api.twitter.com. There are several server-side reasons for Tweets to fail but this pre-validation
                    // will allow quicker feedback.
                    //
                    // Returns false if this text is valid. Otherwise one of the following strings will be returned:
                    //
                    //   "too_long": if the text is too long
                    //   "empty": if the text is nil or empty
                    //   "invalid_characters": if the text contains non-Unicode or any of the disallowed Unicode characters
                    twttr.txt.isInvalidTweet = function (text) {
                        if (!text) {
                            return 'empty';
                        }

                        // Determine max length independent of URL length
                        if (twttr.txt.getTweetLength(text) > MAX_LENGTH) {
                            return 'too_long';
                        }

                        if (twttr.txt.hasInvalidCharacters(text)) {
                            return 'invalid_characters';
                        }

                        return false;
                    };

                    twttr.txt.hasInvalidCharacters = function (text) {
                        return twttr.txt.regexen.invalid_chars.test(text);
                    };

                    twttr.txt.isValidTweetText = function (text) {
                        return !twttr.txt.isInvalidTweet(text);
                    };

                    twttr.txt.isValidUsername = function (username) {
                        if (!username) {
                            return false;
                        }

                        var extracted = twttr.txt.extractMentions(username);

                        // Should extract the username minus the @ sign, hence the .slice(1)
                        return extracted.length === 1 && extracted[0] === username.slice(1);
                    };

                    var VALID_LIST_RE = regexSupplant(/^#{validMentionOrList}$/);

                    twttr.txt.isValidList = function (usernameList) {
                        var match = usernameList.match(VALID_LIST_RE);

                        // Must have matched and had nothing before or after
                        return !!(match && match[1] == '' && match[4]);
                    };

                    twttr.txt.isValidHashtag = function (hashtag) {
                        if (!hashtag) {
                            return false;
                        }

                        var extracted = twttr.txt.extractHashtags(hashtag);

                        // Should extract the hashtag minus the # sign, hence the .slice(1)
                        return extracted.length === 1 && extracted[0] === hashtag.slice(1);
                    };

                    twttr.txt.isValidUrl = function (url, unicodeDomains, requireProtocol) {
                        if (unicodeDomains == null) {
                            unicodeDomains = true;
                        }

                        if (requireProtocol == null) {
                            requireProtocol = true;
                        }

                        if (!url) {
                            return false;
                        }

                        var urlParts = url.match(twttr.txt.regexen.validateUrlUnencoded);

                        if (!urlParts || urlParts[0] !== url) {
                            return false;
                        }

                        var scheme = urlParts[1],
                            authority = urlParts[2],
                            path = urlParts[3],
                            query = urlParts[4],
                            fragment = urlParts[5];

                        if (
                            !(
                                (!requireProtocol ||
                                    (isValidMatch(scheme, twttr.txt.regexen.validateUrlScheme) &&
                                        scheme.match(/^https?$/i))) &&
                                isValidMatch(path, twttr.txt.regexen.validateUrlPath) &&
                                isValidMatch(query, twttr.txt.regexen.validateUrlQuery, true) &&
                                isValidMatch(fragment, twttr.txt.regexen.validateUrlFragment, true)
                            )
                        ) {
                            return false;
                        }

                        return (
                            (unicodeDomains &&
                                isValidMatch(authority, twttr.txt.regexen.validateUrlUnicodeAuthority)) ||
                            (!unicodeDomains && isValidMatch(authority, twttr.txt.regexen.validateUrlAuthority))
                        );
                    };

                    function isValidMatch(string, regex, optional) {
                        if (!optional) {
                            // RegExp["$&"] is the text of the last match
                            // blank strings are ok, but are falsy, so we check stringiness instead of truthiness
                            return typeof string === 'string' && string.match(regex) && RegExp['$&'] === string;
                        }

                        // RegExp["$&"] is the text of the last match
                        return !string || (string.match(regex) && RegExp['$&'] === string);
                    }

                    if (typeof module != 'undefined' && module.exports) {
                        module.exports = twttr.txt;
                    }

                    if (true) {
                        !((__WEBPACK_AMD_DEFINE_ARRAY__ = []),
                        (__WEBPACK_AMD_DEFINE_FACTORY__ = twttr.txt),
                        (__WEBPACK_AMD_DEFINE_RESULT__ =
                            typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function'
                                ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)
                                : __WEBPACK_AMD_DEFINE_FACTORY__),
                        __WEBPACK_AMD_DEFINE_RESULT__ !== undefined &&
                            (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
                    }

                    if (typeof window != 'undefined') {
                        if (window.twttr) {
                            for (var prop in twttr) {
                                window.twttr[prop] = twttr[prop];
                            }
                        } else {
                            window.twttr = twttr;
                        }
                    }
                })();
            },
            /* 2 */
            function (module, exports, __webpack_require__) {
                var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
                /* WEBPACK VAR INJECTION */ (function (module) {
                    'use strict';
                    var _typeof2 =
                        typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol'
                            ? function (obj) {
                                  return typeof obj;
                              }
                            : function (obj) {
                                  return obj && typeof Symbol === 'function' && obj.constructor === Symbol
                                      ? 'symbol'
                                      : typeof obj;
                              };
                    (function webpackUniversalModuleDefinition(root, factory) {
                        if (
                            (false ? 'undefined' : _typeof2(exports)) === 'object' &&
                            (false ? 'undefined' : _typeof2(module)) === 'object'
                        )
                            module.exports = factory();
                        else if (true)
                            !((__WEBPACK_AMD_DEFINE_ARRAY__ = []),
                            (__WEBPACK_AMD_DEFINE_FACTORY__ = factory),
                            (__WEBPACK_AMD_DEFINE_RESULT__ =
                                typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function'
                                    ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)
                                    : __WEBPACK_AMD_DEFINE_FACTORY__),
                            __WEBPACK_AMD_DEFINE_RESULT__ !== undefined &&
                                (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
                        else if ((typeof exports === 'undefined' ? 'undefined' : _typeof2(exports)) === 'object')
                            exports['PDFAnnotate'] = factory();
                        else root['PDFAnnotate'] = factory();
                    })(undefined, function () {
                        return (function (modules) {
                            // webpackBootstrap
                            // The module cache
                            var installedModules = {}; // The require function
                            function __webpack_require__(moduleId) {
                                // Check if module is in cache
                                if (installedModules[moduleId]) return installedModules[moduleId].exports; // Create a new module (and put it into the cache)
                                var module = (installedModules[moduleId] = {
                                    exports: {},
                                    id: moduleId,
                                    loaded: false,
                                }); // Execute the module function
                                modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded
                                module.loaded = true; // Return the exports of the module
                                return module.exports;
                            } // expose the modules object (__webpack_modules__)
                            __webpack_require__.m = modules; // expose the module cache
                            __webpack_require__.c = installedModules; // __webpack_public_path__
                            __webpack_require__.p = ''; // Load entry module and return exports
                            return __webpack_require__(0);
                        })([
                            /* 0 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                exports.default = _PDFJSAnnotate2.default;
                                module.exports = exports['default'];
                            },
                            /* 1 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _StoreAdapter = __webpack_require__(2);
                                var _StoreAdapter2 = _interopRequireDefault(_StoreAdapter);
                                var _LocalStoreAdapter = __webpack_require__(8);
                                var _LocalStoreAdapter2 = _interopRequireDefault(_LocalStoreAdapter);
                                var _render = __webpack_require__(10);
                                var _render2 = _interopRequireDefault(_render);
                                var _UI = __webpack_require__(28);
                                var _UI2 = _interopRequireDefault(_UI);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                exports.default = {
                                    /**
                                     * Abstract class that needs to be defined so PDFJSAnnotate
                                     * knows how to communicate with your server.
                                     */ StoreAdapter: _StoreAdapter2.default,
                                    /**
                                     * Implementation of StoreAdapter that stores annotation data to localStorage.
                                     */ LocalStoreAdapter: _LocalStoreAdapter2.default,
                                    /**
                                     * Abstract instance of StoreAdapter
                                     */ __storeAdapter: new _StoreAdapter2.default(),
                                    /**
                                     * Getter for the underlying StoreAdapter property
                                     *
                                     * @return {StoreAdapter}
                                     */ getStoreAdapter: function getStoreAdapter() {
                                        return this.__storeAdapter;
                                    },
                                    /**
                                     * Setter for the underlying StoreAdapter property
                                     *
                                     * @param {StoreAdapter} adapter The StoreAdapter implementation to be used.
                                     */ setStoreAdapter: function setStoreAdapter(adapter) {
                                        // TODO this throws an error when bundled
                                        // if (!(adapter instanceof StoreAdapter)) {
                                        //   throw new Error('adapter must be an instance of StoreAdapter');
                                        // }
                                        this.__storeAdapter = adapter;
                                    },
                                    /**
                                     * UI is a helper for instrumenting UI interactions for creating,
                                     * editing, and deleting annotations in the browser.
                                     */ UI: _UI2.default,
                                    /**
                                     * Render the annotations for a page in the PDF Document
                                     *
                                     * @param {SVGElement} svg The SVG element that annotations should be rendered to
                                     * @param {PageViewport} viewport The PDFPage.getViewport data
                                     * @param {Object} data The StoreAdapter.getAnnotations data
                                     * @return {Promise}
                                     */ render: _render2.default,
                                    /**
                                     * Convenience method for getting annotation data
                                     *
                                     * @alias StoreAdapter.getAnnotations
                                     * @param {String} documentId The ID of the document
                                     * @param {String} pageNumber The page number
                                     * @return {Promise}
                                     */ getAnnotations: function getAnnotations(documentId, pageNumber) {
                                        var _getStoreAdapter;
                                        return (_getStoreAdapter = this.getStoreAdapter()).getAnnotations.apply(
                                            _getStoreAdapter,
                                            arguments
                                        );
                                    },
                                };
                                module.exports = exports['default'];
                            },
                            /* 2 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _createClass = (function () {
                                    function defineProperties(target, props) {
                                        for (var i = 0; i < props.length; i++) {
                                            var descriptor = props[i];
                                            descriptor.enumerable = descriptor.enumerable || false;
                                            descriptor.configurable = true;
                                            if ('value' in descriptor) descriptor.writable = true;
                                            Object.defineProperty(target, descriptor.key, descriptor);
                                        }
                                    }
                                    return function (Constructor, protoProps, staticProps) {
                                        if (protoProps) defineProperties(Constructor.prototype, protoProps);
                                        if (staticProps) defineProperties(Constructor, staticProps);
                                        return Constructor;
                                    };
                                })();
                                var _abstractFunction = __webpack_require__(3);
                                var _abstractFunction2 = _interopRequireDefault(_abstractFunction);
                                var _event = __webpack_require__(4);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                function _classCallCheck(instance, Constructor) {
                                    if (!(instance instanceof Constructor)) {
                                        throw new TypeError('Cannot call a class as a function');
                                    }
                                }
                                // Adapter should never be invoked publicly
                                var StoreAdapter = (function () {
                                    /**
                                     * Create a new StoreAdapter instance
                                     *
                                     * @param {Object} [definition] The definition to use for overriding abstract methods
                                     */ function StoreAdapter() {
                                        var _this = this;
                                        var definition =
                                            arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
                                        _classCallCheck(this, StoreAdapter); // Copy each function from definition if it is a function we know about
                                        Object.keys(definition).forEach(function (key) {
                                            if (
                                                typeof definition[key] === 'function' &&
                                                typeof _this[key] === 'function'
                                            ) {
                                                _this[key] = definition[key];
                                            }
                                        });
                                    }
                                    _createClass(StoreAdapter, [
                                        /**
                                         * Get all the annotations for a given document and page number.
                                         *
                                         * @param {String} documentId The ID for the document the annotations belong to
                                         * @param {Number} pageNumber The number of the page the annotations belong to
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__getAnnotations',
                                            value: function __getAnnotations(documentId, pageNumber) {
                                                (0, _abstractFunction2.default)('getAnnotations');
                                            },
                                        },
                                        /**
                                         * Get the definition for a specific annotation.
                                         *
                                         * @param {String} documentId The ID for the document the annotation belongs to
                                         * @param {String} annotationId The ID for the annotation
                                         * @return {Promise}
                                         */
                                        {
                                            key: 'getAnnotation',
                                            value: function getAnnotation(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('getAnnotation');
                                            },
                                        },
                                        /**
                                         * Add an annotation
                                         *
                                         * @param {String} documentId The ID for the document to add the annotation to
                                         * @param {String} pageNumber The page number to add the annotation to
                                         * @param {Object} annotation The definition for the new annotation
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__addAnnotation',
                                            value: function __addAnnotation(documentId, pageNumber, annotation) {
                                                (0, _abstractFunction2.default)('addAnnotation');
                                            },
                                        },
                                        /**
                                         * Edit an annotation
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} pageNumber the page number of the annotation
                                         * @param {Object} annotation The definition of the modified annotation
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__editAnnotation',
                                            value: function __editAnnotation(
                                                documentId,
                                                page,
                                                annotationId,
                                                annotation
                                            ) {
                                                (0, _abstractFunction2.default)('editAnnotation');
                                            },
                                        },
                                        // Original:
                                        //                        {key:'__editAnnotation',value:function __editAnnotation(documentId,pageNumber,annotation){
                                        //                                (0,_abstractFunction2.default)('editAnnotation');
                                        //                            }
                                        //                        },
                                        /**
                                         * Delete an annotation
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} annotationId The ID for the annotation
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__deleteAnnotation',
                                            value: function __deleteAnnotation(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('deleteAnnotation');
                                            },
                                        },
                                        /**
                                         * Get all the comments for an annotation
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} annotationId The ID for the annotation
                                         * @return {Promise}
                                         */
                                        {
                                            key: 'getComments',
                                            value: function getComments(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('getComments');
                                            },
                                        },

                                        /**
                                         * Get all the questions of one page
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} pageNumber The number of the requested page
                                         * @return {Promise}
                                         */
                                        {
                                            key: 'getQuestions',
                                            value: function getQuestions(documentId, pageNumber, pattern) {
                                                (0, _abstractFunction2.default)('getQuestions');
                                            },
                                        },
                                        /**
                                         * Get all the questions of one page
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} pageNumber The number of the requested page
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__getQuestions',
                                            value: function getQuestions(documentId, pageNumber, pattern) {
                                                (0, _abstractFunction2.default)('getQuestions');
                                            },
                                        },
                                        /**
                                         * Add a new comment
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} annotationId The ID for the annotation
                                         * @param {Object} content The definition of the comment
                                         * @return {Promise}
                                         *
                                         */
                                        {
                                            key: '__addComment',
                                            value: function __addComment(documentId, annotationId, content) {
                                                (0, _abstractFunction2.default)('addComment');
                                            },
                                        },
                                        /**
                                         * Report a new comment
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The id of the comment that is to be reported
                                         * @param {String} reason for reporting the comment: 'inaccurate', 'inappropriate' or 'other'
                                         * @param {Object} content The definition of the complaint
                                         * @return {Promise}
                                         *
                                         */
                                        {
                                            key: '__reportComment',
                                            value: function reportComment(documentId, commentId, reason, content) {
                                                (0, _abstractFunction2.default)('reportComment');
                                            },
                                        },
                                        /**
                                         * Delete a comment
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__deleteComment',
                                            value: function __deleteComment(documentId, commentId) {
                                                (0, _abstractFunction2.default)('deleteComment');
                                            },
                                        },
                                        /**
                                         * Hide a comment from participants view (i.e. display it as deleted)
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__hideComment',
                                            value: function __hideComment(documentId, commentId) {
                                                (0, _abstractFunction2.default)('hideComment');
                                            },
                                        },
                                        /**
                                         * Redisplay a comment for participants
                                         *
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__redisplayComment',
                                            value: function __redisplayComment(documentId, commentId) {
                                                (0, _abstractFunction2.default)('redisplayComment');
                                            },
                                        },
                                        /**
                                         * Vote for a comment
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__getInformation',
                                            value: function __getInformation(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('getInformation');
                                            },
                                        },

                                        /**
                                         * Vote for a comment
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__voteComment',
                                            value: function __voteComment(documentId, commentId) {
                                                (0, _abstractFunction2.default)('voteComment');
                                            },
                                        },

                                        /**
                                         * Edit a comment
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__editComment',
                                            value: function __editComment(documentId, commentId) {
                                                (0, _abstractFunction2.default)('editComment');
                                            },
                                        },

                                        /**
                                         * Subscribe to a question
                                         * @param {String} documentId The ID for the document
                                         * @param {String} commentId The ID for the comment
                                         * @return {Promise}
                                         */
                                        {
                                            key: '__subscribeQuestion',
                                            value: function __subscribeQuestion(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('subscribeQuestion');
                                            },
                                        },

                                        {
                                            key: '__unsubscribeQuestion',
                                            value: function __unsubscribeQuestion(documentId, annotationId) {
                                                (0, _abstractFunction2.default)('unsubscribeQuestion');
                                            },
                                        },

                                        {
                                            key: '__markSolved',
                                            value: function __markSolved(documentId, comment) {
                                                (0, _abstractFunction2.default)('markSolved');
                                            },
                                        },

                                        {
                                            key: '__getCommentsToPrint',
                                            value: function __getCommentsToPrint(documentId) {
                                                (0, _abstractFunction2.default)('getCommentsToPrint');
                                            },
                                        },

                                        {
                                            key: 'getAnnotations',
                                            get: function get() {
                                                return this.__getAnnotations;
                                            },
                                            set: function set(fn) {
                                                this.__getAnnotations = function getAnnotations(
                                                    documentId,
                                                    pageNumber
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (annotations) {
                                                        // TODO may be best to have this happen on the server
                                                        if (annotations.annotations) {
                                                            annotations.annotations.forEach(function (a) {
                                                                a.documentId = documentId;
                                                            });
                                                        }
                                                        return annotations;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'addAnnotation',
                                            get: function get() {
                                                return this.__addAnnotation;
                                            },
                                            set: function set(fn) {
                                                this.__addAnnotation = function addAnnotation(
                                                    documentId,
                                                    pageNumber,
                                                    annotation
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (annotation) {
                                                        (0,
                                                        _event.fireEvent)('annotation:add', documentId, pageNumber, annotation);
                                                        return annotation;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'editAnnotation',
                                            get: function get() {
                                                return this.__editAnnotation;
                                            },
                                            set: function set(fn) {
                                                this.__editAnnotation = function editAnnotation(
                                                    documentId,
                                                    page,
                                                    annotationId,
                                                    annotation
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (annotation) {
                                                        (0,
                                                        _event.fireEvent)('annotation:edit', documentId, annotationId, annotation);
                                                        return annotation;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'deleteAnnotation',
                                            get: function get() {
                                                return this.__deleteAnnotation;
                                            },
                                            set: function set(fn) {
                                                this.__deleteAnnotation = function deleteAnnotation(
                                                    documentId,
                                                    annotationId
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'annotation:delete',
                                                                documentId,
                                                                annotationId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'addComment',
                                            get: function get() {
                                                return this.__addComment;
                                            },
                                            set: function set(fn) {
                                                this.__addComment = function addComment(
                                                    documentId,
                                                    annotationId,
                                                    content
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (comment) {
                                                        (0,
                                                        _event.fireEvent)('comment:add', documentId, annotationId, comment);
                                                        return comment;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'reportComment',
                                            get: function get() {
                                                return this.__reportComment;
                                            },
                                            set: function set(fn) {
                                                this.__reportComment = function reportComment(
                                                    documentId,
                                                    commentId,
                                                    reason,
                                                    content
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (comment) {
                                                        (0,
                                                        _event.fireEvent)('comment:report', documentId, commentId, reason, content);
                                                        return comment;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'deleteComment',
                                            get: function get() {
                                                return this.__deleteComment;
                                            },
                                            set: function set(fn) {
                                                this.__deleteComment = function deleteComment(documentId, commentId) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:delete',
                                                                documentId,
                                                                commentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'hideComment',
                                            get: function get() {
                                                return this.__hideComment;
                                            },
                                            set: function set(fn) {
                                                this.__hideComment = function hideComment(documentId, commentId) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:hide',
                                                                documentId,
                                                                commentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'redisplayComment',
                                            get: function get() {
                                                return this.__redisplayComment;
                                            },
                                            set: function set(fn) {
                                                this.__redisplayComment = function redisplayComment(
                                                    documentId,
                                                    commentId
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:redisplay',
                                                                documentId,
                                                                commentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'getInformation',
                                            get: function get() {
                                                return this.__getInformation;
                                            },
                                            set: function set(fn) {
                                                this.__getInformation = function getInformation(
                                                    documentId,
                                                    annotationId
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'annotation:getInformation',
                                                                documentId,
                                                                annotationId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'voteComment',
                                            get: function get() {
                                                return this.__voteComment;
                                            },
                                            set: function set(fn) {
                                                this.__voteComment = function voteComment(documentId, commentId) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:vote',
                                                                documentId,
                                                                commentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'editComment',
                                            get: function get() {
                                                return this.__editComment;
                                            },
                                            set: function set(fn) {
                                                this.__editComment = function editComment(documentId, commentId) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:edit',
                                                                documentId,
                                                                commentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'subscribeQuestion',
                                            get: function get() {
                                                return this.__subscribeQuestion;
                                            },
                                            set: function set(fn) {
                                                this.__subscribeQuestion = function subscribeQuestion(
                                                    documentId,
                                                    annotationId
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:subscribe',
                                                                documentId,
                                                                annotationId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'unsubscribeQuestion',
                                            get: function get() {
                                                return this.__unsubscribeQuestion;
                                            },
                                            set: function set(fn) {
                                                this.__unsubscribeQuestion = function unsubscribeQuestion(
                                                    documentId,
                                                    annotationId
                                                ) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:unsubscribe',
                                                                documentId,
                                                                annotationId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'markSolved',
                                            get: function get() {
                                                return this.__markSolved;
                                            },
                                            set: function set(fn) {
                                                this.__markSolved = function markSolved(documentId, comment) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'comment:markSolved',
                                                                documentId,
                                                                comment
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                        {
                                            key: 'getCommentsToPrint',
                                            get: function get() {
                                                return this.__getCommentsToPrint;
                                            },
                                            set: function set(fn) {
                                                this.__getCommentsToPrint = function getCommentsToPrint(documentId) {
                                                    return fn.apply(undefined, arguments).then(function (success) {
                                                        if (success) {
                                                            (0, _event.fireEvent)(
                                                                'document:printannotations',
                                                                documentId
                                                            );
                                                        }
                                                        return success;
                                                    });
                                                };
                                            },
                                        },
                                    ]);
                                    return StoreAdapter;
                                })(); //Ende StoreAdapter
                                exports.default = StoreAdapter;
                                module.exports = exports['default'];
                            },
                            /* 3 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = abstractFunction;
                                /**
                                 * Throw an Error for an abstract function that hasn't been implemented.
                                 *
                                 * @param {String} name The name of the abstract function
                                 */
                                function abstractFunction(name) {
                                    throw new Error(name + ' is not implemented');
                                }
                                module.exports = exports['default'];
                            },
                            /* 4 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.fireEvent = fireEvent;
                                exports.addEventListener = addEventListener;
                                exports.removeEventListener = removeEventListener;
                                exports.handleDocClick = handleDocumentClickFunction;
                                var _events = __webpack_require__(5);
                                var _events2 = _interopRequireDefault(_events);
                                var _utils = __webpack_require__(6);
                                var _editoverlay = __webpack_require__(29);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var emitter = new _events2.default();
                                var clickNode = void 0;
                                var count = 0;

                                /**
                                 * This function handles the document click. It looks for annotations under the click point.
                                 * If there are more than one annotation, a modal window pops up and the user can select, which one he/she wanted to click.
                                 * @param {type} e the event object of the click
                                 * @param {type} commid
                                 * @returns {undefined}
                                 */
                                function handleDocumentClickFunction(e, commid = null) {
                                    let tar = $('#' + e.target.id);
                                    if (tar.hasClass('moodle-dialogue') || tar.parents('.moodle-dialogue').length > 0) {
                                        return; //Dialog (for example from atto-editor) was clicked.
                                    }
                                    //the last parameter is true to get an array instead of the first annotation found.
                                    var target = (0, _utils.findAnnotationAtPoint)(e.clientX, e.clientY, true);

                                    if (
                                        target != null &&
                                        Object.prototype.toString.call(target) === '[object Array]' &&
                                        target.length > 1
                                    ) {
                                        //creats a modal window to select which one of the overlapping annotation should be selected.
                                        var modal = document.createElement('div');
                                        modal.id = 'myModal';
                                        modal.className = 'modal hide fade';
                                        modal.setAttribute('tabindex', -1);
                                        modal.setAttribute('role', 'dialog');
                                        modal.setAttribute('aria-labelledby', 'myModalLabel');
                                        modal.setAttribute('aria-hidden', 'true');
                                        var modaldialog = document.createElement('div');
                                        modaldialog.className = 'modal-dialog';
                                        var modalcontent = document.createElement('div');
                                        modalcontent.className = 'modal-content';
                                        var modalheader = document.createElement('div');
                                        modalheader.className = 'modal-header';
                                        var headerClose = document.createElement('button');
                                        headerClose.setAttribute('type', 'button');
                                        headerClose.className = 'close';
                                        headerClose.setAttribute('data-dismiss', 'modal');
                                        headerClose.setAttribute('aria-hidden', 'true');
                                        headerClose.innerHTML = 'x';

                                        headerClose.addEventListener('click', function () {
                                            $('body').removeClass('modal-open');
                                            $('#myModal').remove();
                                        });

                                        var headertitle = document.createElement('h3');
                                        headertitle.id = 'myModalLabel';
                                        headertitle.innerHTML = M.util.get_string('decision', 'pdfannotator');
                                        headertitle.style.display = 'inline-block';
                                        modalheader.appendChild(headertitle);
                                        modalheader.appendChild(headerClose);

                                        var modalbody = document.createElement('div');
                                        modalbody.className = 'modal-body';
                                        var bodytext = document.createElement('p');
                                        bodytext.innerHTML = M.util.get_string(
                                            'decision:overlappingAnnotation',
                                            'pdfannotator'
                                        );
                                        modalbody.appendChild(bodytext);

                                        modalcontent.appendChild(modalheader);
                                        modalcontent.appendChild(modalbody);

                                        modaldialog.appendChild(modalcontent);
                                        modal.appendChild(modaldialog);

                                        $('#body-wrapper').append(modal);
                                        $('#myModal').modal({ backdrop: false });
                                        for (var i = 0; i < target.length; i++) {
                                            (function (innerI) {
                                                var elemUse = document.createElement('button');
                                                var elemType = target[innerI].getAttribute('data-pdf-annotate-type');
                                                var elemImg = document.createElement('img');
                                                elemImg.setAttribute('style', 'pointer-events:none;');
                                                switch (elemType) {
                                                    case 'point':
                                                        elemImg.alt = M.util.get_string('point', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('point', 'pdfannotator');
                                                        elemImg.src = M.util.image_url('pinbild', 'pdfannotator');
                                                        break;
                                                    case 'area':
                                                        elemImg.alt = M.util.get_string('rectangle', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('rectangle', 'pdfannotator');
                                                        elemImg.src = M.util.image_url('i/completion-manual-n', 'core');
                                                        break;
                                                    case 'highlight':
                                                        elemImg.alt = M.util.get_string('highlight', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('highlight', 'pdfannotator');
                                                        elemImg.src = M.util.image_url(
                                                            'text_highlight_picker',
                                                            'pdfannotator'
                                                        );
                                                        break;
                                                    case 'strikeout':
                                                        elemImg.alt = M.util.get_string('strikeout', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('strikeout', 'pdfannotator');
                                                        elemImg.src = M.util.image_url('strikethrough', 'pdfannotator');
                                                        break;
                                                    case 'textbox':
                                                        elemImg.alt = M.util.get_string('textbox', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('textbox', 'pdfannotator');
                                                        elemImg.src = M.util.image_url(
                                                            'text_color_picker',
                                                            'pdfannotator'
                                                        );
                                                        break;
                                                    case 'drawing':
                                                        elemImg.alt = M.util.get_string('drawing', 'pdfannotator');
                                                        elemImg.title = M.util.get_string('drawing', 'pdfannotator');
                                                        elemImg.src = M.util.image_url('editstring', 'pdfannotator');
                                                        break;
                                                    case 'default':
                                                        elemImg.alt = 'undefined';
                                                        elemImg.title = 'undefined';
                                                        elemImg.src = '';
                                                }

                                                elemUse.appendChild(elemImg);

                                                elemUse.addEventListener('click', function () {
                                                    // Emit annotation:blur if clickNode is no longer clicked
                                                    if (clickNode && clickNode !== target[innerI]) {
                                                        emitter.emit('annotation:blur', clickNode);
                                                    } // Emit annotation:click if target was clicked
                                                    if (target[innerI]) {
                                                        emitter.emit('annotation:click', target[innerI]);
                                                    }
                                                    clickNode = target[innerI];
                                                    $('body').removeClass('modal-open');
                                                    $('#myModal').remove();
                                                });
                                                elemUse.addEventListener('mouseover', function () {
                                                    _editoverlay.createEditOverlay(target[innerI]);
                                                });
                                                elemUse.addEventListener('mouseout', function () {
                                                    _editoverlay.destroyEditOverlay(target[innerI]);
                                                });
                                                modalbody.appendChild(elemUse);
                                            })(i);
                                        }
                                    } else {
                                        // Emit annotation:blur if clickNode is no longer clicked, but not if another node is clicked.
                                        if (clickNode && !target) {
                                            emitter.emit('annotation:blur', clickNode);
                                        }
                                        // Emit annotation:click if target was clicked.
                                        if (target) {
                                            if (commid !== null) {
                                                target.markCommentid = commid;
                                            }
                                            emitter.emit('annotation:click', target);
                                        }
                                        clickNode = target;
                                    }

                                    return;
                                }

                                document.addEventListener('click', function handleDocumentClick(e) {
                                    //R: The ClickEvent should only be happen, if the cursor is selected.
                                    if (document.querySelector('.cursor').className.indexOf('active') === -1) {
                                        return;
                                    }
                                    //if the click is in atto editor nothing should happen.
                                    var editorNodes = document.querySelectorAll('div.editor_atto_wrap')[0];
                                    var clickedElement;
                                    if (e.target.id) {
                                        clickedElement = '#' + e.target.id;
                                    } else if (e.target.className[0]) {
                                        clickedElement = '.' + e.target.className;
                                    } else {
                                        clickedElement = '';
                                    }
                                    if (clickedElement && editorNodes && editorNodes.querySelector(clickedElement)) {
                                        return;
                                    }
                                    //If moodle Modal beeing clicked.
                                    var modal = document.querySelectorAll('.modal.show')[0];
                                    if (modal) {
                                        if (clickedElement && modal.querySelector(clickedElement)) {
                                            return;
                                        }
                                    }

                                    //If Modal Dialogue beeing clicked.
                                    var clickedMoodleDialogue = e.target.closest('.moodle-dialogue-base');
                                    if (clickedMoodleDialogue) {
                                        return;
                                    }

                                    //if the click is on an input field or link or icon in editor toolbar ('I') nothing should happen.
                                    if (
                                        e.target.tagName === 'INPUT' ||
                                        e.target.tagName === 'A' ||
                                        e.target.tagName === 'SELECT' ||
                                        e.target.tagName === 'I' ||
                                        e.target.tagName === 'BUTTON'
                                    ) {
                                        return;
                                    }
                                    //R: if the click is on the Commentlist nothing should happen.
                                    if (
                                        (typeof e.target.getAttribute('id') != 'string' &&
                                            e.target.id.indexOf('comment') !== -1) ||
                                        e.target.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('chat') !== -1
                                    ) {
                                        return;
                                    }
                                    if (!(0, _utils.findSVGAtPoint)(e.clientX, e.clientY, true)) {
                                        return;
                                    }

                                    handleDocumentClickFunction(e);
                                });

                                function fireEvent() {
                                    if (arguments[0] === 'annotation:click') {
                                        clickNode = arguments[1];
                                    }
                                    emitter.emit.apply(emitter, arguments);
                                }
                                function addEventListener() {
                                    emitter.on.apply(emitter, arguments);
                                }
                                function removeEventListener() {
                                    emitter.removeListener.apply(emitter, arguments);
                                }
                            },
                            /* 5 */
                            function (module, exports) {
                                // Copyright Joyent, Inc. and other Node contributors.
                                //
                                // Permission is hereby granted, free of charge, to any person obtaining a
                                // copy of this software and associated documentation files (the
                                // "Software"), to deal in the Software without restriction, including
                                // without limitation the rights to use, copy, modify, merge, publish,
                                // distribute, sublicense, and/or sell copies of the Software, and to permit
                                // persons to whom the Software is furnished to do so, subject to the
                                // following conditions:
                                //
                                // The above copyright notice and this permission notice shall be included
                                // in all copies or substantial portions of the Software.
                                //
                                // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
                                // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
                                // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
                                // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
                                // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
                                // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
                                // USE OR OTHER DEALINGS IN THE SOFTWARE.
                                function EventEmitter() {
                                    this._events = this._events || {};
                                    this._maxListeners = this._maxListeners || undefined;
                                }
                                module.exports = EventEmitter; // Backwards-compat with node 0.10.x
                                EventEmitter.EventEmitter = EventEmitter;
                                EventEmitter.prototype._events = undefined;
                                EventEmitter.prototype._maxListeners = undefined;
                                // By default EventEmitters will print a warning if more than 10 listeners are
                                // added to it. This is a useful default which helps finding memory leaks.
                                EventEmitter.defaultMaxListeners = 10;
                                // Obviously not all Emitters should be limited to 10. This function allows
                                // that to be increased. Set to zero for unlimited.
                                EventEmitter.prototype.setMaxListeners = function (n) {
                                    if (!isNumber(n) || n < 0 || isNaN(n))
                                        throw TypeError('n must be a positive number');
                                    this._maxListeners = n;
                                    return this;
                                };
                                EventEmitter.prototype.emit = function (type) {
                                    var er, handler, len, args, i, listeners;
                                    if (!this._events) this._events = {}; // If there is no 'error' event listener then throw.
                                    if (type === 'error') {
                                        if (
                                            !this._events.error ||
                                            (isObject(this._events.error) && !this._events.error.length)
                                        ) {
                                            er = arguments[1];
                                            if (er instanceof Error) {
                                                throw er; // Unhandled 'error' event
                                            }
                                            throw TypeError('Uncaught, unspecified "error" event.');
                                        }
                                    }
                                    handler = this._events[type];
                                    if (isUndefined(handler)) return false;
                                    if (isFunction(handler)) {
                                        switch (
                                            arguments.length // fast cases
                                        ) {
                                            case 1:
                                                handler.call(this);
                                                break;
                                            case 2:
                                                handler.call(this, arguments[1]);
                                                break;
                                            case 3:
                                                handler.call(this, arguments[1], arguments[2]);
                                                break; // slower
                                            default:
                                                args = Array.prototype.slice.call(arguments, 1);
                                                handler.apply(this, args);
                                        }
                                    } else if (isObject(handler)) {
                                        args = Array.prototype.slice.call(arguments, 1);
                                        listeners = handler.slice();
                                        len = listeners.length;
                                        for (i = 0; i < len; i++) {
                                            listeners[i].apply(this, args);
                                        }
                                    }
                                    return true;
                                };
                                EventEmitter.prototype.addListener = function (type, listener) {
                                    var m;
                                    if (!isFunction(listener)) throw TypeError('listener must be a function');
                                    if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before
                                    // adding it to the listeners, first emit "newListener".
                                    if (this._events.newListener)
                                        this.emit(
                                            'newListener',
                                            type,
                                            isFunction(listener.listener) ? listener.listener : listener
                                        );
                                    if (!this._events[type])
                                        // Optimize the case of one listener. Don't need the extra array object.
                                        this._events[type] = listener;
                                    else if (isObject(this._events[type]))
                                        // If we've already got an array, just append.
                                        this._events[type].push(listener);
                                    // Adding the second element, need to change to array.
                                    else this._events[type] = [this._events[type], listener]; // Check for listener leak
                                    if (isObject(this._events[type]) && !this._events[type].warned) {
                                        if (!isUndefined(this._maxListeners)) {
                                            m = this._maxListeners;
                                        } else {
                                            m = EventEmitter.defaultMaxListeners;
                                        }
                                        if (m && m > 0 && this._events[type].length > m) {
                                            this._events[type].warned = true;
                                            console.error(
                                                '(node) warning: possible EventEmitter memory ' +
                                                    'leak detected. %d listeners added. ' +
                                                    'Use emitter.setMaxListeners() to increase limit.',
                                                this._events[type].length
                                            );
                                            if (typeof console.trace === 'function') {
                                                // not supported in IE 10
                                                console.trace();
                                            }
                                        }
                                    }
                                    return this;
                                };
                                EventEmitter.prototype.on = EventEmitter.prototype.addListener;
                                EventEmitter.prototype.once = function (type, listener) {
                                    if (!isFunction(listener)) throw TypeError('listener must be a function');
                                    var fired = false;
                                    function g() {
                                        this.removeListener(type, g);
                                        if (!fired) {
                                            fired = true;
                                            listener.apply(this, arguments);
                                        }
                                    }
                                    g.listener = listener;
                                    this.on(type, g);
                                    return this;
                                };
                                // emits a 'removeListener' event iff the listener was removed
                                EventEmitter.prototype.removeListener = function (type, listener) {
                                    var list, position, length, i;
                                    if (!isFunction(listener)) throw TypeError('listener must be a function');
                                    if (!this._events || !this._events[type]) return this;
                                    list = this._events[type];
                                    length = list.length;
                                    position = -1;
                                    if (
                                        list === listener ||
                                        (isFunction(list.listener) && list.listener === listener)
                                    ) {
                                        delete this._events[type];
                                        if (this._events.removeListener) this.emit('removeListener', type, listener);
                                    } else if (isObject(list)) {
                                        for (i = length; i-- > 0; ) {
                                            if (
                                                list[i] === listener ||
                                                (list[i].listener && list[i].listener === listener)
                                            ) {
                                                position = i;
                                                break;
                                            }
                                        }
                                        if (position < 0) return this;
                                        if (list.length === 1) {
                                            list.length = 0;
                                            delete this._events[type];
                                        } else {
                                            list.splice(position, 1);
                                        }
                                        if (this._events.removeListener) this.emit('removeListener', type, listener);
                                    }
                                    return this;
                                };
                                EventEmitter.prototype.removeAllListeners = function (type) {
                                    var key, listeners;
                                    if (!this._events) return this; // not listening for removeListener, no need to emit
                                    if (!this._events.removeListener) {
                                        if (arguments.length === 0) this._events = {};
                                        else if (this._events[type]) delete this._events[type];
                                        return this;
                                    } // emit removeListener for all listeners on all events
                                    if (arguments.length === 0) {
                                        for (key in this._events) {
                                            if (key === 'removeListener') continue;
                                            this.removeAllListeners(key);
                                        }
                                        this.removeAllListeners('removeListener');
                                        this._events = {};
                                        return this;
                                    }
                                    listeners = this._events[type];
                                    if (isFunction(listeners)) {
                                        this.removeListener(type, listeners);
                                    } else if (listeners) {
                                        // LIFO order
                                        while (listeners.length) {
                                            this.removeListener(type, listeners[listeners.length - 1]);
                                        }
                                    }
                                    delete this._events[type];
                                    return this;
                                };
                                EventEmitter.prototype.listeners = function (type) {
                                    var ret;
                                    if (!this._events || !this._events[type]) ret = [];
                                    else if (isFunction(this._events[type])) ret = [this._events[type]];
                                    else ret = this._events[type].slice();
                                    return ret;
                                };
                                EventEmitter.prototype.listenerCount = function (type) {
                                    if (this._events) {
                                        var evlistener = this._events[type];
                                        if (isFunction(evlistener)) return 1;
                                        else if (evlistener) return evlistener.length;
                                    }
                                    return 0;
                                };
                                EventEmitter.listenerCount = function (emitter, type) {
                                    return emitter.listenerCount(type);
                                };
                                function isFunction(arg) {
                                    return typeof arg === 'function';
                                }
                                function isNumber(arg) {
                                    return typeof arg === 'number';
                                }
                                function isObject(arg) {
                                    return (
                                        (typeof arg === 'undefined' ? 'undefined' : _typeof2(arg)) === 'object' &&
                                        arg !== null
                                    );
                                }
                                function isUndefined(arg) {
                                    return arg === void 0;
                                }
                            },
                            /* 6 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.BORDER_COLOR = undefined;
                                exports.findSVGContainer = findSVGContainer;
                                exports.findSVGAtPoint = findSVGAtPoint;
                                exports.findAnnotationAtPoint = findAnnotationAtPoint;
                                exports.pointIntersectsRect = pointIntersectsRect;
                                exports.getOffsetAnnotationRect = getOffsetAnnotationRect;
                                exports.getAnnotationRect = getAnnotationRect;
                                exports.scaleUp = scaleUp;
                                exports.scaleDown = scaleDown;
                                exports.getScroll = getScroll;
                                exports.getOffset = getOffset;
                                exports.disableUserSelect = disableUserSelect;
                                exports.enableUserSelect = enableUserSelect;
                                exports.getMetadata = getMetadata;
                                //R: Function to round digits
                                exports.roundDigits = roundDigits;
                                var _createStylesheet = __webpack_require__(7);
                                var _createStylesheet2 = _interopRequireDefault(_createStylesheet);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var BORDER_COLOR = (exports.BORDER_COLOR = '#00BFFF');
                                var userSelectStyleSheet = (0, _createStylesheet2.default)({
                                    body: {
                                        '-webkit-user-select': 'none',
                                        '-moz-user-select': 'none',
                                        '-ms-user-select': 'none',
                                        'user-select': 'none',
                                    },
                                });
                                userSelectStyleSheet.setAttribute('data-pdf-annotate-user-select', 'true');
                                /**
                                 * Find the SVGElement that contains all the annotations for a page
                                 *
                                 * @param {Element} node An annotation within that container
                                 * @return {SVGElement} The container SVG or null if it can't be found
                                 */ function findSVGContainer(node) {
                                    var parentNode = node;
                                    while ((parentNode = parentNode.parentNode) && parentNode !== document) {
                                        if (
                                            parentNode.nodeName.toUpperCase() === 'SVG' &&
                                            parentNode.getAttribute('data-pdf-annotate-container') === 'true'
                                        ) {
                                            return parentNode;
                                        }
                                    }
                                    return null;
                                }
                                /**
                                 * Find an SVGElement container at a given point
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Boolean} array If the return value should be an array or a single svg object.
                                 * @return {SVGElement} The container SVG or null if one can't be found. If more than one and array=true the return value is an array of SVGs.
                                 */ function findSVGAtPoint(x, y, array) {
                                    var elements = document.querySelectorAll('svg[data-pdf-annotate-container="true"]');
                                    if (array) {
                                        var ret = [];
                                        //end R
                                        for (var i = 0, l = elements.length; i < l; i++) {
                                            var el = elements[i];
                                            var rect = el.getBoundingClientRect();
                                            if (pointIntersectsRect(x, y, rect)) {
                                                ret.push(el);
                                            }
                                        }
                                        if (ret.length > 0) {
                                            return ret;
                                        }
                                    } else {
                                        for (var i = 0, l = elements.length; i < l; i++) {
                                            var el = elements[i];
                                            var rect = el.getBoundingClientRect();
                                            if (pointIntersectsRect(x, y, rect)) {
                                                return el;
                                            }
                                        }
                                    }
                                    return null;
                                }
                                /**
                                 * Find an Element that represents an annotation at a given point
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Boolean} array If the return value should be an array or a single svg object.
                                 * @return {Element} The annotation element or null if one can't be found. If array=true an array with annotations elements.
                                 */ function findAnnotationAtPoint(x, y, array) {
                                    var svg = findSVGAtPoint(x, y, array);
                                    if (!svg) {
                                        return;
                                    }
                                    if (array) {
                                        var elements = [];
                                        for (var j = 0; j < svg.length; j++) {
                                            elements.push(svg[j].querySelectorAll('[data-pdf-annotate-type]'));
                                        } // Find a target element within SVG
                                        var ret = [];
                                        for (var i = 0, l = elements.length; i < l; i++) {
                                            for (var inner = 0; inner < elements[i].length; inner++) {
                                                var el = elements[i][inner];
                                                if (pointIntersectsRect(x, y, getOffsetAnnotationRect(el))) {
                                                    ret.push(el);
                                                }
                                            }
                                        }
                                        if (ret.length === 1) {
                                            return ret[0];
                                        }
                                        if (ret.length > 0) {
                                            return ret;
                                        }
                                    } else {
                                        elements = svg.querySelectorAll('[data-pdf-annotate-type]');
                                        for (var i = 0, l = elements.length; i < l; i++) {
                                            var el = elements[i][inner];
                                            if (pointIntersectsRect(x, y, getOffsetAnnotationRect(el))) {
                                                return el;
                                            }
                                        }
                                    }
                                    return null;
                                }

                                /**
                                 * Determine if a point intersects a rect
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Object} rect The points of a rect (likely from getBoundingClientRect)
                                 * @return {Boolean} True if a collision occurs, otherwise false
                                 */ function pointIntersectsRect(x, y, rect) {
                                    return y >= rect.top && y <= rect.bottom && x >= rect.left && x <= rect.right;
                                }
                                /**
                                 * Get the rect of an annotation element accounting for offset.
                                 *
                                 * @param {Element} el The element to get the rect of
                                 * @return {Object} The dimensions of the element
                                 */ function getOffsetAnnotationRect(el) {
                                    var rect = getAnnotationRect(el);
                                    var _getOffset = getOffset(el);
                                    var offsetLeft = _getOffset.offsetLeft;
                                    var offsetTop = _getOffset.offsetTop;
                                    return {
                                        top: rect.top + offsetTop,
                                        left: rect.left + offsetLeft,
                                        right: rect.right + offsetLeft,
                                        bottom: rect.bottom + offsetTop,
                                    };
                                }
                                /**
                                 * Get the rect of an annotation element.
                                 *
                                 * @param {Element} el The element to get the rect of
                                 * @return {Object} The dimensions of the element
                                 */ function getAnnotationRect(el) {
                                    var h = 0,
                                        w = 0,
                                        x = 0,
                                        y = 0;
                                    var rect = el.getBoundingClientRect();
                                    // TODO this should be calculated somehow
                                    var LINE_OFFSET = 16;
                                    var isFirefox = /firefox/i.test(navigator.userAgent);
                                    switch (el.nodeName.toLowerCase()) {
                                        case 'path':
                                            var minX = void 0,
                                                maxX = void 0,
                                                minY = void 0,
                                                maxY = void 0;
                                            el.getAttribute('d')
                                                .replace(/Z/, '')
                                                .split('M')
                                                .splice(1)
                                                .forEach(function (p) {
                                                    var s = p.split(' ').map(function (i) {
                                                        return parseInt(i, 10);
                                                    });
                                                    if (typeof minX === 'undefined' || s[0] < minX) {
                                                        minX = s[0];
                                                    }
                                                    if (typeof maxX === 'undefined' || s[2] > maxX) {
                                                        maxX = s[2];
                                                    }
                                                    if (typeof minY === 'undefined' || s[1] < minY) {
                                                        minY = s[1];
                                                    }
                                                    if (typeof maxY === 'undefined' || s[3] > maxY) {
                                                        maxY = s[3];
                                                    }
                                                });
                                            // +2 and -1 make the path 1 larger in each direction. This makes thin straight lines clickable.
                                            h = maxY - minY + 2;
                                            w = maxX - minX + 2;
                                            x = minX - 1;
                                            y = minY - 1;
                                            break;
                                        case 'line':
                                            h =
                                                parseInt(el.getAttribute('y2'), 10) -
                                                parseInt(el.getAttribute('y1'), 10);
                                            w =
                                                parseInt(el.getAttribute('x2'), 10) -
                                                parseInt(el.getAttribute('x1'), 10);
                                            x = parseInt(el.getAttribute('x1'), 10);
                                            y = parseInt(el.getAttribute('y1'), 10);
                                            if (h === 0) {
                                                h += LINE_OFFSET;
                                                y -= LINE_OFFSET / 2;
                                            }
                                            break;
                                        case 'text':
                                            h = rect.height;
                                            w = rect.width;
                                            x = parseInt(el.getAttribute('x'), 10);
                                            y = parseInt(el.getAttribute('y'), 10) - h;
                                            break;
                                        case 'g':
                                            var _getOffset2 = getOffset(el);
                                            var offsetLeft = _getOffset2.offsetLeft;
                                            var offsetTop = _getOffset2.offsetTop;
                                            h = rect.height;
                                            w = rect.width;
                                            x = rect.left - offsetLeft;
                                            y = rect.top - offsetTop;
                                            if (el.getAttribute('data-pdf-annotate-type') === 'strikeout') {
                                                h += LINE_OFFSET;
                                                y -= LINE_OFFSET / 2;
                                            }
                                            break;
                                        case 'rect':
                                        case 'svg':
                                            h = parseInt(el.getAttribute('height'), 10);
                                            w = parseInt(el.getAttribute('width'), 10);
                                            x = parseInt(el.getAttribute('x'), 10);
                                            y = parseInt(el.getAttribute('y'), 10);
                                            break;
                                    } // Result provides same properties as getBoundingClientRect
                                    var result = {
                                        top: y,
                                        left: x,
                                        width: w,
                                        height: h,
                                        right: x + w,
                                        bottom: y + h,
                                    }; // For the case of nested SVG (point annotations) and grouped
                                    // lines or rects no adjustment needs to be made for scale.
                                    // I assume that the scale is already being handled
                                    // natively by virtue of the `transform` attribute.
                                    if (!['svg', 'g'].includes(el.nodeName.toLowerCase())) {
                                        result = scaleUp(findSVGAtPoint(rect.left, rect.top), result);
                                    }
                                    // FF scales nativly and uses always the 100%-Attributes, so the svg has to be scaled up to proof, if it is on the same position.
                                    if (isFirefox && ['svg'].includes(el.nodeName.toLowerCase())) {
                                        var svgTMP;
                                        if ((svgTMP = findSVGAtPoint(rect.left, rect.top)) !== null) {
                                            result = scaleUp(svgTMP, result);
                                        }
                                    }
                                    return result;
                                }
                                /**
                                 * Adjust scale from normalized scale (100%) to rendered scale.
                                 *
                                 * @param {SVGElement} svg The SVG to gather metadata from
                                 * @param {Object} rect A map of numeric values to scale
                                 * @return {Object} A copy of `rect` with values scaled up
                                 */ function scaleUp(svg, rect) {
                                    if (svg === null) {
                                        return rect;
                                    }
                                    var result = {};
                                    var _getMetadata = getMetadata(svg);
                                    var viewport = _getMetadata.viewport;
                                    Object.keys(rect).forEach(function (key) {
                                        result[key] = rect[key] * viewport.scale;
                                    });
                                    return result;
                                }
                                /**
                                 * Adjust scale from rendered scale to a normalized scale (100%).
                                 *
                                 * @param {SVGElement} svg The SVG to gather metadata from
                                 * @param {Object} rect A map of numeric values to scale
                                 * @return {Object} A copy of `rect` with values scaled down
                                 */ function scaleDown(svg, rect) {
                                    var result = {};
                                    var _getMetadata2 = getMetadata(svg);
                                    var viewport = _getMetadata2.viewport;
                                    Object.keys(rect).forEach(function (key) {
                                        result[key] = rect[key] / viewport.scale;
                                    });
                                    return result;
                                }
                                /**
                                 * Get the scroll position of an element, accounting for parent elements
                                 *
                                 * @param {Element} el The element to get the scroll position for
                                 * @return {Object} The scrollTop and scrollLeft position
                                 */ function getScroll(el) {
                                    var scrollTop = 0;
                                    var scrollLeft = 0;
                                    var parentNode = el;
                                    while ((parentNode = parentNode.parentNode) && parentNode !== document) {
                                        scrollTop += parentNode.scrollTop;
                                        scrollLeft += parentNode.scrollLeft;
                                    }
                                    return { scrollTop: scrollTop, scrollLeft: scrollLeft };
                                }
                                /**
                                 * Get the offset position of an element, accounting for parent elements
                                 *
                                 * @param {Element} el The element to get the offset position for
                                 * @return {Object} The offsetTop and offsetLeft position
                                 */ function getOffset(el) {
                                    var parentNode = el;
                                    while ((parentNode = parentNode.parentNode) && parentNode !== document) {
                                        if (parentNode.nodeName.toUpperCase() === 'SVG') {
                                            break;
                                        }
                                    }
                                    var rect = parentNode.getBoundingClientRect();
                                    return { offsetLeft: rect.left, offsetTop: rect.top };
                                }
                                /**
                                 * Disable user ability to select text on page
                                 */ function disableUserSelect() {
                                    if (!userSelectStyleSheet.parentNode) {
                                        document.head.appendChild(userSelectStyleSheet);
                                    }
                                }
                                /**
                                 * Enable user ability to select text on page
                                 */ function enableUserSelect() {
                                    if (userSelectStyleSheet.parentNode) {
                                        userSelectStyleSheet.parentNode.removeChild(userSelectStyleSheet);
                                    }
                                }
                                /**
                                 * Get the metadata for a SVG container
                                 *
                                 * @param {SVGElement} svg The SVG container to get metadata for
                                 */ function getMetadata(svg) {
                                    return {
                                        documentId: svg.getAttribute('data-pdf-annotate-document'),
                                        pageNumber: parseInt(svg.getAttribute('data-pdf-annotate-page'), 10),
                                        viewport: JSON.parse(svg.getAttribute('data-pdf-annotate-viewport')),
                                    };
                                }

                                /*
                                 * This function rounds a digit
                                 * @param {type} num digit, which should be rounded
                                 * @param {type} places
                                 * @return {undefined}
                                 */
                                function roundDigits(num, places) {
                                    return +(Math.round(num + 'e+' + places) + 'e-' + places);
                                }
                            },
                            /* 7 */
                            function (module, exports) {
                                module.exports = function createStyleSheet(blocks) {
                                    var style = document.createElement('style');
                                    var text = Object.keys(blocks)
                                        .map(function (selector) {
                                            return processRuleSet(selector, blocks[selector]);
                                        })
                                        .join('\n');
                                    style.setAttribute('type', 'text/css');
                                    style.appendChild(document.createTextNode(text));
                                    return style;
                                };
                                function processRuleSet(selector, block) {
                                    return selector + ' {\n' + processDeclarationBlock(block) + '\n}';
                                }
                                function processDeclarationBlock(block) {
                                    return Object.keys(block)
                                        .map(function (prop) {
                                            return processDeclaration(prop, block[prop]);
                                        })
                                        .join('\n');
                                }
                                function processDeclaration(prop, value) {
                                    if (!isNaN(value) && value != 0) {
                                        value = value + 'px';
                                    }
                                    return hyphenate(prop) + ': ' + value + ';';
                                }
                                function hyphenate(prop) {
                                    return prop.replace(/[A-Z]/g, function (match) {
                                        return '-' + match.toLowerCase();
                                    });
                                }
                            },
                            /* 8 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _uuid = __webpack_require__(9);
                                var _uuid2 = _interopRequireDefault(_uuid);
                                var _StoreAdapter2 = __webpack_require__(2);
                                var _StoreAdapter3 = _interopRequireDefault(_StoreAdapter2);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                function _classCallCheck(instance, Constructor) {
                                    if (!(instance instanceof Constructor)) {
                                        throw new TypeError('Cannot call a class as a function');
                                    }
                                }
                                function _possibleConstructorReturn(self, call) {
                                    if (!self) {
                                        throw new ReferenceError(
                                            "this hasn't been initialised - super() hasn't been called"
                                        );
                                    }
                                    return call &&
                                        ((typeof call === 'undefined' ? 'undefined' : _typeof2(call)) === 'object' ||
                                            typeof call === 'function')
                                        ? call
                                        : self;
                                }
                                function _inherits(subClass, superClass) {
                                    if (typeof superClass !== 'function' && superClass !== null) {
                                        throw new TypeError(
                                            'Super expression must either be null or a function, not ' +
                                                (typeof superClass === 'undefined' ? 'undefined' : _typeof2(superClass))
                                        );
                                    }
                                    subClass.prototype = Object.create(superClass && superClass.prototype, {
                                        constructor: {
                                            value: subClass,
                                            enumerable: false,
                                            writable: true,
                                            configurable: true,
                                        },
                                    });
                                    if (superClass)
                                        Object.setPrototypeOf
                                            ? Object.setPrototypeOf(subClass, superClass)
                                            : (subClass.__proto__ = superClass);
                                }
                                // StoreAdapter for working with localStorage
                                // This is ideal for testing, examples, and prototyping
                                var LocalStoreAdapter = (function (_StoreAdapter) {
                                    _inherits(LocalStoreAdapter, _StoreAdapter);
                                    function LocalStoreAdapter() {
                                        _classCallCheck(this, LocalStoreAdapter);
                                        return _possibleConstructorReturn(
                                            this,
                                            Object.getPrototypeOf(LocalStoreAdapter).call(this, {
                                                getAnnotations: function getAnnotations(documentId, pageNumber) {
                                                    return new Promise(function (resolve, reject) {
                                                        var annotations = _getAnnotations(documentId).filter(function (
                                                            i
                                                        ) {
                                                            return i.page === pageNumber && i.class === 'Annotation';
                                                        });
                                                        resolve({
                                                            documentId: documentId,
                                                            pageNumber: pageNumber,
                                                            annotations: annotations,
                                                        });
                                                    });
                                                },
                                                getAnnotation: function getAnnotation(documentId, annotationId) {
                                                    return Promise.resolve(
                                                        _getAnnotations(documentId)[
                                                            findAnnotation(documentId, annotationId)
                                                        ]
                                                    );
                                                },
                                                addAnnotation: function addAnnotation(
                                                    documentId,
                                                    pageNumber,
                                                    annotation
                                                ) {
                                                    return new Promise(function (resolve, reject) {
                                                        annotation.class = 'Annotation';
                                                        annotation.uuid = (0, _uuid2.default)();
                                                        annotation.page = pageNumber;
                                                        var annotations = _getAnnotations(documentId);
                                                        annotations.push(annotation);
                                                        updateAnnotations(documentId, annotations);
                                                        resolve(annotation);
                                                    });
                                                },
                                                editAnnotation: function editAnnotation(
                                                    documentId,
                                                    annotationId,
                                                    annotation
                                                ) {
                                                    return new Promise(function (resolve, reject) {
                                                        var annotations = _getAnnotations(documentId);
                                                        annotations[findAnnotation(documentId, annotationId)] =
                                                            annotation;
                                                        updateAnnotations(documentId, annotations);
                                                        resolve(annotation);
                                                    });
                                                },
                                                deleteAnnotation: function deleteAnnotation(documentId, annotationId) {
                                                    return new Promise(function (resolve, reject) {
                                                        var index = findAnnotation(documentId, annotationId);
                                                        if (index > -1) {
                                                            var annotations = _getAnnotations(documentId);
                                                            annotations.splice(index, 1);
                                                            updateAnnotations(documentId, annotations);
                                                        }
                                                        resolve(true);
                                                    });
                                                },
                                                getComments: function getComments(documentId, annotationId) {
                                                    return new Promise(function (resolve, reject) {
                                                        resolve(
                                                            _getAnnotations(documentId).filter(function (i) {
                                                                return (
                                                                    i.class === 'Comment' &&
                                                                    i.annotation === annotationId
                                                                );
                                                            })
                                                        );
                                                    });
                                                },
                                                addComment: function addComment(documentId, annotationId, content) {
                                                    return new Promise(function (resolve, reject) {
                                                        var comment = {
                                                            class: 'Comment',
                                                            uuid: (0, _uuid2.default)(),
                                                            annotation: annotationId,
                                                            content: content,
                                                        };
                                                        var annotations = _getAnnotations(documentId);
                                                        annotations.push(comment);
                                                        updateAnnotations(documentId, annotations);
                                                        resolve(comment);
                                                    });
                                                },
                                                deleteComment: function deleteComment(documentId, commentId) {
                                                    return new Promise(function (resolve, reject) {
                                                        _getAnnotations(documentId);
                                                        var index = -1;
                                                        var annotations = _getAnnotations(documentId);
                                                        for (var i = 0, l = annotations.length; i < l; i++) {
                                                            if (annotations[i].uuid === commentId) {
                                                                index = i;
                                                                break;
                                                            }
                                                        }
                                                        if (index > -1) {
                                                            annotations.splice(index, 1);
                                                            updateAnnotations(documentId, annotations);
                                                        }
                                                        resolve(true);
                                                    });
                                                },
                                            })
                                        );
                                    }
                                    return LocalStoreAdapter;
                                })(_StoreAdapter3.default);
                                exports.default = LocalStoreAdapter;
                                function _getAnnotations(documentId) {
                                    return JSON.parse(localStorage.getItem(documentId + '/annotations')) || [];
                                }
                                function updateAnnotations(documentId, annotations) {
                                    localStorage.setItem(documentId + '/annotations', JSON.stringify(annotations));
                                }
                                function findAnnotation(documentId, annotationId) {
                                    var index = -1;
                                    var annotations = _getAnnotations(documentId);
                                    for (var i = 0, l = annotations.length; i < l; i++) {
                                        if (annotations[i].uuid === annotationId) {
                                            index = i;
                                            break;
                                        }
                                    }
                                    return index;
                                }
                                module.exports = exports['default'];
                            },
                            /* 9 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = uuid;
                                var REGEXP = /[xy]/g;
                                var PATTERN = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
                                function replacement(c) {
                                    var r = (Math.random() * 16) | 0;
                                    var v = c == 'x' ? r : (r & 0x3) | 0x8;
                                    return v.toString(16);
                                }
                                /**
                                 * Generate a univierally unique identifier
                                 *
                                 * @return {String}
                                 */ function uuid() {
                                    return PATTERN.replace(REGEXP, replacement);
                                }
                                module.exports = exports['default'];
                            },
                            /* 10 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = render;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _renderScreenReaderHints = __webpack_require__(20);
                                var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Render the response from PDFJSAnnotate.getStoreAdapter().getAnnotations to SVG
                                 *
                                 * @param {SVGElement} svg The SVG element to render the annotations to
                                 * @param {Object} viewport The page viewport data
                                 * @param {Object} data The response from PDFJSAnnotate.getStoreAdapter().getAnnotations
                                 * @return {Promise} Settled once rendering has completed
                                 *  A settled Promise will be either:
                                 *    - fulfilled: SVGElement
                                 *    - rejected: Error
                                 */ function render(svg, viewport, data) {
                                    return new Promise(function (resolve, reject) {
                                        // Reset the content of the SVG
                                        svg.innerHTML = '';
                                        svg.setAttribute('data-pdf-annotate-container', true);
                                        svg.setAttribute('data-pdf-annotate-viewport', JSON.stringify(viewport));
                                        svg.removeAttribute('data-pdf-annotate-document');
                                        svg.removeAttribute('data-pdf-annotate-page'); // If there's no data nothing can be done
                                        if (!data) {
                                            return resolve(svg);
                                        }
                                        svg.setAttribute('data-pdf-annotate-document', data.documentId);
                                        svg.setAttribute('data-pdf-annotate-page', data.pageNumber); // Make sure annotations is an array
                                        if (!Array.isArray(data.annotations) || data.annotations.length === 0) {
                                            return resolve(svg);
                                        } // Append annotation to svg

                                        data.annotations.forEach(function (a) {
                                            (0, _appendChild2.default)(svg, a, viewport);
                                        });
                                        resolve(svg);
                                    });
                                }
                                module.exports = exports['default'];
                            },
                            /* 11 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = appendChild;
                                var _objectAssign = __webpack_require__(12);
                                var _objectAssign2 = _interopRequireDefault(_objectAssign);
                                var _renderLine = __webpack_require__(13);
                                var _renderLine2 = _interopRequireDefault(_renderLine);
                                var _renderPath = __webpack_require__(16);
                                var _renderPath2 = _interopRequireDefault(_renderPath);
                                var _renderPoint = __webpack_require__(17);
                                var _renderPoint2 = _interopRequireDefault(_renderPoint);
                                var _renderRect = __webpack_require__(18);
                                var _renderRect2 = _interopRequireDefault(_renderRect);
                                var _renderText = __webpack_require__(19);
                                var _renderText2 = _interopRequireDefault(_renderText);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var isFirefox = /firefox/i.test(navigator.userAgent);
                                /**
                                 * Get the x/y translation to be used for transforming the annotations
                                 * based on the rotation of the viewport.
                                 *
                                 * @param {Object} viewport The viewport data from the page
                                 * @return {Object}
                                 */ function getTranslation(viewport) {
                                    var x = void 0;
                                    var y = void 0; // Modulus 360 on the rotation so that we only
                                    // have to worry about four possible values.
                                    switch (viewport.rotation % 360) {
                                        case 0:
                                            x = y = 0;
                                            break;
                                        case 90:
                                            x = 0;
                                            y = (viewport.width / viewport.scale) * -1;
                                            break;
                                        case 180:
                                            x = (viewport.width / viewport.scale) * -1;
                                            y = (viewport.height / viewport.scale) * -1;
                                            break;
                                        case 270:
                                            x = (viewport.height / viewport.scale) * -1;
                                            y = 0;
                                            break;
                                    }
                                    return { x: x, y: y };
                                }
                                /**
                                 * Transform the rotation and scale of a node using SVG's native transform attribute.
                                 *
                                 * @param {Node} node The node to be transformed
                                 * @param {Object} viewport The page's viewport data
                                 * @return {Node}
                                 */ function transform(node, viewport) {
                                    var trans = getTranslation(viewport); // Let SVG natively transform the element
                                    node.setAttribute(
                                        'transform',
                                        'scale(' +
                                            viewport.scale +
                                            ') rotate(' +
                                            viewport.rotation +
                                            ') translate(' +
                                            trans.x +
                                            ', ' +
                                            trans.y +
                                            ')'
                                    );
                                    // Manually adjust x/y for nested SVG nodes
                                    if (!isFirefox && node.nodeName.toLowerCase() === 'svg') {
                                        node.setAttribute('x', parseInt(node.getAttribute('x'), 10) * viewport.scale);
                                        node.setAttribute('y', parseInt(node.getAttribute('y'), 10) * viewport.scale);
                                        var x = parseInt(node.getAttribute('x', 10));
                                        var y = parseInt(node.getAttribute('y', 10));
                                        var width = parseInt(node.getAttribute('width'), 10);
                                        var height = parseInt(node.getAttribute('height'), 10);
                                        var path = node.querySelector('path');
                                        var svg = path.parentNode; // Scale width/height
                                        [node, svg, path, node.querySelector('circle')].forEach(function (n) {
                                            n.setAttribute(
                                                'width',
                                                parseInt(n.getAttribute('width'), 10) * viewport.scale
                                            );
                                            n.setAttribute(
                                                'height',
                                                parseInt(n.getAttribute('height'), 10) * viewport.scale
                                            );
                                        });
                                        // Transform path but keep scale at 100% since it will be handled natively
                                        transform(path, (0, _objectAssign2.default)({}, viewport, { scale: 1 }));
                                        switch (viewport.rotation % 360) {
                                            case 90:
                                                node.setAttribute('x', viewport.width - y - width);
                                                node.setAttribute('y', x);
                                                svg.setAttribute('x', 1);
                                                svg.setAttribute('y', 0);
                                                break;
                                            case 180:
                                                node.setAttribute('x', viewport.width - x - width);
                                                node.setAttribute('y', viewport.height - y - height);
                                                svg.setAttribute('y', 2);
                                                break;
                                            case 270:
                                                node.setAttribute('x', y);
                                                node.setAttribute('y', viewport.height - x - height);
                                                svg.setAttribute('x', -1);
                                                svg.setAttribute('y', 0);
                                                break;
                                        }
                                    }
                                    return node;
                                }
                                /**
                                 * Append an annotation as a child of an SVG.
                                 *
                                 * @param {SVGElement} svg The SVG element to append the annotation to
                                 * @param {Object} annotation The annotation definition to render and append
                                 * @param {Object} viewport The page's viewport data
                                 * @return {SVGElement} A node that was created and appended by this function
                                 */ function appendChild(svg, annotation, viewport) {
                                    if (!viewport) {
                                        viewport = JSON.parse(svg.getAttribute('data-pdf-annotate-viewport'));
                                    }
                                    annotation.viewport = viewport;
                                    var child = void 0;
                                    switch (annotation.type) {
                                        case 'area':
                                        case 'highlight':
                                            child = (0, _renderRect2.default)(annotation);
                                            break;
                                        case 'strikeout':
                                            child = (0, _renderLine2.default)(annotation);
                                            break;
                                        case 'point':
                                            child = (0, _renderPoint2.default)(annotation);
                                            break;
                                        case 'textbox':
                                            child = (0, _renderText2.default)(annotation);
                                            break;
                                        case 'drawing':
                                            child = (0, _renderPath2.default)(annotation);
                                            break;
                                    } // If no type was provided for an annotation it will result in node being null.
                                    // Skip appending/transforming if node doesn't exist.
                                    if (child) {
                                        // Set attributes
                                        child.setAttribute('data-pdf-annotate-id', annotation.uuid);
                                        child.setAttribute('data-pdf-annotate-type', annotation.type);
                                        child.setAttribute('data-pdf-annotate-owner', annotation.owner);
                                        child.setAttribute('aria-hidden', true);
                                        svg.appendChild(transform(child, viewport));
                                    }
                                    return child;
                                }
                                module.exports = exports['default'];
                            },
                            /* 12 */
                            function (module, exports) {
                                /* eslint-disable no-unused-vars */
                                'use strict';
                                var hasOwnProperty = Object.prototype.hasOwnProperty;
                                var propIsEnumerable = Object.prototype.propertyIsEnumerable;
                                function toObject(val) {
                                    if (val === null || val === undefined) {
                                        throw new TypeError('Object.assign cannot be called with null or undefined');
                                    }
                                    return Object(val);
                                }
                                module.exports =
                                    Object.assign ||
                                    function (target, source) {
                                        var from;
                                        var to = toObject(target);
                                        var symbols;
                                        for (var s = 1; s < arguments.length; s++) {
                                            from = Object(arguments[s]);
                                            for (var key in from) {
                                                if (hasOwnProperty.call(from, key)) {
                                                    to[key] = from[key];
                                                }
                                            }
                                            if (Object.getOwnPropertySymbols) {
                                                symbols = Object.getOwnPropertySymbols(from);
                                                for (var i = 0; i < symbols.length; i++) {
                                                    if (propIsEnumerable.call(from, symbols[i])) {
                                                        to[symbols[i]] = from[symbols[i]];
                                                    }
                                                }
                                            }
                                        }
                                        return to;
                                    };
                            },
                            /* 13 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderLine;
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _normalizeColor = __webpack_require__(15);
                                var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Create SVGLineElements from an annotation definition.
                                 * This is used for anntations of type `strikeout`.
                                 *
                                 * @param {Object} a The annotation definition
                                 * @return {SVGGElement} A group of all lines to be rendered
                                 */ function renderLine(a) {
                                    var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
                                    (0, _setAttributes2.default)(group, {
                                        stroke: (0, _normalizeColor2.default)(a.color || '#f00'),
                                        strokeWidth: 1,
                                    });
                                    a.rectangles.forEach(function (r) {
                                        var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                                        (0,
                                        _setAttributes2.default)(line, { x1: r.x, y1: r.y, x2: r.x + r.width, y2: r.y });
                                        group.appendChild(line);
                                    });
                                    return group;
                                }
                                module.exports = exports['default'];
                            },
                            /* 14 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = setAttributes;
                                var UPPER_REGEX = /[A-Z]/g;
                                // Don't convert these attributes from camelCase to hyphenated-attributes
                                var BLACKLIST = ['viewBox'];
                                var keyCase = function keyCase(key) {
                                    if (BLACKLIST.indexOf(key) === -1) {
                                        key = key.replace(UPPER_REGEX, function (match) {
                                            return '-' + match.toLowerCase();
                                        });
                                    }
                                    return key;
                                };
                                /**
                                 * Set attributes for a node from a map
                                 *
                                 * @param {Node} node The node to set attributes on
                                 * @param {Object} attributes The map of key/value pairs to use for attributes
                                 */ function setAttributes(node, attributes) {
                                    Object.keys(attributes).forEach(function (key) {
                                        node.setAttribute(keyCase(key), attributes[key]);
                                    });
                                }
                                module.exports = exports['default'];
                            },
                            /* 15 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = normalizeColor;
                                var REGEX_HASHLESS_HEX = /^([a-f0-9]{6}|[a-f0-9]{3})$/i;
                                /**
                                 * Normalize a color value
                                 *
                                 * @param {String} color The color to normalize
                                 * @return {String}
                                 */ function normalizeColor(color) {
                                    if (REGEX_HASHLESS_HEX.test(color)) {
                                        color = '#' + color;
                                    }
                                    return color;
                                }
                                module.exports = exports['default'];
                            },
                            /* 16 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderPath;
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _normalizeColor = __webpack_require__(15);
                                var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Create SVGPathElement from an annotation definition.
                                 * This is used for anntations of type `drawing`.
                                 *
                                 * @param {Object} a The annotation definition
                                 * @return {SVGPathElement} The path to be rendered
                                 */ function renderPath(a) {
                                    var d = [];
                                    var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                                    for (var i = 0, l = a.lines.length; i < l; i++) {
                                        var p1 = a.lines[i];
                                        var p2 = a.lines[i + 1];
                                        if (p2) {
                                            d.push('M' + p1[0] + ' ' + p1[1] + ' ' + p2[0] + ' ' + p2[1]);
                                        }
                                    }
                                    (0, _setAttributes2.default)(path, {
                                        d: d.join(' ') + 'Z',
                                        stroke: (0, _normalizeColor2.default)(a.color || '#000'),
                                        strokeWidth: a.width || 1,
                                        fill: 'none',
                                    });
                                    return path;
                                }
                                module.exports = exports['default'];
                            },
                            /* 17 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderPoint;
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var SIZE = 20;
                                var D =
                                    'M499.968 214.336q-113.832 0 -212.877 38.781t-157.356 104.625 -58.311 142.29q0 62.496 39.897 119.133t112.437 97.929l48.546 27.9 -15.066 53.568q-13.392 50.778 -39.06 95.976 84.816 -35.154 153.45 -95.418l23.994 -21.204 31.806 3.348q38.502 4.464 72.54 4.464 113.832 0 212.877 -38.781t157.356 -104.625 58.311 -142.29 -58.311 -142.29 -157.356 -104.625 -212.877 -38.781z';
                                /**
                                 * Create SVGElement from an annotation definition.
                                 * This is used for anntations of type `comment`.
                                 *
                                 * @param {Object} a The annotation definition
                                 * @return {SVGElement} A svg to be rendered
                                 */ function renderPoint(a) {
                                    let posX = a.x;
                                    let posY = a.y;

                                    let colorInner;
                                    let colorLine;
                                    if (a.color) {
                                        colorInner = 'rgba(255,237,0,.8)';
                                        colorLine = 'rgb(246,168,0)';
                                    } else {
                                        colorInner = 'rgba(142,186,229,.8)';
                                        colorLine = 'rgb(0,84,159)';
                                    }

                                    var outerSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                                    var innerSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                                    var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                                    var path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                                    var circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                                    (0, _setAttributes2.default)(outerSVG, {
                                        width: SIZE / 2 + 1,
                                        height: SIZE,
                                        x: posX - SIZE / 4,
                                        y: posY - SIZE,
                                    });
                                    (0, _setAttributes2.default)(innerSVG, {
                                        width: SIZE,
                                        height: SIZE,
                                        x: 0,
                                        y: SIZE * 0.05 * -1,
                                        viewBox: '-16 -18 64 64',
                                    });
                                    (0, _setAttributes2.default)(path, {
                                        d: 'M0,47 Q0,28 10,15 A15,15 0,1,0 -10,15 Q0,28 0,47',
                                        stroke: 'none',
                                        fill: colorInner,
                                        transform: '',
                                    });
                                    (0, _setAttributes2.default)(path2, {
                                        d: 'M0,47 Q0,28 10,15 A15,15 0,1,0 -10,15 Q0,28 0,47',
                                        strokeWidth: 1,
                                        stroke: colorLine,
                                        fill: 'none',
                                    });
                                    (0, _setAttributes2.default)(circle, {
                                        cx: 0,
                                        cy: 4,
                                        r: 4,
                                        stroke: 'none',
                                        fill: colorLine,
                                    });
                                    innerSVG.appendChild(path);
                                    innerSVG.appendChild(path2);
                                    innerSVG.appendChild(circle);
                                    outerSVG.appendChild(innerSVG);

                                    return outerSVG;
                                }
                                module.exports = exports['default'];
                            },
                            /* 18 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _typeof =
                                    typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
                                        ? function (obj) {
                                              return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
                                          }
                                        : function (obj) {
                                              return obj && typeof Symbol === 'function' && obj.constructor === Symbol
                                                  ? 'symbol'
                                                  : typeof obj === 'undefined'
                                                  ? 'undefined'
                                                  : _typeof2(obj);
                                          };
                                exports.default = renderRect;
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _normalizeColor = __webpack_require__(15);
                                var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Create SVGRectElements from an annotation definition.
                                 * This is used for anntations of type `area` and `highlight`.
                                 *
                                 * @param {Object} a The annotation definition
                                 * @return {SVGGElement|SVGRectElement} A group of all rects to be rendered
                                 */ function renderRect(a) {
                                    if (a.type === 'highlight') {
                                        var _ret = (function () {
                                            var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
                                            (0, _setAttributes2.default)(group, {
                                                fill: (0, _normalizeColor2.default)(a.color || 'rgb(142,186,229)'),
                                                fillOpacity: 0.35,
                                            });
                                            a.rectangles.forEach(function (r) {
                                                group.appendChild(createRect(r));
                                            });
                                            return { v: group };
                                        })();
                                        if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object')
                                            return _ret.v;
                                    } else {
                                        var rect = createRect(a);
                                        (0, _setAttributes2.default)(rect, {
                                            stroke: (0, _normalizeColor2.default)(a.color || 'rgb(0,84,159)'),
                                            fill: 'none',
                                        });
                                        return rect;
                                    }
                                }
                                function createRect(r) {
                                    var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
                                    (0, _setAttributes2.default)(rect, {
                                        x: r.x,
                                        y: r.y,
                                        width: r.width,
                                        height: r.height,
                                    });
                                    return rect;
                                }
                                module.exports = exports['default'];
                            },
                            /* 19 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderText;
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _normalizeColor = __webpack_require__(15);
                                var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Create SVGTextElement from an annotation definition.
                                 * This is used for anntations of type `textbox`.
                                 *
                                 * @param {Object} a The annotation definition
                                 * @return {SVGTextElement} A text to be rendered
                                 */ function renderText(a) {
                                    var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                                    (0, _setAttributes2.default)(text, {
                                        x: a.x,
                                        y: a.y + parseInt(a.size, 10),
                                        fill: (0, _normalizeColor2.default)(a.color || '#000'),
                                        fontSize: a.size,
                                    });
                                    text.innerHTML = a.content;
                                    return text;
                                }
                                module.exports = exports['default'];
                            },
                            /* 20 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderScreenReaderHints;
                                var _insertScreenReaderHint = __webpack_require__(21);
                                var _insertScreenReaderHint2 = _interopRequireDefault(_insertScreenReaderHint);
                                var _initEventHandlers = __webpack_require__(27);
                                var _initEventHandlers2 = _interopRequireDefault(_initEventHandlers);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                // TODO This is not the right place for this to live
                                (0, _initEventHandlers2.default)();
                                /**
                                 * Insert hints into the DOM for screen readers.
                                 *
                                 * @param {Array} annotations The annotations that hints are inserted for
                                 */ function renderScreenReaderHints(annotations) {
                                    annotations = Array.isArray(annotations) ? annotations : []; // Insert hints for each type
                                    Object.keys(SORT_TYPES).forEach(function (type) {
                                        var sortBy = SORT_TYPES[type];
                                        annotations
                                            .filter(function (a) {
                                                return a.type === type;
                                            })
                                            .sort(sortBy)
                                            .forEach(function (a, i) {
                                                return (0, _insertScreenReaderHint2.default)(a, i + 1);
                                            });
                                    });
                                }
                                // Sort annotations first by y, then by x.
                                // This allows hints to be injected in the order they appear,
                                // which makes numbering them easier.
                                function sortByPoint(a, b) {
                                    if (a.y < b.y) {
                                        return a.x - b.x;
                                    } else {
                                        return 1;
                                    }
                                } // Sort annotation by it's first rectangle
                                function sortByRectPoint(a, b) {
                                    return sortByPoint(a.rectangles[0], b.rectangles[0]);
                                } // Sort annotation by it's first line
                                function sortByLinePoint(a, b) {
                                    var lineA = a.lines[0];
                                    var lineB = b.lines[0];
                                    return sortByPoint({ x: lineA[0], y: lineA[1] }, { x: lineB[0], y: lineB[1] });
                                } // Arrange supported types and associated sort methods
                                var SORT_TYPES = {
                                    highlight: sortByRectPoint,
                                    strikeout: sortByRectPoint,
                                    drawing: sortByLinePoint,
                                    textbox: sortByPoint,
                                    point: sortByPoint,
                                    area: sortByPoint,
                                };
                                module.exports = exports['default'];
                            },
                            /* 21 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = insertScreenReaderHint;
                                var _createScreenReaderOnly = __webpack_require__(22);
                                var _createScreenReaderOnly2 = _interopRequireDefault(_createScreenReaderOnly);
                                var _insertElementWithinChildren = __webpack_require__(23);
                                var _insertElementWithinChildren2 =
                                    _interopRequireDefault(_insertElementWithinChildren);
                                var _insertElementWithinElement = __webpack_require__(24);
                                var _insertElementWithinElement2 = _interopRequireDefault(_insertElementWithinElement);
                                var _renderScreenReaderComments = __webpack_require__(25);
                                var _renderScreenReaderComments2 = _interopRequireDefault(_renderScreenReaderComments);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                } // Annotation types that support comments
                                var COMMENT_TYPES = ['highlight', 'point', 'area', 'strikeout'];
                                /**
                                 * Insert a hint into the DOM for screen readers for a specific annotation.
                                 *
                                 * @param {Object} annotation The annotation to insert a hint for
                                 * @param {Number} num The number of the annotation out of all annotations of the same type
                                 */ function insertScreenReaderHint(annotation) {
                                    var num = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
                                    switch (annotation.type) {
                                        case 'highlight':
                                        case 'strikeout':
                                            var rects = annotation.rectangles;
                                            var first = rects[0];
                                            var last = rects[rects.length - 1];
                                            (0, _insertElementWithinElement2.default)(
                                                (0, _createScreenReaderOnly2.default)(
                                                    'Begin ' + annotation.type + ' annotation ' + num,
                                                    annotation.uuid
                                                ),
                                                first.x,
                                                first.y,
                                                annotation.page,
                                                true
                                            );
                                            (0, _insertElementWithinElement2.default)(
                                                (0, _createScreenReaderOnly2.default)(
                                                    'End ' + annotation.type + ' annotation ' + num,
                                                    annotation.uuid + '-end'
                                                ),
                                                last.x + last.width,
                                                last.y,
                                                annotation.page,
                                                false
                                            );
                                            break;
                                        case 'textbox':
                                        case 'point':
                                            var text =
                                                annotation.type === 'textbox'
                                                    ? ' (content: ' + annotation.content + ')'
                                                    : '';
                                            (0, _insertElementWithinChildren2.default)(
                                                (0, _createScreenReaderOnly2.default)(
                                                    annotation.type + ' annotation ' + num + text,
                                                    annotation.uuid
                                                ),
                                                annotation.x,
                                                annotation.y,
                                                annotation.page
                                            );
                                            break;
                                        case 'drawing':
                                        case 'area':
                                            var x =
                                                typeof annotation.x !== 'undefined'
                                                    ? annotation.x
                                                    : annotation.lines[0][0];
                                            var y =
                                                typeof annotation.y !== 'undefined'
                                                    ? annotation.y
                                                    : annotation.lines[0][1];
                                            (0, _insertElementWithinChildren2.default)(
                                                (0, _createScreenReaderOnly2.default)(
                                                    'Unlabeled drawing',
                                                    annotation.uuid
                                                ),
                                                x,
                                                y,
                                                annotation.page
                                            );
                                            break;
                                    } // Include comments in screen reader hint
                                    if (COMMENT_TYPES.includes(annotation.type)) {
                                        (0, _renderScreenReaderComments2.default)(
                                            annotation.documentId,
                                            annotation.uuid
                                        );
                                    }
                                }
                                module.exports = exports['default'];
                            },
                            /* 22 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = createScreenReaderOnly;
                                /**
                                 * Create a node that is only visible to screen readers
                                 *
                                 * @param {String} content The text content that should be read by screen reader
                                 * @param {String} [annotationId] The ID of the annotation assocaited
                                 * @return {Element} An Element that is only visible to screen readers
                                 */ function createScreenReaderOnly(content, annotationId) {
                                    var node = document.createElement('div');
                                    var text = document.createTextNode(content);
                                    node.appendChild(text);
                                    node.setAttribute('id', 'pdf-annotate-screenreader-' + annotationId);
                                    node.style.position = 'absolute';
                                    node.style.left = '-10000px';
                                    node.style.top = 'auto';
                                    node.style.width = '1px';
                                    node.style.height = '1px';
                                    node.style.overflow = 'hidden';
                                    return node;
                                }
                                module.exports = exports['default'];
                            },
                            /* 23 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = insertElementWithinChildren;
                                var _insertElementWithinElement = __webpack_require__(24);
                                var _insertElementWithinElement2 = _interopRequireDefault(_insertElementWithinElement);
                                var _utils = __webpack_require__(6);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                function _toConsumableArray(arr) {
                                    if (Array.isArray(arr)) {
                                        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
                                            arr2[i] = arr[i];
                                        }
                                        return arr2;
                                    } else {
                                        return Array.from(arr);
                                    }
                                }
                                /**
                                 * Insert an element at a point within the document.
                                 * This algorithm will try to insert between elements if possible.
                                 * It will however use `insertElementWithinElement` if it is more accurate.
                                 *
                                 * @param {Element} el The element to be inserted
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Number} pageNumber The page number to limit elements to
                                 * @return {Boolean} True if element was able to be inserted, otherwise false
                                 */ function insertElementWithinChildren(el, x, y, pageNumber) {
                                    // Try and use most accurate method of inserting within an element
                                    if ((0, _insertElementWithinElement2.default)(el, x, y, pageNumber, true)) {
                                        return true;
                                    } // Fall back to inserting between elements
                                    var svg = document.querySelector(
                                        'svg[data-pdf-annotate-page="' + pageNumber + '"]'
                                    );
                                    var rect = svg.getBoundingClientRect();
                                    var nodes = [].concat(
                                        _toConsumableArray(svg.parentNode.querySelectorAll('.textLayer > div'))
                                    );
                                    y = (0, _utils.scaleUp)(svg, { y: y }).y + rect.top;
                                    x = (0, _utils.scaleUp)(svg, { x: x }).x + rect.left; // Find the best node to insert before
                                    for (var i = 0, l = nodes.length; i < l; i++) {
                                        var n = nodes[i];
                                        var r = n.getBoundingClientRect();
                                        if (y <= r.top) {
                                            n.parentNode.insertBefore(el, n);
                                            return true;
                                        }
                                    } // If all else fails try to append to the bottom
                                    var textLayer = svg.parentNode.querySelector('.textLayer');
                                    if (textLayer) {
                                        var textRect = textLayer.getBoundingClientRect();
                                        if ((0, _utils.pointIntersectsRect)(x, y, textRect)) {
                                            textLayer.appendChild(el);
                                            return true;
                                        }
                                    }
                                    return false;
                                }
                                module.exports = exports['default'];
                            },
                            /* 24 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = insertElementWithinElement;
                                var _utils = __webpack_require__(6);
                                function _toConsumableArray(arr) {
                                    if (Array.isArray(arr)) {
                                        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
                                            arr2[i] = arr[i];
                                        }
                                        return arr2;
                                    } else {
                                        return Array.from(arr);
                                    }
                                }
                                /**
                                 * Insert an element at a point within the document.
                                 * This algorithm will only insert within an element amidst it's text content.
                                 *
                                 * @param {Element} el The element to be inserted
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Number} pageNumber The page number to limit elements to
                                 * @param {Boolean} insertBefore Whether the element is to be inserted before or after x
                                 * @return {Boolean} True if element was able to be inserted, otherwise false
                                 */ function insertElementWithinElement(el, x, y, pageNumber, insertBefore) {
                                    var OFFSET_ADJUST = 2; // If inserting before adjust `x` by looking for element a few px to the right
                                    // Otherwise adjust a few px to the left
                                    // This is to allow a little tolerance by searching within the box, instead
                                    // of getting a false negative by testing right on the border.
                                    x = Math.max(x + OFFSET_ADJUST * (insertBefore ? 1 : -1), 0);
                                    var node = textLayerElementFromPoint(x, y + OFFSET_ADJUST, pageNumber);
                                    if (!node) {
                                        return false;
                                    } // Now that node has been found inverse the adjustment for `x`.
                                    // This is done to accomodate tolerance by cutting off on the outside of the
                                    // text boundary, instead of missing a character by cutting off within.
                                    x = x + OFFSET_ADJUST * (insertBefore ? -1 : 1);
                                    var svg = document.querySelector(
                                        'svg[data-pdf-annotate-page="' + pageNumber + '"]'
                                    );
                                    var left =
                                        (0, _utils.scaleDown)(svg, { left: node.getBoundingClientRect().left }).left -
                                        svg.getBoundingClientRect().left;
                                    var temp = node.cloneNode(true);
                                    var head = temp.innerHTML.split('');
                                    var tail = []; // Insert temp off screen
                                    temp.style.position = 'absolute';
                                    temp.style.top = '-10000px';
                                    temp.style.left = '-10000px';
                                    document.body.appendChild(temp);
                                    while (head.length) {
                                        // Don't insert within HTML tags
                                        if (head[head.length - 1] === '>') {
                                            while (head.length) {
                                                tail.unshift(head.pop());
                                                if (tail[0] === '<') {
                                                    break;
                                                }
                                            }
                                        } // Check if width of temp based on current head value satisfies x
                                        temp.innerHTML = head.join('');
                                        var width = (0, _utils.scaleDown)(svg, {
                                            width: temp.getBoundingClientRect().width,
                                        }).width;
                                        if (left + width <= x) {
                                            break;
                                        }
                                        tail.unshift(head.pop());
                                    } // Update original node with new markup, including element to be inserted
                                    node.innerHTML = head.join('') + el.outerHTML + tail.join('');
                                    temp.parentNode.removeChild(temp);
                                    return true;
                                }
                                /**
                                 * Get a text layer element at a given point on a page
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 * @param {Number} pageNumber The page to limit elements to
                                 * @return {Element} First text layer element found at the point
                                 */ function textLayerElementFromPoint(x, y, pageNumber) {
                                    var svg = document.querySelector(
                                        'svg[data-pdf-annotate-page="' + pageNumber + '"]'
                                    );
                                    var rect = svg.getBoundingClientRect();
                                    y = (0, _utils.scaleUp)(svg, { y: y }).y + rect.top;
                                    x = (0, _utils.scaleUp)(svg, { x: x }).x + rect.left;
                                    return []
                                        .concat(
                                            _toConsumableArray(
                                                svg.parentNode.querySelectorAll('.textLayer [data-canvas-width]')
                                            )
                                        )
                                        .filter(function (el) {
                                            return (0, _utils.pointIntersectsRect)(x, y, el.getBoundingClientRect());
                                        })[0];
                                }
                                module.exports = exports['default'];
                            },
                            /* 25 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = renderScreenReaderComments;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _insertScreenReaderComment = __webpack_require__(26);
                                var _insertScreenReaderComment2 = _interopRequireDefault(_insertScreenReaderComment);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Insert the comments into the DOM to be available by screen reader
                                 *
                                 * Example output:
                                 *   <div class="screenReaderOnly">
                                 *    <div>Begin highlight 1</div>
                                 *    <ol aria-label="Comments">
                                 *      <li>Foo</li>
                                 *      <li>Bar</li>
                                 *      <li>Baz</li>
                                 *      <li>Qux</li>
                                 *    </ol>
                                 *  </div>
                                 *  <div>Some highlighted text goes here...</div>
                                 *  <div class="screenReaderOnly">End highlight 1</div>
                                 *
                                 * NOTE: `screenReaderOnly` is not a real class, just used for brevity
                                 *
                                 * @param {String} documentId The ID of the document
                                 * @param {String} annotationId The ID of the annotation
                                 * @param {Array} [comments] Optionally preloaded comments to be rendered
                                 * @return {Promise}
                                 */ function renderScreenReaderComments(documentId, annotationId, comments) {
                                    var promise = void 0;
                                    if (Array.isArray(comments)) {
                                        promise = Promise.resolve(comments);
                                    } else {
                                        promise = _PDFJSAnnotate2.default
                                            .getStoreAdapter()
                                            .getComments(documentId, annotationId);
                                    }
                                    return promise.then(function (comments) {
                                        // Node needs to be found by querying DOM as it may have been inserted as innerHTML
                                        // leaving `screenReaderNode` as an invalid reference (see `insertElementWithinElement`).
                                        var node = document.getElementById('pdf-annotate-screenreader-' + annotationId);
                                        if (node) {
                                            var list = document.createElement('ol');
                                            list.setAttribute(
                                                'id',
                                                'pdf-annotate-screenreader-comment-list-' + annotationId
                                            );
                                            list.setAttribute('aria-label', 'Comments');
                                            node.appendChild(list);
                                            // comments.forEach(_insertScreenReaderComment2.default);

                                            for (var i = 0; i < comments.length; i++) {
                                                _insertScreenReaderComment2.default(comments[i]);
                                            }
                                        }
                                    });
                                }
                                module.exports = exports['default'];
                            },
                            /* 26 */
                            function (module, exports) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = insertScreenReaderComment;
                                /**
                                 * Insert a comment into the DOM to be available by screen reader
                                 *
                                 * @param {Object} comment The comment to be inserted
                                 */ function insertScreenReaderComment(comment) {
                                    if (!comment) {
                                        return;
                                    }
                                    var list = document.querySelector(
                                        '#pdf-annotate-screenreader-' + comment.annotation + ' ol'
                                    );
                                    if (list) {
                                        var item = document.createElement('li');
                                        item.setAttribute('id', 'pdf-annotate-screenreader-comment-' + comment.uuid);
                                        item.appendChild(document.createTextNode('' + comment.content));
                                        list.appendChild(item);
                                    }
                                }
                                module.exports = exports['default'];
                            },
                            /* 27 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.default = initEventHandlers;
                                var _insertScreenReaderHint = __webpack_require__(21);
                                var _insertScreenReaderHint2 = _interopRequireDefault(_insertScreenReaderHint);
                                var _renderScreenReaderHints = __webpack_require__(20);
                                var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
                                var _insertScreenReaderComment = __webpack_require__(26);
                                var _insertScreenReaderComment2 = _interopRequireDefault(_insertScreenReaderComment);
                                var _renderScreenReaderComments = __webpack_require__(25);
                                var _renderScreenReaderComments2 = _interopRequireDefault(_renderScreenReaderComments);
                                var _event = __webpack_require__(4);
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);

                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                /**
                                 * Initialize the event handlers for keeping screen reader hints synced with data
                                 */ function initEventHandlers() {
                                    (0, _event.addEventListener)(
                                        'annotation:add',
                                        function (documentId, pageNumber, annotation) {
                                            reorderAnnotationsByType(documentId, pageNumber, annotation.type);
                                        }
                                    );
                                    (0, _event.addEventListener)(
                                        'annotation:edit',
                                        function (documentId, annotationId, annotation) {
                                            reorderAnnotationsByType(documentId, annotation.page, annotation.type);
                                        }
                                    );
                                    (0, _event.addEventListener)('annotation:delete', removeAnnotation);
                                    (0, _event.addEventListener)('comment:add', insertComments);
                                    (0, _event.addEventListener)('comment:delete', removeComment);
                                }
                                /**
                                 * Reorder the annotation numbers by annotation type
                                 *
                                 * @param {String} documentId The ID of the document
                                 * @param {Number} pageNumber The page number of the annotations
                                 * @param {Strig} type The annotation type
                                 */ function reorderAnnotationsByType(documentId, pageNumber, type) {
                                    _PDFJSAnnotate2.default
                                        .getStoreAdapter()
                                        .getAnnotations(documentId, pageNumber)
                                        .then(function (annotations) {
                                            return annotations.annotations.filter(function (a) {
                                                return a.type === type;
                                            });
                                        })
                                        .then(function (annotations) {
                                            annotations.forEach(function (a) {
                                                removeAnnotation(documentId, a.uuid);
                                            });
                                            return annotations;
                                        })
                                        .then(/*_renderScreenReaderHints2.default*/);
                                }
                                /**
                                 * Remove the screen reader hint for an annotation
                                 *
                                 * @param {String} documentId The ID of the document
                                 * @param {String} annotationId The Id of the annotation
                                 */ function removeAnnotation(documentId, annotationId) {
                                    removeElementById('pdf-annotate-screenreader-' + annotationId);
                                    removeElementById('pdf-annotate-screenreader-' + annotationId + '-end');
                                }
                                /**
                                 * Insert a screen reader hint for a comment
                                 *
                                 * @param {String} documentId The ID of the document
                                 * @param {String} annotationId The ID of tha assocated annotation
                                 * @param {Object} comment The comment to insert a hint for
                                 */ function insertComments(documentId, annotationId, comment) {
                                    var list = document.querySelector(
                                        'pdf-annotate-screenreader-comment-list-' + annotationId
                                    );
                                    var promise = void 0;
                                    if (!list) {
                                        promise = (0, _renderScreenReaderComments2.default)(
                                            documentId,
                                            annotationId,
                                            []
                                        ).then(function () {
                                            list = document.querySelector(
                                                'pdf-annotate-screenreader-comment-list-' + annotationId
                                            );
                                            return true;
                                        });
                                    } else {
                                        promise = Promise.resolve(true);
                                    }
                                    promise.then(function () {
                                        (0, _insertScreenReaderComment2.default)(comment);
                                    });
                                }
                                /**
                                 * Remove a screen reader hint for a comment
                                 *
                                 * @param {String} documentId The ID of the document
                                 * @param {String} commentId The ID of the comment
                                 */ function removeComment(documentId, commentId) {
                                    removeElementById('pdf-annotate-screenreader-comment-' + commentId);
                                }
                                /**
                                 * Remove an element from the DOM by it's ID if it exists
                                 *
                                 * @param {String} elementID The ID of the element to be removed
                                 */ function removeElementById(elementId) {
                                    var el = document.getElementById(elementId);
                                    if (el) {
                                        el.parentNode.removeChild(el);
                                    }
                                }
                                module.exports = exports['default'];
                            },
                            /* 28 */ /* Combines the UI functions to export for parent-module 1 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _event = __webpack_require__(4);
                                var _edit = __webpack_require__(29);
                                var _pen = __webpack_require__(30);
                                var _point = __webpack_require__(31);
                                var _rect = __webpack_require__(32);
                                var _text = __webpack_require__(33);
                                var _page = __webpack_require__(34);
                                var _pickAnno = __webpack_require__(37);
                                var _questionsRenderer = __webpack_require__(38);
                                var _shortText = __webpack_require__(39);
                                var _newAnnotations = __webpack_require__(40);
                                var _ajaxloader = __webpack_require__(36);
                                var _commentWrapper = __webpack_require__(35);
                                exports.default = {
                                    addEventListener: _event.addEventListener,
                                    removeEventListener: _event.removeEventListener,
                                    fireEvent: _event.fireEvent,
                                    disableEdit: _edit.disableEdit,
                                    enableEdit: _edit.enableEdit,
                                    disablePen: _pen.disablePen,
                                    enablePen: _pen.enablePen,
                                    setPen: _pen.setPen,
                                    disablePoint: _point.disablePoint,
                                    enablePoint: _point.enablePoint,
                                    disableRect: _rect.disableRect,
                                    enableRect: _rect.enableRect,
                                    disableText: _text.disableText,
                                    enableText: _text.enableText,
                                    setText: _text.setText,
                                    createPage: _page.createPage,
                                    renderPage: _page.renderPage,
                                    showLoader: _ajaxloader.showLoader,
                                    hideLoader: _ajaxloader.hideLoader,
                                    pickAnnotation: _pickAnno.pickAnnotation,
                                    renderQuestions: _questionsRenderer.renderQuestions,
                                    renderAllQuestions: _questionsRenderer.renderAllQuestions,
                                    shortenTextDynamic: _shortText.shortenTextDynamic,
                                    /*mathJaxAndShortenText: _shortText.mathJaxAndShortenText,*/
                                    loadNewAnnotations: _newAnnotations.load,
                                    loadEditor: _commentWrapper.loadEditor,
                                };
                                module.exports = exports['default'];
                            },
                            /* 29 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _slicedToArray = (function () {
                                    function sliceIterator(arr, i) {
                                        var _arr = [];
                                        var _n = true;
                                        var _d = false;
                                        var _e = undefined;
                                        try {
                                            for (
                                                var _i = arr[Symbol.iterator](), _s;
                                                !(_n = (_s = _i.next()).done);
                                                _n = true
                                            ) {
                                                _arr.push(_s.value);
                                                if (i && _arr.length === i) break;
                                            }
                                        } catch (err) {
                                            _d = true;
                                            _e = err;
                                        } finally {
                                            try {
                                                if (!_n && _i['return']) _i['return']();
                                            } finally {
                                                if (_d) throw _e;
                                            }
                                        }
                                        return _arr;
                                    }
                                    return function (arr, i) {
                                        if (Array.isArray(arr)) {
                                            return arr;
                                        } else if (Symbol.iterator in Object(arr)) {
                                            return sliceIterator(arr, i);
                                        } else {
                                            throw new TypeError('Invalid attempt to destructure non-iterable instance');
                                        }
                                    };
                                })();
                                exports.enableEdit = enableEdit;
                                exports.disableEdit = disableEdit;
                                exports.createEditOverlay = createEditOverlay;
                                exports.destroyEditOverlay = destroyEditOverlay;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _event = __webpack_require__(4);
                                var _utils = __webpack_require__(6);
                                var _ajaxloader = __webpack_require__(36);
                                var _renderPoint = __webpack_require__(17);
                                var _questionsRenderer = __webpack_require__(38);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                function _toConsumableArray(arr) {
                                    if (Array.isArray(arr)) {
                                        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
                                            arr2[i] = arr[i];
                                        }
                                        return arr2;
                                    } else {
                                        return Array.from(arr);
                                    }
                                }
                                var _enabled = false;
                                var isDragging = false,
                                    overlay = void 0,
                                    overlayOld = void 0,
                                    annoId = 0,
                                    isMoved = true;
                                var dragOffsetX = void 0,
                                    dragOffsetY = void 0,
                                    dragStartX = void 0,
                                    dragStartY = void 0;
                                var OVERLAY_BORDER_SIZE = 3;
                                var SIZE = 20;
                                /**
                                 * Create an overlay for editing an annotation.
                                 *
                                 * @param {Element} target The annotation element to apply overlay for
                                 */ function createEditOverlay(target) {
                                    destroyEditOverlay();
                                    overlay = document.createElement('div');
                                    var anchor = document.createElement('a');
                                    var node = (0, _utils.findSVGContainer)(target);
                                    if (node) {
                                        var parentNode = node.parentNode;
                                        var id = target.getAttribute('data-pdf-annotate-id');
                                        var rect = (0, _utils.getAnnotationRect)(target);
                                        var styleLeft = rect.left - OVERLAY_BORDER_SIZE;
                                        var styleTop = rect.top - OVERLAY_BORDER_SIZE;
                                        overlay.setAttribute('id', 'pdf-annotate-edit-overlay');
                                        overlay.setAttribute('data-target-id', id);
                                        overlay.style.boxSizing = 'content-box';
                                        overlay.style.position = 'absolute';
                                        overlay.style.top = styleTop + 'px';
                                        overlay.style.left = styleLeft + 'px';
                                        overlay.style.width = rect.width + 'px';
                                        overlay.style.height = rect.height + 'px';
                                        overlay.style.border = OVERLAY_BORDER_SIZE + 'px solid ' + _utils.BORDER_COLOR;
                                        overlay.style.borderRadius = OVERLAY_BORDER_SIZE + 'px';
                                        overlay.style.zIndex = 22;
                                        anchor.innerHTML = 'x';
                                        anchor.setAttribute('href', 'javascript://');
                                        anchor.style.background = '#fff';
                                        anchor.style.borderRadius = '20px';
                                        anchor.style.border = '1px solid #bbb';
                                        anchor.style.color = '#bbb';
                                        anchor.style.fontSize = '12px';
                                        anchor.style.padding = '0px 3px 7px';
                                        anchor.style.textAlign = 'center';
                                        anchor.style.textDecoration = 'none';
                                        anchor.style.position = 'absolute';
                                        anchor.style.top = '-10px';
                                        anchor.style.right = '-10px';
                                        anchor.style.width = '11px';
                                        anchor.style.height = '11px';
                                        anchor.style.boxSizing = 'content-box';
                                        overlay.appendChild(anchor);
                                        parentNode.appendChild(overlay);
                                        document.addEventListener('click', handleDocumentClick);
                                        document.addEventListener('keyup', handleDocumentKeyup);
                                        document.addEventListener('mousedown', handleDocumentMousedown);
                                        anchor.addEventListener('click', deleteAnnotation);
                                        anchor.addEventListener('mouseover', function () {
                                            anchor.style.color = '#35A4DC';
                                            anchor.style.borderColor = '#999';
                                            anchor.style.boxShadow = '0 1px 1px #ccc';
                                        });
                                        anchor.addEventListener('mouseout', function () {
                                            anchor.style.color = '#bbb';
                                            anchor.style.borderColor = '#bbb';
                                            anchor.style.boxShadow = '';
                                        });
                                        overlay.addEventListener('mouseover', function () {
                                            if (!isDragging) {
                                                anchor.style.display = '';
                                            }
                                        });
                                        overlay.addEventListener('mouseout', function () {
                                            anchor.style.display = 'none';
                                        });
                                        overlayOld = { x: overlay.style.top, y: overlay.style.left };
                                    }
                                }
                                /**
                                 * Destroy the edit overlay if it exists.
                                 */ function destroyEditOverlay() {
                                    if (overlay && overlay.parentNode !== null) {
                                        overlay.parentNode.removeChild(overlay);
                                        overlay = null;
                                    }
                                    document.removeEventListener('click', handleDocumentClick);
                                    document.removeEventListener('keyup', handleDocumentKeyup);
                                    document.removeEventListener('mousedown', handleDocumentMousedown);
                                    document.removeEventListener('mousemove', handleDocumentMousemove);
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                    (0, _utils.enableUserSelect)();
                                }
                                /**
                                 * Delete currently selected annotation
                                 */ function deleteAnnotation() {
                                    if (!overlay) {
                                        return;
                                    }
                                    annoId = overlay.getAttribute('data-target-id');
                                    if (_capabilities.deleteany) {
                                        notification.confirm(
                                            M.util.get_string('deletingCommentTitle', 'pdfannotator'),
                                            M.util.get_string('deletingAnnotation_manager', 'pdfannotator'),
                                            M.util.get_string('yesButton', 'pdfannotator'),
                                            M.util.get_string('cancelButton', 'pdfannotator'),
                                            deleteAnnotationCallback
                                        );
                                    } else {
                                        notification.confirm(
                                            M.util.get_string('deletingCommentTitle', 'pdfannotator'),
                                            M.util.get_string('deletingAnnotation_student', 'pdfannotator'),
                                            M.util.get_string('yesButton', 'pdfannotator'),
                                            M.util.get_string('cancelButton', 'pdfannotator'),
                                            deleteAnnotationCallback
                                        );
                                    }
                                }
                                /**
                                 * Is called if the user confirms to delete the annotation.
                                 * This function destroys the annotation and deletes it from the database
                                 * @returns {undefined}
                                 */
                                function deleteAnnotationCallback() {
                                    var annotationId;
                                    if (!overlay) {
                                        annotationId = annoId;
                                    } else {
                                        annotationId = overlay.getAttribute('data-target-id');
                                    }
                                    var nodes = document.querySelectorAll(
                                        '[data-pdf-annotate-id="' + annotationId + '"]'
                                    );

                                    _PDFJSAnnotate2.default
                                        .getStoreAdapter()
                                        .deleteAnnotation(_documentObject.annotatorid, annotationId)
                                        .then(
                                            function (data) {
                                                if (data.status === 'success') {
                                                    // destroy blue box (overlay)
                                                    destroyEditOverlay();
                                                    // destroy annotation DOM element
                                                    [].concat(_toConsumableArray(nodes)).forEach(function (n) {
                                                        n.parentNode.removeChild(n);
                                                    });
                                                    // destroy Commentsfield
                                                    document.querySelector('.comment-list-container').innerHTML = '';
                                                    document
                                                        .querySelector('.comment-list-form')
                                                        .setAttribute('style', 'display:none');
                                                    var visiblePageNum = document.getElementById('currentPage').value;
                                                    _questionsRenderer.renderQuestions(
                                                        _documentObject.annotatorid,
                                                        visiblePageNum
                                                    );
                                                } else {
                                                }
                                            },
                                            function (err) {
                                                notification.addNotification({
                                                    message: M.util.get_string(
                                                        'error:deleteAnnotation',
                                                        'pdfannotator'
                                                    ),
                                                    type: 'error',
                                                });
                                                console.error(
                                                    M.util.get_string('error:deleteAnnotation', 'pdfannotator')
                                                );
                                            }
                                        );
                                }

                                /**
                                 * Handle document.click event
                                 *
                                 * @param {Event} e The DOM event that needs to be handled
                                 */ function handleDocumentClick(e) {
                                    //if the click is on an input field or link or icon in editor toolbar ('I') nothing should happen.
                                    if (
                                        e.target.tagName === 'INPUT' ||
                                        e.target.tagName === 'TEXTAREA' ||
                                        e.target.tagName === 'BUTTON' ||
                                        e.target.tagName === 'I'
                                    ) {
                                        return;
                                    }
                                    //if the click is on the Commentlist nothing should happen.
                                    if (
                                        (typeof e.target.getAttribute('id') != 'string' &&
                                            e.target.id.indexOf('comment') !== -1) ||
                                        e.target.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('chat') !== -1
                                    ) {
                                        return;
                                    }
                                    if (!(0, _utils.findSVGAtPoint)(e.clientX, e.clientY)) {
                                        return;
                                    } // Remove current overlay
                                    var overlay = document.getElementById('pdf-annotate-edit-overlay');
                                    if (overlay) {
                                        if (isDragging || e.target === overlay) {
                                            return;
                                        }
                                        destroyEditOverlay();
                                    }
                                    isMoved = false;
                                }
                                /**
                                 * Handle document.keyup event
                                 *
                                 * @param {Event} e The DOM event that needs to be handled
                                 */ function handleDocumentKeyup(e) {
                                    if (
                                        overlay &&
                                        e.keyCode === 46 &&
                                        !e.target.closest('.edit-comment-form') &&
                                        !e.target.closest('.comment-list-form')
                                    ) {
                                        deleteAnnotation();
                                    }
                                }
                                /**
                                 * Handle document.mousedown event
                                 *
                                 * @param {Event} e The DOM event that needs to be handled
                                 */ function handleDocumentMousedown(e) {
                                    if (e.target !== overlay) {
                                        return;
                                    } // Highlight and strikeout annotations are bound to text within the document.
                                    // It doesn't make sense to allow repositioning these types of annotations.
                                    var annotationId = overlay.getAttribute('data-target-id');
                                    var target = document.querySelector(
                                        '[data-pdf-annotate-id="' + annotationId + '"]'
                                    );
                                    var type = target.getAttribute('data-pdf-annotate-type');
                                    if (type === 'highlight' || type === 'strikeout') {
                                        return;
                                    }
                                    isDragging = true;
                                    dragOffsetX = e.clientX;
                                    dragOffsetY = e.clientY;
                                    dragStartX = overlay.offsetLeft;
                                    dragStartY = overlay.offsetTop;
                                    overlay.style.background = 'rgba(255, 255, 255, 0.7)';
                                    overlay.style.setProperty('cursor', 'move', 'important');
                                    overlay.querySelector('a').style.display = 'none';
                                    document.addEventListener('mousemove', handleDocumentMousemove);
                                    document.addEventListener('mouseup', handleDocumentMouseup);
                                    (0, _utils.disableUserSelect)();
                                }
                                /**
                                 * Handle document.mousemove event
                                 *
                                 *
                                 * @param {Event} e The DOM event that needs to be handled
                                 */ function handleDocumentMousemove(e) {
                                    var annotationId = overlay.getAttribute('data-target-id');
                                    var parentNode = overlay.parentNode;
                                    var rect = parentNode.getBoundingClientRect();
                                    var y = dragStartY + (e.clientY - dragOffsetY);
                                    var x = dragStartX + (e.clientX - dragOffsetX);
                                    var minY = 0;
                                    var maxY = rect.height;
                                    var minX = 0;
                                    var maxX = rect.width;
                                    if (y > minY && y + overlay.offsetHeight < maxY) {
                                        overlay.style.top = y + 'px';
                                    }
                                    if (x > minX && x + overlay.offsetWidth < maxX) {
                                        overlay.style.left = x + 'px';
                                    }
                                    isMoved = true;
                                }
                                /**
                                 * Handle document.mouseup event
                                 * This function is responsible for shifting areas, pins, textboxes and drawings
                                 *
                                 * @param {Event} e The DOM event that needs to be handled
                                 */ function handleDocumentMouseup(e) {
                                    var annotationId = overlay.getAttribute('data-target-id');
                                    var target = document.querySelectorAll(
                                        '[data-pdf-annotate-id="' + annotationId + '"]'
                                    );
                                    var type = target[0].getAttribute('data-pdf-annotate-type');
                                    var svg = overlay.parentNode.querySelector('svg.annotationLayer');
                                    var _getMetadata2 = (0, _utils.getMetadata)(svg);
                                    var documentId = _getMetadata2.documentId;
                                    var pageNumber = _getMetadata2.pageNumber;
                                    var isFirefox = /firefox/i.test(navigator.userAgent);

                                    overlay.querySelector('a').style.display = '';
                                    function getDelta(propX, propY) {
                                        return calcDelta(
                                            parseInt(target[0].getAttribute(propX), 10),
                                            parseInt(target[0].getAttribute(propY), 10)
                                        );
                                    }
                                    function calcDelta(x, y) {
                                        return {
                                            deltaX:
                                                OVERLAY_BORDER_SIZE +
                                                (0, _utils.scaleDown)(svg, { x: overlay.offsetLeft }).x -
                                                x,
                                            deltaY:
                                                OVERLAY_BORDER_SIZE +
                                                (0, _utils.scaleDown)(svg, { y: overlay.offsetTop }).y -
                                                y,
                                        };
                                    }
                                    (0, _ajaxloader.showLoader)();
                                    var oldX = 0;
                                    var oldY = 0;
                                    var viewY = dragStartY;
                                    var viewX = dragStartX;
                                    _PDFJSAnnotate2.default
                                        .getStoreAdapter()
                                        .getAnnotation(documentId, annotationId)
                                        .then(
                                            function (annotation) {
                                                oldX = annotation['annotation'].x;
                                                oldY = annotation['annotation'].y;
                                                (0, _ajaxloader.showLoader)();
                                                if (['area', 'point', 'textbox'].indexOf(type) > -1) {
                                                    (function () {
                                                        var _getDelta = getDelta('x', 'y');
                                                        var deltaX = _getDelta.deltaX;
                                                        var deltaY = _getDelta.deltaY;
                                                        [].concat(_toConsumableArray(target)).forEach(function (t, i) {
                                                            // adjust y coordinate if necessary
                                                            if (deltaY !== 0) {
                                                                var modelY = parseInt(t.getAttribute('y'), 10) + deltaY;
                                                                viewY = modelY;
                                                                if (type === 'point') {
                                                                    //+SIZE, because the pin should not be rendered right under the click point, instead it should be rendered centered above the click point
                                                                    modelY += SIZE;
                                                                }
                                                                if (type === 'textbox') {
                                                                    viewY += parseInt(
                                                                        annotation['annotation'].size,
                                                                        10
                                                                    );
                                                                }
                                                                if (type === 'point' && !isFirefox) {
                                                                    viewY = (0, _utils.scaleUp)(svg, {
                                                                        viewY: viewY,
                                                                    }).viewY;
                                                                }
                                                                if (isFirefox) {
                                                                    viewY -= 6;
                                                                }
                                                                if (annotation.rectangles) {
                                                                    annotation.rectangles[i].y = modelY;
                                                                } else {
                                                                    annotation['annotation'].y = modelY; // .toString();
                                                                }
                                                            }
                                                            // adjust x coordinate if necessary
                                                            if (deltaX !== 0) {
                                                                var modelX = parseInt(t.getAttribute('x'), 10) + deltaX;
                                                                viewX = modelX;
                                                                //+(1/4)Size, because the pin should be rendered centered of the click point not on the righthand side.
                                                                if (type === 'point') {
                                                                    modelX += SIZE / 4;
                                                                }
                                                                if (type === 'point' && !isFirefox) {
                                                                    viewX = (0, _utils.scaleUp)(svg, {
                                                                        viewX: viewX,
                                                                    }).viewX;
                                                                }
                                                                if (isFirefox) {
                                                                    viewX -= 6;
                                                                }
                                                                //t.setAttribute('x',viewX);
                                                                if (annotation.rectangles) {
                                                                    annotation.rectangles[i].x = modelX;
                                                                } else {
                                                                    annotation['annotation'].x = modelX; // .toString();
                                                                }
                                                            }
                                                        });
                                                    })();
                                                } else if (type === 'drawing') {
                                                    (function () {
                                                        var rect = (0, _utils.scaleDown)(
                                                            svg,
                                                            (0, _utils.getAnnotationRect)(target[0])
                                                        );

                                                        var _annotation$lines$ = _slicedToArray(
                                                            annotation['annotation'].lines[0],
                                                            2
                                                        );

                                                        var originX = _annotation$lines$[0];
                                                        var originY = _annotation$lines$[1];

                                                        var _calcDelta = calcDelta(originX, originY);

                                                        var deltaX = _calcDelta.deltaX;

                                                        var deltaY = _calcDelta.deltaY; // origin isn't necessarily at 0/0 in relation to overlay x/y
                                                        // adjust the difference between overlay and drawing coords

                                                        deltaY += originY - rect.top;
                                                        deltaX += originX - rect.left;

                                                        annotation['annotation'].lines.forEach(function (line, i) {
                                                            var _annotation$lines$i = _slicedToArray(
                                                                annotation['annotation'].lines[i],
                                                                2
                                                            );
                                                            var x = _annotation$lines$i[0];
                                                            var y = _annotation$lines$i[1];
                                                            annotation['annotation'].lines[i][0] = (0,
                                                            _utils.roundDigits)(x + deltaX, 4);
                                                            annotation['annotation'].lines[i][1] = (0,
                                                            _utils.roundDigits)(y + deltaY, 4);
                                                        });
                                                    })();
                                                }
                                                (function editAnnotation() {
                                                    if (!overlay) {
                                                        return;
                                                    }
                                                    if (dragStartX === viewX && dragStartY === viewY) {
                                                        return;
                                                    }
                                                    annoId = overlay.getAttribute('data-target-id');
                                                    notification.confirm(
                                                        M.util.get_string('editAnnotationTitle', 'pdfannotator'),
                                                        M.util.get_string('editAnnotation', 'pdfannotator'),
                                                        M.util.get_string('yesButton', 'pdfannotator'),
                                                        M.util.get_string('cancelButton', 'pdfannotator'),
                                                        editAnnotationCallback,
                                                        overlayToOldPlace
                                                    );
                                                })();

                                                function overlayToOldPlace() {
                                                    // Overlay back to old place.
                                                    overlay.style.top = overlayOld.x;
                                                    overlay.style.left = overlayOld.y;
                                                    // Show comments.
                                                    _event.fireEvent('annotation:click', target[0]);
                                                }
                                                /**
                                                 * Is called if the user confirms to move the annotation.
                                                 * This function destroys the annotation and deletes it from the database
                                                 * @returns {undefined}
                                                 */
                                                function editAnnotationCallback() {
                                                    _PDFJSAnnotate2.default
                                                        .getStoreAdapter()
                                                        .editAnnotation(
                                                            documentId,
                                                            pageNumber,
                                                            annotationId,
                                                            annotation
                                                        )
                                                        .then(
                                                            function (success) {
                                                                (0, _ajaxloader.hideLoader)();
                                                                if (!success) {
                                                                    overlayToOldPlace();

                                                                    // Notification, that the annotation could not be edited.
                                                                    notification.addNotification({
                                                                        message: M.util.get_string(
                                                                            'editNotAllowed',
                                                                            'pdfannotator'
                                                                        ),
                                                                        type: 'error',
                                                                    });
                                                                    setTimeout(function () {
                                                                        let notificationpanel =
                                                                            document.getElementById(
                                                                                'user-notifications'
                                                                            );
                                                                        while (notificationpanel.hasChildNodes()) {
                                                                            notificationpanel.removeChild(
                                                                                notificationpanel.firstChild
                                                                            );
                                                                        }
                                                                    }, 4000);
                                                                } else {
                                                                    if (
                                                                        ['area', 'point', 'textbox'].indexOf(type) > -1
                                                                    ) {
                                                                        (function () {
                                                                            []
                                                                                .concat(_toConsumableArray(target))
                                                                                .forEach(function (t, i) {
                                                                                    t.setAttribute('y', viewY);
                                                                                    t.setAttribute('x', viewX);
                                                                                });
                                                                        })();
                                                                    } else if (type === 'drawing') {
                                                                        target[0].parentNode.removeChild(target[0]);
                                                                        (0, _appendChild2.default)(
                                                                            svg,
                                                                            annotation['annotation']
                                                                        );
                                                                    }
                                                                    //_renderPoint(annotation['annotation']);
                                                                    _event.fireEvent('annotation:click', target[0]);
                                                                }
                                                            },
                                                            function (err) {
                                                                overlayToOldPlace();

                                                                notification.addNotification({
                                                                    message: M.util.get_string(
                                                                        'error:editAnnotation',
                                                                        'pdfannotator'
                                                                    ),
                                                                    type: 'error',
                                                                });
                                                            }
                                                        );
                                                }
                                            },
                                            function (err) {
                                                notification.addNotification({
                                                    message: M.util.get_string('error:getAnnotation', 'pdfannotator'),
                                                    type: 'error',
                                                });
                                            }
                                        );
                                    //                getComments(_fileid, annotationId);
                                    setTimeout(function () {
                                        isDragging = false;
                                    }, 0);
                                    overlay.style.background = '';
                                    overlay.style.cursor = '';
                                    document.removeEventListener('mousemove', handleDocumentMousemove);
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                    (0, _utils.enableUserSelect)();
                                }

                                /**
                                 * Handle annotation.click event
                                 *
                                 * @param {Element} e The annotation element that was clicked
                                 */ function handleAnnotationClick(target) {
                                    if (isDragging) {
                                        return;
                                    }
                                    createEditOverlay(target);
                                }
                                /**
                                 * Enable edit mode behavior.
                                 */ function enableEdit() {
                                    if (_enabled) {
                                        return;
                                    }
                                    _enabled = true;
                                    document.getElementById('content-wrapper').classList.add('cursor-edit');
                                    (0, _event.addEventListener)('annotation:click', handleAnnotationClick);
                                }
                                /**
                                 * Disable edit mode behavior.
                                 */ function disableEdit() {
                                    destroyEditOverlay();
                                    if (!_enabled) {
                                        return;
                                    }
                                    _enabled = false;
                                    document.getElementById('content-wrapper').classList.remove('cursor-edit');
                                    (0, _event.removeEventListener)('annotation:click', handleAnnotationClick);
                                }
                            },
                            /* 30 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.setPen = setPen;
                                exports.enablePen = enablePen;
                                exports.disablePen = disablePen;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _utils = __webpack_require__(6);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var _enabled = false;
                                var _penSize = void 0;
                                var _penColor = void 0;
                                var path = void 0;
                                var lines = void 0;
                                var _svg = void 0;
                                /**
                                 * Handle document.mousedown event
                                 */ function handleDocumentMousedown() {
                                    path = null;
                                    lines = [];
                                    document.addEventListener('mousemove', handleDocumentMousemove);
                                    document.addEventListener('mouseup', handleDocumentMouseup);
                                }
                                /**
                                 * Handle document.mouseup event
                                 *
                                 * @param {Event} e The DOM event to be handled
                                 */ function handleDocumentMouseup(e) {
                                    var svg = void 0;
                                    if (lines.length > 1 && (svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY))) {
                                        var _getMetadata = (0, _utils.getMetadata)(svg);
                                        var documentId = _getMetadata.documentId;
                                        var pageNumber = _getMetadata.pageNumber;
                                        _PDFJSAnnotate2.default
                                            .getStoreAdapter()
                                            .addAnnotation(documentId, pageNumber, {
                                                type: 'drawing',
                                                width: _penSize,
                                                color: _penColor,
                                                lines: lines,
                                            })
                                            .then(
                                                function (annotation) {
                                                    if (path) {
                                                        svg.removeChild(path);
                                                    }
                                                    (0, _appendChild2.default)(svg, annotation);
                                                },
                                                function (err) {
                                                    // Remove path
                                                    if (path) {
                                                        svg.removeChild(path);
                                                    }
                                                    notification.addNotification({
                                                        message: M.util.get_string(
                                                            'error:addAnnotation',
                                                            'pdfannotator'
                                                        ),
                                                        type: 'error',
                                                    });
                                                }
                                            );
                                    }
                                    document.removeEventListener('mousemove', handleDocumentMousemove);
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                }
                                /**
                                 * Handle document.mousemove event
                                 *
                                 * @param {Event} e The DOM event to be handled
                                 */ function handleDocumentMousemove(e) {
                                    savePoint(e.clientX, e.clientY);
                                }
                                /**
                                 * Handle document.keyup event
                                 *
                                 * @param {Event} e The DOM event to be handled
                                 */ function handleDocumentKeyup(e) {
                                    // Cancel rect if Esc is pressed
                                    if (e.keyCode === 27) {
                                        lines = null;
                                        path.parentNode.removeChild(path);
                                        document.removeEventListener('mousemove', handleDocumentMousemove);
                                        document.removeEventListener('mouseup', handleDocumentMouseup);
                                    }
                                }
                                /**
                                 * Save a point to the line being drawn.
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 */
                                function savePoint(x, y) {
                                    var svg = (0, _utils.findSVGAtPoint)(x, y);
                                    if (!svg) {
                                        return;
                                    }
                                    var rect = svg.getBoundingClientRect();
                                    var point = (0, _utils.scaleDown)(svg, {
                                        x: (0, _utils.roundDigits)(x - rect.left, 4),
                                        y: (0, _utils.roundDigits)(y - rect.top, 4),
                                    });
                                    lines.push([point.x, point.y]);
                                    if (lines.length <= 1) {
                                        return;
                                    }
                                    if (path) {
                                        svg.removeChild(path);
                                    }
                                    path = (0, _appendChild2.default)(svg, {
                                        type: 'drawing',
                                        color: _penColor,
                                        width: _penSize,
                                        lines: lines,
                                    });
                                }
                                function handleContentTouchstart(e) {
                                    path = null;
                                    lines = [];
                                    _svg = (0, _utils.findSVGAtPoint)(e.touches[0].clientX, e.touches[0].clientY);
                                    saveTouchPoint(e.touches[0].clientX, e.touches[0].clientY);
                                }
                                function handleContentTouchmove(e) {
                                    e.preventDefault();
                                    saveTouchPoint(e.touches[0].clientX, e.touches[0].clientY);
                                }
                                function handleContentTouchend(e) {
                                    if (lines.length > 1) {
                                        var _getMetadata = (0, _utils.getMetadata)(_svg);
                                        var documentId = _getMetadata.documentId;
                                        var pageNumber = _getMetadata.pageNumber;
                                        _PDFJSAnnotate2.default
                                            .getStoreAdapter()
                                            .addAnnotation(documentId, pageNumber, {
                                                type: 'drawing',
                                                width: _penSize,
                                                color: _penColor,
                                                lines: lines,
                                            })
                                            .then(
                                                function (annotation) {
                                                    if (path) {
                                                        _svg.removeChild(path);
                                                    }
                                                    (0, _appendChild2.default)(_svg, annotation);
                                                },
                                                function (err) {
                                                    // Remove path
                                                    if (path) {
                                                        _svg.removeChild(path);
                                                    }
                                                    notification.addNotification({
                                                        message: M.util.get_string(
                                                            'error:addAnnotation',
                                                            'pdfannotator'
                                                        ),
                                                        type: 'error',
                                                    });
                                                }
                                            );
                                    }
                                }
                                function handleContentTouchcancel(e) {
                                    lines = null;
                                    path.parentNode.removeChild(path);
                                }

                                /* Save a touchpoint to the line being drawn.
                                 *
                                 * @param {Number} x The x coordinate of the point
                                 * @param {Number} y The y coordinate of the point
                                 */ function saveTouchPoint(x, y) {
                                    if (!_svg) {
                                        return;
                                    }
                                    var rect = _svg.getBoundingClientRect();
                                    var point = (0, _utils.scaleDown)(_svg, {
                                        x: (0, _utils.roundDigits)(x - rect.left, 4),
                                        y: (0, _utils.roundDigits)(y - rect.top, 4),
                                    });
                                    lines.push([point.x, point.y]);
                                    if (lines.length <= 1) {
                                        return;
                                    }
                                    if (path) {
                                        _svg.removeChild(path);
                                    }
                                    path = (0, _appendChild2.default)(_svg, {
                                        type: 'drawing',
                                        color: _penColor,
                                        width: _penSize,
                                        lines: lines,
                                    });
                                }

                                /**
                                 * Set the attributes of the pen.
                                 *
                                 * @param {Number} penSize The size of the lines drawn by the pen
                                 * @param {String} penColor The color of the lines drawn by the pen
                                 */ function setPen() {
                                    var penSize =
                                        arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];
                                    var penColor =
                                        arguments.length <= 1 || arguments[1] === undefined ? '000000' : arguments[1];
                                    _penSize = parseInt(penSize, 10);
                                    _penColor = penColor;
                                }
                                /**
                                 * Enable the pen behavior
                                 */ function enablePen() {
                                    if (_enabled) {
                                        return;
                                    }
                                    _enabled = true;
                                    var contentWrapper = document.getElementById('content-wrapper');
                                    contentWrapper.classList.add('cursor-pen');
                                    document.addEventListener('mousedown', handleDocumentMousedown);
                                    document.addEventListener('keyup', handleDocumentKeyup);
                                    contentWrapper.addEventListener('touchstart', handleContentTouchstart);
                                    contentWrapper.addEventListener('touchmove', handleContentTouchmove);
                                    contentWrapper.addEventListener('touchend', handleContentTouchend);
                                    contentWrapper.addEventListener('touchcancel', handleContentTouchcancel);
                                    (0, _utils.disableUserSelect)();
                                }
                                /**
                                 * Disable the pen behavior
                                 */ function disablePen() {
                                    if (!_enabled) {
                                        return;
                                    }
                                    _enabled = false;
                                    var contentWrapper = document.getElementById('content-wrapper');
                                    contentWrapper.classList.remove('cursor-pen');
                                    document.removeEventListener('mousedown', handleDocumentMousedown);
                                    document.removeEventListener('keyup', handleDocumentKeyup);
                                    contentWrapper.removeEventListener('touchstart', handleContentTouchstart);
                                    contentWrapper.removeEventListener('touchmove', handleContentTouchmove);
                                    contentWrapper.removeEventListener('touchend', handleContentTouchend);
                                    contentWrapper.removeEventListener('touchcancel', handleContentTouchcancel);
                                    (0, _utils.enableUserSelect)();
                                }
                            },
                            /* 31 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _typeof =
                                    typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
                                        ? function (obj) {
                                              return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
                                          }
                                        : function (obj) {
                                              return obj && typeof Symbol === 'function' && obj.constructor === Symbol
                                                  ? 'symbol'
                                                  : typeof obj === 'undefined'
                                                  ? 'undefined'
                                                  : _typeof2(obj);
                                          };
                                exports.enablePoint = enablePoint;
                                exports.disablePoint = disablePoint;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _utils = __webpack_require__(6);
                                var _commentWrapper = __webpack_require__(35);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var _enabled = false;
                                var data = void 0;
                                var _svg = void 0;
                                var _rect = void 0;
                                var dragging = false;
                                //Test
                                var textarea = void 0;
                                var submitbutton = void 0;
                                var form = void 0;
                                var annotationObj;
                                var documentId = -1;
                                var pageNumber = 1;

                                /**
                                 * Handle document.mouseup event
                                 *
                                 * @param {Event} The DOM event to be handled
                                 */ function handleDocumentMouseup(e) {
                                    //if the click is in comment wrapper area nothing should happen.
                                    var commentWrapperNodes = document.querySelectorAll('div#comment-wrapper')[0];
                                    var clickedElement;
                                    if (e.target.id) {
                                        clickedElement = '#' + e.target.id;
                                    } else if (e.target.className[0]) {
                                        clickedElement = '.' + e.target.className;
                                    } else {
                                        clickedElement = '';
                                    }
                                    if (clickedElement && commentWrapperNodes.querySelector(clickedElement)) {
                                        return;
                                    }

                                    //If Modal Dialogue beeing clicked.
                                    var clickedMoodleDialogue = e.target.closest('.moodle-dialogue-base');
                                    if (clickedMoodleDialogue) {
                                        return;
                                    }

                                    //if the click is on the Commentlist nothing should happen.
                                    if (
                                        (typeof e.target.getAttribute('id') == 'string' &&
                                            e.target.id.indexOf('comment') !== -1) ||
                                        e.target.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('chat') !== -1 ||
                                        e.target.tagName == 'INPUT' ||
                                        e.target.tagName == 'LABEL'
                                    ) {
                                        return;
                                    }
                                    _svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY);
                                    if (!_svg) {
                                        return;
                                    }
                                    var _getMetadata = (0, _utils.getMetadata)(_svg);
                                    documentId = _getMetadata.documentId;
                                    pageNumber = _getMetadata.pageNumber;
                                    deleteUndefinedPin();
                                    var fn = () => {
                                        [textarea, data] = (0, _commentWrapper.openComment)(
                                            e,
                                            handleCancelClick,
                                            handleSubmitClick,
                                            handleToolbarClick,
                                            handleSubmitBlur,
                                            'pin'
                                        );
                                        renderPin();
                                    };
                                    _commentWrapper.loadEditor('add', 0, fn);
                                }

                                // Reset dragging to false.
                                function handleContentTouchstart(e) {
                                    dragging = false;
                                }
                                // Set dragging to true, so we stop the handleContentTouchend function from running.
                                function handleContentTouchmove(e) {
                                    dragging = true;
                                }
                                /**
                                 * Handle content.touchend event
                                 *
                                 * @param {Event} The DOM event to be handled
                                 */ function handleContentTouchend(e) {
                                    // If the mobile user was scrolling return from this function.
                                    if (dragging) {
                                        return;
                                    }
                                    //if the click is on the Commentlist nothing should happen.
                                    if (
                                        (typeof e.target.getAttribute('id') == 'string' &&
                                            e.target.id.indexOf('comment') !== -1) ||
                                        e.target.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('comment') !== -1 ||
                                        e.target.parentNode.className.indexOf('chat') !== -1 ||
                                        e.target.tagName == 'INPUT' ||
                                        e.target.tagName == 'LABEL'
                                    ) {
                                        return;
                                    }
                                    let svg = (0, _utils.findSVGAtPoint)(
                                        e.changedTouches[0].clientX,
                                        e.changedTouches[0].clientY
                                    );
                                    if (!svg) {
                                        return;
                                    }
                                    var _getMetadata = (0, _utils.getMetadata)(svg);
                                    documentId = _getMetadata.documentId;
                                    pageNumber = _getMetadata.pageNumber;
                                    deleteUndefinedPin();
                                    var coordinates = {
                                        x: e.changedTouches[0].clientX,
                                        y: e.changedTouches[0].clientY,
                                    };
                                    renderPinTouchscreen(coordinates);
                                    [textarea, data] = (0, _commentWrapper.openCommentTouchscreen)(
                                        e,
                                        handleCancelClick,
                                        handleSubmitClick,
                                        handleToolbarClick,
                                        handleSubmitBlur,
                                        'pin'
                                    );
                                }

                                /**
                                 * If the toolbar is clicked, the point tool should be disabled and the commentswrapper should be closed
                                 * @param {type} e
                                 * @returns {undefined}
                                 */
                                function handleToolbarClick(e) {
                                    disablePoint();
                                    document.querySelector('.toolbar').removeEventListener('click', handleToolbarClick);

                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                    deleteUndefinedPin();
                                    textarea = void 0;
                                }

                                function handleSubmitClick(e) {
                                    savePoint(_svg);
                                    return false;
                                }
                                function handleCancelClick(e) {
                                    textarea = void 0;
                                    //delete the temporay rendered Pin
                                    deleteUndefinedPin();
                                    enablePoint();
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                }
                                function handleSubmitBlur() {
                                    disablePoint();
                                    textarea = void 0;
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                }
                                /**
                                 * Handle input.blur event
                                 */ function handleInputBlur() {
                                    /*disablePoint();*/ savePoint();
                                }
                                /**
                                 * Handle input.keyup event
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */ function handleInputKeyup(e) {
                                    if (e.keyCode === 27) {
                                        disablePoint();
                                        closeInput();
                                    } else if (e.keyCode === 13) {
                                        /*disablePoint();*/ savePoint();
                                    }
                                }

                                function renderPin() {
                                    var clientX = (0, _utils.roundDigits)(data.x, 4);
                                    var clientY = (0, _utils.roundDigits)(data.y, 4);
                                    var content = textarea.value.trim();
                                    var svg = (0, _utils.findSVGAtPoint)(clientX, clientY);
                                    if (!svg) {
                                        return { v: void 0 };
                                    }
                                    _rect = svg.getBoundingClientRect();
                                    var annotation = initializeAnnotation(_rect, svg);
                                    annotationObj = annotation;
                                    annotation.color = true;
                                    (0, _appendChild2.default)(svg, annotation);
                                }
                                function renderPinTouchscreen(coordinates) {
                                    var clientX = (0, _utils.roundDigits)(coordinates.x, 4);
                                    var clientY = (0, _utils.roundDigits)(coordinates.y, 4);
                                    var svg = (0, _utils.findSVGAtPoint)(clientX, clientY);
                                    if (!svg) {
                                        return { v: void 0 };
                                    }
                                    _rect = svg.getBoundingClientRect();
                                    var annotation = initializeAnnotationTouchscreen(_rect, svg, coordinates);
                                    annotationObj = annotation;
                                    annotation.color = true;
                                    (0, _appendChild2.default)(svg, annotation);
                                }

                                /**
                                 * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
                                 * @returns {undefined}
                                 */
                                function deleteUndefinedPin() {
                                    let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
                                    if (n) {
                                        n.parentNode.removeChild(n);
                                    }
                                }

                                function initializeAnnotation(rect, svg) {
                                    var clientX = (0, _utils.roundDigits)(data.x, 4);
                                    var clientY = (0, _utils.roundDigits)(data.y, 4);
                                    return Object.assign(
                                        { type: 'point' },
                                        (0, _utils.scaleDown)(svg, {
                                            x: clientX - (0, _utils.roundDigits)(rect.left, 4),
                                            y: clientY - (0, _utils.roundDigits)(rect.top, 4),
                                        })
                                    );
                                }
                                function initializeAnnotationTouchscreen(rect, svg, coordinates) {
                                    var clientX = (0, _utils.roundDigits)(coordinates.x, 4);
                                    var clientY = (0, _utils.roundDigits)(coordinates.y, 4);
                                    return Object.assign(
                                        { type: 'point' },
                                        (0, _utils.scaleDown)(svg, {
                                            x: clientX - (0, _utils.roundDigits)(rect.left, 4),
                                            y: clientY - (0, _utils.roundDigits)(rect.top, 4),
                                        })
                                    );
                                }
                                /**
                                 * Save a new point annotation from input
                                 */
                                function savePoint(svg = null) {
                                    if (textarea.value.trim().length > 0) {
                                        disablePoint();
                                        var page = pageNumber;
                                        if (!svg) {
                                            var elements = document.querySelectorAll(
                                                'svg[data-pdf-annotate-container="true"]'
                                            );
                                            var svg = elements[page - 1];
                                        }
                                        var _ret = (function () {
                                            var clientX = (0, _utils.roundDigits)(data.x, 4);
                                            var clientY = (0, _utils.roundDigits)(data.y, 4);
                                            var content = textarea.value.trim();
                                            if (!svg) {
                                                return { v: void 0 };
                                            }
                                            var rect = svg.getBoundingClientRect();

                                            var _getMetadata = (0, _utils.getMetadata)(svg);
                                            var documentId = _getMetadata.documentId;
                                            var pageNumber = page;
                                            var annotation = Object.assign(
                                                { type: 'point' },
                                                (0, _utils.scaleDown)(svg, {
                                                    x: clientX - (0, _utils.roundDigits)(_rect.left, 4),
                                                    y: clientY - (0, _utils.roundDigits)(_rect.top, 4),
                                                })
                                            );
                                            var commentVisibility = read_visibility_of_checkbox();
                                            var isquestion = 1; //The Point was created so the comment is a question
                                            _PDFJSAnnotate2.default
                                                .getStoreAdapter()
                                                .addAnnotation(documentId, pageNumber, annotation)
                                                .then(
                                                    function (annotation) {
                                                        _PDFJSAnnotate2.default
                                                            .getStoreAdapter()
                                                            .addComment(
                                                                documentId,
                                                                annotation.uuid,
                                                                content,
                                                                commentVisibility,
                                                                isquestion
                                                            )
                                                            .then(function (msg) {
                                                                if (!msg) {
                                                                    throw new Error();
                                                                }
                                                                deleteUndefinedPin();
                                                                //get old y-koordniate, because of scrolling
                                                                annotation.y = annotationObj.y;
                                                                (0, _appendChild2.default)(svg, annotation);
                                                                document
                                                                    .querySelector('.toolbar')
                                                                    .removeEventListener('click', handleToolbarClick);
                                                                document.querySelector('button.cursor').click();
                                                                (0,
                                                                _commentWrapper.showCommentsAfterCreation)(annotation.uuid);
                                                            })
                                                            .catch(function (err) {
                                                                /*if there is an error in addComment, the annotation will be deleted!*/
                                                                var annotationid = annotation.uuid;
                                                                _PDFJSAnnotate2.default
                                                                    .getStoreAdapter()
                                                                    .deleteAnnotation(documentId, annotationid, false);
                                                            });
                                                    },
                                                    function (err) {
                                                        deleteUndefinedPin();
                                                        notification.addNotification({
                                                            message: M.util.get_string(
                                                                'error:addAnnotation',
                                                                'pdfannotator'
                                                            ),
                                                            type: 'error',
                                                        });
                                                    }
                                                );
                                        })();
                                        if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object') {
                                            (0, _commentWrapper.closeComment)(
                                                documentId,
                                                pageNumber,
                                                handleSubmitClick,
                                                handleCancelClick,
                                                null,
                                                true
                                            );
                                            return _ret.v;
                                        }
                                        textarea = void 0;
                                        (0, _commentWrapper.closeComment)(
                                            documentId,
                                            pageNumber,
                                            handleSubmitClick,
                                            handleCancelClick,
                                            null,
                                            true
                                        );
                                    } else {
                                        notification.addNotification({
                                            message: M.util.get_string('min0Chars', 'pdfannotator'),
                                            type: 'error',
                                        });
                                        textarea.focus();
                                    }
                                }
                                function closeInput() {
                                    data.removeEventListener('blur', handleInputBlur);
                                    data.removeEventListener('keyup', handleInputKeyup);
                                    document.body.removeChild(data);
                                    data = null;
                                }
                                /**
                                 * Enable point annotation behavior
                                 */ function enablePoint() {
                                    if (_enabled) {
                                        return;
                                    }
                                    _enabled = true;
                                    document.getElementById('content-wrapper').classList.add('cursor-point');
                                    document.addEventListener('mouseup', handleDocumentMouseup);
                                    document.addEventListener('touchstart', handleContentTouchstart);
                                    document.addEventListener('touchmove', handleContentTouchmove);
                                    document.addEventListener('touchend', handleContentTouchend);
                                }
                                /**
                                 * Disable point annotation behavior
                                 */ function disablePoint() {
                                    _enabled = false;
                                    document.getElementById('content-wrapper').classList.remove('cursor-point');
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                    document.removeEventListener('touchstart', handleContentTouchstart);
                                    document.removeEventListener('touchmove', handleContentTouchmove);
                                    document.removeEventListener('touchend', handleContentTouchend);
                                }
                            },
                            /* 32 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.enableRect = enableRect;
                                exports.disableRect = disableRect;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _utils = __webpack_require__(6);
                                var _event = __webpack_require__(4);

                                var _commentWrapper = __webpack_require__(35);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                function _toConsumableArray(arr) {
                                    if (Array.isArray(arr)) {
                                        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
                                            arr2[i] = arr[i];
                                        }
                                        return arr2;
                                    } else {
                                        return Array.from(arr);
                                    }
                                }
                                var _enabled = false;
                                var _type = void 0;
                                var overlay = void 0;
                                var originY = void 0;
                                var originX = void 0;
                                var documentId = -1;
                                var pageNumber = 1;

                                var textarea = void 0;
                                var submitbutton = void 0;
                                var resetbutton = void 0;
                                var form = void 0;
                                var data = void 0;
                                var rectsSelection = void 0;
                                var rectObj;
                                var _svg = void 0;
                                var rect = void 0;

                                /**
                                 * Get the current window selection as rects
                                 *
                                 * @return {Array} An Array of rects
                                 */
                                function getSelectionRects() {
                                    try {
                                        var selection = window.getSelection();
                                        try {
                                            var helper = selection.anchorNode.className.indexOf('helper');
                                        } catch (e) {
                                            helper = null;
                                        }
                                        if (helper !== null && helper !== -1) {
                                            return null;
                                        }
                                        var range = selection.getRangeAt(0);
                                        var rects = range.getClientRects();
                                        if (rects.length > 0 && rects[0].width > 0 && rects[0].height > 0) {
                                            return rects;
                                        }
                                    } catch (e) {}
                                    return null;
                                }
                                /**
                                 * Handle document.mousedown event
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */
                                function handleDocumentMousedown(e) {
                                    if (
                                        !(_svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY)) ||
                                        _type !== 'area'
                                    ) {
                                        return;
                                    }
                                    rect = _svg.getBoundingClientRect();
                                    originY = e.clientY;
                                    originX = e.clientX;
                                    overlay = document.createElement('div');
                                    overlay.style.position = 'absolute';
                                    overlay.id = 'overlay-rect';
                                    overlay.style.top = originY - rect.top + 'px';
                                    overlay.style.left = originX - rect.left + 'px';
                                    overlay.style.border = '3px solid ' + _utils.BORDER_COLOR;
                                    overlay.style.borderRadius = '3px';
                                    _svg.parentNode.appendChild(overlay);
                                    document.addEventListener('mousemove', handleDocumentMousemove);
                                    (0, _utils.disableUserSelect)();
                                }

                                // Handle document.touchstart event
                                function handleDocumentTouchstart(e) {
                                    if (_type == 'highlight' || _type == 'strikeout') {
                                        // Dont show the contextmenu for highlighting and strikeout.
                                        document
                                            .getElementById('content-wrapper')
                                            .addEventListener('contextmenu', (event) => {
                                                event.preventDefault();
                                                event.stopPropagation();
                                                event.stopImmediatePropagation();
                                                return false;
                                            });
                                    }

                                    if (
                                        !(_svg = (0, _utils.findSVGAtPoint)(
                                            e.touches[0].clientX,
                                            e.touches[0].clientY
                                        )) ||
                                        _type !== 'area'
                                    ) {
                                        return;
                                    }
                                    // Disable scrolling on the page.
                                    document.documentElement.style.overflow = 'hidden';
                                    document.getElementById('content-wrapper').style.overflow = 'hidden';

                                    rect = _svg.getBoundingClientRect();
                                    originY = e.touches[0].clientY;
                                    originX = e.touches[0].clientX;
                                    overlay = document.createElement('div');
                                    overlay.style.position = 'absolute';
                                    overlay.style.top = originY - rect.top + 'px';
                                    overlay.style.left = originX - rect.left + 'px';
                                    overlay.style.border = '3px solid ' + _utils.BORDER_COLOR;
                                    overlay.style.borderRadius = '3px';
                                    _svg.parentNode.appendChild(overlay);
                                    document.addEventListener('touchmove', handleDocumentTouchmove);

                                    (0, _utils.disableUserSelect)();
                                }

                                /**
                                 * Handle document.mousemove event
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */
                                function handleDocumentMousemove(e) {
                                    if (originX + (e.clientX - originX) < rect.right) {
                                        overlay.style.width = e.clientX - originX + 'px';
                                    }
                                    if (originY + (e.clientY - originY) < rect.bottom) {
                                        overlay.style.height = e.clientY - originY + 'px';
                                    }
                                }

                                // Handle document.touchmove event
                                function handleDocumentTouchmove(e) {
                                    if (originX + (e.touches[0].clientX - originX) < rect.right) {
                                        overlay.style.width = e.touches[0].clientX - originX + 'px';
                                    }
                                    if (originY + (e.touches[0].clientY - originY) < rect.bottom) {
                                        overlay.style.height = e.touches[0].clientY - originY + 'px';
                                    }
                                }

                                /**
                                 * Tests if the overlay is too small. An overlay is too small if the width or height are less 10 px or are NaN
                                 * @param {type} overlay
                                 * @returns {unresolved}
                                 */
                                function isOverlayTooSmall(overlay) {
                                    var width = parseInt(overlay.style.width);
                                    var height = parseInt(overlay.style.height);
                                    return isNaN(width) || isNaN(height) || width < 10 || height < 10;
                                }
                                /**
                                 * Handle document.mouseup event
                                 * concerns area,highlight and strikeout
                                 * @param {Event} e The DOM event to handle
                                 */
                                function handleDocumentMouseup(e) {
                                    //if the cursor is clicked nothing should happen!
                                    if (
                                        typeof e.target.getAttribute('className') != 'string' &&
                                        e.target.className.indexOf('cursor') === -1
                                    ) {
                                        document.removeEventListener('mousemove', handleDocumentMousemove);
                                        disableRect();
                                        if (_type === 'area' && overlay) {
                                            if (isOverlayTooSmall(overlay)) {
                                                overlay.parentNode.removeChild(overlay);
                                                overlay = null;
                                                enableRect(_type);
                                                return;
                                            }
                                            renderRect(
                                                _type,
                                                [
                                                    {
                                                        top: parseInt(overlay.style.top, 10) + rect.top,
                                                        left: parseInt(overlay.style.left, 10) + rect.left,
                                                        width: parseInt(overlay.style.width, 10),
                                                        height: parseInt(overlay.style.height, 10),
                                                    },
                                                ],
                                                null
                                            );

                                            let fn = () => {
                                                [textarea, data] = (0, _commentWrapper.openComment)(
                                                    e,
                                                    handleCancelClick,
                                                    handleSubmitClick,
                                                    handleToolbarClick,
                                                    handleSubmitBlur,
                                                    _type
                                                );
                                            };
                                            _commentWrapper.loadEditor('add', 0, fn);
                                        } else if ((rectsSelection = getSelectionRects()) && _type !== 'area') {
                                            renderRect(
                                                _type,
                                                [].concat(_toConsumableArray(rectsSelection)).map(function (r) {
                                                    return {
                                                        top: r.top,
                                                        left: r.left,
                                                        width: r.width,
                                                        height: r.height,
                                                    };
                                                }),
                                                null
                                            );

                                            let fn = () => {
                                                [textarea, data] = (0, _commentWrapper.openComment)(
                                                    e,
                                                    handleCancelClick,
                                                    handleSubmitClick,
                                                    handleToolbarClick,
                                                    handleSubmitBlur,
                                                    _type
                                                );
                                            };
                                            _commentWrapper.loadEditor('add', 0, fn);
                                        } else {
                                            enableRect(_type);
                                            //Do nothing!
                                        }
                                    }
                                }
                                // Handle document.touchend event
                                function handleDocumentTouchend(e) {
                                    // Enable the scrolling again
                                    document.documentElement.style.overflow = 'auto';
                                    document.getElementById('content-wrapper').style.overflow = 'auto';

                                    //if the cursor is clicked nothing should happen!
                                    if (
                                        typeof e.target.getAttribute('className') != 'string' &&
                                        e.target.className.indexOf('cursor') === -1
                                    ) {
                                        document.removeEventListener('touchmove', handleDocumentTouchmove);
                                        disableRect();
                                        if (_type === 'area' && overlay) {
                                            if (isOverlayTooSmall(overlay)) {
                                                overlay.parentNode.removeChild(overlay);
                                                overlay = null;
                                                enableRect(_type);
                                                return;
                                            }
                                            var _svg = overlay.parentNode.querySelector('svg.annotationLayer');
                                            renderRect(
                                                _type,
                                                [
                                                    {
                                                        top: parseInt(overlay.style.top, 10) + rect.top,
                                                        left: parseInt(overlay.style.left, 10) + rect.left,
                                                        width: parseInt(overlay.style.width, 10),
                                                        height: parseInt(overlay.style.height, 10),
                                                    },
                                                ],
                                                null
                                            );

                                            [textarea, data] = (0, _commentWrapper.openComment)(
                                                e,
                                                handleCancelTouch,
                                                handleSubmitClick,
                                                handleToolbarClick,
                                                handleSubmitBlur,
                                                _type
                                            );
                                        } else if ((rectsSelection = getSelectionRects()) && _type !== 'area') {
                                            renderRect(
                                                _type,
                                                [].concat(_toConsumableArray(rectsSelection)).map(function (r) {
                                                    return {
                                                        top: r.top,
                                                        left: r.left,
                                                        width: r.width,
                                                        height: r.height,
                                                    };
                                                }),
                                                null
                                            );
                                            [textarea, data] = (0, _commentWrapper.openComment)(
                                                e,
                                                handleCancelTouch,
                                                handleSubmitClick,
                                                handleToolbarClick,
                                                handleSubmitBlur,
                                                _type
                                            );
                                        } else {
                                            enableRect(_type);
                                            //Do nothing!
                                        }
                                    }
                                }

                                function handleToolbarClick(e) {
                                    //delete Overlay
                                    if (_type === 'area' && overlay) {
                                        if (overlay.parentNode) {
                                            overlay.parentNode.removeChild(overlay);
                                            overlay = null;
                                        }
                                    }
                                    document.querySelector('.toolbar').removeEventListener('click', handleToolbarClick);
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                    deleteUndefinedRect();
                                }

                                function handleSubmitClick(e) {
                                    var rects = void 0;
                                    if (_type !== 'area' && (rects = rectsSelection)) {
                                        saveRect(
                                            _type,
                                            [].concat(_toConsumableArray(rects)).map(function (r) {
                                                return {
                                                    top: r.top,
                                                    left: r.left,
                                                    width: r.width,
                                                    height: r.height,
                                                };
                                            }),
                                            null,
                                            e
                                        );
                                    } else if (_type === 'area' && overlay) {
                                        saveRect(
                                            _type,
                                            [
                                                {
                                                    top: parseInt(overlay.style.top, 10) + rect.top,
                                                    left: parseInt(overlay.style.left, 10) + rect.left,
                                                    width: parseInt(overlay.style.width, 10),
                                                    height: parseInt(overlay.style.height, 10),
                                                },
                                            ],
                                            null,
                                            e,
                                            overlay
                                        );
                                    }
                                    return false;
                                }

                                function handleCancelClick(e) {
                                    //delete Overlay
                                    if (_type === 'area' && overlay) {
                                        overlay.parentNode.removeChild(overlay);
                                        overlay = null;
                                    }
                                    //Hide the form for Comments
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                    deleteUndefinedRect();
                                    //register EventListeners to allow new Annotations
                                    enableRect(_type);
                                    (0, _utils.enableUserSelect)();
                                }

                                function handleCancelTouch(e) {
                                    // When using on mobile devices scrolling will be prevented, here we have to allow it again.
                                    document.documentElement.style.overflow = 'auto';
                                    document.getElementById('content-wrapper').style.overflow = 'auto';

                                    //delete Overlay
                                    if (_type === 'area' && overlay) {
                                        overlay.parentNode.removeChild(overlay);
                                        overlay = null;
                                    }
                                    //Hide the form for Comments
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                    deleteUndefinedRect();

                                    // Because of a scrolling issue we have to disable the area annotation after canceling the annotation.
                                    if (_type === 'area') {
                                        disableRect();
                                        document.querySelector('button.cursor').click();
                                    } else {
                                        enableRect(_type);
                                        (0, _utils.enableUserSelect)();
                                    }
                                }

                                function handleSubmitBlur() {
                                    if (overlay) {
                                        overlay.parentNode.removeChild(overlay);
                                        overlay = null;
                                    }
                                    (0, _commentWrapper.closeComment)(
                                        documentId,
                                        pageNumber,
                                        handleSubmitClick,
                                        handleCancelClick,
                                        null,
                                        false
                                    );
                                    deleteUndefinedRect();
                                }

                                /**
                                 * Handle document.keyup event
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */
                                function handleDocumentKeyup(e) {
                                    // Cancel rect if Esc is pressed
                                    if (e.keyCode === 27) {
                                        var selection = window.getSelection();
                                        selection.removeAllRanges();
                                        if (overlay && overlay.parentNode) {
                                            overlay.parentNode.removeChild(overlay);
                                            overlay = null;
                                            document.removeEventListener('mousemove', handleDocumentMousemove);
                                        }
                                    }
                                }

                                function renderRect(type, rects, color) {
                                    rect = _svg.getBoundingClientRect();
                                    var _getMetadata = (0, _utils.getMetadata)(_svg);
                                    documentId = _getMetadata.documentId;
                                    pageNumber = _getMetadata.pageNumber;
                                    var annotation = initializeAnnotation(type, rects, 'rgb(255,237,0)', _svg);
                                    rectObj = [_svg, annotation];
                                    (0, _appendChild2.default)(_svg, annotation);
                                }
                                /**
                                 * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
                                 * @returns {undefined}
                                 */
                                function deleteUndefinedRect() {
                                    let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
                                    if (n) {
                                        n.parentNode.removeChild(n);
                                    }
                                }

                                function initializeAnnotation(type, rects, color, svg) {
                                    var node = void 0;
                                    var annotation = void 0;
                                    if (!svg) {
                                        return;
                                    }
                                    if (!color) {
                                        if (type === 'highlight') {
                                            color = 'rgb(142,186,229)';
                                        } else if (type === 'strikeout') {
                                            color = 'rgb(0,84,159)';
                                        }
                                    }
                                    // Initialize the annotation
                                    annotation = {
                                        type: type,
                                        color: color,
                                        rectangles: []
                                            .concat(_toConsumableArray(rects))
                                            .map(function (r) {
                                                var offset = 0;
                                                if (type === 'strikeout') {
                                                    offset = r.height / 2;
                                                }
                                                return (0,
                                                _utils.scaleDown)(svg, { y: r.top + offset - rect.top, x: r.left - rect.left, width: r.width, height: r.height });
                                            })
                                            .filter(function (r) {
                                                return r.width > 0 && r.height > 0 && r.x > -1 && r.y > -1;
                                            }),
                                    }; // Short circuit if no rectangles exist
                                    if (annotation.rectangles.length === 0) {
                                        return;
                                    } // Special treatment for area as it only supports a single rect
                                    if (type === 'area') {
                                        var _rect = annotation.rectangles[0];
                                        delete annotation.rectangles;
                                        annotation.x = (0, _utils.roundDigits)(_rect.x, 4);
                                        annotation.y = (0, _utils.roundDigits)(_rect.y, 4);
                                        annotation.width = (0, _utils.roundDigits)(_rect.width, 4);
                                        annotation.height = (0, _utils.roundDigits)(_rect.height, 4);
                                    } else {
                                        annotation.rectangles = annotation.rectangles.map(function (
                                            elem,
                                            index,
                                            array
                                        ) {
                                            return {
                                                x: (0, _utils.roundDigits)(elem.x, 4),
                                                y: (0, _utils.roundDigits)(elem.y, 4),
                                                width: (0, _utils.roundDigits)(elem.width, 4),
                                                height: (0, _utils.roundDigits)(elem.height, 4),
                                            };
                                        });
                                    }
                                    return annotation;
                                }

                                /**
                                 * Save a rect annotation
                                 *
                                 * @param {String} type The type of rect (area, highlight, strikeout)
                                 * @param {Array} rects The rects to use for annotation
                                 * @param {String} color The color of the rects
                                 */
                                function saveRect(type, rects, color, e, overlay) {
                                    var annotation = initializeAnnotation(type, rects, color, _svg);
                                    var _getMetadata = (0, _utils.getMetadata)(_svg);
                                    var documentId = _getMetadata.documentId;
                                    var pageNumber = _getMetadata.pageNumber;
                                    var content = textarea.value.trim();
                                    if (textarea.value.trim().length > 0) {
                                        (0, _commentWrapper.closeComment)(
                                            documentId,
                                            pageNumber,
                                            handleSubmitClick,
                                            handleCancelClick,
                                            null,
                                            true
                                        );

                                        if (_type === 'area' && overlay) {
                                            overlay.parentNode.removeChild(overlay);
                                            overlay = null;
                                            document.removeEventListener('mousemove', handleDocumentMousemove);
                                            (0, _utils.enableUserSelect)();
                                        }
                                        // Add the annotation
                                        _PDFJSAnnotate2.default
                                            .getStoreAdapter()
                                            .addAnnotation(documentId, pageNumber, annotation)
                                            .then(
                                                function (annotation) {
                                                    var commentVisibility = read_visibility_of_checkbox();
                                                    var isquestion = 1; //The annotation was created, so this comment has to be a question;
                                                    _PDFJSAnnotate2.default
                                                        .getStoreAdapter()
                                                        .addComment(
                                                            documentId,
                                                            annotation.uuid,
                                                            content,
                                                            commentVisibility,
                                                            isquestion
                                                        )
                                                        .then(function (msg) {
                                                            if (!msg) throw new Error();
                                                            //delete previous annotation to render new one with the right id
                                                            deleteUndefinedRect();
                                                            //get Old rectangles because of scrolling
                                                            annotation.rectangles = rectObj[1].rectangles;

                                                            (0, _appendChild2.default)(_svg, annotation);
                                                            document
                                                                .querySelector('.toolbar')
                                                                .removeEventListener('click', handleToolbarClick);
                                                            //simulate an click on cursor
                                                            document.querySelector('button.cursor').click();
                                                            (0,
                                                            _commentWrapper.showCommentsAfterCreation)(annotation.uuid);
                                                        })
                                                        .catch(function () {
                                                            //if there is an error in addComment, the annotation should be deleted!
                                                            var annotationid = annotation.uuid;
                                                            _PDFJSAnnotate2.default
                                                                .getStoreAdapter()
                                                                .deleteAnnotation(documentId, annotationid, false);
                                                        });
                                                },
                                                function (err) {
                                                    deleteUndefinedRect();
                                                    notification.addNotification({
                                                        message: M.util.get_string(
                                                            'error:addAnnotation',
                                                            'pdfannotator'
                                                        ),
                                                        type: 'error',
                                                    });
                                                }
                                            );
                                    } else {
                                        notification.addNotification({
                                            message: M.util.get_string('min0Chars', 'pdfannotator'),
                                            type: 'error',
                                        });
                                        handleCancelClick(e);
                                        textarea.focus();
                                    }
                                }
                                /**
                                 * Enable rect behavior
                                 */
                                function enableRect(type) {
                                    _type = type;
                                    if (_enabled) {
                                        return;
                                    }

                                    if (_type === 'area') {
                                        document.getElementById('content-wrapper').classList.add('cursor-area');
                                    } else if (_type === 'highlight') {
                                        document.getElementById('content-wrapper').classList.add('cursor-highlight');
                                    } else if (_type === 'strikeout') {
                                        document.getElementById('content-wrapper').classList.add('cursor-strikeout');
                                    }

                                    _enabled = true;
                                    document.addEventListener('mouseup', handleDocumentMouseup);
                                    document.addEventListener('mousedown', handleDocumentMousedown);
                                    document.addEventListener('keyup', handleDocumentKeyup);

                                    document.addEventListener('touchstart', handleDocumentTouchstart);
                                    document.addEventListener('touchend', handleDocumentTouchend);
                                }
                                /**
                                 * Disable rect behavior
                                 */
                                function disableRect() {
                                    if (!_enabled) {
                                        return;
                                    }
                                    _enabled = false;
                                    if (_type === 'area') {
                                        document.getElementById('content-wrapper').classList.remove('cursor-area');
                                    } else if (_type === 'highlight') {
                                        document.getElementById('content-wrapper').classList.remove('cursor-highlight');
                                    } else if (_type === 'strikeout') {
                                        document.getElementById('content-wrapper').classList.remove('cursor-strikeout');
                                    }
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                    document.removeEventListener('mousedown', handleDocumentMousedown);
                                    document.removeEventListener('keyup', handleDocumentKeyup);

                                    document.removeEventListener('touchstart', handleDocumentTouchstart);
                                    document.removeEventListener('touchend', handleDocumentTouchend);
                                }
                            },
                            /* 33 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _typeof =
                                    typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
                                        ? function (obj) {
                                              return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
                                          }
                                        : function (obj) {
                                              return obj && typeof Symbol === 'function' && obj.constructor === Symbol
                                                  ? 'symbol'
                                                  : typeof obj === 'undefined'
                                                  ? 'undefined'
                                                  : _typeof2(obj);
                                          };
                                exports.setText = setText;
                                exports.enableText = enableText;
                                exports.disableText = disableText;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _utils = __webpack_require__(6);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var _enabled = false;
                                var input = void 0;
                                var pos = void 0;
                                var _textSize = void 0;
                                var _textColor = void 0;
                                var svg = void 0;
                                var rect = void 0;
                                /**
                                 * Handle document.mouseup event
                                 *
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */ function handleDocumentMouseup(e) {
                                    // betrifft textbox
                                    if (input || !(svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY))) {
                                        return;
                                    }
                                    let scrollTop = window.pageYOffset;
                                    input = document.createElement('input');
                                    input.setAttribute('id', 'pdf-annotate-text-input');
                                    input.setAttribute('placeholder', M.util.get_string('enterText', 'pdfannotator'));
                                    input.style.border = '3px solid ' + _utils.BORDER_COLOR;
                                    input.style.borderRadius = '3px';
                                    input.style.position = 'absolute';
                                    input.style.top = e.clientY + scrollTop + 'px';
                                    input.style.left = e.clientX + 'px';
                                    input.style.fontSize = _textSize + 'px';
                                    input.addEventListener('blur', handleInputBlur);
                                    input.addEventListener('keyup', handleInputKeyup);
                                    document.body.appendChild(input);
                                    input.focus();
                                    rect = svg.getBoundingClientRect();
                                    pos = { x: e.clientX, y: e.clientY };
                                }
                                /**
                                 * Handle input.blur event
                                 */ function handleInputBlur() {
                                    saveText();
                                }
                                /**
                                 * Handle input.keyup event
                                 *
                                 * @param {Event} e The DOM event to handle
                                 */ function handleInputKeyup(e) {
                                    if (e.keyCode === 27) {
                                        closeInput();
                                    } else if (e.keyCode === 13) {
                                        saveText();
                                    }
                                }
                                /**
                                 * Save a text annotation from input
                                 */ function saveText() {
                                    if (input.value.trim().length > 0) {
                                        var _ret = (function () {
                                            var clientX = parseInt(pos.x, 10);
                                            //text size additional to y to render the text right under the mouse click
                                            var clientY = parseInt(pos.y, 10);
                                            //var svg=(0,_utils.findSVGAtPoint)(clientX,clientY);
                                            if (!svg) {
                                                return { v: void 0 };
                                            }
                                            var _getMetadata = (0, _utils.getMetadata)(svg);
                                            var documentId = _getMetadata.documentId;
                                            var pageNumber = _getMetadata.pageNumber;

                                            var annotation = Object.assign(
                                                {
                                                    type: 'textbox',
                                                    size: _textSize,
                                                    color: _textColor,
                                                    content: input.value.trim(),
                                                },
                                                (0, _utils.scaleDown)(svg, {
                                                    x: (0, _utils.roundDigits)(clientX - rect.left, 4),
                                                    y: (0, _utils.roundDigits)(clientY - rect.top, 4),
                                                    width: (0, _utils.roundDigits)(input.offsetWidth, 4),
                                                    height: (0, _utils.roundDigits)(input.offsetHeight, 4),
                                                })
                                            );
                                            _PDFJSAnnotate2.default
                                                .getStoreAdapter()
                                                .addAnnotation(documentId, pageNumber, annotation)
                                                .then(
                                                    function (annotation) {
                                                        //annotation.y = annotation.y +parseInt(annotation.size,10);
                                                        (0, _appendChild2.default)(svg, annotation);
                                                        document.querySelector('button.cursor').click();
                                                    },
                                                    function (err) {
                                                        notification.addNotification({
                                                            message: M.util.get_string(
                                                                'error:addAnnotation',
                                                                'pdfannotator'
                                                            ),
                                                            type: 'error',
                                                        });
                                                    }
                                                );
                                        })();
                                        if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object')
                                            return _ret.v;
                                    }
                                    closeInput();
                                }
                                /**
                                 * Close the input
                                 */ function closeInput() {
                                    try {
                                        if (input) {
                                            input.removeEventListener('blur', handleInputBlur);
                                            input.removeEventListener('keyup', handleInputKeyup);
                                            document.body.removeChild(input);
                                            input = null;
                                            pos = null;
                                        }
                                    } catch {}
                                }
                                /**
                                 * Set the text attributes
                                 *
                                 * @param {Number} textSize The size of the text
                                 * @param {String} textColor The color of the text
                                 */ function setText() {
                                    var textSize =
                                        arguments.length <= 0 || arguments[0] === undefined ? 12 : arguments[0];
                                    var textColor =
                                        arguments.length <= 1 || arguments[1] === undefined ? '000000' : arguments[1];
                                    _textSize = parseInt(textSize, 10);
                                    _textColor = textColor;
                                }
                                /**
                                 * Enable text behavior
                                 */ function enableText() {
                                    if (_enabled) {
                                        return;
                                    }
                                    _enabled = true;
                                    document.getElementById('content-wrapper').classList.add('cursor-text');
                                    document.addEventListener('mouseup', handleDocumentMouseup);
                                }
                                /**
                                 * Disable text behavior
                                 */ function disableText() {
                                    if (!_enabled) {
                                        return;
                                    }
                                    _enabled = false;
                                    document.getElementById('content-wrapper').classList.remove('cursor-text');
                                    document.removeEventListener('mouseup', handleDocumentMouseup);
                                }
                            },
                            /* 34 */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                var _slicedToArray = (function () {
                                    function sliceIterator(arr, i) {
                                        var _arr = [];
                                        var _n = true;
                                        var _d = false;
                                        var _e = undefined;
                                        try {
                                            for (
                                                var _i = arr[Symbol.iterator](), _s;
                                                !(_n = (_s = _i.next()).done);
                                                _n = true
                                            ) {
                                                _arr.push(_s.value);
                                                if (i && _arr.length === i) break;
                                            }
                                        } catch (err) {
                                            _d = true;
                                            _e = err;
                                        } finally {
                                            try {
                                                if (!_n && _i['return']) _i['return']();
                                            } finally {
                                                if (_d) throw _e;
                                            }
                                        }
                                        return _arr;
                                    }
                                    return function (arr, i) {
                                        if (Array.isArray(arr)) {
                                            return arr;
                                        } else if (Symbol.iterator in Object(arr)) {
                                            return sliceIterator(arr, i);
                                        } else {
                                            throw new TypeError('Invalid attempt to destructure non-iterable instance');
                                        }
                                    };
                                })();

                                exports.createPage = createPage;
                                exports.renderPage = renderPage;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _renderScreenReaderHints = __webpack_require__(20);
                                var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                var _utils = __webpack_require__(6);
                                var _renderQuestions = __webpack_require__(38);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var SIZE = 20;
                                // Template for creating a new page
                                //helper Layer as a Child of Textlayer added, because in firefox the handleDocumentClick only fires, if the click is outside of Textlayer or is on a child of Textlayer
                                var PAGE_TEMPLATE =
                                    '\n  <div style="visibility: hidden;" class="page" data-loaded="false">\n    <div class="canvasWrapper">\n      <canvas></canvas>\n    </div>\n    <svg class="annotationLayer"></svg>\n    <div class="textLayer"><div class="helperLayer"></div></div>\n  </div>\n';
                                /**
                                 * Create a new page to be appended to the DOM.
                                 *
                                 * @param {Number} pageNumber The page number that is being created
                                 * @return {HTMLElement}
                                 */ function createPage(pageNumber) {
                                    var temp = document.createElement('div');
                                    temp.innerHTML = PAGE_TEMPLATE;
                                    var page = temp.children[0];
                                    var canvas = page.querySelector('canvas');
                                    page.setAttribute('id', 'pageContainer' + pageNumber);
                                    page.setAttribute('data-page-number', pageNumber);
                                    canvas.mozOpaque = true;
                                    canvas.setAttribute('id', 'page' + pageNumber);
                                    return page;
                                }

                                let listOfPagesLoaded = [];
                                /**
                                 * Render a page that has already been created.
                                 *
                                 * @param {Number} pageNumber The page number to be rendered
                                 * @param {Object} renderOptions The options for rendering
                                 * @return {Promise} Settled once rendering has completed
                                 *  A settled Promise will be either:
                                 *    - fulfilled: [pdfPage, annotations]
                                 *    - rejected: Error
                                 */ function renderPage(pageNumber, renderOptions, reset = false) {
                                    if (reset) {
                                        listOfPagesLoaded = [];
                                        currentAnnotations = [];
                                    }
                                    if (listOfPagesLoaded.indexOf(pageNumber) !== -1) {
                                        return;
                                    }
                                    listOfPagesLoaded.push(pageNumber);

                                    var documentId = renderOptions.documentId;
                                    var pdfDocument = renderOptions.pdfDocument;
                                    var scale = renderOptions.scale;
                                    var _rotate = renderOptions.rotate; // Load the page and annotations
                                    return Promise.all([
                                        pdfDocument.getPage(pageNumber),
                                        _PDFJSAnnotate2.default.getAnnotations(documentId, pageNumber),
                                    ]).then(
                                        function (_ref) {
                                            var _ref2 = _slicedToArray(_ref, 2);
                                            var pdfPage = _ref2[0];
                                            var annotations = _ref2[1];
                                            currentAnnotations[pageNumber] = annotations.annotations;

                                            var page = document.getElementById('pageContainer' + pageNumber);
                                            var svg = page.querySelector('.annotationLayer');
                                            var canvas = page.querySelector('.canvasWrapper canvas');
                                            var canvasContext = canvas.getContext('2d', { alpha: false });
                                            var viewport = pdfPage.getViewport({
                                                scale: scale,
                                                rotation: _rotate,
                                            });
                                            var viewportWithoutRotate = pdfPage.getViewport({
                                                scale: scale,
                                                rotation: 0,
                                            });
                                            var transform = scalePage(pageNumber, viewport, canvasContext); // Render the page
                                            return Promise.all([
                                                pdfPage.render({
                                                    canvasContext: canvasContext,
                                                    viewport: viewport,
                                                    transform: transform,
                                                }),
                                                _PDFJSAnnotate2.default.render(svg, viewportWithoutRotate, annotations),
                                            ])
                                                .then(function () {
                                                    // Text content is needed for a11y, but is also necessary for creating
                                                    // highlight and strikeout annotations which require selecting text.
                                                    return pdfPage
                                                        .getTextContent({ normalizeWhitespace: true })
                                                        .then(function (textContent) {
                                                            return new Promise(function (resolve, reject) {
                                                                require([
                                                                    'mod_pdfannotator/pdf_viewer',
                                                                ], function (pdfjsViewer) {
                                                                    // Render text layer for a11y of text content
                                                                    var textLayer = page.querySelector('.textLayer');
                                                                    var textLayerFactory =
                                                                        new pdfjsViewer.DefaultTextLayerFactory();
                                                                    var eventBus = new pdfjsViewer.EventBus();
                                                                    // (Optionally) enable hyperlinks within PDF files.
                                                                    var pdfLinkService = new pdfjsViewer.PDFLinkService(
                                                                        {
                                                                            eventBus,
                                                                        }
                                                                    );
                                                                    // (Optionally) enable find controller.
                                                                    var pdfFindController =
                                                                        new pdfjsViewer.PDFFindController({
                                                                            linkService: pdfLinkService,
                                                                            eventBus,
                                                                        });
                                                                    var pageIdx = pageNumber - 1;
                                                                    var highlighter = new pdfjsViewer.TextHighlighter({
                                                                        pdfFindController,
                                                                        eventBus,
                                                                        pageIdx,
                                                                    });
                                                                    var textLayerBuilder =
                                                                        textLayerFactory.createTextLayerBuilder(
                                                                            textLayer,
                                                                            pageIdx,
                                                                            viewport,
                                                                            true,
                                                                            eventBus,
                                                                            highlighter
                                                                        );
                                                                    pdfLinkService.setViewer(textLayerBuilder);
                                                                    textLayerBuilder.setTextContent(textContent);
                                                                    textLayerBuilder.render(); // Enable a11y for annotations

                                                                    // Timeout is needed to wait for `textLayerBuilder.render`
                                                                    //setTimeout(function(){try{(0,_renderScreenReaderHints2.default)(annotations.annotations);resolve();}catch(e){reject(e);}});
                                                                    //ur weil setTimeout auskommentiert ist!!!!!
                                                                    resolve();
                                                                });
                                                            });
                                                        });
                                                })
                                                .then(function () {
                                                    // Indicate that the page was loaded
                                                    page.setAttribute('data-loaded', 'true');

                                                    return [pdfPage, annotations];
                                                });
                                        },
                                        function (err) {
                                            notification.addNotification({
                                                message: M.util.get_string('error:renderPage', 'pdfannotator'),
                                                type: 'error',
                                            });
                                        }
                                    );
                                }
                                /**
                                 * Scale the elements of a page.
                                 *
                                 * @param {Number} pageNumber The page number to be scaled
                                 * @param {Object} viewport The viewport of the PDF page (see pdfPage.getViewport(scale, rotation))
                                 * @param {Object} context The canvas context that the PDF page is rendered to
                                 * @return {Array} The transform data for rendering the PDF page
                                 */ function scalePage(pageNumber, viewport, context) {
                                    var page = document.getElementById('pageContainer' + pageNumber);
                                    var canvas = page.querySelector('.canvasWrapper canvas');
                                    var svg = page.querySelector('.annotationLayer');
                                    var wrapper = page.querySelector('.canvasWrapper');
                                    var textLayer = page.querySelector('.textLayer');
                                    var outputScale = getOutputScale(context);
                                    var transform = !outputScale.scaled
                                        ? null
                                        : [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
                                    var sfx = approximateFraction(outputScale.sx);
                                    var sfy = approximateFraction(outputScale.sy); // Adjust width/height for scale
                                    page.style.visibility = '';
                                    canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]);
                                    canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]);
                                    canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px';
                                    canvas.style.height = roundToDivide(viewport.height, sfx[1]) + 'px';
                                    svg.setAttribute('width', viewport.width);
                                    svg.setAttribute('height', viewport.height);
                                    svg.style.width = viewport.width + 'px';
                                    svg.style.height = viewport.height + 'px';
                                    page.style.width = viewport.width + 'px';
                                    page.style.height = viewport.height + 'px';
                                    wrapper.style.width = viewport.width + 'px';
                                    wrapper.style.height = viewport.height + 'px';
                                    textLayer.style.width = viewport.width + 'px';
                                    textLayer.style.height = viewport.height + 'px';
                                    return transform;
                                }
                                /**
                                 * Approximates a float number as a fraction using Farey sequence (max order of 8).
                                 *
                                 * @param {Number} x Positive float number
                                 * @return {Array} Estimated fraction: the first array item is a numerator,
                                 *                 the second one is a denominator.
                                 */ function approximateFraction(x) {
                                    // Fast path for int numbers or their inversions.
                                    if (Math.floor(x) === x) {
                                        return [x, 1];
                                    }
                                    var xinv = 1 / x;
                                    var limit = 8;
                                    if (xinv > limit) {
                                        return [1, limit];
                                    } else if (Math.floor(xinv) === xinv) {
                                        return [1, xinv];
                                    }
                                    var x_ = x > 1 ? xinv : x; // a/b and c/d are neighbours in Farey sequence.
                                    var a = 0,
                                        b = 1,
                                        c = 1,
                                        d = 1; // Limit search to order 8.
                                    while (true) {
                                        // Generating next term in sequence (order of q).
                                        var p = a + c,
                                            q = b + d;
                                        if (q > limit) {
                                            break;
                                        }
                                        if (x_ <= p / q) {
                                            c = p;
                                            d = q;
                                        } else {
                                            a = p;
                                            b = q;
                                        }
                                    } // Select closest of neighbours to x.
                                    if (x_ - a / b < c / d - x_) {
                                        return x_ === x ? [a, b] : [b, a];
                                    } else {
                                        return x_ === x ? [c, d] : [d, c];
                                    }
                                }
                                function getOutputScale(ctx) {
                                    var devicePixelRatio = window.devicePixelRatio || 1;
                                    var backingStoreRatio =
                                        ctx.webkitBackingStorePixelRatio ||
                                        ctx.mozBackingStorePixelRatio ||
                                        ctx.msBackingStorePixelRatio ||
                                        ctx.oBackingStorePixelRatio ||
                                        ctx.backingStorePixelRatio ||
                                        1;
                                    var pixelRatio = devicePixelRatio / backingStoreRatio;
                                    return { sx: pixelRatio, sy: pixelRatio, scaled: pixelRatio !== 1 };
                                }
                                function roundToDivide(x, div) {
                                    var r = x % div;
                                    return r === 0 ? x : Math.round(x - r + div);
                                }
                            },
                            /* 35 */ /* own module to handle the comment wrapper */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.deleteUndefinedRect = deleteUndefinedRect;
                                exports.openComment = openComment;
                                exports.closeComment = closeComment;
                                exports.showCommentsAfterCreation = showCommentsAfterCreation;
                                exports.openCommentTouchscreen = openCommentTouchscreen;
                                exports.loadEditor = loadEditor;
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _event = __webpack_require__(4);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _setAttributes = __webpack_require__(14);
                                var _setAttributes2 = _interopRequireDefault(_setAttributes);
                                var _utils = __webpack_require__(6);
                                var _ajaxloader = __webpack_require__(36);
                                var _questionRenderer = __webpack_require__(38);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }

                                var _e = null;
                                var textarea = void 0;
                                var submitbutton = void 0;
                                var resetbutton = void 0;
                                var form = void 0;
                                var data = void 0;
                                var rectsSelection = void 0;

                                function deleteUndefinedRect() {
                                    let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
                                    n.parentNode.removeChild(n);
                                }

                                function showCommentsAfterCreation(annoid) {
                                    //Remove Loader from Comment-Container
                                    (0, _ajaxloader.hideLoader)();

                                    //Show Comments
                                    let target = $('[data-pdf-annotate-id=' + annoid + ']')[0];
                                    //fire annotation:click event with the annotation as target
                                    _event.fireEvent('annotation:click', target);
                                }

                                /**
                                 * This function closes the comment wrapper
                                 * @param {type} documentId The id of the document (for render the questions afterwards)
                                 * @param {type} pageNumber The page number (for render the questions afterwards)
                                 * @param {type} handleSubmitClick Handler to remove
                                 * @param {type} handleCancelClick Handler to remove
                                 * @param {type} toolbarClick Handler to remove
                                 * @param {boolean} loading True, if the loader should be displayed
                                 * @returns {void}
                                 */
                                function closeComment(
                                    documentId,
                                    pageNumber,
                                    handleSubmitClick,
                                    handleCancelClick,
                                    toolbarClick,
                                    loading
                                ) {
                                    document.querySelector('.comment-list-form').setAttribute('style', 'display:none');
                                    document
                                        .querySelector('.comment-list-form')
                                        .removeEventListener('onsubmit', handleSubmitClick);
                                    document
                                        .getElementById('commentCancel')
                                        .removeEventListener('click', handleCancelClick);
                                    document.querySelector('.toolbar').removeEventListener('click', toolbarClick);
                                    document.getElementById('commentSubmit').value = M.util.get_string(
                                        'answerButton',
                                        'pdfannotator'
                                    );
                                    document.getElementById('id_pdfannotator_content').value = '';
                                    document.getElementById('id_pdfannotator_content').placeholder = M.util.get_string(
                                        'addAComment',
                                        'pdfannotator'
                                    );
                                    // Reset the typed text for other editors.
                                    var editorArea = document.querySelector('#id_pdfannotator_contenteditable'); // Atto editor.
                                    if (!editorArea) {
                                        // TinyMCE editor.
                                        var iframe = document.getElementById('myarea_ifr');
                                        if (iframe) {
                                            editorArea = iframe.contentWindow.document.getElementById('tinymce');
                                        }
                                    }
                                    if (editorArea) {
                                        editorArea.innerHTML = '';
                                    }
                                    data = null;
                                    textarea = null;
                                    submitbutton = null;
                                    if (loading) {
                                        (0, _ajaxloader.showLoader)();
                                    } else {
                                        _questionRenderer.renderQuestions(documentId, pageNumber);
                                    }
                                }

                                /**
                                 * Opens the commen wrapper
                                 * @param {event} e the click Event of the annotation
                                 * @param {type} cancelClick EventListener to add
                                 * @param {type} submitClick EventListener to add
                                 * @param {type} toolbarClick EventListener to add
                                 * @param {type} submitBlur EventListener to add
                                 * @param {type} _type which type of annotation
                                 * @returns {Array} [0] textarea [1] data (position of the annotation)
                                 */
                                function openComment(e, cancelClick, submitClick, toolbarClick, submitBlur, _type) {
                                    //save e for later
                                    _e = e;

                                    var button1 = document.getElementById('allQuestions'); // to be found in index template
                                    button1.style.display = 'inline';
                                    var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
                                    button2.style.display = 'inline';

                                    //title
                                    $('#comment-wrapper h4')[0].innerHTML = M.util.get_string(
                                        'comments',
                                        'pdfannotator'
                                    );
                                    //add Eventlistener to Toolbar. Every Click in Toolbar should cancel the Annotation-Comment-Creation
                                    document.querySelector('.toolbar').addEventListener('click', toolbarClick);
                                    //Hide shown comments
                                    document.querySelector('.comment-list-container').innerHTML = '<p></p>';
                                    form = document.querySelector('.comment-list-form');
                                    $(document).ready(function () {
                                        form.setAttribute('style', 'display:inherit');
                                        $('#anonymousDiv').show();
                                        $('#privateDiv').show();
                                        $('#protectedDiv').show();
                                    });
                                    textarea = document.getElementById('id_pdfannotator_content');
                                    textarea.placeholder = M.util.get_string('startDiscussion', 'pdfannotator');
                                    submitbutton = document.getElementById('commentSubmit');
                                    submitbutton.value = M.util.get_string('createAnnotation', 'pdfannotator');
                                    resetbutton = document.getElementById('commentCancel');
                                    resetbutton.addEventListener('click', cancelClick);
                                    form.onsubmit = submitClick;
                                    //fixCommentForm();
                                    if (_type === 'pin') {
                                        data = new Object();
                                        data.x = e.clientX;
                                        data.y = e.clientY;
                                    } else {
                                        data = document.createElement('div');
                                        data.setAttribute('id', 'pdf-annotate-point-input');
                                        data.style.border = '3px solid ' + _utils.BORDER_COLOR;
                                        data.style.borderRadius = '3px';
                                        data.style.display = 'none';
                                        data.style.position = 'absolute';
                                        data.style.top = e.clientY + 'px';
                                        data.style.left = e.clientX + 'px';
                                    }

                                    form.addEventListener('blur', submitBlur);
                                    textarea.focus();
                                    return [textarea, data];
                                }

                                function openCommentTouchscreen(
                                    e,
                                    cancelClick,
                                    submitClick,
                                    toolbarClick,
                                    submitBlur,
                                    _type
                                ) {
                                    //save e for later
                                    _e = e;

                                    var button1 = document.getElementById('allQuestions'); // to be found in index template
                                    button1.style.display = 'inline';
                                    var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
                                    button2.style.display = 'inline';

                                    //title
                                    $('#comment-wrapper h4')[0].innerHTML = M.util.get_string(
                                        'comments',
                                        'pdfannotator'
                                    );
                                    //add Eventlistener to Toolbar. Every Click in Toolbar should cancel the Annotation-Comment-Creation
                                    document.querySelector('.toolbar').addEventListener('click', toolbarClick);
                                    //Hide shown comments
                                    document.querySelector('.comment-list-container').innerHTML = '<p></p>';
                                    form = document.querySelector('.comment-list-form');
                                    form.setAttribute('style', 'display:inherit');
                                    $('#anonymousCheckbox').show();
                                    $('#privateCheckbox').show();
                                    $('#protectedCheckbox').show();
                                    textarea = document.getElementById('id_pdfannotator_content');
                                    textarea.placeholder = M.util.get_string('startDiscussion', 'pdfannotator');
                                    submitbutton = document.getElementById('commentSubmit');
                                    submitbutton.value = M.util.get_string('createAnnotation', 'pdfannotator');
                                    resetbutton = document.getElementById('commentCancel');
                                    resetbutton.addEventListener('click', cancelClick);
                                    form.onsubmit = submitClick;
                                    //fixCommentForm();
                                    if (_type === 'pin') {
                                        data = new Object();
                                        data.x = e.changedTouches[0].clientX;
                                        data.y = e.changedTouches[0].clientY;
                                    } else {
                                        data = document.createElement('div');
                                        data.setAttribute('id', 'pdf-annotate-point-input');
                                        data.style.border = '3px solid ' + _utils.BORDER_COLOR;
                                        data.style.borderRadius = '3px';
                                        data.style.display = 'none';
                                        data.style.position = 'absolute';
                                        data.style.top = e.clientY + 'px';
                                        data.style.left = e.clientX + 'px';
                                    }

                                    form.addEventListener('blur', submitBlur);
                                    textarea.focus();
                                    return [textarea, data];
                                }

                                /**
                                 *
                                 * @param {type} action can be add for adding comments. Or edit for editing comments.
                                 * @param {int} uuid
                                 * @param {Function} fn a callback funtion. It will be called after the Promises in this funktion finish.
                                 *
                                 *
                                 */
                                function loadEditor(action = 'add', uuid = 0, fn = null, fnParams = null) {
                                    // search the placeholder for editor.
                                    let addCommentEditor = document.querySelectorAll('#add_comment_editor_wrapper');
                                    let editCommentEditor = document.querySelectorAll(
                                        `#edit_comment_editor_wrapper_${uuid}`
                                    );

                                    if (action === 'add') {
                                        _ajaxloader.showLoader(`.editor-loader-placeholder-${action}`);

                                        // remove old editor and old input values of draftitemid and editorformat, if exists.
                                        if (addCommentEditor.length > 0) {
                                            addCommentEditor[0].remove();
                                        }

                                        let data = {};
                                        templates
                                            .render('mod_pdfannotator/add_comment_editor_placeholder', data)
                                            .then(function (html, js) {
                                                let commentListForm = document.getElementById('comment-list-form');
                                                templates.prependNodeContents(commentListForm, html, js);
                                                if (_editorSettings.active_editor === 'textarea_texteditor') {
                                                    document
                                                        .getElementById('id_pdfannotator_content')
                                                        .setAttribute('style', 'display:unset !important');
                                                }
                                            })
                                            .then(function () {
                                                let args = { action: action, cmid: _cm.id };
                                                Fragment.loadFragment(
                                                    'mod_pdfannotator',
                                                    'open_add_comment_editor',
                                                    _contextId,
                                                    args
                                                )
                                                    .done(function (html, js) {
                                                        if (!html) {
                                                            throw new TypeError('Invalid HMTL Input');
                                                        }
                                                        templates.replaceNode(
                                                            document.getElementById('editor-commentlist-inputs'),
                                                            html,
                                                            js
                                                        );
                                                        if (fn instanceof Function) {
                                                            (0, fn)(fnParams);
                                                        }
                                                        _ajaxloader.hideLoader(`.editor-loader-placeholder-${action}`);
                                                        return true;
                                                    })
                                                    .then(function () {
                                                        let commentText = document.getElementById(
                                                            'id_pdfannotator_contenteditable'
                                                        );
                                                        if (commentText) {
                                                            commentText.focus();
                                                        }
                                                    });
                                            })
                                            .catch(notification.exception);
                                    } else if (action === 'edit') {
                                        _ajaxloader.showLoader(`.editor-loader-placeholder-${action}-${uuid}`);

                                        // remove old editor and old input values of draftitemid and editorformat, if exists.
                                        if (editCommentEditor.length > 0) {
                                            editCommentEditor[0].remove();
                                        }

                                        let data = { uuid: uuid };
                                        templates
                                            .render('mod_pdfannotator/edit_comment_editor_placeholder', data)
                                            .then(function (html, js) {
                                                let editForm = document.getElementById(`edit${uuid}`);
                                                templates.prependNodeContents(editForm, html, js);
                                                return true;
                                            })
                                            .then(function () {
                                                let args = { action: action, cmid: _cm.id, uuid: uuid };
                                                Fragment.loadFragment(
                                                    'mod_pdfannotator',
                                                    'open_edit_comment_editor',
                                                    _contextId,
                                                    args
                                                )
                                                    .then(function (html, js) {
                                                        if (!html) {
                                                            throw new TypeError('Invalid HMTL Input');
                                                        }
                                                        //templates.runTemplateJS(js);
                                                        let editCommentEditorElement = document.getElementById(
                                                            `edit_comment_editor_wrapper_${uuid}`
                                                        );
                                                        html = html.split('displaycontent:');
                                                        let isreplaced = templates.appendNodeContents(
                                                            editCommentEditorElement,
                                                            html[0],
                                                            js
                                                        );
                                                        let editTextarea = document.getElementById(`editarea${uuid}`);
                                                        editTextarea.innerText = html[1];

                                                        _ajaxloader.hideLoader(
                                                            `.editor-loader-placeholder-${action}-${uuid}`
                                                        );

                                                        let editForm = document.getElementById(`edit${uuid}`);
                                                        let chatMessage = document.getElementById(`chatmessage${uuid}`);
                                                        let editAreaEditable = document.getElementById(
                                                            `editarea${uuid}editable`
                                                        );
                                                        if (editAreaEditable) {
                                                            // Does not exist for tinymce editor.
                                                            editAreaEditable.innerHTML = editTextarea.value;
                                                        }
                                                        if (editForm.style.display === 'none') {
                                                            editForm.style.cssText += ';display:block;';
                                                            chatMessage.innerHTML = '';
                                                        }
                                                        return true;
                                                    })
                                                    .then(function () {
                                                        let commentText = document.getElementById(`editarea${uuid}`);
                                                        if (commentText) {
                                                            commentText.focus();
                                                        }
                                                        if (fn instanceof Function) {
                                                            (0, fn)(fnParams);
                                                        }
                                                    });
                                            })
                                            .catch(notification.exception);
                                    } else {
                                        // nothing to do.
                                    }
                                }
                            },
                            /* 36 */ /*OWN Module! To show and hide ajaxloader */
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.showLoader = showLoader;
                                exports.hideLoader = hideLoader;

                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }

                                /**
                                 * hides the loading animation
                                 * @returns {undefined}
                                 */
                                function hideLoader(selector = '.comment-list-container') {
                                    let loader = document.querySelector('#ajaxLoaderCreation');
                                    if (loader !== null) {
                                        let commentContainer = document.querySelectorAll(`${selector}`)[0];
                                        commentContainer.removeChild(loader);
                                    }
                                }

                                /**
                                 * Shows an loading animation in the comment wrapper
                                 * @returns {undefined}
                                 */
                                function showLoader(selector = '.comment-list-container') {
                                    let commentContainer = document.querySelector(`${selector}`);
                                    commentContainer.innerHTML = '';
                                    let img = document.createElement('img');
                                    img.id = 'ajaxLoaderCreation';
                                    img.src = M.util.image_url('i/loading');
                                    img.alt = M.util.get_string('loading', 'pdfannotator');
                                    img.classList.add('icon');
                                    img.style = 'display: block; margin-left: auto;margin-right: auto;';
                                    commentContainer.appendChild(img);
                                }
                            },
                            /* 37 */ /*OWN Module! To pick an annotation*/
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.pickAnnotation = pickAnnotation;
                                var _event = __webpack_require__(4);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }

                                /**
                                 * This function scrolls to the specific annotation and selects the annotation
                                 * @param {type} page of the annotation
                                 * @param {type} annoid the id of the picked annotation
                                 * @param {type} commid id of the comment, if a comment should be marked, else null
                                 * @return {void}
                                 */
                                function pickAnnotation(page, annoid, commid) {
                                    //[0] for only first element (it only can be one element)
                                    var target = $('[data-pdf-annotate-id=' + annoid + ']')[0];
                                    if (commid !== null) {
                                        target.markCommentid = commid;
                                    }
                                    _event.fireEvent('annotation:click', target);

                                    //Scroll to defined page (because of the picked annotation (new annotation, new answer or report) from overview)
                                    var targetDiv = $('[data-target-id=' + annoid + ']')[0];
                                    var pageOffset = document.getElementById('pageContainer' + page).offsetTop;

                                    var contentWrapper = $('#content-wrapper');
                                    contentWrapper.scrollTop(pageOffset + targetDiv.offsetTop - 100);
                                    contentWrapper.scrollLeft(targetDiv.offsetLeft - contentWrapper.width() + 100);
                                }
                            },
                            /* 38 */ /*OWN Module! To show questions of one PDF-Page on the right side*/
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.renderQuestions = renderQuestions;
                                exports.renderAllQuestions = renderAllQuestions;
                                var _event = __webpack_require__(4);
                                var _shortText = __webpack_require__(39);
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);

                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }

                                /**
                                 * This function renders on the right side the questions of all annotations of a specific page.
                                 *
                                 * @param {type} documentId the Id of the pdf
                                 * @param {type} pageNumber the requested pagenumber
                                 * @param {type} activeCall specifies that the function was called by click on button with id='questionsOnThisPage'
                                 * @return {undefined}
                                 */
                                function renderQuestions(documentId, pageNumber, activeCall = null) {
                                    let pattern = $('#searchPattern').val();
                                    _PDFJSAnnotate2.default
                                        .getStoreAdapter()
                                        .getQuestions(documentId, pageNumber, pattern)
                                        .then(
                                            function (questions) {
                                                const showAllQuestions =  document.querySelector('#showAllComments').getAttribute('data-active');
                                                if(showAllQuestions === 'false'){
                                                    let visibility;
                                                    const showPrivate = document.querySelector('#showPrivateComments').getAttribute('data-active');
                                                    
                                                    if(showPrivate === 'true') {
                                                        visibility = ['private', 'protected'];
                                                    } else {
                                                        visibility = ['anonymous', 'public'];
                                                    }
                                                    questions = questions.filter(e => visibility.includes(e.visibility));
                                                }

                                                let container = document.querySelector('.comment-list-container');
                                                let title = $('#comment-wrapper > h4')[0];
                                                if (pattern === '') {
                                                    title.innerHTML =
                                                        M.util.get_string('questionstitle', 'pdfannotator') +
                                                        ' ' +
                                                        pageNumber;
                                                } else {
                                                    title.innerHTML = M.util.get_string(
                                                        'searchresults',
                                                        'pdfannotator'
                                                    );
                                                }
                                                var button1 = document.getElementById('allQuestions'); // to be found in index template
                                                button1.style.display = 'inline';
                                                var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
                                                button2.style.display = 'none';
                                                let visibilityButtons = document.querySelector('.comment-visibility');
                                                visibilityButtons.style.display = 'inline';

                                                //only if form is not shown, otherwise the questions should not be rendered
                                                if (
                                                    document.querySelector('.comment-list-form').style.display ===
                                                        'none' ||
                                                    activeCall
                                                ) {
                                                    if (activeCall) {
                                                        document.querySelector('.comment-list-form').style.display =
                                                            'none';
                                                    }
                                                    container.innerHTML = '';

                                                    if (questions.length < 1) {
                                                        if (pattern === '') {
                                                            container.innerHTML = M.util.get_string(
                                                                'noquestions',
                                                                'pdfannotator'
                                                            );
                                                        } else {
                                                            container.innerHTML = M.util.get_string(
                                                                'nosearchresults',
                                                                'pdfannotator'
                                                            );
                                                        }
                                                    } else {
                                                        for (let id in questions) {
                                                            let question = questions[id];
                                                            let questionWrapper = document.createElement('div');
                                                            questionWrapper.className =
                                                                'chat-message comment-list-item questions';
                                                            // Add different background colors (orange/blue) and icons to distinguish private from public
                                                            let questionVisibility = document.createElement('img');
                                                            if (question.visibility === 'private' || question.visibility === 'protected') {
                                                                questionWrapper.className =
                                                                'chat-message comment-list-item questions questions-private';                                                              
                                                                questionVisibility.src = M.util.image_url('comments_private_indicator','pdfannotator');
                                                                questionVisibility.alt = M.util.get_string('comments_icon_private','pdfannotator');
                                                                questionVisibility.title = M.util.get_string('comments_icon_private','pdfannotator');
                                                                questionVisibility.className = 'question-private-icon';
                                                            } else if (question.visibility === 'anonymous' || question.visibility === 'public'){
                                                                questionVisibility.src = M.util.image_url('comments_public_indicator','pdfannotator');
                                                                questionVisibility.alt = M.util.get_string('comments_icon_public','pdfannotator'); 
                                                                questionVisibility.title = M.util.get_string('comments_icon_public','pdfannotator');
                                                                questionVisibility.className = 'question-public-icon';
                                                            }

                                                            let questionText = document.createElement('span');
                                                            questionText.className = 'more';
                                                            questionText.innerHTML = question.content;
                                                            let questionAnswercount = document.createElement('span');
                                                            questionAnswercount.innerHTML = question.answercount;
                                                            questionAnswercount.className = 'questionanswercount';

                                                            let questionPix = document.createElement('i');
                                                            questionPix.classList =
                                                                'icon fa fa-comment fa-fw questionanswercount';
                                                            questionPix.title = M.util.get_string(
                                                                'answers',
                                                                'pdfannotator'
                                                            );

                                                            let iconWrapper = document.createElement('div');
                                                            iconWrapper.className = 'icon-wrapper';

                                                            if (question.solved != 0) {
                                                                let solvedPix = document.createElement('i');
                                                                solvedPix.classList =
                                                                    'icon fa fa-lock fa-fw solvedicon';
                                                                solvedPix.title = M.util.get_string(
                                                                    'questionSolved',
                                                                    'pdfannotator'
                                                                );
                                                                iconWrapper.appendChild(solvedPix);
                                                            }

                                                            iconWrapper.appendChild(questionPix);
                                                            iconWrapper.appendChild(questionAnswercount);

                                                            questionWrapper.style.position = 'relative';
                                                            questionWrapper.appendChild(questionVisibility); 
                                                            questionWrapper.appendChild(questionText);
                                                            questionWrapper.appendChild(iconWrapper);

                                                            container.appendChild(questionWrapper);
                                                            (function (questionObj, questionDOM) {
                                                                questionDOM.onclick = function (e) {
                                                                    if (
                                                                        questionObj.page !== undefined &&
                                                                        questionObj.page !== $('#currentPage').val()
                                                                    ) {
                                                                        $('#content-wrapper').scrollTop(
                                                                            document.getElementById(
                                                                                'pageContainer' + questionObj.page
                                                                            ).offsetTop
                                                                        );
                                                                    }
                                                                    (function scrollToAnnotation(
                                                                        annotationid,
                                                                        pageNumber
                                                                    ) {
                                                                        let target = $(
                                                                            '[data-pdf-annotate-id=' +
                                                                                annotationid +
                                                                                ']'
                                                                        )[0];
                                                                        // if scrolled to a different page (see a few lines above) and page isn't loaded yet; wait and try again
                                                                        if (target === undefined) {
                                                                            setTimeout(function () {
                                                                                scrollToAnnotation(
                                                                                    annotationid,
                                                                                    pageNumber
                                                                                );
                                                                            }, 200);
                                                                        } else {
                                                                            _event.fireEvent(
                                                                                'annotation:click',
                                                                                target
                                                                            );
                                                                            var targetDiv = $(
                                                                                '[data-target-id=' + annotationid + ']'
                                                                            )[0];
                                                                            var contentWrapper = $('#content-wrapper');
                                                                            if (pageNumber === undefined) {
                                                                                pageNumber = $('#currentPage').val();
                                                                            }
                                                                            var pageOffset = document.getElementById(
                                                                                'pageContainer' + pageNumber
                                                                            ).offsetTop;
                                                                            contentWrapper.scrollTop(
                                                                                pageOffset + targetDiv.offsetTop - 100
                                                                            );
                                                                            contentWrapper.scrollLeft(
                                                                                targetDiv.offsetLeft -
                                                                                    contentWrapper.width() +
                                                                                    100
                                                                            );
                                                                        }
                                                                    })(questionObj.annotationid, questionObj.page);
                                                                };
                                                            })(question, questionWrapper);
                                                        }
                                                        // comment overview column
                                                        //_shortText.mathJaxAndShortenText('.more', 4);
                                                        _shortText.shortenTextDynamic(null, '.more', 4);
                                                    }
                                                }
                                            },
                                            function (err) {
                                                notification.addNotification({
                                                    message: M.util.get_string('error:getQuestions', 'pdfannotator'),
                                                    type: 'error',
                                                });
                                            }
                                        );
                                }

                                /**
                                 * Function renders overview column for all questions in this document
                                 *
                                 * @param {type} documentId
                                 * @return {undefined}
                                 */
                                function renderAllQuestions(documentId) {
                                    _PDFJSAnnotate2.default
                                        .getStoreAdapter()
                                        .getQuestions(documentId)
                                        .then(
                                            function (questions) {
                                                let container = document.querySelector('.comment-list-container');
                                                let title = $('#comment-wrapper > h4')[0];
                                                title.innerHTML =
                                                    M.util.get_string('allquestionstitle', 'pdfannotator') +
                                                    ' ' +
                                                    questions.pdfannotatorname;

                                                container.innerHTML = '';

                                                questions = questions.questions;

                                                var button1 = document.getElementById('allQuestions'); // to be found in index.mustache template
                                                button1.style.display = 'none';
                                                var button2 = document.getElementById('questionsOnThisPage'); // to be found in index.mustache template
                                                button2.style.display = 'inline';
                                                let visibilityButtons = document.querySelector('.comment-visibility');
                                                visibilityButtons.style.display = 'none';

                                                if (
                                                    document.querySelector('.comment-list-form').style.display !==
                                                    'none'
                                                ) {
                                                    document.querySelector('.comment-list-form').style.display = 'none';
                                                }

                                                if (questions.length < 1) {
                                                    container.innerHTML = M.util.get_string(
                                                        'noquestions_view',
                                                        'pdfannotator'
                                                    );
                                                } else {
                                                    for (var page in questions) {
                                                        let questionWrapper = document.createElement('div');
                                                        questionWrapper.className =
                                                            'chat-message comment-list-item questions page';
                                                        let questionText = document.createElement('span');
                                                        questionText.innerHTML =
                                                            M.util.get_string('page', 'pdfannotator') + ' ' + page;
                                                        let questionAnswercount = document.createElement('span');
                                                        questionAnswercount.innerHTML = questions[page].length;
                                                        questionAnswercount.className = 'questionanswercount';

                                                        let questionPix = document.createElement('i');
                                                        questionPix.classList =
                                                            'icon fa fa-comments fa-fw questionanswercount';
                                                        questionPix.title = M.util.get_string(
                                                            'questionsimgtitle',
                                                            'pdfannotator'
                                                        );
                                                        let iconWrapper = document.createElement('div');
                                                        iconWrapper.classList = 'icon-wrapper';
                                                        iconWrapper.appendChild(questionAnswercount);
                                                        iconWrapper.appendChild(questionPix);
                                                        questionWrapper.appendChild(questionText);
                                                        questionWrapper.appendChild(iconWrapper);
                                                        container.appendChild(questionWrapper);
                                                        (function (page, questionDOM) {
                                                            questionDOM.onclick = function (e) {
                                                                $('#content-wrapper').scrollTop(
                                                                    document.getElementById('pageContainer' + page)
                                                                        .offsetTop
                                                                );
                                                                var pageinputfield =
                                                                    document.getElementById('currentPage');
                                                                if (pageinputfield.value === page) {
                                                                    renderQuestions(documentId, page, 1);
                                                                }
                                                            };
                                                        })(page, questionWrapper);
                                                    }
                                                }
                                            },
                                            function (err) {
                                                notification.addNotification({
                                                    message: M.util.get_string('error:getAllQuestions', 'pdfannotator'),
                                                    type: 'error',
                                                });
                                            }
                                        );
                                }
                            },
                            /* 39 */ /*OWN Module! To shorten a specific text*/
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.shortenText = shortenText;
                                exports.shortenTextDynamic = shortenTextDynamic;
                                exports.mathJaxAndShortenText = mathJaxAndShortenText;

                                /**
                                 * Shorten display of any report or question to a maximum of 80 characters and display
                                 * a 'view more'/'view less' link
                                 *
                                 * Copyright 2013 Viral Patel and other contributors
                                 * http://viralpatel.net
                                 *
                                 * slightly modified by RWTH Aachen in 2018
                                 *
                                 * Permission is hereby granted, free of charge, to any person obtaining
                                 * a copy of this software and associated documentation files (the
                                 * "Software"), to deal in the Software without restriction, including
                                 * without limitation the rights to use, copy, modify, merge, publish,
                                 * distribute, sublicense, and/or sell copies of the Software, and to
                                 * permit persons to whom the Software is furnished to do so, subject to
                                 * the following conditions:
                                 *
                                 * The above copyright notice and this permission notice shall be
                                 * included in all copies or substantial portions of the Software.
                                 *
                                 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
                                 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
                                 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
                                 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
                                 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
                                 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
                                 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                                 *
                                 * @param {type} selector
                                 * @param {type} maxLength
                                 * @param {type} ellipsesText
                                 * @returns {undefined}
                                 */
                                function shortenText(selector, maxLength = 80, ellipsesText = '...') {
                                    var showChar = maxLength;
                                    var moretext = M.util.get_string('showmore', 'pdfannotator');
                                    var lesstext = M.util.get_string('showless', 'pdfannotator');
                                    $(selector).each(function () {
                                        if ($(this).children().first().attr('id') === 'content') {
                                            return;
                                        }
                                        var content = $(this).html();
                                        //determine if the message should be shortend, here only the characters without the html should be considered
                                        var contentWithoudTags = this.innerText;
                                        if (contentWithoudTags.length > showChar + ellipsesText.length) {
                                            //for the clip-function you should import textclipper.js
                                            var c = clip(unescape(content), showChar, {
                                                html: true,
                                                indicator: '',
                                            }); //clipped content, the indicator is nothing, because we add the ellipsesText manually in the html
                                            var h = content; // complete content
                                            var html =
                                                '<span id="content">' +
                                                c +
                                                '</span><span class="moreellipses">' +
                                                ellipsesText +
                                                '&nbsp;</span><span class="morecontent"><span class="completeContent">' +
                                                h +
                                                '</span><span class="clippedContent">' +
                                                c +
                                                '</span>&nbsp;&nbsp;<a href="" class="morelink">' +
                                                moretext +
                                                '</a></span>';
                                            $(this).html(html);
                                        }
                                    });

                                    $(selector + ' .morelink').click(function () {
                                        if ($(this).hasClass('less')) {
                                            $(this).removeClass('less');
                                            $(this).html(moretext); // entspricht innerHTML
                                            $(this).parent().prev().prev().html($(this).prev().html());
                                            //    $(selector+" #content").html($(selector+" .morecontent .clippedContent").html());
                                        } else {
                                            $(this).addClass('less');
                                            $(this).html(lesstext);
                                            $(this).parent().prev().prev().html($(this).prev().prev().html());
                                            //   $(selector+" #content").html($(selector+" .morecontent .completeContent").html());
                                        }
                                        $(this).parent().prev().toggle(); //span .moreellipses
                                        return false;
                                    });
                                }

                                /**
                                 * This function shortens the text. The length of the string is determined by the size of the parent and the given divisor.
                                 * @param {type} parentselector The selector of which the size should be referenced
                                 * @param {type} selector The selector where the text should be shortened
                                 * @param {type} divisor The textlength is the size / divisior
                                 * @param {type} ellipsesText text which should be displayed to point out that the text was shortened
                                 * @returns {undefined}
                                 */
                                function shortenTextDynamic(parentselector, selector, divisor) {
                                    if (parentselector === null) {
                                        let elem = document.querySelector(selector);
                                        if (elem !== null) {
                                            var parent = elem.parentElement;
                                        } else {
                                            return;
                                        }
                                    } else {
                                        var parent = document.querySelector(parentselector);
                                    }
                                    if (parent !== null) {
                                        let minCharacters = 80;
                                        let maxCharacters = 120;
                                        let nCharactersToDisplay = parent.offsetWidth / divisor;

                                        if (nCharactersToDisplay < minCharacters) {
                                            shortenText(selector);
                                        } else if (nCharactersToDisplay > maxCharacters) {
                                            nCharactersToDisplay = maxCharacters;
                                            shortenText(selector, nCharactersToDisplay);
                                        } else {
                                            shortenText(selector, nCharactersToDisplay);
                                        }
                                    } else {
                                        shortenText(selector); // Default: 80 characters
                                    }
                                }

                                /**
                                 * Renders MathJax and calls shortenText() afterwards.
                                 * @param {type} selector
                                 * @param {type} divisor
                                 * @param {type} click
                                 * @returns {undefined}
                                 */
                                function mathJaxAndShortenText(selector, divisor, click = false) {
                                    /*
                                    if (typeof MathJax !== 'undefined') {
                                        // Add the Mathjax-function and the shortenText function to the queue.
                                        if (MathJax.Hub !== 'undefined') {
                                            MathJax.Hub.Queue(
                                                ['Typeset', MathJax.Hub],
                                                [
                                                    function () {
                                                        shortenTextDynamic(null, selector, divisor);
                                                        if (click) {
                                                            $(selector + ' .morelink').click();
                                                        }
                                                    },
                                                    null,
                                                ]
                                            );
                                        }
                                    } else {
                                        shortenTextDynamic(null, selector, divisor);
                                        if (click) {
                                            $(selector + ' .morelink').click();
                                        }
                                    }*/
                                }
                            },
                            /* 40 */ /*OWN Module! To load new annotations (Synchronisation between sessions)*/
                            function (module, exports, __webpack_require__) {
                                'use strict';
                                Object.defineProperty(exports, '__esModule', { value: true });
                                exports.load = loadNewAnnotations;
                                var _event = __webpack_require__(4);
                                var _shortText = __webpack_require__(39);
                                var _PDFJSAnnotate = __webpack_require__(1);
                                var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
                                var _appendChild = __webpack_require__(11);
                                var _appendChild2 = _interopRequireDefault(_appendChild);
                                function _interopRequireDefault(obj) {
                                    return obj && obj.__esModule ? obj : { default: obj };
                                }
                                var _utils = __webpack_require__(6);
                                var SIZE = 20;
                                /**
                                 * This functions checks, if two annotations are at the same position an looks the same.
                                 * @return boolean, true if same and false if not
                                 */
                                function isAnnotationsPosEqual(annotationA, annotationB) {
                                    switch (annotationA.type) {
                                        case 'area':
                                            return (
                                                parseInt(annotationA.x) === parseInt(annotationB.x) &&
                                                parseInt(annotationA.y) === parseInt(annotationB.y) &&
                                                parseInt(annotationA.width) === parseInt(annotationB.width) &&
                                                parseInt(annotationA.height) === parseInt(annotationB.height)
                                            );
                                        case 'drawing':
                                            return (
                                                annotationA.color === annotationB.color &&
                                                JSON.stringify(annotationA.lines) ===
                                                    JSON.stringify(annotationB.lines) &&
                                                parseInt(annotationA.width) === parseInt(annotationB.width)
                                            );
                                        case 'highlight':
                                        case 'strikeout':
                                            //strikeout and highlight cannot be shifted, so they are the same
                                            return true;
                                        case 'point':
                                            return (
                                                parseInt(annotationA.x) === parseInt(annotationB.x) &&
                                                parseInt(annotationA.y) === parseInt(annotationB.y)
                                            );
                                        case 'textbox':
                                            return (
                                                parseInt(annotationA.x) === parseInt(annotationB.x) &&
                                                parseInt(annotationA.y) === parseInt(annotationB.y) &&
                                                parseInt(annotationA.width) === parseInt(annotationB.width) &&
                                                parseInt(annotationA.height) === parseInt(annotationB.height) &&
                                                annotationA.content === annotationB.content &&
                                                annotationA.color === annotationB.color &&
                                                parseInt(annotationA.size) === parseInt(annotationB.size)
                                            );
                                        default:
                                            return false;
                                    }
                                }
                                /**
                                 * This function edits the SVG-Object of the annotation in the DOM
                                 * @param {type} type type of annotation
                                 * @param {type} node the annotation node
                                 * @param {type} svg the outer svg
                                 * @param {type} annotation the annotation object
                                 * @returns {void}
                                 */
                                function editAnnotationSVG(type, node, svg, annotation) {
                                    if (['area', /*'highlight',*/ 'point', 'textbox'].indexOf(type) > -1) {
                                        (function () {
                                            var x = annotation.x;
                                            var y = annotation.y;
                                            if (type === 'point') {
                                                x = annotation.x - SIZE / 4;
                                                y = annotation.y - SIZE;
                                            }

                                            node.setAttribute('y', y);
                                            node.setAttribute('x', x);
                                        })();
                                    } else if (type === 'drawing') {
                                        (function () {
                                            node.parentNode.removeChild(node);
                                            (0, _appendChild2.default)(svg, annotation);
                                        })();
                                    }
                                }
                                /**
                                 * This function synchronizes the annotations
                                 * It calls itself 5 secs after the function finishes. So every 5+ seconds the annotations are updated.
                                 * It loads only the annotations of the current shown page.
                                 */
                                function loadNewAnnotations() {
                                    //determine which page is shown, to only load these annotations.
                                    var pageNumber = document.getElementById('currentPage').value;
                                    var page = document.getElementById('pageContainer' + pageNumber);
                                    if (page === null) {
                                        setTimeout(loadNewAnnotations, 5000);
                                        return;
                                    }
                                    var svg = page.querySelector('.annotationLayer');
                                    var metadata = _utils.getMetadata(svg);
                                    var viewport = metadata.viewport;
                                    var documentId = metadata.documentId;
                                    //Sometimes the page is not loaded yet, than try again in 5secs
                                    if (isNaN(documentId) || documentId === null) {
                                        setTimeout(loadNewAnnotations, 5000);
                                        return;
                                    }
                                    //Get annotations from database to get the newest.
                                    _PDFJSAnnotate2.default.getAnnotations(documentId, pageNumber).then(
                                        function (data) {
                                            var newAnnotations = [];
                                            newAnnotations[pageNumber] = data.annotations;
                                            var oldAnnotations = currentAnnotations.slice();
                                            currentAnnotations[pageNumber] = newAnnotations[pageNumber];
                                            var exists = false;
                                            for (var annotationID in newAnnotations[pageNumber]) {
                                                var annotation = newAnnotations[pageNumber][annotationID];
                                                for (var oldAnnoid in oldAnnotations[pageNumber]) {
                                                    var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
                                                    annotation.uuid = parseInt(annotation.uuid);
                                                    oldAnno.uuid = parseInt(oldAnno.uuid);
                                                    if (oldAnno !== undefined && annotation.uuid === oldAnno.uuid) {
                                                        if (!isAnnotationsPosEqual(annotation, oldAnno)) {
                                                            var node = document.querySelector(
                                                                '[data-pdf-annotate-id="' + oldAnno.uuid + '"]'
                                                            );
                                                            if (node !== null) {
                                                                editAnnotationSVG(
                                                                    annotation.type,
                                                                    node,
                                                                    svg,
                                                                    annotation
                                                                );
                                                            }
                                                        }
                                                        exists = true;
                                                        break;
                                                    } else if (
                                                        oldAnno.newAnno &&
                                                        isAnnotationsPosEqual(annotation, oldAnno)
                                                    ) {
                                                        //Annotation was just added and is the same in newAnnotations
                                                        //do Nothing
                                                        delete oldAnno.newAnno;
                                                        break;
                                                    }
                                                }
                                                if (!exists) {
                                                    //append annotation to svg
                                                    (0, _appendChild2.default)(svg, annotation, viewport);
                                                }
                                                exists = false;
                                            }
                                            var exists = false;
                                            for (var oldAnnoid in oldAnnotations[pageNumber]) {
                                                var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
                                                for (var annotationID in newAnnotations[pageNumber]) {
                                                    var annotation = newAnnotations[pageNumber][annotationID];
                                                    if (oldAnno.uuid == annotation.uuid) {
                                                        exists = true;
                                                        break;
                                                    }
                                                }
                                                if (!exists && !oldAnno.newAnno) {
                                                    var node = document.querySelector(
                                                        '[data-pdf-annotate-id="' + oldAnno.uuid + '"]'
                                                    );
                                                    if (node !== null) {
                                                        node.parentNode.removeChild(node);
                                                    }
                                                }
                                                exists = false;
                                            }
                                            //call this function to repeat in 5 secs
                                            //    setTimeout(loadNewAnnotations, 5000);
                                        },
                                        function (err) {
                                            notification.addNotification({
                                                message: M.util.get_string('error:getAnnotations', 'pdfannotator'),
                                                type: 'error',
                                            });
                                        }
                                    );
                                }
                            },
                            /*end of submodules of Module 2*/
                        ]);
                    }); //# sourceMappingURL=pdf-annotate.js.map
                    /* WEBPACK VAR INJECTION */
                }).call(exports, __webpack_require__(3)(module));
            },
            /* 3 */
            function (module, exports) {
                module.exports = function (module) {
                    if (!module.webpackPolyfill) {
                        module.deprecate = function () {};
                        module.paths = [];
                        // module.parent = undefined by default
                        module.children = [];
                        module.webpackPolyfill = 1;
                    }
                    return module;
                };
            },
            /* 4 */
            function (module, exports) {
                'use strict';

                Object.defineProperty(exports, '__esModule', {
                    value: true,
                });
                exports.default = initColorPicker;
                // Color picker component
                var COLORS = [
                    { hex: '#000000', name: 'Black' },
                    { hex: '#EF4437', name: 'Red' },
                    { hex: '#E71F63', name: 'Pink' },
                    { hex: '#8F3E97', name: 'Purple' },
                    { hex: '#65499D', name: 'Deep Purple' },
                    { hex: '#4554A4', name: 'Indigo' },
                    { hex: '#2083C5', name: 'Blue' },
                    { hex: '#35A4DC', name: 'Light Blue' },
                    { hex: '#09BCD3', name: 'Cyan' },
                    { hex: '#009688', name: 'Teal' },
                    { hex: '#43A047', name: 'Green' },
                    { hex: '#8BC34A', name: 'Light Green' },
                    { hex: '#FDC010', name: 'Yellow' },
                    { hex: '#F8971C', name: 'Orange' },
                    { hex: '#F0592B', name: 'Deep Orange' },
                    { hex: '#F06291', name: 'Light Pink' },
                ];

                function initColorPicker(el, value, onChange) {
                    function setColor(value) {
                        var fireOnChange = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];

                        currentValue = value;
                        a.setAttribute('data-color', value);
                        a.style.background = value;
                        if (fireOnChange && typeof onChange === 'function') {
                            onChange(value);
                        }
                        closePicker();
                    }

                    function togglePicker() {
                        if (isPickerOpen) {
                            closePicker();
                        } else {
                            openPicker();
                        }
                    }

                    function closePicker() {
                        document.removeEventListener('keyup', handleDocumentKeyup);
                        if (picker && picker.parentNode) {
                            picker.parentNode.removeChild(picker);
                        }
                        isPickerOpen = false;
                        a.focus();
                    }

                    function openPicker() {
                        if (!picker) {
                            picker = document.createElement('div');
                            picker.style.background = '#fff';
                            picker.style.border = '1px solid #ccc';
                            picker.style.padding = '2px';
                            picker.style.position = 'absolute';
                            picker.style.width = '122px';
                            el.style.position = 'relative';

                            COLORS.map(createColorOption).forEach(function (c) {
                                c.style.margin = '2px';
                                c.onclick = function () {
                                    // Select text/pen instead of cursor.
                                    if (c.parentNode.parentNode.className === 'text-color') {
                                        document.querySelector('#pdftoolbar button.text').click();
                                    } else if (c.parentNode.parentNode.className === 'pen-color') {
                                        document.querySelector('#pdftoolbar button.pen').click();
                                    }
                                    setColor(c.getAttribute('data-color'));
                                };
                                picker.appendChild(c);
                            });
                        }

                        document.addEventListener('keyup', handleDocumentKeyup);
                        el.appendChild(picker);
                        isPickerOpen = true;
                    }

                    function createColorOption(color) {
                        var e = document.createElement('a');
                        e.className = 'color';
                        e.setAttribute('href', 'javascript://');
                        e.setAttribute('title', color.name);
                        e.setAttribute('data-color', color.hex);
                        e.style.background = color.hex;
                        return e;
                    }

                    function handleDocumentKeyup(e) {
                        if (e.keyCode === 27) {
                            closePicker();
                        }
                    }

                    var picker = void 0;
                    var isPickerOpen = false;
                    var currentValue = void 0;
                    var a = createColorOption({ hex: value });
                    a.title = M.util.get_string('colorPicker', 'pdfannotator');
                    a.onclick = togglePicker;
                    el.appendChild(a);
                    setColor(value, false);
                }
            },
        ]);
    }); //require JQuery closed
}

function read_visibility_of_checkbox() {
    var commentVisibility = 'public';
    if (document.querySelector('#anonymousCheckbox').checked) {
        commentVisibility = 'anonymous';
        document.querySelector('#anonymousCheckbox').checked = false;
    }

    if (document.querySelector('#privateCheckbox') != null) {
        if (document.querySelector('#privateCheckbox').checked) {
            commentVisibility = 'private';
            document.querySelector('#privateCheckbox').checked = false;
        }
    }

    if (document.querySelector('#protectedCheckbox') != null) {
        if (document.querySelector('#protectedCheckbox').checked) {
            commentVisibility = 'protected';
            document.querySelector('#protectedCheckbox').checked = false;
        }
    }
    return commentVisibility;
}

/**
 * Extract text from HTML.
 */
function extract_text_from_html(html) {
    let tmp = document.createElement('div');
    tmp.innerHTML = html;
    return tmp.textContent;
}

function get_post_content(commentList) {
    var commentInsidePtag = commentList.querySelectorAll('');
}