403Webshell
Server IP : 85.158.181.41  /  Your IP : 216.73.217.12
Web Server : Apache
System : Linux cloud9-vm129 6.1.178+1-ph #ph SMP PREEMPT_DYNAMIC Wed Jul 29 09:00:54 UTC 2026 x86_64
User : moncbefd ( 1024)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/moncbefd/www.moneta.at/admin/html/assets/javascript/engine/libs/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/moncbefd/www.moneta.at/admin/html/assets/javascript/engine/libs/emails.js
'use strict';

/* --------------------------------------------------------------
 emails.js 2016-02-22
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2016 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

jse.libs.emails = jse.libs.emails || {};

/**
 * ## Emails Library
 *
 * This library contains all the admin/emails page common functionality and is used by the page
 * controllers. You might also use this library in other pages where you need to trigger specific
 * email operations in the server.
 *
 * You will need to provide the full URL in order to load this library as a dependency to a module:
 *
 * ```javascript
 * gx.controller.module(
 *   'my_custom_page',
 *
 *   [
 *      gx.source + '/libs/emails'
 *   ],
 *
 *   function(data) {
 *      // Module code ... 
 *   });
 *```
 *
 * Required Translation Sections: 'admin_labels', 'buttons', 'db_backup', 'emails', 'lightbox_buttons', 'messages'
 *
 * @module Admin/Libs/emails
 * @exports jse.libs.emails
 */
(function (exports) {

    'use strict';

    exports.CONTACT_TYPE_SENDER = 'sender';
    exports.CONTACT_TYPE_RECIPIENT = 'recipient';
    exports.CONTACT_TYPE_REPLY_TO = 'reply_to';
    exports.CONTACT_TYPE_BCC = 'bcc';
    exports.CONTACT_TYPE_CC = 'cc';

    /**
     * Reset Modal (DOM)
     *
     * This method will reset the emails modal back to its initial state. The default
     * modal markup is used in the admin/emails page, but this method can work without
     * all the elements too.
     *
     * @param {object} $modal jQuery selector for the modal.
     */
    exports.resetModal = function ($modal) {
        // Clear basic elements
        $modal.find('input, textarea').val('');
        $modal.find('select option:first').prop('selected', 'selected');

        // Remove validation classes.
        $modal.trigger('validator.reset');

        // Remove all rows from DataTables.
        if ($modal.find('.dataTables_wrapper').length > 0) {
            $modal.find('.dataTables_wrapper table').DataTable().clear().draw();
            $modal.find('.dataTables_wrapper').find('.dataTables_length select option:eq(0)').prop('selected', true);
        }

        // Set all tab widgets to the first tab.
        if ($modal.find('.tab-headline-wrapper').length > 0) {
            $modal.find('.tab-headline').css('color', '').show();
            $modal.find('.tab-headline-wrapper').each(function () {
                $(this).find('a:eq(0)').trigger('click'); // toggle first tab
            });
        }

        // Need to recreate the ckeditor instance every time the modal appears.
        if ($modal.find('#content-html').length > 0) {
            if (CKEDITOR.instances['content-html'] !== undefined) {
                CKEDITOR.instances['content-html'].destroy();
            }
            CKEDITOR.replace('content-html', {
                language: jse.core.config.get('languageCode')
            });
            CKEDITOR.instances['content-html'].setData('');
        }

        // If contact type hidden inputs are present then we have to re-apply their value.
        if ($modal.find('#sender-type').length > 0) {
            $modal.find('#sender-type').val('sender');
        }
        if ($modal.find('#recipient-type').length > 0) {
            $modal.find('#recipient-type').val('recipient');
        }
        if ($modal.find('#reply-to-type').length > 0) {
            $modal.find('#reply-to-type').val('reply_to');
        }

        // Update Tab Counters
        jse.libs.emails.updateTabCounters($modal);
    };

    /**
     * Returns the email information from modal (DOM).
     *
     * The method will grab the values from the modal and bundle them in a single object.
     * The returned object will have the same structure as the valueMapping object. This
     * method is recursive.
     *
     * @param {object} $modal jQuery selector for the modal.
     *
     * @return {object} Returns the email data of the modal.
     */
    exports.getEmailFromModal = function ($modal) {
        var email = {};

        // Required Email Fields
        email.sender = {
            email_address: $modal.find('#sender-email').val(),
            contact_name: $modal.find('#sender-name').val(),
            contact_type: exports.CONTACT_TYPE_SENDER
        };

        email.recipient = {
            email_address: $modal.find('#recipient-email').val(),
            contact_name: $modal.find('#recipient-name').val(),
            contact_type: exports.CONTACT_TYPE_RECIPIENT
        };

        email.subject = $modal.find('#subject').val();
        email.content_html = CKEDITOR.instances['content-html'].getData();

        // Optional Email fields
        email.email_id = $modal.find('#email-id').val() !== '' ? $modal.find('#email-id').val() : null;
        email.is_pending = $modal.find('#is-pending').val() === 'true';
        email.content_plain = $modal.find('#content-plain').val() !== '' ? $modal.find('#content-plain').val() : null;

        email.reply_to = $modal.find('#reply-to-email').val() !== '' ? {} : null;
        if (email.reply_to) {
            email.reply_to.email_address = $modal.find('#reply-to-email').val();
            email.reply_to.contact_name = $modal.find('#reply-to-name').val();
            email.reply_to.contact_type = exports.CONTACT_TYPE_REPLY_TO;
        }

        // BCC & CC Contacts
        email.bcc = null;
        email.cc = null;
        var contacts = $modal.find('#contacts-table').DataTable().rows().data();

        $.each(contacts, function (index, contact) {
            if (email[contact.type] == null) {
                email[contact.type] = [];
            }

            email[contact.type].push({
                email_address: contact.email,
                contact_name: contact.name,
                contact_type: contact.type
            });
        });

        // Attachments
        email.attachments = null;
        var attachments = $modal.find('#attachments-table').DataTable().rows().data();
        $.each(attachments, function (index, attachment) {
            if (email.attachments === null) {
                email.attachments = [];
            }
            email.attachments.push(attachment);
        });

        return email;
    };

    /**
     * Loads email data on modal (DOM).
     *
     * @param {object} email Contains the email data.
     * @param {object} $modal jQuery selector for the modal.
     */
    exports.loadEmailOnModal = function (email, $modal) {
        // Required Email Fields
        $modal.find('#sender-email').val(email.sender.email_address);
        $modal.find('#sender-name').val(email.sender.contact_name);

        $modal.find('#recipient-email').val(email.recipient.email_address);
        $modal.find('#recipient-name').val(email.recipient.contact_name);

        $modal.find('#subject').val(email.subject);
        CKEDITOR.instances['content-html'].setData(email.content_html);

        $modal.find('#is-pending').val(email.is_pending ? 'true' : 'false');

        // Optional Email Fields

        if (email.email_id !== null) {
            $modal.find('#email-id').val(email.email_id);
        }

        if (email.creation_date !== null) {
            $modal.find('#creation-date').val(email.creation_date);
        }

        if (email.sent_date !== null) {
            $modal.find('#sent-date').val(email.sent_date);
        }

        if (email.reply_to !== null) {
            $modal.find('#reply-to-email').val(email.reply_to.email_address);
            $modal.find('#reply-to-name').val(email.reply_to.contact_name);
        }

        if (email.content_plain !== null) {
            $modal.find('#content-plain').val(email.content_plain);
        }

        if (email.bcc !== null) {
            $.each(email.bcc, function (index, contact) {
                var row = {
                    email: jse.libs.normalize.escapeHtml(contact.email_address),
                    name: jse.libs.normalize.escapeHtml(contact.contact_name),
                    type: jse.libs.normalize.escapeHtml(contact.contact_type)
                };
                $modal.find('#contacts-table').DataTable().row.add(row).draw();
            });
        }

        if (email.cc !== null) {
            $.each(email.cc, function (index, contact) {
                var row = {
                    email: jse.libs.normalize.escapeHtml(contact.email_address),
                    name: jse.libs.normalize.escapeHtml(contact.contact_name),
                    type: jse.libs.normalize.escapeHtml(contact.contact_type)
                };
                $modal.find('#contacts-table').DataTable().row.add(row).draw();
            });
        }

        if (email.attachments !== null) {
            $.each(email.attachments, function (index, attachment) {
                attachment.path = jse.libs.normalize.escapeHtml(attachment.path);
                $modal.find('#attachments-table').DataTable().row.add(attachment).draw();
            });
        }

        // Update Tab Counters
        jse.libs.emails.updateTabCounters($modal);
    };

    /**
     * Sends an email collection
     *
     * Provide an array of email objects and this method will send them to the requested
     * URL through AJAX POST. You can omit the url and the default EmailsController will
     * be used.
     *
     * @param {array} collection Array of email objects.
     * @param {string} ajaxUrl (optional) The AJAX URL for the POST request.
     *
     * @return {object} Returns a promise object that will provide the server's response.
     */
    exports.sendCollection = function (collection, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/Send';

        var deferred = $.Deferred(),
            data = {
            pageToken: jse.core.config.get('pageToken'),
            collection: collection
        };

        $.post(ajaxUrl, data, function (response) {
            if (response.exception) {
                deferred.reject(response);
                return;
            }
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Queues the email collection
     *
     * Provide an array of email objects and this method will queue them to the requested
     * URL through AJAX POST. You can omit the url and the default EmailsController will
     * be used.
     *
     * @param {array} collection Array of email objects.
     * @param {string} ajaxUrl (optional) The AJAX URL for the POST request.
     *
     * @return {object} Returns a promise object that will provide the server's response.
     */
    exports.queueCollection = function (collection, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/Queue';

        var deferred = $.Deferred(),
            data = {
            pageToken: jse.core.config.get('pageToken'),
            collection: collection
        };

        $.post(ajaxUrl, data, function (response) {
            if (response.exception) {
                deferred.reject(response);
                return;
            }
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Deletes an email collection
     *
     * Provide an array of email objects and this method will delete them to the requested
     * URL through AJAX POST. You can omit the url and the default EmailsController will
     * be used.
     *
     * @param {array} collection Array of email objects.
     * @param {string} ajaxUrl (optional) The AJAX URL for the POST request.
     *
     * @return {object} Returns a promise object that will provide the server's response.
     */
    exports.deleteCollection = function (collection, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/Delete';

        var deferred = $.Deferred(),
            data = {
            pageToken: jse.core.config.get('pageToken'),
            collection: collection
        };

        $.post(ajaxUrl, data, function (response) {
            if (response.exception) {
                deferred.reject(response);
                return;
            }
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Returns default modal buttons
     *
     * Used by various sections of the admin/emails page. With the proper use of valueMapping object
     * you can use this method in other pages too.
     *
     * @param {object} $modal jQuery selector for the modal.
     * @param {object} $table jQuery selector for the main table.
     *
     * @return {object} Returns the dialog modal buttons.
     */
    exports.getDefaultModalButtons = function ($modal, $table) {
        var buttons = [{
            text: jse.core.lang.translate('close', 'buttons'),
            click: function click() {
                $(this).dialog('close');
            }
        }, {
            text: jse.core.lang.translate('queue', 'buttons'),
            click: function click() {
                $modal.find('.tab-content.details').trigger('validator.validate');
                if ($modal.find('.tab-content.details .error').length > 0) {
                    return; // There are fields with errors.
                }
                var email = jse.libs.emails.getEmailFromModal($modal);
                jse.libs.emails.queueCollection([email]).done(function (response) {
                    $table.DataTable().ajax.reload();
                    jse.libs.emails.getAttachmentsSize($('#attachments-size'));
                }).fail(function (response) {
                    jse.libs.modal.message({
                        title: jse.core.lang.translate('error', 'messages'),
                        content: response.message
                    });
                });
                $(this).dialog('close');
            }
        }, {
            text: jse.core.lang.translate('send', 'buttons'),
            click: function click() {
                $modal.find('.tab-content.details').trigger('validator.validate');
                if ($modal.find('.tab-content.details .error').length > 0) {
                    return; // There are fields with errors.
                }
                var email = jse.libs.emails.getEmailFromModal($modal);
                jse.libs.emails.sendCollection([email]).done(function (response) {
                    $table.DataTable().ajax.reload();
                    jse.libs.emails.getAttachmentsSize($('#attachments-size'));
                }).fail(function (response) {
                    jse.libs.modal.message({
                        title: jse.core.lang.translate('error', 'messages'),
                        content: response.message
                    });
                });
                $(this).dialog('close');
            }
        }];

        return buttons;
    };

    /**
     * Returns preview modal buttons
     *
     * This method will return the preview modal buttons for the jQuery UI dialog widget. With the proper
     * use of valueMapping object you can use this method in other pages too.
     *
     * @param {object} $modal jQuery selector for the modal.
     * @param {object} $table jQuery selector for the main table.
     *
     * @return {object} Returns the dialog modal buttons.
     */
    exports.getPreviewModalButtons = function ($modal, $table) {
        var buttons = [{
            text: jse.core.lang.translate('close', 'buttons'),
            click: function click() {
                $(this).dialog('close');
            }
        }, {
            text: jse.core.lang.translate('delete', 'buttons'),
            click: function click() {
                var modalOptions = {
                    title: 'Delete Email Record',
                    content: 'Are you sure that you want to delete this email record?',
                    buttons: [{
                        text: jse.core.lang.translate('yes', 'lightbox_buttons'),
                        click: function click() {
                            var email = jse.libs.emails.getEmailFromModal($modal);

                            jse.libs.emails.deleteCollection([email]).done(function (response) {
                                $table.DataTable().ajax.reload();
                                jse.libs.emails.getAttachmentsSize($('#attachments-size'));
                            }).fail(function (response) {
                                jse.libs.modal.message({
                                    title: jse.core.lang.translate('error', 'messages'),
                                    content: response.message
                                });
                            });
                            $(this).dialog('close');
                            $modal.dialog('close');
                        }
                    }, {
                        text: jse.core.lang.translate('no', 'lightbox_buttons'),
                        click: function click() {
                            $(this).dialog('close');
                        }
                    }]
                };

                jse.libs.modal.message(modalOptions);
            }
        }, {
            text: jse.core.lang.translate('queue', 'buttons'),
            click: function click() {
                var email = jse.libs.emails.getEmailFromModal($modal);

                // Duplicate record only if the original one is already sent.
                // Otherwise we just need to update the data of the current email record.
                if (!email.is_pending) {
                    delete email.email_id; // will duplicate the record
                }

                jse.libs.emails.queueCollection([email]).done(function (response) {
                    $table.DataTable().ajax.reload();
                    jse.libs.emails.getAttachmentsSize($('#attachments-size'));
                }).fail(function (response) {
                    jse.libs.modal.message({
                        title: jse.core.lang.translate('error', 'messages'),
                        content: response.message
                    });
                });
                $(this).dialog('close');
            }
        }, {
            text: jse.core.lang.translate('send', 'buttons'),
            click: function click() {
                var email = jse.libs.emails.getEmailFromModal($modal);
                jse.libs.emails.sendCollection([email]).done(function (response) {
                    $table.DataTable().ajax.reload();
                    jse.libs.emails.getAttachmentsSize($('#attachments-size'));
                }).fail(function (response) {
                    jse.libs.modal.message({
                        title: jse.core.lang.translate('error', 'messages'),
                        content: response.message
                    });
                });
                $(this).dialog('close');
            }
        }];

        return buttons;
    };

    /**
     * Colorizes modal buttons for the edit mode
     *
     * jQuery UI does not support direct addition of classes to the dialog buttons,
     * so we need to apply the classes during the "create" event of the dialog.
     *
     * @param event {event} Event to trigger this function.
     * @param ui {object} Dialog UI.
     */
    exports.colorizeButtonsForEditMode = function (event, ui) {
        $(this).closest('.ui-dialog').find('.ui-button').eq(3).addClass('btn-primary'); // Send Button
    };

    /**
     * Colorizes modal buttons for preview mode
     *
     * jQuery UI does not support direct addition of classes to the dialog buttons,
     * so we need to apply the classes during the "create" event of the dialog.
     *
     * @param event {object} Event to trigger this function.
     * @param ui {object} Dialog UI.
     */
    exports.colorizeButtonsForPreviewMode = function (event, ui) {
        $(this).closest('.ui-dialog').find('.ui-button').eq(4).addClass('btn-primary'); // Send Button
    };

    /**
     * Deletes old attachments from selected removal date and before.
     *
     * @param {date} removalDate The date when the removal should start.
     * @param {object} ajaxUrl (optional) Specific ajaxUrl to be used for the request.
     * @returns {object} Returns a promise object to be used when the requests ends.
     */
    exports.deleteOldAttachments = function (removalDate, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/DeleteOldAttachments';

        var deferred = $.Deferred(),
            data = {
            pageToken: jse.core.config.get('pageToken'),
            removalDate: removalDate
        };

        $.post(ajaxUrl, data, function (response) {
            if (response.exception) {
                deferred.reject(response);
                return;
            }
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Deletes old emails from selected removal date and before.
     *
     * @param {string} removalDate The date when the removal should start.
     * @param {object} ajaxUrl (optional) Specific ajaxUrl to be used for the request.
     * @returns {object} Returns a promise object to be used when the requests ends.
     */
    exports.deleteOldEmails = function (removalDate, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/DeleteOldEmails';

        var deferred = $.Deferred(),
            data = {
            pageToken: jse.core.config.get('pageToken'),
            removalDate: removalDate
        };

        $.post(ajaxUrl, data, function (response) {
            if (response.exception) {
                deferred.reject(response);
                return;
            }
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Returns the attachments size in MB and refreshes the UI.
     *
     * This method will make a GET request to the server in order to fetch and display
     * the total attachments size, so that users know when it is time to remove old
     * attachments.
     *
     * @param {object} $target jQuery selector for the element to contain the size info.
     * @param {string} ajaxUrl (optional) Specific ajaxUrl to be used for the request.
     *
     * @return {object} Returns the promise object for chaining callbacks.
     */
    exports.getAttachmentsSize = function ($target, ajaxUrl) {
        ajaxUrl = ajaxUrl || jse.core.config.get('appUrl') + '/admin/admin.php?do=Emails/GetAttachmentsSize';

        var deferred = $.Deferred();

        $.get(ajaxUrl, function (response) {
            if (response.exception) {
                jse.libs.modal.message({
                    title: jse.core.lang.translate('error', 'messages'),
                    content: response.message
                });
                deferred.reject(response);
                return;
            }

            var size = response.size.megabytes !== 0 ? response.size.megabytes + ' MB' : response.size.bytes + ' bytes';

            $target.text('(' + size + ')');
            deferred.resolve(response);
        }, 'json');

        return deferred.promise();
    };

    /**
     * Updates modal tabs counters.
     *
     * Displays item number on tabs so that users know how many items there are
     * included in the contacts and attachments tables.
     *
     * @param {object} $modal The modal selector to be updated.
     * @param {object} $contactsTable (optional) The contacts table selector, default selector: '#contacts-table'.
     * @param {object} $contactsTab (optional) The contacts tab selector, default selector: '.tab-headline.bcc-cc'.
     * @param {object} $attachmentsTable (optional) The attachments table selector, default
     * selector: '#attachments-table'.
     * @param {object} $attachmentsTab (optional) The attachments tab selector, default
     * selector: '.tab-headline.attachments'.
     */
    exports.updateTabCounters = function ($modal, $contactsTable, $contactsTab, $attachmentsTable, $attachmentsTab) {
        $contactsTable = $contactsTable || $modal.find('#contacts-table');
        $contactsTab = $contactsTab || $modal.find('.tab-headline.bcc-cc');
        $attachmentsTable = $attachmentsTable || $modal.find('#attachments-table');
        $attachmentsTab = $attachmentsTab || $modal.find('.tab-headline.attachments');

        if ($contactsTable.length === 0) {
            return; // There is no such table (emails.js unit testing).
        }

        var contactsCount = $contactsTable.DataTable().rows().data().length,
            newContactsText = $contactsTab.text().replace(/\(.*\)/g, '(' + contactsCount + ')'),
            attachmentsCount = $attachmentsTable.DataTable().rows().data().length,
            newAttachmentsText = $attachmentsTab.text().replace(/\(.*\)/g, '(' + attachmentsCount + ')');

        if (newContactsText.indexOf('(') === -1) {
            newContactsText += ' (' + contactsCount + ')';
        }

        if (newAttachmentsText.indexOf('(') === -1) {
            newAttachmentsText += ' (' + attachmentsCount + ')';
        }

        $contactsTab.text(newContactsText);
        $attachmentsTab.text(newAttachmentsText);
    };

    /**
     * Returns an object array with the selected emails of the main emails table.
     *
     * @param {object} $table (optional) The main table selector, if omitted the "#emails-table" selector
     * will be used.
     *
     * @returns {array} Returns an array with the emails data (collection).
     */
    exports.getSelectedEmails = function ($table) {
        $table = $table || $('#emails-table');

        var collection = [];

        $table.find('tr td input:checked').each(function (index, checkbox) {
            collection.push($(checkbox).parents('tr').data());
        });

        return collection;
    };
})(jse.libs.emails);
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVtYWlscy5qcyJdLCJuYW1lcyI6WyJqc2UiLCJsaWJzIiwiZW1haWxzIiwiZXhwb3J0cyIsIkNPTlRBQ1RfVFlQRV9TRU5ERVIiLCJDT05UQUNUX1RZUEVfUkVDSVBJRU5UIiwiQ09OVEFDVF9UWVBFX1JFUExZX1RPIiwiQ09OVEFDVF9UWVBFX0JDQyIsIkNPTlRBQ1RfVFlQRV9DQyIsInJlc2V0TW9kYWwiLCIkbW9kYWwiLCJmaW5kIiwidmFsIiwicHJvcCIsInRyaWdnZXIiLCJsZW5ndGgiLCJEYXRhVGFibGUiLCJjbGVhciIsImRyYXciLCJjc3MiLCJzaG93IiwiZWFjaCIsIiQiLCJDS0VESVRPUiIsImluc3RhbmNlcyIsInVuZGVmaW5lZCIsImRlc3Ryb3kiLCJyZXBsYWNlIiwibGFuZ3VhZ2UiLCJjb3JlIiwiY29uZmlnIiwiZ2V0Iiwic2V0RGF0YSIsInVwZGF0ZVRhYkNvdW50ZXJzIiwiZ2V0RW1haWxGcm9tTW9kYWwiLCJlbWFpbCIsInNlbmRlciIsImVtYWlsX2FkZHJlc3MiLCJjb250YWN0X25hbWUiLCJjb250YWN0X3R5cGUiLCJyZWNpcGllbnQiLCJzdWJqZWN0IiwiY29udGVudF9odG1sIiwiZ2V0RGF0YSIsImVtYWlsX2lkIiwiaXNfcGVuZGluZyIsImNvbnRlbnRfcGxhaW4iLCJyZXBseV90byIsImJjYyIsImNjIiwiY29udGFjdHMiLCJyb3dzIiwiZGF0YSIsImluZGV4IiwiY29udGFjdCIsInR5cGUiLCJwdXNoIiwibmFtZSIsImF0dGFjaG1lbnRzIiwiYXR0YWNobWVudCIsImxvYWRFbWFpbE9uTW9kYWwiLCJjcmVhdGlvbl9kYXRlIiwic2VudF9kYXRlIiwicm93Iiwibm9ybWFsaXplIiwiZXNjYXBlSHRtbCIsImFkZCIsInBhdGgiLCJzZW5kQ29sbGVjdGlvbiIsImNvbGxlY3Rpb24iLCJhamF4VXJsIiwiZGVmZXJyZWQiLCJEZWZlcnJlZCIsInBhZ2VUb2tlbiIsInBvc3QiLCJyZXNwb25zZSIsImV4Y2VwdGlvbiIsInJlamVjdCIsInJlc29sdmUiLCJwcm9taXNlIiwicXVldWVDb2xsZWN0aW9uIiwiZGVsZXRlQ29sbGVjdGlvbiIsImdldERlZmF1bHRNb2RhbEJ1dHRvbnMiLCIkdGFibGUiLCJidXR0b25zIiwidGV4dCIsImxhbmciLCJ0cmFuc2xhdGUiLCJjbGljayIsImRpYWxvZyIsImRvbmUiLCJhamF4IiwicmVsb2FkIiwiZ2V0QXR0YWNobWVudHNTaXplIiwiZmFpbCIsIm1vZGFsIiwibWVzc2FnZSIsInRpdGxlIiwiY29udGVudCIsImdldFByZXZpZXdNb2RhbEJ1dHRvbnMiLCJtb2RhbE9wdGlvbnMiLCJjb2xvcml6ZUJ1dHRvbnNGb3JFZGl0TW9kZSIsImV2ZW50IiwidWkiLCJjbG9zZXN0IiwiZXEiLCJhZGRDbGFzcyIsImNvbG9yaXplQnV0dG9uc0ZvclByZXZpZXdNb2RlIiwiZGVsZXRlT2xkQXR0YWNobWVudHMiLCJyZW1vdmFsRGF0ZSIsImRlbGV0ZU9sZEVtYWlscyIsIiR0YXJnZXQiLCJzaXplIiwibWVnYWJ5dGVzIiwiYnl0ZXMiLCIkY29udGFjdHNUYWJsZSIsIiRjb250YWN0c1RhYiIsIiRhdHRhY2htZW50c1RhYmxlIiwiJGF0dGFjaG1lbnRzVGFiIiwiY29udGFjdHNDb3VudCIsIm5ld0NvbnRhY3RzVGV4dCIsImF0dGFjaG1lbnRzQ291bnQiLCJuZXdBdHRhY2htZW50c1RleHQiLCJpbmRleE9mIiwiZ2V0U2VsZWN0ZWRFbWFpbHMiLCJjaGVja2JveCIsInBhcmVudHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQUEsSUFBSUMsSUFBSixDQUFTQyxNQUFULEdBQWtCRixJQUFJQyxJQUFKLENBQVNDLE1BQVQsSUFBbUIsRUFBckM7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJCQSxDQUFDLFVBQVVDLE9BQVYsRUFBbUI7O0FBRWhCOztBQUVBQSxZQUFRQyxtQkFBUixHQUE4QixRQUE5QjtBQUNBRCxZQUFRRSxzQkFBUixHQUFpQyxXQUFqQztBQUNBRixZQUFRRyxx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b3VyY2VzQ29udGVudCI6WyIvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIGVtYWlscy5qcyAyMDE2LTAyLTIyXG4gR2FtYmlvIEdtYkhcbiBodHRwOi8vd3d3LmdhbWJpby5kZVxuIENvcHlyaWdodCAoYykgMjAxNiBHYW1iaW8gR21iSFxuIFJlbGVhc2VkIHVuZGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoVmVyc2lvbiAyKVxuIFtodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC5odG1sXVxuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuanNlLmxpYnMuZW1haWxzID0ganNlLmxpYnMuZW1haWxzIHx8IHt9O1xuXG4vKipcbiAqICMjIEVtYWlscyBMaWJyYXJ5XG4gKlxuICogVGhpcyBsaWJyYXJ5IGNvbnRhaW5zIGFsbCB0aGUgYWRtaW4vZW1haWxzIHBhZ2UgY29tbW9uIGZ1bmN0aW9uYWxpdHkgYW5kIGlzIHVzZWQgYnkgdGhlIHBhZ2VcbiAqIGNvbnRyb2xsZXJzLiBZb3UgbWlnaHQgYWxzbyB1c2UgdGhpcyBsaWJyYXJ5IGluIG90aGVyIHBhZ2VzIHdoZXJlIHlvdSBuZWVkIHRvIHRyaWdnZXIgc3BlY2lmaWNcbiAqIGVtYWlsIG9wZXJhdGlvbnMgaW4gdGhlIHNlcnZlci5cbiAqXG4gKiBZb3Ugd2lsbCBuZWVkIHRvIHByb3ZpZGUgdGhlIGZ1bGwgVVJMIGluIG9yZGVyIHRvIGxvYWQgdGhpcyBsaWJyYXJ5IGFzIGEgZGVwZW5kZW5jeSB0byBhIG1vZHVsZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBneC5jb250cm9sbGVyLm1vZHVsZShcbiAqICAgJ215X2N1c3RvbV9wYWdlJyxcbiAqXG4gKiAgIFtcbiAqICAgICAgZ3guc291cmNlICsgJy9saWJzL2VtYWlscydcbiAqICAgXSxcbiAqXG4gKiAgIGZ1bmN0aW9uKGRhdGEpIHtcbiAqICAgICAgLy8gTW9kdWxlIGNvZGUgLi4uIFxuICogICB9KTtcbiAqYGBgXG4gKlxuICogUmVxdWlyZWQgVHJhbnNsYXRpb24gU2VjdGlvbnM6ICdhZG1pbl9sYWJlbHMnLCAnYnV0dG9ucycsICdkYl9iYWNrdXAnLCAnZW1haWxzJywgJ2xpZ2h0Ym94X2J1dHRvbnMnLCAnbWVzc2FnZXMnXG4gKlxuICogQG1vZHVsZSBBZG1pbi9MaWJzL2VtYWlsc1xuICogQGV4cG9ydHMganNlLmxpYnMuZW1haWxzXG4gKi9cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgZXhwb3J0cy5DT05UQUNUX1RZUEVfU0VOREVSID0gJ3NlbmRlcic7XG4gICAgZXhwb3J0cy5DT05UQUNUX1RZUEVfUkVDSVBJRU5UID0gJ3JlY2lwaWVudCc7XG4gICAgZXhwb3J0cy5DT05UQUNUX1RZUEVfUkVQTFlfVE8gPSAncmVwbHlfdG8nO1xuICAgIGV4cG9ydHMuQ09OVEFDVF9UWVBFX0JDQyA9ICdiY2MnO1xuICAgIGV4cG9ydHMuQ09OVEFDVF9UWVBFX0NDID0gJ2NjJztcblxuICAgIC8qKlxuICAgICAqIFJlc2V0IE1vZGFsIChET00pXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIHJlc2V0IHRoZSBlbWFpbHMgbW9kYWwgYmFjayB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gVGhlIGRlZmF1bHRcbiAgICAgKiBtb2RhbCBtYXJrdXAgaXMgdXNlZCBpbiB0aGUgYWRtaW4vZW1haWxzIHBhZ2UsIGJ1dCB0aGlzIG1ldGhvZCBjYW4gd29yayB3aXRob3V0XG4gICAgICogYWxsIHRoZSBlbGVtZW50cyB0b28uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gJG1vZGFsIGpRdWVyeSBzZWxlY3RvciBmb3IgdGhlIG1vZGFsLlxuICAgICAqL1xuICAgIGV4cG9ydHMucmVzZXRNb2RhbCA9IGZ1bmN0aW9uICgkbW9kYWwpIHtcbiAgICAgICAgLy8gQ2xlYXIgYmFzaWMgZWxlbWVudHNcbiAgICAgICAgJG1vZGFsLmZpbmQoJ2lucHV0LCB0ZXh0YXJlYScpLnZhbCgnJyk7XG4gICAgICAgICRtb2RhbC5maW5kKCdzZWxlY3Qgb3B0aW9uOmZpcnN0JykucHJvcCgnc2VsZWN0ZWQnLCAnc2VsZWN0ZWQnKTtcblxuICAgICAgICAvLyBSZW1vdmUgdmFsaWRhdGlvbiBjbGFzc2VzLlxuICAgICAgICAkbW9kYWwudHJpZ2dlcigndmFsaWRhdG9yLnJlc2V0Jyk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGFsbCByb3dzIGZyb20gRGF0YVRhYmxlcy5cbiAgICAgICAgaWYgKCRtb2RhbC5maW5kKCcuZGF0YVRhYmxlc193cmFwcGVyJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJG1vZGFsLmZpbmQoJy5kYXRhVGFibGVzX3dyYXBwZXIgdGFibGUnKS5EYXRhVGFibGUoKS5jbGVhcigpLmRyYXcoKTtcbiAgICAgICAgICAgICRtb2RhbC5maW5kKCcuZGF0YVRhYmxlc193cmFwcGVyJykuZmluZCgnLmRhdGFUYWJsZXNfbGVuZ3RoIHNlbGVjdCBvcHRpb246ZXEoMCknKS5wcm9wKFxuICAgICAgICAgICAgICAgICdzZWxlY3RlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGFsbCB0YWIgd2lkZ2V0cyB0byB0aGUgZmlyc3QgdGFiLlxuICAgICAgICBpZiAoJG1vZGFsLmZpbmQoJy50YWItaGVhZGxpbmUtd3JhcHBlcicpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICRtb2RhbC5maW5kKCcudGFiLWhlYWRsaW5lJykuY3NzKCdjb2xvcicsICcnKS5zaG93KCk7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnLnRhYi1oZWFkbGluZS13cmFwcGVyJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5maW5kKCdhOmVxKDApJykudHJpZ2dlcignY2xpY2snKTsgLy8gdG9nZ2xlIGZpcnN0IHRhYlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOZWVkIHRvIHJlY3JlYXRlIHRoZSBja2VkaXRvciBpbnN0YW5jZSBldmVyeSB0aW1lIHRoZSBtb2RhbCBhcHBlYXJzLlxuICAgICAgICBpZiAoJG1vZGFsLmZpbmQoJyNjb250ZW50LWh0bWwnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZiAoQ0tFRElUT1IuaW5zdGFuY2VzWydjb250ZW50LWh0bWwnXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgQ0tFRElUT1IuaW5zdGFuY2VzWydjb250ZW50LWh0bWwnXS5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBDS0VESVRPUi5yZXBsYWNlKCdjb250ZW50LWh0bWwnLCB7XG4gICAgICAgICAgICAgICAgbGFuZ3VhZ2U6IGpzZS5jb3JlLmNvbmZpZy5nZXQoJ2xhbmd1YWdlQ29kZScpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIENLRURJVE9SLmluc3RhbmNlc1snY29udGVudC1odG1sJ10uc2V0RGF0YSgnJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBjb250YWN0IHR5cGUgaGlkZGVuIGlucHV0cyBhcmUgcHJlc2VudCB0aGVuIHdlIGhhdmUgdG8gcmUtYXBwbHkgdGhlaXIgdmFsdWUuXG4gICAgICAgIGlmICgkbW9kYWwuZmluZCgnI3NlbmRlci10eXBlJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJG1vZGFsLmZpbmQoJyNzZW5kZXItdHlwZScpLnZhbCgnc2VuZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCRtb2RhbC5maW5kKCcjcmVjaXBpZW50LXR5cGUnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnI3JlY2lwaWVudC10eXBlJykudmFsKCdyZWNpcGllbnQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoJG1vZGFsLmZpbmQoJyNyZXBseS10by10eXBlJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJG1vZGFsLmZpbmQoJyNyZXBseS10by10eXBlJykudmFsKCdyZXBseV90bycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIFRhYiBDb3VudGVyc1xuICAgICAgICBqc2UubGlicy5lbWFpbHMudXBkYXRlVGFiQ291bnRlcnMoJG1vZGFsKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZW1haWwgaW5mb3JtYXRpb24gZnJvbSBtb2RhbCAoRE9NKS5cbiAgICAgKlxuICAgICAqIFRoZSBtZXRob2Qgd2lsbCBncmFiIHRoZSB2YWx1ZXMgZnJvbSB0aGUgbW9kYWwgYW5kIGJ1bmRsZSB0aGVtIGluIGEgc2luZ2xlIG9iamVjdC5cbiAgICAgKiBUaGUgcmV0dXJuZWQgb2JqZWN0IHdpbGwgaGF2ZSB0aGUgc2FtZSBzdHJ1Y3R1cmUgYXMgdGhlIHZhbHVlTWFwcGluZyBvYmplY3QuIFRoaXNcbiAgICAgKiBtZXRob2QgaXMgcmVjdXJzaXZlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9ICRtb2RhbCBqUXVlcnkgc2VsZWN0b3IgZm9yIHRoZSBtb2RhbC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJucyB0aGUgZW1haWwgZGF0YSBvZiB0aGUgbW9kYWwuXG4gICAgICovXG4gICAgZXhwb3J0cy5nZXRFbWFpbEZyb21Nb2RhbCA9IGZ1bmN0aW9uICgkbW9kYWwpIHtcbiAgICAgICAgdmFyIGVtYWlsID0ge307XG5cbiAgICAgICAgLy8gUmVxdWlyZWQgRW1haWwgRmllbGRzXG4gICAgICAgIGVtYWlsLnNlbmRlciA9IHtcbiAgICAgICAgICAgIGVtYWlsX2FkZHJlc3M6ICRtb2RhbC5maW5kKCcjc2VuZGVyLWVtYWlsJykudmFsKCksXG4gICAgICAgICAgICBjb250YWN0X25hbWU6ICRtb2RhbC5maW5kKCcjc2VuZGVyLW5hbWUnKS52YWwoKSxcbiAgICAgICAgICAgIGNvbnRhY3RfdHlwZTogZXhwb3J0cy5DT05UQUNUX1RZUEVfU0VOREVSXG4gICAgICAgIH07XG5cbiAgICAgICAgZW1haWwucmVjaXBpZW50ID0ge1xuICAgICAgICAgICAgZW1haWxfYWRkcmVzczogJG1vZGFsLmZpbmQoJyNyZWNpcGllbnQtZW1haWwnKS52YWwoKSxcbiAgICAgICAgICAgIGNvbnRhY3RfbmFtZTogJG1vZGFsLmZpbmQoJyNyZWNpcGllbnQtbmFtZScpLnZhbCgpLFxuICAgICAgICAgICAgY29udGFjdF90eXBlOiBleHBvcnRzLkNPTlRBQ1RfVFlQRV9SRUNJUElFTlRcbiAgICAgICAgfTtcblxuICAgICAgICBlbWFpbC5zdWJqZWN0ID0gJG1vZGFsLmZpbmQoJyNzdWJqZWN0JykudmFsKCk7XG4gICAgICAgIGVtYWlsLmNvbnRlbnRfaHRtbCA9IENLRURJVE9SLmluc3RhbmNlc1snY29udGVudC1odG1sJ10uZ2V0RGF0YSgpO1xuXG4gICAgICAgIC8vIE9wdGlvbmFsIEVtYWlsIGZpZWxkc1xuICAgICAgICBlbWFpbC5lbWFpbF9pZCA9ICgkbW9kYWwuZmluZCgnI2VtYWlsLWlkJykudmFsKCkgIT09ICcnKSA/ICRtb2RhbC5maW5kKCcjZW1haWwtaWQnKS52YWwoKSA6XG4gICAgICAgICAgICBudWxsO1xuICAgICAgICBlbWFpbC5pc19wZW5kaW5nID0gKCRtb2RhbC5maW5kKCcjaXMtcGVuZGluZycpLnZhbCgpID09PSAndHJ1ZScpO1xuICAgICAgICBlbWFpbC5jb250ZW50X3BsYWluID0gKCRtb2RhbC5maW5kKCcjY29udGVudC1wbGFpbicpLnZhbCgpICE9PSAnJykgPyAkbW9kYWwuZmluZChcbiAgICAgICAgICAgICcjY29udGVudC1wbGFpbicpLnZhbCgpIDogbnVsbDtcblxuICAgICAgICBlbWFpbC5yZXBseV90byA9ICgkbW9kYWwuZmluZCgnI3JlcGx5LXRvLWVtYWlsJykudmFsKCkgIT09ICcnKSA/IHt9IDogbnVsbDtcbiAgICAgICAgaWYgKGVtYWlsLnJlcGx5X3RvKSB7XG4gICAgICAgICAgICBlbWFpbC5yZXBseV90by5lbWFpbF9hZGRyZXNzID0gJG1vZGFsLmZpbmQoJyNyZXBseS10by1lbWFpbCcpLnZhbCgpO1xuICAgICAgICAgICAgZW1haWwucmVwbHlfdG8uY29udGFjdF9uYW1lID0gJG1vZGFsLmZpbmQoJyNyZXBseS10by1uYW1lJykudmFsKCk7XG4gICAgICAgICAgICBlbWFpbC5yZXBseV90by5jb250YWN0X3R5cGUgPSBleHBvcnRzLkNPTlRBQ1RfVFlQRV9SRVBMWV9UTztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJDQyAmIENDIENvbnRhY3RzXG4gICAgICAgIGVtYWlsLmJjYyA9IG51bGw7XG4gICAgICAgIGVtYWlsLmNjID0gbnVsbDtcbiAgICAgICAgdmFyIGNvbnRhY3RzID0gJG1vZGFsLmZpbmQoJyNjb250YWN0cy10YWJsZScpLkRhdGFUYWJsZSgpLnJvd3MoKS5kYXRhKCk7XG5cbiAgICAgICAgJC5lYWNoKGNvbnRhY3RzLCBmdW5jdGlvbiAoaW5kZXgsIGNvbnRhY3QpIHtcbiAgICAgICAgICAgIGlmIChlbWFpbFtjb250YWN0LnR5cGVdID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBlbWFpbFtjb250YWN0LnR5cGVdID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGVtYWlsW2NvbnRhY3QudHlwZV0ucHVzaCh7XG4gICAgICAgICAgICAgICAgZW1haWxfYWRkcmVzczogY29udGFjdC5lbWFpbCxcbiAgICAgICAgICAgICAgICBjb250YWN0X25hbWU6IGNvbnRhY3QubmFtZSxcbiAgICAgICAgICAgICAgICBjb250YWN0X3R5cGU6IGNvbnRhY3QudHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaG1lbnRzXG4gICAgICAgIGVtYWlsLmF0dGFjaG1lbnRzID0gbnVsbDtcbiAgICAgICAgdmFyIGF0dGFjaG1lbnRzID0gJG1vZGFsLmZpbmQoJyNhdHRhY2htZW50cy10YWJsZScpLkRhdGFUYWJsZSgpLnJvd3MoKS5kYXRhKCk7XG4gICAgICAgICQuZWFjaChhdHRhY2htZW50cywgZnVuY3Rpb24gKGluZGV4LCBhdHRhY2htZW50KSB7XG4gICAgICAgICAgICBpZiAoZW1haWwuYXR0YWNobWVudHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBlbWFpbC5hdHRhY2htZW50cyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZW1haWwuYXR0YWNobWVudHMucHVzaChhdHRhY2htZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGVtYWlsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2FkcyBlbWFpbCBkYXRhIG9uIG1vZGFsIChET00pLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGVtYWlsIENvbnRhaW5zIHRoZSBlbWFpbCBkYXRhLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSAkbW9kYWwgalF1ZXJ5IHNlbGVjdG9yIGZvciB0aGUgbW9kYWwuXG4gICAgICovXG4gICAgZXhwb3J0cy5sb2FkRW1haWxPbk1vZGFsID0gZnVuY3Rpb24gKGVtYWlsLCAkbW9kYWwpIHtcbiAgICAgICAgLy8gUmVxdWlyZWQgRW1haWwgRmllbGRzXG4gICAgICAgICRtb2RhbC5maW5kKCcjc2VuZGVyLWVtYWlsJykudmFsKGVtYWlsLnNlbmRlci5lbWFpbF9hZGRyZXNzKTtcbiAgICAgICAgJG1vZGFsLmZpbmQoJyNzZW5kZXItbmFtZScpLnZhbChlbWFpbC5zZW5kZXIuY29udGFjdF9uYW1lKTtcblxuICAgICAgICAkbW9kYWwuZmluZCgnI3JlY2lwaWVudC1lbWFpbCcpLnZhbChlbWFpbC5yZWNpcGllbnQuZW1haWxfYWRkcmVzcyk7XG4gICAgICAgICRtb2RhbC5maW5kKCcjcmVjaXBpZW50LW5hbWUnKS52YWwoZW1haWwucmVjaXBpZW50LmNvbnRhY3RfbmFtZSk7XG5cbiAgICAgICAgJG1vZGFsLmZpbmQoJyNzdWJqZWN0JykudmFsKGVtYWlsLnN1YmplY3QpO1xuICAgICAgICBDS0VESVRPUi5pbnN0YW5jZXNbJ2NvbnRlbnQtaHRtbCddLnNldERhdGEoZW1haWwuY29udGVudF9odG1sKTtcblxuICAgICAgICAkbW9kYWwuZmluZCgnI2lzLXBlbmRpbmcnKS52YWwoKGVtYWlsLmlzX3BlbmRpbmcpID8gJ3RydWUnIDogJ2ZhbHNlJyk7XG5cbiAgICAgICAgLy8gT3B0aW9uYWwgRW1haWwgRmllbGRzXG5cbiAgICAgICAgaWYgKGVtYWlsLmVtYWlsX2lkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnI2VtYWlsLWlkJykudmFsKGVtYWlsLmVtYWlsX2lkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbWFpbC5jcmVhdGlvbl9kYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnI2NyZWF0aW9uLWRhdGUnKS52YWwoZW1haWwuY3JlYXRpb25fZGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW1haWwuc2VudF9kYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnI3NlbnQtZGF0ZScpLnZhbChlbWFpbC5zZW50X2RhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVtYWlsLnJlcGx5X3RvICE9PSBudWxsKSB7XG4gICAgICAgICAgICAkbW9kYWwuZmluZCgnI3JlcGx5LXRvLWVtYWlsJykudmFsKGVtYWlsLnJlcGx5X3RvLmVtYWlsX2FkZHJlc3MpO1xuICAgICAgICAgICAgJG1vZGFsLmZpbmQoJyNyZXBseS10by1uYW1lJykudmFsKGVtYWlsLnJlcGx5X3RvLmNvbnRhY3RfbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW1haWwuY29udGVudF9wbGFpbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgJG1vZGFsLmZpbmQoJyNjb250ZW50LXBsYWluJykudmFsKGVtYWlsLmNvbnRlbnRfcGxhaW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVtYWlsLmJjYyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgJC5lYWNoKGVtYWlsLmJjYywgZnVuY3Rpb24gKGluZGV4LCBjb250YWN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHJvdyA9IHtcbiAgICAgICAgICAgICAgICAgICAgZW1haWw6IGpzZS5saWJzLm5vcm1hbGl6ZS5lc2NhcGVIdG1sKGNvbnRhY3QuZW1haWxfYWRkcmVzcyksXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGpzZS5saWJzLm5vcm1hbGl6ZS5lc2NhcGVIdG1sKGNvbnRhY3QuY29udGFjdF9uYW1lKSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZToganNlLmxpYnMubm9ybWFsaXplLmVzY2FwZUh0bWwoY29udGFjdC5jb250YWN0X3R5cGUpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAkbW9kYWwuZmluZCgnI2NvbnRhY3RzLXRhYmxlJykuRGF0YVRhYmxlKCkucm93LmFkZChyb3cpLmRyYXcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVtYWlsLmNjICE9PSBudWxsKSB7XG4gICAgICAgICAgICAkLmVhY2goZW1haWwuY2MsIGZ1bmN0aW9uIChpbmRleCwgY29udGFjdCkge1xuICAgICAgICAgICAgICAgIHZhciByb3cgPSB7XG4gICAgICAgICAgICAgICAgICAgIGVtYWlsOiBqc2UubGlicy5ub3JtYWxpemUuZXNjYXBlSHRtbChjb250YWN0LmVtYWlsX2FkZHJlc3MpLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBqc2UubGlicy5ub3JtYWxpemUuZXNjYXBlSHRtbChjb250YWN0LmNvbnRhY3RfbmFtZSksXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IGpzZS5saWJzLm5vcm1hbGl6ZS5lc2NhcGVIdG1sKGNvbnRhY3QuY29udGFjdF90eXBlKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgJG1vZGFsLmZpbmQoJyNjb250YWN0cy10YWJsZScpLkRhdGFUYWJsZSgpLnJvdy5hZGQocm93KS5kcmF3KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbWFpbC5hdHRhY2htZW50cyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgJC5lYWNoKGVtYWlsLmF0dGFjaG1lbnRzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dGFjaG1lbnQpIHtcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50LnBhdGggPSBqc2UubGlicy5ub3JtYWxpemUuZXNjYXBlSHRtbChhdHRhY2htZW50LnBhdGgpO1xuICAgICAgICAgICAgICAgICRtb2RhbC5maW5kKCcjYXR0YWNobWVudHMtdGFibGUnKS5EYXRhVGFibGUoKS5yb3cuYWRkKGF0dGFjaG1lbnQpLmRyYXcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIFRhYiBDb3VudGVyc1xuICAgICAgICBqc2UubGlicy5lbWFpbHMudXBkYXRlVGFiQ291bnRlcnMoJG1vZGFsKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYW4gZW1haWwgY29sbGVjdGlvblxuICAgICAqXG4gICAgICogUHJvdmlkZSBhbiBhcnJheSBvZiBlbWFpbCBvYmplY3RzIGFuZCB0aGlzIG1ldGhvZCB3aWxsIHNlbmQgdGhlbSB0byB0aGUgcmVxdWVzdGVkXG4gICAgICogVVJMIHRocm91Z2ggQUpBWCBQT1NULiBZb3UgY2FuIG9taXQgdGhlIHVybCBhbmQgdGhlIGRlZmF1bHQgRW1haWxzQ29udHJvbGxlciB3aWxsXG4gICAgICogYmUgdXNlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YXJyYXl9IGNvbGxlY3Rpb24gQXJyYXkgb2YgZW1haWwgb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWpheFVybCAob3B0aW9uYWwpIFRoZSBBSkFYIFVSTCBmb3IgdGhlIFBPU1QgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJucyBhIHByb21pc2Ugb2JqZWN0IHRoYXQgd2lsbCBwcm92aWRlIHRoZSBzZXJ2ZXIncyByZXNwb25zZS5cbiAgICAgKi9cbiAgICBleHBvcnRzLnNlbmRDb2xsZWN0aW9uID0gZnVuY3Rpb24gKGNvbGxlY3Rpb24sIGFqYXhVcmwpIHtcbiAgICAgICAgYWpheFVybCA9IGFqYXhVcmwgfHwganNlLmNvcmUuY29uZmlnLmdldCgnYXBwVXJsJykgKyAnL2FkbWluL2FkbWluLnBocD9kbz1FbWFpbHMvU2VuZCc7XG5cbiAgICAgICAgdmFyIGRlZmVycmVkID0gJC5EZWZlcnJlZCgpLFxuICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBwYWdlVG9rZW46IGpzZS5jb3JlLmNvbmZpZy5nZXQoJ3BhZ2VUb2tlbicpLFxuICAgICAgICAgICAgICAgIGNvbGxlY3Rpb246IGNvbGxlY3Rpb25cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgJC5wb3N0KGFqYXhVcmwsIGRhdGEsIGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICAgIH0sICdqc29uJyk7XG5cbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUXVldWVzIHRoZSBlbWFpbCBjb2xsZWN0aW9uXG4gICAgICpcbiAgICAgKiBQcm92aWRlIGFuIGFycmF5IG9mIGVtYWlsIG9iamVjdHMgYW5kIHRoaXMgbWV0aG9kIHdpbGwgcXVldWUgdGhlbSB0byB0aGUgcmVxdWVzdGVkXG4gICAgICogVVJMIHRocm91Z2ggQUpBWCBQT1NULiBZb3UgY2FuIG9taXQgdGhlIHVybCBhbmQgdGhlIGRlZmF1bHQgRW1haWxzQ29udHJvbGxlciB3aWxsXG4gICAgICogYmUgdXNlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YXJyYXl9IGNvbGxlY3Rpb24gQXJyYXkgb2YgZW1haWwgb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWpheFVybCAob3B0aW9uYWwpIFRoZSBBSkFYIFVSTCBmb3IgdGhlIFBPU1QgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJucyBhIHByb21pc2Ugb2JqZWN0IHRoYXQgd2lsbCBwcm92aWRlIHRoZSBzZXJ2ZXIncyByZXNwb25zZS5cbiAgICAgKi9cbiAgICBleHBvcnRzLnF1ZXVlQ29sbGVjdGlvbiA9IGZ1bmN0aW9uIChjb2xsZWN0aW9uLCBhamF4VXJsKSB7XG4gICAgICAgIGFqYXhVcmwgPSBhamF4VXJsIHx8IGpzZS5jb3JlLmNvbmZpZy5nZXQoJ2FwcFVybCcpICsgJy9hZG1pbi9hZG1pbi5waHA/ZG89RW1haWxzL1F1ZXVlJztcblxuICAgICAgICB2YXIgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCksXG4gICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgIHBhZ2VUb2tlbjoganNlLmNvcmUuY29uZmlnLmdldCgncGFnZVRva2VuJyksXG4gICAgICAgICAgICAgICAgY29sbGVjdGlvbjogY29sbGVjdGlvblxuICAgICAgICAgICAgfTtcblxuICAgICAgICAkLnBvc3QoYWpheFVybCwgZGF0YSwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgfSwgJ2pzb24nKTtcblxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGFuIGVtYWlsIGNvbGxlY3Rpb25cbiAgICAgKlxuICAgICAqIFByb3ZpZGUgYW4gYXJyYXkgb2YgZW1haWwgb2JqZWN0cyBhbmQgdGhpcyBtZXRob2Qgd2lsbCBkZWxldGUgdGhlbSB0byB0aGUgcmVxdWVzdGVkXG4gICAgICogVVJMIHRocm91Z2ggQUpBWCBQT1NULiBZb3UgY2FuIG9taXQgdGhlIHVybCBhbmQgdGhlIGRlZmF1bHQgRW1haWxzQ29udHJvbGxlciB3aWxsXG4gICAgICogYmUgdXNlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YXJyYXl9IGNvbGxlY3Rpb24gQXJyYXkgb2YgZW1haWwgb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWpheFVybCAob3B0aW9uYWwpIFRoZSBBSkFYIFVSTCBmb3IgdGhlIFBPU1QgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJucyBhIHByb21pc2Ugb2JqZWN0IHRoYXQgd2lsbCBwcm92aWRlIHRoZSBzZXJ2ZXIncyByZXNwb25zZS5cbiAgICAgKi9cbiAgICBleHBvcnRzLmRlbGV0ZUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAoY29sbGVjdGlvbiwgYWpheFVybCkge1xuICAgICAgICBhamF4VXJsID0gYWpheFVybCB8fCBqc2UuY29yZS5jb25maWcuZ2V0KCdhcHBVcmwnKSArICcvYWRtaW4vYWRtaW4ucGhwP2RvPUVtYWlscy9EZWxldGUnO1xuXG4gICAgICAgIHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKSxcbiAgICAgICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgICAgICAgcGFnZVRva2VuOiBqc2UuY29yZS5jb25maWcuZ2V0KCdwYWdlVG9rZW4nKSxcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uOiBjb2xsZWN0aW9uXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICQucG9zdChhamF4VXJsLCBkYXRhLCBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5leGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICB9LCAnanNvbicpO1xuXG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgZGVmYXVsdCBtb2RhbCBidXR0b25zXG4gICAgICpcbiAgICAgKiBVc2VkIGJ5IHZhcmlvdXMgc2VjdGlvbnMgb2YgdGhlIGFkbWluL2VtYWlscyBwYWdlLiBXaXRoIHRoZSBwcm9wZXIgdXNlIG9mIHZhbHVlTWFwcGluZyBvYmplY3RcbiAgICAgKiB5b3UgY2FuIHVzZSB0aGlzIG1ldGhvZCBpbiBvdGhlciBwYWdlcyB0b28uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gJG1vZGFsIGpRdWVyeSBzZWxlY3RvciBmb3IgdGhlIG1vZGFsLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSAkdGFibGUgalF1ZXJ5IHNlbGVjdG9yIGZvciB0aGUgbWFpbiB0YWJsZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJucyB0aGUgZGlhbG9nIG1vZGFsIGJ1dHRvbnMuXG4gICAgICovXG4gICAgZXhwb3J0cy5nZXREZWZhdWx0TW9kYWxCdXR0b25zID0gZnVuY3Rpb24gKCRtb2RhbCwgJHRhYmxlKSB7XG4gICAgICAgIHZhciBidXR0b25zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRleHQ6IGpzZS5jb3JlLmxhbmcudHJhbnNsYXRlKCdjbG9zZScsICdidXR0b25zJyksXG4gICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5kaWFsb2coJ2Nsb3NlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgncXVldWUnLCAnYnV0dG9ucycpLFxuICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICRtb2RhbC5maW5kKCcudGFiLWNvbnRlbnQuZGV0YWlscycpLnRyaWdnZXIoJ3ZhbGlkYXRvci52YWxpZGF0ZScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJG1vZGFsLmZpbmQoJy50YWItY29udGVudC5kZXRhaWxzIC5lcnJvcicpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgLy8gVGhlcmUgYXJlIGZpZWxkcyB3aXRoIGVycm9ycy5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgZW1haWwgPSBqc2UubGlicy5lbWFpbHMuZ2V0RW1haWxGcm9tTW9kYWwoJG1vZGFsKTtcbiAgICAgICAgICAgICAgICAgICAganNlLmxpYnMuZW1haWxzLnF1ZXVlQ29sbGVjdGlvbihbZW1haWxdKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmRvbmUoZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRhYmxlLkRhdGFUYWJsZSgpLmFqYXgucmVsb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMuZW1haWxzLmdldEF0dGFjaG1lbnRzU2l6ZSgkKCcjYXR0YWNobWVudHMtc2l6ZScpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAuZmFpbChmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc2UubGlicy5tb2RhbC5tZXNzYWdlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGpzZS5jb3JlLmxhbmcudHJhbnNsYXRlKCdlcnJvcicsICdtZXNzYWdlcycpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiByZXNwb25zZS5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5kaWFsb2coJ2Nsb3NlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnc2VuZCcsICdidXR0b25zJyksXG4gICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgJG1vZGFsLmZpbmQoJy50YWItY29udGVudC5kZXRhaWxzJykudHJpZ2dlcigndmFsaWRhdG9yLnZhbGlkYXRlJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICgkbW9kYWwuZmluZCgnLnRhYi1jb250ZW50LmRldGFpbHMgLmVycm9yJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBUaGVyZSBhcmUgZmllbGRzIHdpdGggZXJyb3JzLlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciBlbWFpbCA9IGpzZS5saWJzLmVtYWlscy5nZXRFbWFpbEZyb21Nb2RhbCgkbW9kYWwpO1xuICAgICAgICAgICAgICAgICAgICBqc2UubGlicy5lbWFpbHMuc2VuZENvbGxlY3Rpb24oW2VtYWlsXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YWJsZS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLmVtYWlscy5nZXRBdHRhY2htZW50c1NpemUoJCgnI2F0dGFjaG1lbnRzLXNpemUnKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZhaWwoZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMubW9kYWwubWVzc2FnZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnZXJyb3InLCAnbWVzc2FnZXMnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVzcG9uc2UubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykuZGlhbG9nKCdjbG9zZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgXTtcblxuICAgICAgICByZXR1cm4gYnV0dG9ucztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBwcmV2aWV3IG1vZGFsIGJ1dHRvbnNcbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBwcmV2aWV3IG1vZGFsIGJ1dHRvbnMgZm9yIHRoZSBqUXVlcnkgVUkgZGlhbG9nIHdpZGdldC4gV2l0aCB0aGUgcHJvcGVyXG4gICAgICogdXNlIG9mIHZhbHVlTWFwcGluZyBvYmplY3QgeW91IGNhbiB1c2UgdGhpcyBtZXRob2QgaW4gb3RoZXIgcGFnZXMgdG9vLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9ICRtb2RhbCBqUXVlcnkgc2VsZWN0b3IgZm9yIHRoZSBtb2RhbC5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gJHRhYmxlIGpRdWVyeSBzZWxlY3RvciBmb3IgdGhlIG1haW4gdGFibGUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IFJldHVybnMgdGhlIGRpYWxvZyBtb2RhbCBidXR0b25zLlxuICAgICAqL1xuICAgIGV4cG9ydHMuZ2V0UHJldmlld01vZGFsQnV0dG9ucyA9IGZ1bmN0aW9uICgkbW9kYWwsICR0YWJsZSkge1xuICAgICAgICB2YXIgYnV0dG9ucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnY2xvc2UnLCAnYnV0dG9ucycpLFxuICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykuZGlhbG9nKCdjbG9zZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGV4dDoganNlLmNvcmUubGFuZy50cmFuc2xhdGUoJ2RlbGV0ZScsICdidXR0b25zJyksXG4gICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vZGFsT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnRGVsZXRlIEVtYWlsIFJlY29yZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiAnQXJlIHlvdSBzdXJlIHRoYXQgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgZW1haWwgcmVjb3JkPycsXG4gICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgneWVzJywgJ2xpZ2h0Ym94X2J1dHRvbnMnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbWFpbCA9IGpzZS5saWJzLmVtYWlscy5nZXRFbWFpbEZyb21Nb2RhbCgkbW9kYWwpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc2UubGlicy5lbWFpbHMuZGVsZXRlQ29sbGVjdGlvbihbZW1haWxdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGFibGUuRGF0YVRhYmxlKCkuYWpheC5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMuZW1haWxzLmdldEF0dGFjaG1lbnRzU2l6ZSgkKCcjYXR0YWNobWVudHMtc2l6ZScpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5mYWlsKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc2UubGlicy5tb2RhbC5tZXNzYWdlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtZXNzYWdlcycpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVzcG9uc2UubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuZGlhbG9nKCdjbG9zZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1vZGFsLmRpYWxvZygnY2xvc2UnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnbm8nLCAnbGlnaHRib3hfYnV0dG9ucycpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGljazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5kaWFsb2coJ2Nsb3NlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAganNlLmxpYnMubW9kYWwubWVzc2FnZShtb2RhbE9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGV4dDoganNlLmNvcmUubGFuZy50cmFuc2xhdGUoJ3F1ZXVlJywgJ2J1dHRvbnMnKSxcbiAgICAgICAgICAgICAgICBjbGljazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZW1haWwgPSBqc2UubGlicy5lbWFpbHMuZ2V0RW1haWxGcm9tTW9kYWwoJG1vZGFsKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBEdXBsaWNhdGUgcmVjb3JkIG9ubHkgaWYgdGhlIG9yaWdpbmFsIG9uZSBpcyBhbHJlYWR5IHNlbnQuXG4gICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSB3ZSBqdXN0IG5lZWQgdG8gdXBkYXRlIHRoZSBkYXRhIG9mIHRoZSBjdXJyZW50IGVtYWlsIHJlY29yZC5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbWFpbC5pc19wZW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZW1haWwuZW1haWxfaWQ7IC8vIHdpbGwgZHVwbGljYXRlIHRoZSByZWNvcmRcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLmVtYWlscy5xdWV1ZUNvbGxlY3Rpb24oW2VtYWlsXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YWJsZS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLmVtYWlscy5nZXRBdHRhY2htZW50c1NpemUoJCgnI2F0dGFjaG1lbnRzLXNpemUnKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZhaWwoZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMubW9kYWwubWVzc2FnZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnZXJyb3InLCAnbWVzc2FnZXMnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVzcG9uc2UubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykuZGlhbG9nKCdjbG9zZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGV4dDoganNlLmNvcmUubGFuZy50cmFuc2xhdGUoJ3NlbmQnLCAnYnV0dG9ucycpLFxuICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlbWFpbCA9IGpzZS5saWJzLmVtYWlscy5nZXRFbWFpbEZyb21Nb2RhbCgkbW9kYWwpO1xuICAgICAgICAgICAgICAgICAgICBqc2UubGlicy5lbWFpbHMuc2VuZENvbGxlY3Rpb24oW2VtYWlsXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YWJsZS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLmVtYWlscy5nZXRBdHRhY2htZW50c1NpemUoJCgnI2F0dGFjaG1lbnRzLXNpemUnKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZhaWwoZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMubW9kYWwubWVzc2FnZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnZXJyb3InLCAnbWVzc2FnZXMnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVzcG9uc2UubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykuZGlhbG9nKCdjbG9zZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgXTtcblxuICAgICAgICByZXR1cm4gYnV0dG9ucztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29sb3JpemVzIG1vZGFsIGJ1dHRvbnMgZm9yIHRoZSBlZGl0IG1vZGVcbiAgICAgKlxuICAgICAqIGpRdWVyeSBVSSBkb2VzIG5vdCBzdXBwb3J0IGRpcmVjdCBhZGRpdGlvbiBvZiBjbGFzc2VzIHRvIHRoZSBkaWFsb2cgYnV0dG9ucyxcbiAgICAgKiBzbyB3ZSBuZWVkIHRvIGFwcGx5IHRoZSBjbGFzc2VzIGR1cmluZyB0aGUgXCJjcmVhdGVcIiBldmVudCBvZiB0aGUgZGlhbG9nLlxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50IHtldmVudH0gRXZlbnQgdG8gdHJpZ2dlciB0aGlzIGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB1aSB7b2JqZWN0fSBEaWFsb2cgVUkuXG4gICAgICovXG4gICAgZXhwb3J0cy5jb2xvcml6ZUJ1dHRvbnNGb3JFZGl0TW9kZSA9IGZ1bmN0aW9uIChldmVudCwgdWkpIHtcbiAgICAgICAgJCh0aGlzKS5jbG9zZXN0KCcudWktZGlhbG9nJykuZmluZCgnLnVpLWJ1dHRvbicpLmVxKDMpLmFkZENsYXNzKCdidG4tcHJpbWFyeScpOyAvLyBTZW5kIEJ1dHRvblxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb2xvcml6ZXMgbW9kYWwgYnV0dG9ucyBmb3IgcHJldmlldyBtb2RlXG4gICAgICpcbiAgICAgKiBqUXVlcnkgVUkgZG9lcyBub3Qgc3VwcG9ydCBkaXJlY3QgYWRkaXRpb24gb2YgY2xhc3NlcyB0byB0aGUgZGlhbG9nIGJ1dHRvbnMsXG4gICAgICogc28gd2UgbmVlZCB0byBhcHBseSB0aGUgY2xhc3NlcyBkdXJpbmcgdGhlIFwiY3JlYXRlXCIgZXZlbnQgb2YgdGhlIGRpYWxvZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBldmVudCB7b2JqZWN0fSBFdmVudCB0byB0cmlnZ2VyIHRoaXMgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHVpIHtvYmplY3R9IERpYWxvZyBVSS5cbiAgICAgKi9cbiAgICBleHBvcnRzLmNvbG9yaXplQnV0dG9uc0ZvclByZXZpZXdNb2RlID0gZnVuY3Rpb24gKGV2ZW50LCB1aSkge1xuICAgICAgICAkKHRoaXMpLmNsb3Nlc3QoJy51aS1kaWFsb2cnKS5maW5kKCcudWktYnV0dG9uJykuZXEoNCkuYWRkQ2xhc3MoJ2J0bi1wcmltYXJ5Jyk7IC8vIFNlbmQgQnV0dG9uXG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlbGV0ZXMgb2xkIGF0dGFjaG1lbnRzIGZyb20gc2VsZWN0ZWQgcmVtb3ZhbCBkYXRlIGFuZCBiZWZvcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2RhdGV9IHJlbW92YWxEYXRlIFRoZSBkYXRlIHdoZW4gdGhlIHJlbW92YWwgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBhamF4VXJsIChvcHRpb25hbCkgU3BlY2lmaWMgYWpheFVybCB0byBiZSB1c2VkIGZvciB0aGUgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSBSZXR1cm5zIGEgcHJvbWlzZSBvYmplY3QgdG8gYmUgdXNlZCB3aGVuIHRoZSByZXF1ZXN0cyBlbmRzLlxuICAgICAqL1xuICAgIGV4cG9ydHMuZGVsZXRlT2xkQXR0YWNobWVudHMgPSBmdW5jdGlvbiAocmVtb3ZhbERhdGUsIGFqYXhVcmwpIHtcbiAgICAgICAgYWpheFVybCA9IGFqYXhVcmwgfHwganNlLmNvcmUuY29uZmlnLmdldCgnYXBwVXJsJykgKyAnL2FkbWluL2FkbWluLnBocD9kbz1FbWFpbHMvRGVsZXRlT2xkQXR0YWNobWVudHMnO1xuXG4gICAgICAgIHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKSxcbiAgICAgICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgICAgICAgcGFnZVRva2VuOiBqc2UuY29yZS5jb25maWcuZ2V0KCdwYWdlVG9rZW4nKSxcbiAgICAgICAgICAgICAgICByZW1vdmFsRGF0ZTogcmVtb3ZhbERhdGVcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgJC5wb3N0KGFqYXhVcmwsIGRhdGEsIGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICAgIH0sICdqc29uJyk7XG5cbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBvbGQgZW1haWxzIGZyb20gc2VsZWN0ZWQgcmVtb3ZhbCBkYXRlIGFuZCBiZWZvcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcmVtb3ZhbERhdGUgVGhlIGRhdGUgd2hlbiB0aGUgcmVtb3ZhbCBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGFqYXhVcmwgKG9wdGlvbmFsKSBTcGVjaWZpYyBhamF4VXJsIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IFJldHVybnMgYSBwcm9taXNlIG9iamVjdCB0byBiZSB1c2VkIHdoZW4gdGhlIHJlcXVlc3RzIGVuZHMuXG4gICAgICovXG4gICAgZXhwb3J0cy5kZWxldGVPbGRFbWFpbHMgPSBmdW5jdGlvbiAocmVtb3ZhbERhdGUsIGFqYXhVcmwpIHtcbiAgICAgICAgYWpheFVybCA9IGFqYXhVcmwgfHwganNlLmNvcmUuY29uZmlnLmdldCgnYXBwVXJsJykgKyAnL2FkbWluL2FkbWluLnBocD9kbz1FbWFpbHMvRGVsZXRlT2xkRW1haWxzJztcblxuICAgICAgICB2YXIgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCksXG4gICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgIHBhZ2VUb2tlbjoganNlLmNvcmUuY29uZmlnLmdldCgncGFnZVRva2VuJyksXG4gICAgICAgICAgICAgICAgcmVtb3ZhbERhdGU6IHJlbW92YWxEYXRlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICQucG9zdChhamF4VXJsLCBkYXRhLCBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5leGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICB9LCAnanNvbicpO1xuXG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGF0dGFjaG1lbnRzIHNpemUgaW4gTUIgYW5kIHJlZnJlc2hlcyB0aGUgVUkuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIG1ha2UgYSBHRVQgcmVxdWVzdCB0byB0aGUgc2VydmVyIGluIG9yZGVyIHRvIGZldGNoIGFuZCBkaXNwbGF5XG4gICAgICogdGhlIHRvdGFsIGF0dGFjaG1lbnRzIHNpemUsIHNvIHRoYXQgdXNlcnMga25vdyB3aGVuIGl0IGlzIHRpbWUgdG8gcmVtb3ZlIG9sZFxuICAgICAqIGF0dGFjaG1lbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9ICR0YXJnZXQgalF1ZXJ5IHNlbGVjdG9yIGZvciB0aGUgZWxlbWVudCB0byBjb250YWluIHRoZSBzaXplIGluZm8uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFqYXhVcmwgKG9wdGlvbmFsKSBTcGVjaWZpYyBhamF4VXJsIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQHJldHVybiB7b2JqZWN0fSBSZXR1cm5zIHRoZSBwcm9taXNlIG9iamVjdCBmb3IgY2hhaW5pbmcgY2FsbGJhY2tzLlxuICAgICAqL1xuICAgIGV4cG9ydHMuZ2V0QXR0YWNobWVudHNTaXplID0gZnVuY3Rpb24gKCR0YXJnZXQsIGFqYXhVcmwpIHtcbiAgICAgICAgYWpheFVybCA9IGFqYXhVcmwgfHwganNlLmNvcmUuY29uZmlnLmdldCgnYXBwVXJsJykgKyAnL2FkbWluL2FkbWluLnBocD9kbz1FbWFpbHMvR2V0QXR0YWNobWVudHNTaXplJztcblxuICAgICAgICB2YXIgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCk7XG5cbiAgICAgICAgJC5nZXQoYWpheFVybCwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAganNlLmxpYnMubW9kYWwubWVzc2FnZSh7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBqc2UuY29yZS5sYW5nLnRyYW5zbGF0ZSgnZXJyb3InLCAnbWVzc2FnZXMnKSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVzcG9uc2UubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc2l6ZSA9IChyZXNwb25zZS5zaXplLm1lZ2FieXRlcyAhPT0gMCkgPyByZXNwb25zZS5zaXplLm1lZ2FieXRlcyArICcgTUInIDogcmVzcG9uc2Uuc2l6ZVxuICAgICAgICAgICAgICAgIC5ieXRlcyArICcgYnl0ZXMnO1xuXG4gICAgICAgICAgICAkdGFyZ2V0LnRleHQoJygnICsgc2l6ZSArICcpJyk7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgfSwgJ2pzb24nKTtcblxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIG1vZGFsIHRhYnMgY291bnRlcnMuXG4gICAgICpcbiAgICAgKiBEaXNwbGF5cyBpdGVtIG51bWJlciBvbiB0YWJzIHNvIHRoYXQgdXNlcnMga25vdyBob3cgbWFueSBpdGVtcyB0aGVyZSBhcmVcbiAgICAgKiBpbmNsdWRlZCBpbiB0aGUgY29udGFjdHMgYW5kIGF0dGFjaG1lbnRzIHRhYmxlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSAkbW9kYWwgVGhlIG1vZGFsIHNlbGVjdG9yIHRvIGJlIHVwZGF0ZWQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9ICRjb250YWN0c1RhYmxlIChvcHRpb25hbCkgVGhlIGNvbnRhY3RzIHRhYmxlIHNlbGVjdG9yLCBkZWZhdWx0IHNlbGVjdG9yOiAnI2NvbnRhY3RzLXRhYmxlJy5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gJGNvbnRhY3RzVGFiIChvcHRpb25hbCkgVGhlIGNvbnRhY3RzIHRhYiBzZWxlY3RvciwgZGVmYXVsdCBzZWxlY3RvcjogJy50YWItaGVhZGxpbmUuYmNjLWNjJy5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gJGF0dGFjaG1lbnRzVGFibGUgKG9wdGlvbmFsKSBUaGUgYXR0YWNobWVudHMgdGFibGUgc2VsZWN0b3IsIGRlZmF1bHRcbiAgICAgKiBzZWxlY3RvcjogJyNhdHRhY2htZW50cy10YWJsZScuXG4gICAgICogQHBhcmFtIHtvYmplY3R9ICRhdHRhY2htZW50c1RhYiAob3B0aW9uYWwpIFRoZSBhdHRhY2htZW50cyB0YWIgc2VsZWN0b3IsIGRlZmF1bHRcbiAgICAgKiBzZWxlY3RvcjogJy50YWItaGVhZGxpbmUuYXR0YWNobWVudHMnLlxuICAgICAqL1xuICAgIGV4cG9ydHMudXBkYXRlVGFiQ291bnRlcnMgPSBmdW5jdGlvbiAoJG1vZGFsLCAkY29udGFjdHNUYWJsZSwgJGNvbnRhY3RzVGFiLCAkYXR0YWNobWVudHNUYWJsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRhdHRhY2htZW50c1RhYikge1xuICAgICAgICAkY29udGFjdHNUYWJsZSA9ICRjb250YWN0c1RhYmxlIHx8ICRtb2RhbC5maW5kKCcjY29udGFjdHMtdGFibGUnKTtcbiAgICAgICAgJGNvbnRhY3RzVGFiID0gJGNvbnRhY3RzVGFiIHx8ICRtb2RhbC5maW5kKCcudGFiLWhlYWRsaW5lLmJjYy1jYycpO1xuICAgICAgICAkYXR0YWNobWVudHNUYWJsZSA9ICRhdHRhY2htZW50c1RhYmxlIHx8ICRtb2RhbC5maW5kKCcjYXR0YWNobWVudHMtdGFibGUnKTtcbiAgICAgICAgJGF0dGFjaG1lbnRzVGFiID0gJGF0dGFjaG1lbnRzVGFiIHx8ICRtb2RhbC5maW5kKCcudGFiLWhlYWRsaW5lLmF0dGFjaG1lbnRzJyk7XG5cbiAgICAgICAgaWYgKCRjb250YWN0c1RhYmxlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuOyAvLyBUaGVyZSBpcyBubyBzdWNoIHRhYmxlIChlbWFpbHMuanMgdW5pdCB0ZXN0aW5nKS5cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb250YWN0c0NvdW50ID0gJGNvbnRhY3RzVGFibGUuRGF0YVRhYmxlKCkucm93cygpLmRhdGEoKS5sZW5ndGgsXG4gICAgICAgICAgICBuZXdDb250YWN0c1RleHQgPSAkY29udGFjdHNUYWIudGV4dCgpLnJlcGxhY2UoL1xcKC4qXFwpL2csICcoJyArIGNvbnRhY3RzQ291bnQgKyAnKScpLFxuICAgICAgICAgICAgYXR0YWNobWVudHNDb3VudCA9ICRhdHRhY2htZW50c1RhYmxlLkRhdGFUYWJsZSgpLnJvd3MoKS5kYXRhKCkubGVuZ3RoLFxuICAgICAgICAgICAgbmV3QXR0YWNobWVudHNUZXh0ID0gJGF0dGFjaG1lbnRzVGFiLnRleHQoKS5yZXBsYWNlKC9cXCguKlxcKS9nLCAnKCcgKyBhdHRhY2htZW50c0NvdW50ICsgJyknKTtcblxuICAgICAgICBpZiAobmV3Q29udGFjdHNUZXh0LmluZGV4T2YoJygnKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIG5ld0NvbnRhY3RzVGV4dCArPSAnICgnICsgY29udGFjdHNDb3VudCArICcpJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuZXdBdHRhY2htZW50c1RleHQuaW5kZXhPZignKCcpID09PSAtMSkge1xuICAgICAgICAgICAgbmV3QXR0YWNobWVudHNUZXh0ICs9ICcgKCcgKyBhdHRhY2htZW50c0NvdW50ICsgJyknO1xuICAgICAgICB9XG5cbiAgICAgICAgJGNvbnRhY3RzVGFiLnRleHQobmV3Q29udGFjdHNUZXh0KTtcbiAgICAgICAgJGF0dGFjaG1lbnRzVGFiLnRleHQobmV3QXR0YWNobWVudHNUZXh0KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBvYmplY3QgYXJyYXkgd2l0aCB0aGUgc2VsZWN0ZWQgZW1haWxzIG9mIHRoZSBtYWluIGVtYWlscyB0YWJsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSAkdGFibGUgKG9wdGlvbmFsKSBUaGUgbWFpbiB0YWJsZSBzZWxlY3RvciwgaWYgb21pdHRlZCB0aGUgXCIjZW1haWxzLXRhYmxlXCIgc2VsZWN0b3JcbiAgICAgKiB3aWxsIGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9IFJldHVybnMgYW4gYXJyYXkgd2l0aCB0aGUgZW1haWxzIGRhdGEgKGNvbGxlY3Rpb24pLlxuICAgICAqL1xuICAgIGV4cG9ydHMuZ2V0U2VsZWN0ZWRFbWFpbHMgPSBmdW5jdGlvbiAoJHRhYmxlKSB7XG4gICAgICAgICR0YWJsZSA9ICR0YWJsZSB8fCAkKCcjZW1haWxzLXRhYmxlJyk7XG5cbiAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBbXTtcblxuICAgICAgICAkdGFibGVcbiAgICAgICAgICAgIC5maW5kKCd0ciB0ZCBpbnB1dDpjaGVja2VkJylcbiAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uIChpbmRleCwgY2hlY2tib3gpIHtcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLnB1c2goJChjaGVja2JveCkucGFyZW50cygndHInKS5kYXRhKCkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgfTtcblxufSkoanNlLmxpYnMuZW1haWxzKTtcbiJdfQ==

Youez - 2016 - github.com/yon3zu
LinuXploit