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/extensions/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

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

/* --------------------------------------------------------------
 table_inline_edit.js 2015-10-16 gm
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2015 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

/**
 * ## Extension for making tables editable.
 *
 * @module Admin/Extensions/table_inline_edit
 * @ignore
 */
gx.extensions.module('table_inline_edit', ['form', 'xhr', 'fallback'], function (data) {

    'use strict';

    // ------------------------------------------------------------------------
    // VARIABLE DEFINITION
    // ------------------------------------------------------------------------

    var
    /**
     * Extension Reference
     *
     * @type {object}
     */
    $this = $(this),


    /**
     * Template Selector
     *
     * @type {object}
     */
    $template = null,


    /**
     * Table Body Selector
     *
     * @type {object}
     */
    $table_body = null,


    /**
     * Default Options for Extension
     *
     * @type {object}
     */
    defaults = {
        'multiEdit': false
    },


    /**
     * Final Extension Options
     *
     * @type {object}
     */
    options = $.extend(true, {}, defaults, data),


    /**
     * Module Object
     *
     * @type {object}
     */
    module = {};

    // ------------------------------------------------------------------------
    // FUNCTIONALITY
    // ------------------------------------------------------------------------

    /**
     * Switch State
     *
     * Function that enables / disables, depending on the mode, all input fields inside
     * the $element and shows / hides the corresponding buttons.
     *
     * @param {string} mode Set the given mode. Possible values: 'edit', 'add', 'default'
     * @param {object} $element The element jQuery selection that gets modified
     * @param {boolean} addClass If true, the state class gets added to the element
     */
    var _switchState = function _switchState(mode, $element, addClass) {

        var $targets = $element.find('input, textarea, select, button, i'),
            $edit = $targets.filter('.editmode'),
            $add = $targets.filter('.addmode'),
            $default = $targets.filter('.defaultmode'),
            $others = $targets.filter(':not(.editmode):not(.addmode):not(.defaultmode)');

        // Hide all buttons
        $edit.hide();
        $add.hide();
        $default.hide();

        // Remove alt-text if available
        $element.find('.table_inlineedit_alt').remove();

        switch (mode) {
            case 'edit':
                // Switch to edit mode
                $edit.show();
                $others.prop('disabled', false);
                break;
            case 'add':
                // Switch to add mode
                $add.show();
                $others.prop('disabled', false);
                break;
            default:
                // Switch to default-mode
                $default.show();
                $others.prop('disabled', true).each(function () {
                    // Check if there is an alt text given for the input field
                    var $self = $(this),
                        dataset = jse.libs.fallback._data($self, 'table_inline_edit');

                    // Replace some kind of form fields with span tags
                    if ($self.attr('type') && $self.attr('type').toLowerCase() === 'checkbox' && dataset.alt) {
                        var values = dataset.alt.split('_'),
                            checked = $self.prop('checked');
                        $self.after('<span class="table_inlineedit_alt">' + (checked ? values[0] : values[1]) + '</span>');
                    } else if ($self.prop('tagName').toLowerCase() === 'select') {
                        var waitUntilValues = function waitUntilValues() {
                            $edit.hide();
                            if (!$self.children().length) {
                                setTimeout(function () {
                                    waitUntilValues();
                                }, 200);
                            } else {
                                $self.children('[value="' + $self.val() + '"]').text();
                                $self.after('<span class="table_inlineedit_alt">' + $self.children('[value="' + $self.val() + '"]').text() + '</span>');
                                return;
                            }
                        };

                        waitUntilValues();
                    }
                });
                break;
        }

        $this.trigger('FORM_UPDATE', []);

        // Add the mode class
        if (addClass) {
            $element.removeClass('edit add default').addClass(mode);
        }
    };

    /**
     * Create New Line
     *
     * Creates a new "add"-line by cloning the footer template.
     */
    var _createNewLine = function _createNewLine() {
        var $newLine = $template.clone();

        $newLine.find('[name]').each(function () {
            var $self = $(this);

            $self.attr('name', $self.attr('name').replace('[]', '[0]'));
        });

        _switchState('add', $newLine, true);
        // Rename the temporarily widget data attributes
        jse.libs.fallback.setupWidgetAttr($newLine);
        $table_body.append($newLine);
        // Start the widgets
        gx.widgets.init($table_body.find('tr').last());
        gx.extensions.init($table_body.find('tr').last());
        gx.controllers.init($table_body.find('tr').last());
        gx.compatibility.init($table_body.find('tr').last());
        jse.widgets.init($table_body.find('tr').last());
        jse.extensions.init($table_body.find('tr').last());
    };

    // ------------------------------------------------------------------------
    // EVENT HANDLERS
    // ------------------------------------------------------------------------

    /**
     * Handler for the "abort"-button
     *
     * @returns {boolean} If function gets called directly, the return value is the state of the abort.
     */
    var _abortHandler = function _abortHandler() {
        var $tr = $(this).closest('tr'),
            cache = JSON.stringify($tr.data('formcache')),
            current = JSON.stringify(jse.libs.form.getData($tr, undefined, true)),
            deferred = $.Deferred();

        /**
         * Helper function to reset a line state
         *
         * @private
         */
        var _resetLine = function _resetLine(e) {
            if (e) {
                $('#lightbox_package_' + e.data.id + 'admin_button').off();
                $('#lightbox_package_' + e.data.id);
                $.lightbox_plugin('close', e.data.id);
            }

            if (e && e.data.reject) {
                deferred.reject();
            } else {
                // Reset the validation state
                $tr.trigger('validator.reset', []);
                // Reset the form data
                jse.libs.form.prefillForm($tr, $tr.data('formcache'), true);
                _switchState('default', $tr, true);
                deferred.resolve();
            }
        };

        // Compare the old with the new data. If changes were made, confirm the abort
        if (cache !== current) {
            var href = 'lightbox_confirm.html?section=shop_offline&amp;' + 'message=dicard_changes_hint&amp;buttons=cancel-discard',
                linkHtml = '<a href="' + href + '"></a>',
                lightboxLink = $(linkHtml),
                lightboxId = lightboxLink.lightbox_plugin({
                'lightbox_width': '360px'
            });

            $('#lightbox_package_' + lightboxId).one('click', '.discard', {
                'reject': false,
                'id': lightboxId
            }, _resetLine).one('click', '.cancel', {
                'reject': true,
                'id': lightboxId
            }, _resetLine);
        } else {
            _resetLine();
        }

        return deferred.promise();
    };

    /**
     * Handler for the "edit"-button
     */
    var _editHandler = function _editHandler() {
        var $tr = $(this).closest('tr'),
            $edited = $this.find('tr.edit'),
            promises = [];

        if (!options.multiEdit && $edited.length) {
            // If multiEdit is disabled and other lines are in edit mode, wait for confirmation
            // of the abort event on the other lines.
            $edited.each(function () {
                promises.push(_abortHandler.call($(this).find('.row_abort').first()));
            });
        }

        $.when.apply(undefined, promises).promise().done(function () {
            // Store the current data of the line in cache
            $tr.data('formcache', jse.libs.form.getData($tr, undefined, true));
            _switchState('edit', $tr, true);
        });
    };

    /**
     * Handler for the "save"-button
     */
    var _saveHandler = function _saveHandler() {
        var $self = $(this),
            $tr = $self.closest('tr'),
            dataset = jse.libs.form.getData($tr, undefined, true),
            url = $self.data().url,
            deferred = $.Deferred();

        // Done callback on validation success
        deferred.done(function () {
            if (url) {
                // If a url is given, post the data against the server
                jse.core.debug.info('Sending data:', dataset);
                jse.libs.xhr.ajax({
                    'url': url,
                    'data': dataset
                });
            }

            $this.trigger('row_saved', [dataset]);
            _switchState('default', $tr, true);
        });

        // Get validation state of the line. On success goto deferred.done callback
        $tr.trigger('validator.validate', [{
            'deferred': deferred
        }]);
    };

    /**
     * Handler for the "delete"-button
     */
    var _deleteHandler = function _deleteHandler() {
        var $self = $(this),
            $tr = $self.closest('tr'),
            dataset = {
            id: $tr.data('id')
        },
            url = $self.data().url,
            html = '<a href="lightbox_confirm.html?section=shop_offline&amp;message=delete_job' + '&amp;buttons=cancel-delete"></a>',
            lightboxLink = $(html),
            lightboxId = lightboxLink.lightbox_plugin({
            'lightbox_width': '360px'
        });

        $('#lightbox_package_' + lightboxId).one('click', '.delete', function () {
            $.lightbox_plugin('close', lightboxId);

            if (url) {
                // If a url is given, post the data against the server
                jse.libs.xhr.ajax({
                    'url': url,
                    'data': dataset
                });
            }

            $this.trigger('row_deleted', [dataset]);
            $tr.remove();
        });
    };

    /**
     * Handler for the 'add'-button
     */
    var _addHandler = function _addHandler() {
        var $self = $(this),
            url = $self.data().url,
            $tr = $self.closest('tr'),
            dataset = jse.libs.form.getData($tr, undefined, true),
            deferred = $.Deferred();

        // Done callback on validation success
        deferred.done(function () {
            var _finalize = function _finalize() {
                // Switch the state of the line and
                // create a new 'add'-line
                $this.trigger('row_added', [dataset]);
                _switchState('default', $tr, true);
                _createNewLine();
            };

            if (url) {
                // If a url is given, post the data against the server
                // The respone of the server contains an id, which will be
                // injected into the field names
                jse.core.debug.info('Sending data:', dataset);
                jse.libs.xhr.ajax({
                    'url': url,
                    'data': dataset
                }).done(function (result) {
                    var id = result.id,
                        $targets = $tr.find('input:not(:button), textarea, select');

                    $targets.each(function () {
                        var $elem = $(this),
                            name = $elem.attr('name').replace('[0]', '[' + id + ']');

                        if ($elem.data().lightboxHref) {
                            $elem.data().lightboxHref = $elem.data().lightboxHref.replace('id=0', 'id=' + id);
                        }
                        $elem.attr('name', name);
                    });

                    $tr.find('[data-lightbox-href]').each(function () {
                        var newLink = $(this).attr('data-lightbox-href').replace('id=0', 'id=' + id);
                        $(this).attr('data-lightbox-href', newLink).data().lightboxHref = newLink;
                    });

                    // Update the hidden editor identifiers with the new record ID.
                    $tr.find('input:hidden').each(function (index, inputHidden) {
                        var $inputHidden = $(inputHidden),
                            name = $inputHidden.attr('name');

                        if (name && name.indexOf('{id}') !== -1) {
                            $inputHidden.attr('name', name.replace('{id}', id));
                        }
                    });

                    _finalize();
                });
            } else {
                _finalize();
            }
        });

        // Get validation state of the line. On success goto deferred.done callback
        $tr.trigger('validator.validate', [{
            'deferred': deferred
        }]);
    };

    /**
     * Handler to update the table state, if an widget inside the table gets initialized
     * (needed to disable the datepicker buttons).
     *
     * @param {object} e    jQuery event-object
     */
    var _initialiedHandler = function _initialiedHandler(e) {
        var inside = $this.filter($(e.target)).add($this.find($(e.target))).length;

        if (!inside) {
            var $tr = $(e.target).closest('tr'),
                type = $tr.hasClass('edit') ? 'edit' : $tr.hasClass('add') ? 'add' : 'default';

            _switchState(type, $tr, true);
        }
    };

    // ------------------------------------------------------------------------
    // INITIALIZATION
    // ------------------------------------------------------------------------

    /**
     * Initialize method of the extension, called by the engine.
     */
    module.init = function (done) {
        $template = $this.find('tfoot > tr');
        $table_body = $this.children('tbody');

        // Add a special class to the table, to style
        // disabled input boxes
        $this.addClass('table_inlineedit');

        // Set the default state for all tr
        _switchState('default', $table_body);
        // Add the "Add"-line to the table
        _createNewLine();

        // Add event listeners for all buttons and
        // a listener for the widget initialized event
        // from widgets inside the table
        $this.on('click', '.row_edit', _editHandler).on('click', '.row_delete', _deleteHandler).on('click', '.row_save', _saveHandler).on('click', '.row_add', _addHandler).on('click', '.row_abort', _abortHandler).on('widget.initialized', _initialiedHandler);

        $('body').on('validator.validate', function (e, d) {
            if (d && d.deferred) {
                // Event listener that performs on every validate trigger that isn't handled by the validator.
                d.deferred.resolve();
            }
        });
        done();
    };

    // Return data to module engine.
    return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRhYmxlX2lubGluZV9lZGl0LmpzIl0sIm5hbWVzIjpbImd4IiwiZXh0ZW5zaW9ucyIsIm1vZHVsZSIsImRhdGEiLCIkdGhpcyIsIiQiLCIkdGVtcGxhdGUiLCIkdGFibGVfYm9keSIsImRlZmF1bHRzIiwib3B0aW9ucyIsImV4dGVuZCIsIl9zd2l0Y2hTdGF0ZSIsIm1vZGUiLCIkZWxlbWVudCIsImFkZENsYXNzIiwiJHRhcmdldHMiLCJmaW5kIiwiJGVkaXQiLCJmaWx0ZXIiLCIkYWRkIiwiJGRlZmF1bHQiLCIkb3RoZXJzIiwiaGlkZSIsInJlbW92ZSIsInNob3ciLCJwcm9wIiwiZWFjaCIsIiRzZWxmIiwiZGF0YXNldCIsImpzZSIsImxpYnMiLCJmYWxsYmFjayIsIl9kYXRhIiwiYXR0ciIsInRvTG93ZXJDYXNlIiwiYWx0IiwidmFsdWVzIiwic3BsaXQiLCJjaGVja2VkIiwiYWZ0ZXIiLCJ3YWl0VW50aWxWYWx1ZXMiLCJjaGlsZHJlbiIsImxlbmd0aCIsInNldFRpbWVvdXQiLCJ2YWwiLCJ0ZXh0IiwidHJpZ2dlciIsInJlbW92ZUNsYXNzIiwiX2NyZWF0ZU5ld0xpbmUiLCIkbmV3TGluZSIsImNsb25lIiwicmVwbGFjZSIsInNldHVwV2lkZ2V0QXR0ciIsImFwcGVuZCIsIndpZGdldHMiLCJpbml0IiwibGFzdCIsImNvbnRyb2xsZXJzIiwiY29tcGF0aWJpbGl0eSIsIl9hYm9ydEhhbmRsZXIiLCIkdHIiLCJjbG9zZXN0IiwiY2FjaGUiLCJKU09OIiwic3RyaW5naWZ5IiwiY3VycmVudCIsImZvcm0iLCJnZXREYXRhIiwidW5kZWZpbmVkIiwiZGVmZXJyZWQiLCJEZWZlcnJlZCIsIl9yZXNldExpbmUiLCJlIiwiaWQiLCJvZmYiLCJsaWdodGJveF9wbHVnaW4iLCJyZWplY3QiLCJwcmVmaWxsRm9ybSIsInJlc29sdmUiLCJocmVmIiwibGlua0h0bWwiLCJsaWdodGJveExpbmsiLCJsaWdodGJveElkIiwib25lIiwicHJvbWlzZSIsIl9lZGl0SGFuZGxlciIsIiRlZGl0ZWQiLCJwcm9taXNlcyIsIm11bHRpRWRpdCIsInB1c2giLCJjYWxsIiwiZmlyc3QiLCJ3aGVuIiwiYXBwbHkiLCJkb25lIiwiX3NhdmVIYW5kbGVyIiwidXJsIiwiY29yZSIsImRlYnVnIiwiaW5mbyIsInhociIsImFqYXgiLCJfZGVsZXRlSGFuZGxlciIsImh0bWwiLCJfYWRkSGFuZGxlciIsIl9maW5hbGl6ZSIsInJlc3VsdCIsIiRlbGVtIiwibmFtZSIsImxpZ2h0Ym94SHJlZiIsIm5ld0xpbmsiLCJpbmRleCIsImlucHV0SGlkZGVuIiwiJGlucHV0SGlkZGVuIiwiaW5kZXhPZiIsIl9pbml0aWFsaWVkSGFuZGxlciIsImluc2lkZSIsInRhcmdldCIsImFkZCIsInR5cGUiLCJoYXNDbGFzcyIsIm9uIiwiZCJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7Ozs7Ozs7OztBQVVBOzs7Ozs7QUFNQUEsR0FBR0MsVUFBSCxDQUFjQyxNQUFkLENBQ0ksbUJBREosRUFHSSxDQUFDLE1BQUQsRUFBUyxLQUFULEVBQWdCLFVBQWhCLENBSEosRUFLSSxVQUFVQyxJQUFWLEVBQWdCOztBQUVaOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNJOzs7OztBQUtBQyxZQUFRQyxFQUFFLElBQUYsQ0FOWjs7O0FBUUk7Ozs7O0FBS0FDLGdCQUFZLElBYmhCOzs7QUFlSTs7Ozs7QUFLQUMsa0JBQWMsSUFwQmxCOzs7QUFzQkk7Ozs7O0FBS0FDLGVBQVc7QUFDUCxxQkFBYTtBQUROLEtBM0JmOzs7QUErQkk7Ozs7O0FBS0FDLGNBQVVKLEVBQUVLLE1BQUYsQ0FBUyxJQUFULEVBQWUsRUFBZixFQUFtQkYsUUFBbkIsRUFBNkJMLElBQTdCLENBcENkOzs7QUFzQ0k7Ozs7O0FBS0FELGFBQVMsRUEzQ2I7O0FBNkNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7Ozs7OztBQVVBLFFBQUlTLGVBQWUsU0FBZkEsWUFBZSxDQUFVQyxJQUFWLEVBQWdCQyxRQUFoQixFQUEwQkMsUUFBMUIsRUFBb0M7O0FBRW5ELFlBQUlDLFdB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UUE5RyxVQUFFLE1BQUYsRUFDS29ILEVBREwsQ0FDUSxvQkFEUixFQUM4QixVQUFVakQsQ0FBVixFQUFha0QsQ0FBYixFQUFnQjtBQUN0QyxnQkFBSUEsS0FBS0EsRUFBRXJELFFBQVgsRUFBcUI7QUFDakI7QUFDQXFELGtCQUFFckQsUUFBRixDQUFXUyxPQUFYO0FBQ0g7QUFDSixTQU5MO0FBT0FnQjtBQUNILEtBaENEOztBQWtDQTtBQUNBLFdBQU81RixNQUFQO0FBQ0gsQ0FsZUwiLCJmaWxlIjoidGFibGVfaW5saW5lX2VkaXQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIHRhYmxlX2lubGluZV9lZGl0LmpzIDIwMTUtMTAtMTYgZ21cbiBHYW1iaW8gR21iSFxuIGh0dHA6Ly93d3cuZ2FtYmlvLmRlXG4gQ29weXJpZ2h0IChjKSAyMDE1IEdhbWJpbyBHbWJIXG4gUmVsZWFzZWQgdW5kZXIgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChWZXJzaW9uIDIpXG4gW2h0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLmh0bWxdXG4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG4vKipcbiAqICMjIEV4dGVuc2lvbiBmb3IgbWFraW5nIHRhYmxlcyBlZGl0YWJsZS5cbiAqXG4gKiBAbW9kdWxlIEFkbWluL0V4dGVuc2lvbnMvdGFibGVfaW5saW5lX2VkaXRcbiAqIEBpZ25vcmVcbiAqL1xuZ3guZXh0ZW5zaW9ucy5tb2R1bGUoXG4gICAgJ3RhYmxlX2lubGluZV9lZGl0JyxcblxuICAgIFsnZm9ybScsICd4aHInLCAnZmFsbGJhY2snXSxcblxuICAgIGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBWQVJJQUJMRSBERUZJTklUSU9OXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIHZhclxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFeHRlbnNpb24gUmVmZXJlbmNlXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgJHRoaXMgPSAkKHRoaXMpLFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFRlbXBsYXRlIFNlbGVjdG9yXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgJHRlbXBsYXRlID0gbnVsbCxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBUYWJsZSBCb2R5IFNlbGVjdG9yXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgJHRhYmxlX2JvZHkgPSBudWxsLFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlZmF1bHQgT3B0aW9ucyBmb3IgRXh0ZW5zaW9uXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZGVmYXVsdHMgPSB7XG4gICAgICAgICAgICAgICAgJ211bHRpRWRpdCc6IGZhbHNlXG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEZpbmFsIEV4dGVuc2lvbiBPcHRpb25zXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgZGF0YSksXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogTW9kdWxlIE9iamVjdFxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEB0eXBlIHtvYmplY3R9XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIG1vZHVsZSA9IHt9O1xuXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBGVU5DVElPTkFMSVRZXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTd2l0Y2ggU3RhdGVcbiAgICAgICAgICpcbiAgICAgICAgICogRnVuY3Rpb24gdGhhdCBlbmFibGVzIC8gZGlzYWJsZXMsIGRlcGVuZGluZyBvbiB0aGUgbW9kZSwgYWxsIGlucHV0IGZpZWxkcyBpbnNpZGVcbiAgICAgICAgICogdGhlICRlbGVtZW50IGFuZCBzaG93cyAvIGhpZGVzIHRoZSBjb3JyZXNwb25kaW5nIGJ1dHRvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlIFNldCB0aGUgZ2l2ZW4gbW9kZS4gUG9zc2libGUgdmFsdWVzOiAnZWRpdCcsICdhZGQnLCAnZGVmYXVsdCdcbiAgICAgICAgICogQHBhcmFtIHtvYmplY3R9ICRlbGVtZW50IFRoZSBlbGVtZW50IGpRdWVyeSBzZWxlY3Rpb24gdGhhdCBnZXRzIG1vZGlmaWVkXG4gICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYWRkQ2xhc3MgSWYgdHJ1ZSwgdGhlIHN0YXRlIGNsYXNzIGdldHMgYWRkZWQgdG8gdGhlIGVsZW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfc3dpdGNoU3RhdGUgPSBmdW5jdGlvbiAobW9kZSwgJGVsZW1lbnQsIGFkZENsYXNzKSB7XG5cbiAgICAgICAgICAgIHZhciAkdGFyZ2V0cyA9ICRlbGVtZW50LmZpbmQoJ2lucHV0LCB0ZXh0YXJlYSwgc2VsZWN0LCBidXR0b24sIGknKSxcbiAgICAgICAgICAgICAgICAkZWRpdCA9ICR0YXJnZXRzLmZpbHRlcignLmVkaXRtb2RlJyksXG4gICAgICAgICAgICAgICAgJGFkZCA9ICR0YXJnZXRzLmZpbHRlcignLmFkZG1vZGUnKSxcbiAgICAgICAgICAgICAgICAkZGVmYXVsdCA9ICR0YXJnZXRzLmZpbHRlcignLmRlZmF1bHRtb2RlJyksXG4gICAgICAgICAgICAgICAgJG90aGVycyA9ICR0YXJnZXRzLmZpbHRlcignOm5vdCguZWRpdG1vZGUpOm5vdCguYWRkbW9kZSk6bm90KC5kZWZhdWx0bW9kZSknKTtcblxuICAgICAgICAgICAgLy8gSGlkZSBhbGwgYnV0dG9uc1xuICAgICAgICAgICAgJGVkaXQuaGlkZSgpO1xuICAgICAgICAgICAgJGFkZC5oaWRlKCk7XG4gICAgICAgICAgICAkZGVmYXVsdC5oaWRlKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbHQtdGV4dCBpZiBhdmFpbGFibGVcbiAgICAgICAgICAgICRlbGVtZW50XG4gICAgICAgICAgICAgICAgLmZpbmQoJy50YWJsZV9pbmxpbmVlZGl0X2FsdCcpXG4gICAgICAgICAgICAgICAgLnJlbW92ZSgpO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdlZGl0JzpcbiAgICAgICAgICAgICAgICAgICAgLy8gU3dpdGNoIHRvIGVkaXQgbW9kZVxuICAgICAgICAgICAgICAgICAgICAkZWRpdC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICRvdGhlcnMucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2FkZCc6XG4gICAgICAgICAgICAgICAgICAgIC8vIFN3aXRjaCB0byBhZGQgbW9kZVxuICAgICAgICAgICAgICAgICAgICAkYWRkLnNob3coKTtcbiAgICAgICAgICAgICAgICAgICAgJG90aGVycy5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgLy8gU3dpdGNoIHRvIGRlZmF1bHQtbW9kZVxuICAgICAgICAgICAgICAgICAgICAkZGVmYXVsdC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICRvdGhlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgaXMgYW4gYWx0IHRleHQgZ2l2ZW4gZm9yIHRoZSBpbnB1dCBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzZXQgPSBqc2UubGlicy5mYWxsYmFjay5fZGF0YSgkc2VsZiwgJ3RhYmxlX2lubGluZV9lZGl0Jyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHNvbWUga2luZCBvZiBmb3JtIGZpZWxkcyB3aXRoIHNwYW4gdGFnc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc2VsZi5hdHRyKCd0eXBlJykgJiYgJHNlbGYuYXR0cigndHlwZScpLnRvTG93ZXJDYXNlKCkgPT09ICdjaGVja2JveCcgJiYgZGF0YXNldC5hbHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IGRhdGFzZXQuYWx0LnNwbGl0KCdfJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja2VkID0gJHNlbGYucHJvcCgnY2hlY2tlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VsZi5hZnRlcignPHNwYW4gY2xhc3M9XCJ0YWJsZV9pbmxpbmVlZGl0X2FsdFwiPicgKyAoY2hlY2tlZCA/IHZhbHVlc1swXSA6IHZhbHVlc1sxXSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvc3Bhbj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCRzZWxmLnByb3AoJ3RhZ05hbWUnKS50b0xvd2VyQ2FzZSgpID09PSAnc2VsZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2FpdFVudGlsVmFsdWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVkaXQuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkc2VsZi5jaGlsZHJlbigpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YWl0VW50aWxWYWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAyMDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VsZi5jaGlsZHJlbignW3ZhbHVlPVwiJyArICRzZWxmLnZhbCgpICsgJ1wiXScpLnRleHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2VsZi5hZnRlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwidGFibGVfaW5saW5lZWRpdF9hbHRcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNlbGYuY2hpbGRyZW4oJ1t2YWx1ZT1cIicgKyAkc2VsZi52YWwoKSArICdcIl0nKS50ZXh0KCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zcGFuPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YWl0VW50aWxWYWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR0aGlzLnRyaWdnZXIoJ0ZPUk1fVVBEQVRFJywgW10pO1xuXG4gICAgICAgICAgICAvLyBBZGQgdGhlIG1vZGUgY2xhc3NcbiAgICAgICAgICAgIGlmIChhZGRDbGFzcykge1xuICAgICAgICAgICAgICAgICRlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnZWRpdCBhZGQgZGVmYXVsdCcpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhtb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlIE5ldyBMaW5lXG4gICAgICAgICAqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgXCJhZGRcIi1saW5lIGJ5IGNsb25pbmcgdGhlIGZvb3RlciB0ZW1wbGF0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHZhciBfY3JlYXRlTmV3TGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkbmV3TGluZSA9ICR0ZW1wbGF0ZS5jbG9uZSgpO1xuXG4gICAgICAgICAgICAkbmV3TGluZVxuICAgICAgICAgICAgICAgIC5maW5kKCdbbmFtZV0nKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyICRzZWxmID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgICAgICAgICAkc2VsZi5hdHRyKCduYW1lJywgJHNlbGYuYXR0cignbmFtZScpLnJlcGxhY2UoJ1tdJywgJ1swXScpKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgX3N3aXRjaFN0YXRlKCdhZGQnLCAkbmV3TGluZSwgdHJ1ZSk7XG4gICAgICAgICAgICAvLyBSZW5hbWUgdGhlIHRlbXBvcmFyaWx5IHdpZGdldCBkYXRhIGF0dHJpYnV0ZXNcbiAgICAgICAgICAgIGpzZS5saWJzLmZhbGxiYWNrLnNldHVwV2lkZ2V0QXR0cigkbmV3TGluZSk7XG4gICAgICAgICAgICAkdGFibGVfYm9keS5hcHBlbmQoJG5ld0xpbmUpO1xuICAgICAgICAgICAgLy8gU3RhcnQgdGhlIHdpZGdldHNcbiAgICAgICAgICAgIGd4LndpZGdldHMuaW5pdCgkdGFibGVfYm9keS5maW5kKCd0cicpLmxhc3QoKSk7XG4gICAgICAgICAgICBneC5leHRlbnNpb25zLmluaXQoJHRhYmxlX2JvZHkuZmluZCgndHInKS5sYXN0KCkpO1xuICAgICAgICAgICAgZ3guY29udHJvbGxlcnMuaW5pdCgkdGFibGVfYm9keS5maW5kKCd0cicpLmxhc3QoKSk7XG4gICAgICAgICAgICBneC5jb21wYXRpYmlsaXR5LmluaXQoJHRhYmxlX2JvZHkuZmluZCgndHInKS5sYXN0KCkpO1xuICAgICAgICAgICAganNlLndpZGdldHMuaW5pdCgkdGFibGVfYm9keS5maW5kKCd0cicpLmxhc3QoKSk7XG4gICAgICAgICAgICBqc2UuZXh0ZW5zaW9ucy5pbml0KCR0YWJsZV9ib2R5LmZpbmQoJ3RyJykubGFzdCgpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gRVZFTlQgSEFORExFUlNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZXIgZm9yIHRoZSBcImFib3J0XCItYnV0dG9uXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBJZiBmdW5jdGlvbiBnZXRzIGNhbGxlZCBkaXJlY3RseSwgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc3RhdGUgb2YgdGhlIGFib3J0LlxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9hYm9ydEhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRyID0gJCh0aGlzKS5jbG9zZXN0KCd0cicpLFxuICAgICAgICAgICAgICAgIGNhY2hlID0gSlNPTi5zdHJpbmdpZnkoJHRyLmRhdGEoJ2Zvcm1jYWNoZScpKSxcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gSlNPTi5zdHJpbmdpZnkoanNlLmxpYnMuZm9ybS5nZXREYXRhKCR0ciwgdW5kZWZpbmVkLCB0cnVlKSksXG4gICAgICAgICAgICAgICAgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCk7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHJlc2V0IGEgbGluZSBzdGF0ZVxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHZhciBfcmVzZXRMaW5lID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAkKCcjbGlnaHRib3hfcGFja2FnZV8nICsgZS5kYXRhLmlkICsgJ2FkbWluX2J1dHRvbicpLm9mZigpO1xuICAgICAgICAgICAgICAgICAgICAkKCcjbGlnaHRib3hfcGFja2FnZV8nICsgZS5kYXRhLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgJC5saWdodGJveF9wbHVnaW4oJ2Nsb3NlJywgZS5kYXRhLmlkKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZSAmJiBlLmRhdGEucmVqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSB2YWxpZGF0aW9uIHN0YXRlXG4gICAgICAgICAgICAgICAgICAgICR0ci50cmlnZ2VyKCd2YWxpZGF0b3IucmVzZXQnLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBmb3JtIGRhdGFcbiAgICAgICAgICAgICAgICAgICAganNlLmxpYnMuZm9ybS5wcmVmaWxsRm9ybSgkdHIsICR0ci5kYXRhKCdmb3JtY2FjaGUnKSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIF9zd2l0Y2hTdGF0ZSgnZGVmYXVsdCcsICR0ciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBDb21wYXJlIHRoZSBvbGQgd2l0aCB0aGUgbmV3IGRhdGEuIElmIGNoYW5nZXMgd2VyZSBtYWRlLCBjb25maXJtIHRoZSBhYm9ydFxuICAgICAgICAgICAgaWYgKGNhY2hlICE9PSBjdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyXG4gICAgICAgICAgICAgICAgICAgIGhyZWYgPSAnbGlnaHRib3hfY29uZmlybS5odG1sP3NlY3Rpb249c2hvcF9vZmZsaW5lJmFtcDsnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdtZXNzYWdlPWRpY2FyZF9jaGFuZ2VzX2hpbnQmYW1wO2J1dHRvbnM9Y2FuY2VsLWRpc2NhcmQnLFxuICAgICAgICAgICAgICAgICAgICBsaW5rSHRtbCA9ICc8YSBocmVmPVwiJyArIGhyZWYgKyAnXCI+PC9hPicsXG4gICAgICAgICAgICAgICAgICAgIGxpZ2h0Ym94TGluayA9ICQobGlua0h0bWwpLFxuICAgICAgICAgICAgICAgICAgICBsaWdodGJveElkID0gbGlnaHRib3hMaW5rLmxpZ2h0Ym94X3BsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgICAgICAnbGlnaHRib3hfd2lkdGgnOiAnMzYwcHgnXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgJCgnI2xpZ2h0Ym94X3BhY2thZ2VfJyArIGxpZ2h0Ym94SWQpXG4gICAgICAgICAgICAgICAgICAgIC5vbmUoJ2NsaWNrJywgJy5kaXNjYXJkJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ3JlamVjdCc6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2lkJzogbGlnaHRib3hJZFxuICAgICAgICAgICAgICAgICAgICB9LCBfcmVzZXRMaW5lKVxuICAgICAgICAgICAgICAgICAgICAub25lKCdjbGljaycsICcuY2FuY2VsJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ3JlamVjdCc6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAnaWQnOiBsaWdodGJveElkXG4gICAgICAgICAgICAgICAgICAgIH0sIF9yZXNldExpbmUpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIF9yZXNldExpbmUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcblxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVyIGZvciB0aGUgXCJlZGl0XCItYnV0dG9uXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX2VkaXRIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0ciA9ICQodGhpcykuY2xvc2VzdCgndHInKSxcbiAgICAgICAgICAgICAgICAkZWRpdGVkID0gJHRoaXMuZmluZCgndHIuZWRpdCcpLFxuICAgICAgICAgICAgICAgIHByb21pc2VzID0gW107XG5cbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5tdWx0aUVkaXQgJiYgJGVkaXRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBtdWx0aUVkaXQgaXMgZGlzYWJsZWQgYW5kIG90aGVyIGxpbmVzIGFyZSBpbiBlZGl0IG1vZGUsIHdhaXQgZm9yIGNvbmZpcm1hdGlvblxuICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBhYm9ydCBldmVudCBvbiB0aGUgb3RoZXIgbGluZXMuXG4gICAgICAgICAgICAgICAgJGVkaXRlZFxuICAgICAgICAgICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKF9hYm9ydEhhbmRsZXIuY2FsbCgkKHRoaXMpLmZpbmQoJy5yb3dfYWJvcnQnKS5maXJzdCgpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkLndoZW4uYXBwbHkodW5kZWZpbmVkLCBwcm9taXNlcykucHJvbWlzZSgpLmRvbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBjdXJyZW50IGRhdGEgb2YgdGhlIGxpbmUgaW4gY2FjaGVcbiAgICAgICAgICAgICAgICAkdHIuZGF0YSgnZm9ybWNhY2hlJywganNlLmxpYnMuZm9ybS5nZXREYXRhKCR0ciwgdW5kZWZpbmVkLCB0cnVlKSk7XG4gICAgICAgICAgICAgICAgX3N3aXRjaFN0YXRlKCdlZGl0JywgJHRyLCB0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVyIGZvciB0aGUgXCJzYXZlXCItYnV0dG9uXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3NhdmVIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICRzZWxmID0gJCh0aGlzKSxcbiAgICAgICAgICAgICAgICAkdHIgPSAkc2VsZi5jbG9zZXN0KCd0cicpLFxuICAgICAgICAgICAgICAgIGRhdGFzZXQgPSBqc2UubGlicy5mb3JtLmdldERhdGEoJHRyLCB1bmRlZmluZWQsIHRydWUpLFxuICAgICAgICAgICAgICAgIHVybCA9ICRzZWxmLmRhdGEoKS51cmwsXG4gICAgICAgICAgICAgICAgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCk7XG5cbiAgICAgICAgICAgIC8vIERvbmUgY2FsbGJhY2sgb24gdmFsaWRhdGlvbiBzdWNjZXNzXG4gICAgICAgICAgICBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGEgdXJsIGlzIGdpdmVuLCBwb3N0IHRoZSBkYXRhIGFnYWluc3QgdGhlIHNlcnZlclxuICAgICAgICAgICAgICAgICAgICBqc2UuY29yZS5kZWJ1Zy5pbmZvKCdTZW5kaW5nIGRhdGE6JywgZGF0YXNldCk7XG4gICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLnhoci5hamF4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICd1cmwnOiB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGF0YSc6IGRhdGFzZXRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgJHRoaXMudHJpZ2dlcigncm93X3NhdmVkJywgW2RhdGFzZXRdKTtcbiAgICAgICAgICAgICAgICBfc3dpdGNoU3RhdGUoJ2RlZmF1bHQnLCAkdHIsIHRydWUpO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gR2V0IHZhbGlkYXRpb24gc3RhdGUgb2YgdGhlIGxpbmUuIE9uIHN1Y2Nlc3MgZ290byBkZWZlcnJlZC5kb25lIGNhbGxiYWNrXG4gICAgICAgICAgICAkdHIudHJpZ2dlcigndmFsaWRhdG9yLnZhbGlkYXRlJywgW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgJ2RlZmVycmVkJzogZGVmZXJyZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdKTtcblxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVyIGZvciB0aGUgXCJkZWxldGVcIi1idXR0b25cbiAgICAgICAgICovXG4gICAgICAgIHZhciBfZGVsZXRlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgJHRyID0gJHNlbGYuY2xvc2VzdCgndHInKSxcbiAgICAgICAgICAgICAgICBkYXRhc2V0ID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogJHRyLmRhdGEoJ2lkJylcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVybCA9ICRzZWxmLmRhdGEoKS51cmwsXG4gICAgICAgICAgICAgICAgaHRtbCA9ICc8YSBocmVmPVwibGlnaHRib3hfY29uZmlybS5odG1sP3NlY3Rpb249c2hvcF9vZmZsaW5lJmFtcDttZXNzYWdlPWRlbGV0ZV9qb2InXG4gICAgICAgICAgICAgICAgICAgICsgJyZhbXA7YnV0dG9ucz1jYW5jZWwtZGVsZXRlXCI+PC9hPicsXG4gICAgICAgICAgICAgICAgbGlnaHRib3hMaW5rID0gJChodG1sKSxcbiAgICAgICAgICAgICAgICBsaWdodGJveElkID0gbGlnaHRib3hMaW5rLmxpZ2h0Ym94X3BsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgICdsaWdodGJveF93aWR0aCc6ICczNjBweCdcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJCgnI2xpZ2h0Ym94X3BhY2thZ2VfJyArIGxpZ2h0Ym94SWQpLm9uZSgnY2xpY2snLCAnLmRlbGV0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAkLmxpZ2h0Ym94X3BsdWdpbignY2xvc2UnLCBsaWdodGJveElkKTtcblxuICAgICAgICAgICAgICAgIGlmICh1cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgYSB1cmwgaXMgZ2l2ZW4sIHBvc3QgdGhlIGRhdGEgYWdhaW5zdCB0aGUgc2VydmVyXG4gICAgICAgICAgICAgICAgICAgIGpzZS5saWJzLnhoci5hamF4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICd1cmwnOiB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGF0YSc6IGRhdGFzZXRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgJHRoaXMudHJpZ2dlcigncm93X2RlbGV0ZWQnLCBbZGF0YXNldF0pO1xuICAgICAgICAgICAgICAgICR0ci5yZW1vdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVyIGZvciB0aGUgJ2FkZCctYnV0dG9uXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX2FkZEhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHNlbGYgPSAkKHRoaXMpLFxuICAgICAgICAgICAgICAgIHVybCA9ICRzZWxmLmRhdGEoKS51cmwsXG4gICAgICAgICAgICAgICAgJHRyID0gJHNlbGYuY2xvc2VzdCgndHInKSxcbiAgICAgICAgICAgICAgICBkYXRhc2V0ID0ganNlLmxpYnMuZm9ybS5nZXREYXRhKCR0ciwgdW5kZWZpbmVkLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcblxuICAgICAgICAgICAgLy8gRG9uZSBjYWxsYmFjayBvbiB2YWxpZGF0aW9uIHN1Y2Nlc3NcbiAgICAgICAgICAgIGRlZmVycmVkLmRvbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBfZmluYWxpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN3aXRjaCB0aGUgc3RhdGUgb2YgdGhlIGxpbmUgYW5kXG4gICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyAnYWRkJy1saW5lXG4gICAgICAgICAgICAgICAgICAgICR0aGlzLnRyaWdnZXIoJ3Jvd19hZGRlZCcsIFtkYXRhc2V0XSk7XG4gICAgICAgICAgICAgICAgICAgIF9zd2l0Y2hTdGF0ZSgnZGVmYXVsdCcsICR0ciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIF9jcmVhdGVOZXdMaW5lKCk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGlmICh1cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgYSB1cmwgaXMgZ2l2ZW4sIHBvc3QgdGhlIGRhdGEgYWdhaW5zdCB0aGUgc2VydmVyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSByZXNwb25lIG9mIHRoZSBzZXJ2ZXIgY29udGFpbnMgYW4gaWQsIHdoaWNoIHdpbGwgYmVcbiAgICAgICAgICAgICAgICAgICAgLy8gaW5qZWN0ZWQgaW50byB0aGUgZmllbGQgbmFtZXNcbiAgICAgICAgICAgICAgICAgICAganNlLmNvcmUuZGVidWcuaW5mbygnU2VuZGluZyBkYXRhOicsIGRhdGFzZXQpO1xuICAgICAgICAgICAgICAgICAgICBqc2UubGlicy54aHIuYWpheCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAndXJsJzogdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RhdGEnOiBkYXRhc2V0XG4gICAgICAgICAgICAgICAgICAgIH0pLmRvbmUoZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlkID0gcmVzdWx0LmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0YXJnZXRzID0gJHRyLmZpbmQoJ2lucHV0Om5vdCg6YnV0dG9uKSwgdGV4dGFyZWEsIHNlbGVjdCcpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAkdGFyZ2V0cy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGVsZW0gPSAkKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gJGVsZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCduYW1lJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCdbMF0nLCAnWycgKyBpZCArICddJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGVsZW0uZGF0YSgpLmxpZ2h0Ym94SHJlZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZWxlbS5kYXRhKCkubGlnaHRib3hIcmVmID0gJGVsZW0uZGF0YSgpLmxpZ2h0Ym94SHJlZi5yZXBsYWNlKCdpZD0wJywgJ2lkPScgKyBpZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtLmF0dHIoJ25hbWUnLCBuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAkdHIuZmluZCgnW2RhdGEtbGlnaHRib3gtaHJlZl0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3TGluayA9ICQodGhpcykuYXR0cignZGF0YS1saWdodGJveC1ocmVmJykucmVwbGFjZSgnaWQ9MCcsICdpZD0nICsgaWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtbGlnaHRib3gtaHJlZicsIG5ld0xpbmspXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kYXRhKCkubGlnaHRib3hIcmVmID0gbmV3TGluaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIGhpZGRlbiBlZGl0b3IgaWRlbnRpZmllcnMgd2l0aCB0aGUgbmV3IHJlY29yZCBJRC5cbiAgICAgICAgICAgICAgICAgICAgICAgICR0ci5maW5kKCdpbnB1dDpoaWRkZW4nKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgaW5wdXRIaWRkZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGlucHV0SGlkZGVuID0gJChpbnB1dEhpZGRlbiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAkaW5wdXRIaWRkZW4uYXR0cignbmFtZScpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgJiYgbmFtZS5pbmRleE9mKCd7aWR9JykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dEhpZGRlbi5hdHRyKCduYW1lJywgbmFtZS5yZXBsYWNlKCd7aWR9JywgaWQpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgX2ZpbmFsaXplKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIF9maW5hbGl6ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBHZXQgdmFsaWRhdGlvbiBzdGF0ZSBvZiB0aGUgbGluZS4gT24gc3VjY2VzcyBnb3RvIGRlZmVycmVkLmRvbmUgY2FsbGJhY2tcbiAgICAgICAgICAgICR0ci50cmlnZ2VyKCd2YWxpZGF0b3IudmFsaWRhdGUnLCBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAnZGVmZXJyZWQnOiBkZWZlcnJlZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZXIgdG8gdXBkYXRlIHRoZSB0YWJsZSBzdGF0ZSwgaWYgYW4gd2lkZ2V0IGluc2lkZSB0aGUgdGFibGUgZ2V0cyBpbml0aWFsaXplZFxuICAgICAgICAgKiAobmVlZGVkIHRvIGRpc2FibGUgdGhlIGRhdGVwaWNrZXIgYnV0dG9ucykuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7b2JqZWN0fSBlICAgIGpRdWVyeSBldmVudC1vYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfaW5pdGlhbGllZEhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIGluc2lkZSA9ICR0aGlzXG4gICAgICAgICAgICAgICAgLmZpbHRlcigkKGUudGFyZ2V0KSlcbiAgICAgICAgICAgICAgICAuYWRkKCR0aGlzLmZpbmQoJChlLnRhcmdldCkpKVxuICAgICAgICAgICAgICAgIC5sZW5ndGg7XG5cbiAgICAgICAgICAgIGlmICghaW5zaWRlKSB7XG4gICAgICAgICAgICAgICAgdmFyICR0ciA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoJ3RyJyksXG4gICAgICAgICAgICAgICAgICAgIHR5cGUgPSAoJHRyLmhhc0NsYXNzKCdlZGl0JykpID8gJ2VkaXQnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICgkdHIuaGFzQ2xhc3MoJ2FkZCcpKSA/ICdhZGQnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVmYXVsdCc7XG5cbiAgICAgICAgICAgICAgICBfc3dpdGNoU3RhdGUodHlwZSwgJHRyLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gSU5JVElBTElaQVRJT05cbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgbWV0aG9kIG9mIHRoZSBleHRlbnNpb24sIGNhbGxlZCBieSB0aGUgZW5naW5lLlxuICAgICAgICAgKi9cbiAgICAgICAgbW9kdWxlLmluaXQgPSBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgJHRlbXBsYXRlID0gJHRoaXMuZmluZCgndGZvb3QgPiB0cicpO1xuICAgICAgICAgICAgJHRhYmxlX2JvZHkgPSAkdGhpcy5jaGlsZHJlbigndGJvZHknKTtcblxuICAgICAgICAgICAgLy8gQWRkIGEgc3BlY2lhbCBjbGFzcyB0byB0aGUgdGFibGUsIHRvIHN0eWxlXG4gICAgICAgICAgICAvLyBkaXNhYmxlZCBpbnB1dCBib3hlc1xuICAgICAgICAgICAgJHRoaXMuYWRkQ2xhc3MoJ3RhYmxlX2lubGluZWVkaXQnKTtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhbGwgdHJcbiAgICAgICAgICAgIF9zd2l0Y2hTdGF0ZSgnZGVmYXVsdCcsICR0YWJsZV9ib2R5KTtcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgXCJBZGRcIi1saW5lIHRvIHRoZSB0YWJsZVxuICAgICAgICAgICAgX2NyZWF0ZU5ld0xpbmUoKTtcblxuICAgICAgICAgICAgLy8gQWRkIGV2ZW50IGxpc3RlbmVycyBmb3IgYWxsIGJ1dHRvbnMgYW5kXG4gICAgICAgICAgICAvLyBhIGxpc3RlbmVyIGZvciB0aGUgd2lkZ2V0IGluaXRpYWxpemVkIGV2ZW50XG4gICAgICAgICAgICAvLyBmcm9tIHdpZGdldHMgaW5zaWRlIHRoZSB0YWJsZVxuICAgICAgICAgICAgJHRoaXNcbiAgICAgICAgICAgICAgICAub24oJ2NsaWNrJywgJy5yb3dfZWRpdCcsIF9lZGl0SGFuZGxlcilcbiAgICAgICAgICAgICAgICAub24oJ2NsaWNrJywgJy5yb3dfZGVsZXRlJywgX2RlbGV0ZUhhbmRsZXIpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsICcucm93X3NhdmUnLCBfc2F2ZUhhbmRsZXIpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsICcucm93X2FkZCcsIF9hZGRIYW5kbGVyKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCAnLnJvd19hYm9ydCcsIF9hYm9ydEhhbmRsZXIpXG4gICAgICAgICAgICAgICAgLm9uKCd3aWRnZXQuaW5pdGlhbGl6ZWQnLCBfaW5pdGlhbGllZEhhbmRsZXIpO1xuXG4gICAgICAgICAgICAkKCdib2R5JylcbiAgICAgICAgICAgICAgICAub24oJ3ZhbGlkYXRvci52YWxpZGF0ZScsIGZ1bmN0aW9uIChlLCBkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkICYmIGQuZGVmZXJyZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV2ZW50IGxpc3RlbmVyIHRoYXQgcGVyZm9ybXMgb24gZXZlcnkgdmFsaWRhdGUgdHJpZ2dlciB0aGF0IGlzbid0IGhhbmRsZWQgYnkgdGhlIHZhbGlkYXRvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIGQuZGVmZXJyZWQucmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJuIGRhdGEgdG8gbW9kdWxlIGVuZ2luZS5cbiAgICAgICAgcmV0dXJuIG1vZHVsZTtcbiAgICB9KTtcbiJdfQ==

Youez - 2016 - github.com/yon3zu
LinuXploit