all files / test/base/module/ Editor.spec.js

99.61% Statements 258/259
63.64% Branches 7/11
100% Functions 58/58
99.61% Lines 257/258
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387           37×     32× 32× 32× 32× 32× 32×       32×                                                                             1000×                                                                                                                                                                    
(function(global){global.wrappers['/Users/lqez/Dev/summernote/test/base/module/Editor.spec.js']=[function(require,module,exports,__dirname,__filename){ "use strict";
/**
 * Editor.spec.js
 * (c) 2015~ Summernote Team
 * summernote may be freely distributed under the MIT license./
 */
exports.__esModule = true;
var chai_1 = require("chai");
var chai_spies_1 = require("chai-spies");
var chaidom_1 = require("../../chaidom");
var jquery_1 = require("jquery");
var env_1 = require("../../../src/js/base/core/env");
var range_1 = require("../../../src/js/base/core/range");
var Context_1 = require("../../../src/js/base/Context");
require("../../../src/js/bs4/settings");
describe('Editor', function () {
    var expect = chai_1["default"].expect;
    chai_1["default"].use(chai_spies_1["default"]);
    chai_1["default"].use(chaidom_1["default"]);
    var editor, context, $editable;
    function expectContents(context, markup) {
        expect(context.layoutInfo.editable.html()).to.equalsIgnoreCase(markup);
    }
    function expectToHaveBeenCalled(context, customEvent, handler) {
        var $note = context.layoutInfo.note;
        var spy = chai_1["default"].spy();
        $note.on(customEvent, spy);
        handler();
        expect(spy).to.have.been.called();
    }
    beforeEach(function () {
        jquery_1["default"]('body').empty(); // important !
        var $note = jquery_1["default"]('<div><p>hello</p></div>');
        var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
        context = new Context_1["default"]($note, options);
        editor = context.modules.editor;
        $editable = context.layoutInfo.editable;
        // [workaround]
        //  - Firefox need setTimeout for applying contents
        //  - IE8-11 can't create range in headless mode
        Iif (env_1["default"].isFF || env_1["default"].isMSIE || env_1["default"].isEdge) {
            this.skip();
        }
    });
    describe('initialize', function () {
        it('should bind custom events', function () {
            [
                'keydown', 'keyup', 'blur', 'mousedown', 'mouseup',
                'scroll', 'focusin', 'focusout',
            ].forEach(function (eventName) {
                expectToHaveBeenCalled(context, 'summernote.' + eventName, function () {
                    $editable.trigger(eventName);
                });
            });
            expectToHaveBeenCalled(context, 'summernote.change', function () {
                editor.insertText('hello');
            });
        });
    });
    Eif (env_1["default"].isWebkit) {
        describe('undo and redo', function () {
            it('should control history', function () {
                editor.insertText(' world');
                expectContents(context, '<p>hello world</p>');
                editor.undo();
                expectContents(context, '<p>hello</p>');
                editor.redo();
                expectContents(context, '<p>hello world</p>');
            });
        });
    }
    describe('tab', function () {
        it('should insert tab', function () {
            editor.tab();
            expectContents(context, '<p>hello&nbsp;&nbsp;&nbsp;&nbsp;</p>');
        });
    });
    describe('insertParagraph', function () {
        it('should insert paragraph', function () {
            editor.insertParagraph();
            expectContents(context, '<p>hello</p><p><br></p>');
            editor.insertParagraph();
            expectContents(context, '<p>hello</p><p><br></p><p><br></p>');
        });
    });
    Eif (env_1["default"].isWebkit) {
        describe('insertImage', function () {
            it('should insert image', function () {
                var source = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAF0lEQVQYGWP8////fwYsgAmLGFiIHhIAT+oECGHuN2UAAAAASUVORK5CYII=';
                return editor.insertImage(source, 'image').then(function () {
                    expectContents(context, '<p>hello<img src="' + source + '" data-filename="image" style="width: 0px;"></p>');
                });
            });
        });
    }
    describe('insertOrderedList and insertUnorderedList', function () {
        it('should toggle paragraph to list', function () {
            editor.insertOrderedList();
            expectContents(context, '<ol><li>hello</li></ol>');
            editor.insertUnorderedList();
            expectContents(context, '<ul><li>hello</li></ul>');
            editor.insertUnorderedList();
            expectContents(context, '<p>hello</p>');
        });
    });
    describe('indent and outdent', function () {
        // [workaround] style is different by browser
        Eif (env_1["default"].isPhantom) {
            it('should indent and outdent paragraph', function () {
                editor.indent();
                expectContents(context, '<p style="margin-left: 25px;">hello</p>');
                editor.outdent();
                expectContents(context, '<p style="">hello</p>');
            });
        }
        it('should indent and outdent list', function () {
            editor.insertOrderedList();
            expectContents(context, '<ol><li>hello</li></ol>');
            editor.indent();
            expectContents(context, '<ol><li><ol><li>hello</li></ol></li></ol>');
            editor.indent();
            expectContents(context, '<ol><li><ol><li><ol><li>hello</li></ol></li></ol></li></ol>');
            editor.outdent();
            expectContents(context, '<ol><li><ol><li>hello</li></ol></li></ol>');
            editor.outdent();
            expectContents(context, '<ol><li>hello</li></ol>');
        });
    });
    describe('insertNode', function () {
        it('should insert node', function () {
            editor.insertNode(jquery_1["default"]('<span> world</span>')[0]);
            expectContents(context, '<p>hello<span> world</span></p>');
        });
        it('should be limited', function () {
            var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
            options.maxTextLength = 5;
            context = new Context_1["default"](jquery_1["default"]('<div><p>hello</p></div>'), options);
            editor = context.modules.editor;
            editor.insertNode(jquery_1["default"]('<span> world</span>')[0]);
            expectContents(context, '<p>hello</p>');
        });
        it('should insert node in last focus', function () {
            $editable.appendTo('body');
            context.invoke('editor.focus');
            editor.insertNode(jquery_1["default"]('<span> world</span>')[0]);
            jquery_1["default"]('body').focus();
            editor.insertNode(jquery_1["default"]('<span> hello</span>')[0]);
            expectContents(context, '<p><span> world</span><span> hello</span>hello</p>');
            $editable.remove();
        });
    });
    describe('insertText', function () {
        it('should insert text', function () {
            editor.insertText(' world');
            expectContents(context, '<p>hello world</p>');
        });
        it('should be limited', function () {
            var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
            options.maxTextLength = 5;
            context = new Context_1["default"](jquery_1["default"]('<div><p>hello</p></div>'), options);
            editor = context.modules.editor;
            editor.insertText(' world');
            expectContents(context, '<p>hello</p>');
        });
        it('should insert text in last focus', function () {
            $editable.appendTo('body');
            context.invoke('editor.focus');
            editor.insertText(' world');
            jquery_1["default"]('body').focus();
            editor.insertText(' summernote ');
            expectContents(context, '<p> world summernote hello</p>');
            $editable.remove();
        });
    });
    describe('pasteHTML', function () {
        it('should paste html', function () {
            editor.pasteHTML('<span> world</span>');
            expectContents(context, '<p>hello<span> world</span></p>');
        });
        it('should not call change change event more than once per paste event', function () {
            var generateLargeHtml = function () {
                var html = '<div>';
                for (var i = 0; i < 1000; i++) {
                    html += '<p>HTML element #' + i + '</p>';
                }
                html += '</div>';
                return html;
            };
            var $note = context.layoutInfo.note;
            var spy = chai_1["default"].spy();
            $note.on('summernote.change', spy);
            var html = generateLargeHtml();
            editor.pasteHTML(html);
            expect(spy).to.have.been.called.once;
        });
        it('should be limited', function () {
            var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
            options.maxTextLength = 5;
            context = new Context_1["default"](jquery_1["default"]('<div><p>hello</p></div>'), options);
            editor = context.modules.editor;
            editor.pasteHTML('<span> world</span>');
            expectContents(context, '<p>hello</p>');
        });
    });
    describe('insertHorizontalRule', function () {
        it('should insert horizontal rule', function () {
            editor.insertHorizontalRule();
            expectContents(context, '<p>hello</p><hr><p><br></p>');
        });
    });
    describe('insertTable', function () {
        it('should insert table', function () {
            var markup = [
                '<p>hello</p>',
                '<table class="table table-bordered"><tbody>',
                '<tr><td><br></td><td><br></td></tr>',
                '<tr><td><br></td><td><br></td></tr>',
                '</tbody></table>',
                '<p><br></p>',
            ].join('');
            editor.insertTable('2x2');
            expectContents(context, markup);
        });
    });
    describe('empty', function () {
        it('should make contents empty', function () {
            editor.empty();
            expect(editor.isEmpty()).to.be["true"];
        });
    });
    describe('formatBlock', function () {
        it('should apply formatBlock', function () {
            $editable.appendTo('body');
            editor.formatBlock('blockquote');
            // start <p>hello</p> => <blockquote>hello</blockquote>
            expectContents(context, '<blockquote>hello</blockquote>');
        });
        it('should apply multi formatBlock', function () {
            // set multi block html
            var codes = [
                '<p><a href="http://summernote.org">hello world</a></p>',
                '<p><a href="http://summernote.org">hello world</a></p>',
                '<p><a href="http://summernote.org">hello world</a></p>',
            ];
            context.invoke('code', codes.join(''));
            // run formatBlock
            $editable.appendTo('body');
            editor.formatBlock('blockquote');
            // check current range position in blockquote element
            var nodeName = $editable.children()[0].nodeName;
            expect(nodeName).to.equalsIgnoreCase('blockquote');
        });
        it('should apply multi test 2 - formatBlock', function () {
            var codes = [
                '<p><a href="http://summernote.org">hello world</a></p>',
                '<p><a href="http://summernote.org">hello world</a></p>',
                '<p><a href="http://summernote.org">hello world</a></p>',
            ];
            context.invoke('code', codes.join(''));
            $editable.appendTo('body');
            var startNode = $editable.find('p').first()[0];
            var endNode = $editable.find('p').last()[0];
            // all p tags is wrapped
            range_1["default"].create(startNode, 1, endNode, 1).normalize().select();
            editor.formatBlock('blockquote');
            var nodeName = $editable.children()[0].nodeName;
            expect(nodeName).to.equalsIgnoreCase('blockquote');
            // p -> blockquote, p is none
            expect($editable.find('p').length).to.equals(0);
        });
        it('should apply custom className in formatBlock', function () {
            var $target = jquery_1["default"]('<blockquote class="blockquote" />');
            $editable.appendTo('body');
            editor.formatBlock('blockquote', $target);
            // start <p>hello</p> => <blockquote class="blockquote">hello</blockquote>
            expectContents(context, '<blockquote class="blockquote">hello</blockquote>');
        });
        it('should find exact target in formatBlock', function () {
            var $target = jquery_1["default"]('<a class="dropdown-item" href="#" data-value="blockquote" role="listitem" aria-label="blockquote"><blockquote class="blockquote">Blockquote</blockquote></a>');
            $editable.appendTo('body');
            editor.formatBlock('blockquote', $target);
            // start <p>hello</p> => <blockquote class="blockquote">hello</blockquote>
            expectContents(context, '<blockquote class="blockquote">hello</blockquote>');
        });
    });
    describe('createLink', function () {
        it('should create normal link', function () {
            var text = 'hello';
            var pNode = $editable.find('p')[0];
            var textNode = pNode.childNodes[0];
            var startIndex = textNode.wholeText.indexOf(text);
            var endIndex = startIndex + text.length;
            range_1["default"].create(textNode, startIndex, textNode, endIndex).normalize().select();
            // check creation normal link
            editor.createLink({
                url: 'http://summernote.org',
                text: 'summernote'
            });
            expectContents(context, '<p>hello<a href="http://summernote.org">summernote</a></p>');
        });
        it('should create a link with range', function () {
            var text = 'hello';
            var pNode = $editable.find('p')[0];
            var textNode = pNode.childNodes[0];
            var startIndex = textNode.wholeText.indexOf(text);
            var endIndex = startIndex + text.length;
            var rng = range_1["default"].create(textNode, startIndex, textNode, endIndex);
            editor.createLink({
                url: 'http://summernote.org',
                text: 'summernote',
                range: rng
            });
            expectContents(context, '<p><a href="http://summernote.org">summernote</a></p>');
        });
        it('should create a link with isNewWindow', function () {
            var text = 'hello';
            var pNode = $editable.find('p')[0];
            var textNode = pNode.childNodes[0];
            var startIndex = textNode.wholeText.indexOf(text);
            var endIndex = startIndex + text.length;
            var rng = range_1["default"].create(textNode, startIndex, textNode, endIndex);
            editor.createLink({
                url: 'http://summernote.org',
                text: 'summernote',
                range: rng,
                isNewWindow: true
            });
            expectContents(context, '<p><a href="http://summernote.org" target="_blank">summernote</a></p>');
        });
        it('should create a relative link without scheme', function () {
            var text = 'hello';
            var pNode = $editable.find('p')[0];
            var textNode = pNode.childNodes[0];
            var startIndex = textNode.wholeText.indexOf(text);
            var endIndex = startIndex + text.length;
            var rng = range_1["default"].create(textNode, startIndex, textNode, endIndex);
            editor.createLink({
                url: '/relative/url',
                text: 'summernote',
                range: rng,
                isNewWindow: true
            });
            expectContents(context, '<p><a href="/relative/url" target="_blank">summernote</a></p>');
        });
        it('should modify a link', function () {
            context.invoke('code', '<p><a href="http://summernote.org">hello world</a></p>');
            var anchorNode = $editable.find('a')[0];
            var rng = range_1["default"].createFromNode(anchorNode);
            editor.createLink({
                url: 'http://wow.summernote.org',
                text: 'summernote wow',
                range: rng
            });
            expectContents(context, '<p><a href="http://wow.summernote.org">summernote wow</a></p>');
        });
        it('should be limited when creating a link', function () {
            var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
            options.maxTextLength = 5;
            context = new Context_1["default"](jquery_1["default"]('<div><p>hello</p></div>'), options);
            editor = context.modules.editor;
            editor.createLink({
                url: 'http://summernote.org',
                text: 'summernote'
            });
            expectContents(context, '<p>hello</p>');
        });
        it('should be limited when modifying a link', function () {
            var options = jquery_1["default"].extend({}, jquery_1["default"].summernote.options);
            options.maxTextLength = 5;
            context = new Context_1["default"](jquery_1["default"]('<p><a href="http://summernote.org">hello</a></p>'), options);
            var editable = context.layoutInfo.editable;
            var anchorNode = editable.find('a')[0];
            var rng = range_1["default"].createFromNode(anchorNode);
            editor = context.modules.editor;
            editor.createLink({
                url: 'http://summernote.org',
                text: 'hello world',
                range: rng
            });
            expectContents(context, '<a href="http://summernote.org">hello</a>');
        });
    });
});
 
},'test/base/module/Editor.spec.js',{"chai":"/Users/lqez/Dev/summernote/node_modules/chai/index.js","chai-spies":"/Users/lqez/Dev/summernote/node_modules/chai-spies/chai-spies.js","../../chaidom":"/Users/lqez/Dev/summernote/test/chaidom.js","jquery":"/Users/lqez/Dev/summernote/node_modules/jquery/dist/jquery.js","../../../src/js/base/core/env":"/Users/lqez/Dev/summernote/src/js/base/core/env.js","../../../src/js/base/core/range":"/Users/lqez/Dev/summernote/src/js/base/core/range.js","../../../src/js/base/Context":"/Users/lqez/Dev/summernote/src/js/base/Context.js","../../../src/js/bs4/settings":"/Users/lqez/Dev/summernote/src/js/bs4/settings.js"}];})(this);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWRpdG9yLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJFZGl0b3Iuc3BlYy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7QUFFSCw2QkFBd0I7QUFDeEIseUNBQStCO0FBQy9CLHlDQUFvQztBQUNwQyxpQ0FBdUI7QUFDdkIscURBQWdEO0FBQ2hELHlEQUFvRDtBQUNwRCx3REFBbUQ7QUFDbkQsd0NBQXNDO0FBRXRDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7SUFDakIsSUFBSSxNQUFNLEdBQUcsaUJBQUksQ0FBQyxNQUFNLENBQUM7SUFDekIsaUJBQUksQ0FBQyxHQUFHLENBQUMsdUJBQUssQ0FBQyxDQUFDO0lBQ2hCLGlCQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFPLENBQUMsQ0FBQztJQUVsQixJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDO0lBRS9CLFNBQVMsY0FBYyxDQUFDLE9BQU8sRUFBRSxNQUFNO1FBQ3JDLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsU0FBUyxzQkFBc0IsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU87UUFDM0QsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFDdEMsSUFBTSxHQUFHLEdBQUcsaUJBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixLQUFLLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMzQixPQUFPLEVBQUUsQ0FBQztRQUNWLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRUQsVUFBVSxDQUFDO1FBQ1QsbUJBQUMsQ0FB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QUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRWRpdG9yLnNwZWMuanNcbiAqIChjKSAyMDE1fiBTdW1tZXJub3RlIFRlYW1cbiAqIHN1bW1lcm5vdGUgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuL1xuICovXG5cbmltcG9ydCBjaGFpIGZyb20gJ2NoYWknO1xuaW1wb3J0IHNwaWVzIGZyb20gJ2NoYWktc3BpZXMnO1xuaW1wb3J0IGNoYWlkb20gZnJvbSAnLi4vLi4vY2hhaWRvbSc7XG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xuaW1wb3J0IGVudiBmcm9tICcuLi8uLi8uLi9zcmMvanMvYmFzZS9jb3JlL2Vudic7XG5pbXBvcnQgcmFuZ2UgZnJvbSAnLi4vLi4vLi4vc3JjL2pzL2Jhc2UvY29yZS9yYW5nZSc7XG5pbXBvcnQgQ29udGV4dCBmcm9tICcuLi8uLi8uLi9zcmMvanMvYmFzZS9Db250ZXh0JztcbmltcG9ydCAnLi4vLi4vLi4vc3JjL2pzL2JzNC9zZXR0aW5ncyc7XG5cbmRlc2NyaWJlKCdFZGl0b3InLCAoKSA9PiB7XG4gIHZhciBleHBlY3QgPSBjaGFpLmV4cGVjdDtcbiAgY2hhaS51c2Uoc3BpZXMpO1xuICBjaGFpLnVzZShjaGFpZG9tKTtcblxuICB2YXIgZWRpdG9yLCBjb250ZXh0LCAkZWRpdGFibGU7XG5cbiAgZnVuY3Rpb24gZXhwZWN0Q29udGVudHMoY29udGV4dCwgbWFya3VwKSB7XG4gICAgZXhwZWN0KGNvbnRleHQubGF5b3V0SW5mby5lZGl0YWJsZS5odG1sKCkpLnRvLmVxdWFsc0lnbm9yZUNhc2UobWFya3VwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4cGVjdFRvSGF2ZUJlZW5DYWxsZWQoY29udGV4dCwgY3VzdG9tRXZlbnQsIGhhbmRsZXIpIHtcbiAgICBjb25zdCAkbm90ZSA9IGNvbnRleHQubGF5b3V0SW5mby5ub3RlO1xuICAgIGNvbnN0IHNweSA9IGNoYWkuc3B5KCk7XG4gICAgJG5vdGUub24oY3VzdG9tRXZlbnQsIHNweSk7XG4gICAgaGFuZGxlcigpO1xuICAgIGV4cGVjdChzcHkpLnRvLmhhdmUuYmVlbi5jYWxsZWQoKTtcbiAgfVxuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24oKSB7XG4gICAgJCgnYm9keScpLmVtcHR5KCk7IC8vIGltcG9ydGFudCAhXG4gICAgdmFyICRub3RlID0gJCgnPGRpdj48cD5oZWxsbzwvcD48L2Rpdj4nKTtcblxuICAgIHZhciBvcHRpb25zID0gJC5leHRlbmQoe30sICQuc3VtbWVybm90ZS5vcHRpb25zKTtcbiAgICBjb250ZXh0ID0gbmV3IENvbnRleHQoJG5vdGUsIG9wdGlvbnMpO1xuXG4gICAgZWRpdG9yID0gY29udGV4dC5tb2R1bGVzLmVkaXRvcjtcbiAgICAkZWRpdGFibGUgPSBjb250ZXh0LmxheW91dEluZm8uZWRpdGFibGU7XG5cbiAgICAvLyBbd29ya2Fyb3VuZF1cbiAgICAvLyAgLSBGaXJlZm94IG5lZWQgc2V0VGltZW91dCBmb3IgYXBwbHlpbmcgY29udGVudHNcbiAgICAvLyAgLSBJRTgtMTEgY2FuJ3QgY3JlYXRlIHJhbmdlIGluIGhlYWRsZXNzIG1vZGVcbiAgICBpZiAoZW52LmlzRkYgfHwgZW52LmlzTVNJRSB8fCBlbnYuaXNFZGdlKSB7XG4gICAgICB0aGlzLnNraXAoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbml0aWFsaXplJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmluZCBjdXN0b20gZXZlbnRzJywgKCkgPT4ge1xuICAgICAgW1xuICAgICAgICAna2V5ZG93bicsICdrZXl1cCcsICdibHVyJywgJ21vdXNlZG93bicsICdtb3VzZXVwJyxcbiAgICAgICAgJ3Njcm9sbCcsICdmb2N1c2luJywgJ2ZvY3Vzb3V0JyxcbiAgICAgIF0uZm9yRWFjaCgoZXZlbnROYW1lKSA9PiB7XG4gICAgICAgIGV4cGVjdFRvSGF2ZUJlZW5DYWxsZWQoY29udGV4dCwgJ3N1bW1lcm5vdGUuJyArIGV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICRlZGl0YWJsZS50cmlnZ2VyKGV2ZW50TmFtZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdFRvSGF2ZUJlZW5DYWxsZWQoY29udGV4dCwgJ3N1bW1lcm5vdGUuY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICBlZGl0b3IuaW5zZXJ0VGV4dCgnaGVsbG8nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBpZiAoZW52LmlzV2Via2l0KSB7XG4gICAgZGVzY3JpYmUoJ3VuZG8gYW5kIHJlZG8nLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGNvbnRyb2wgaGlzdG9yeScsICgpID0+IHtcbiAgICAgICAgZWRpdG9yLmluc2VydFRleHQoJyB3b3JsZCcpO1xuICAgICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG8gd29ybGQ8L3A+Jyk7XG5cbiAgICAgICAgZWRpdG9yLnVuZG8oKTtcbiAgICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPmhlbGxvPC9wPicpO1xuXG4gICAgICAgIGVkaXRvci5yZWRvKCk7XG4gICAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbyB3b3JsZDwvcD4nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVzY3JpYmUoJ3RhYicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGluc2VydCB0YWInLCAoKSA9PiB7XG4gICAgICBlZGl0b3IudGFiKCk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG8mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8L3A+Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbnNlcnRQYXJhZ3JhcGgnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBpbnNlcnQgcGFyYWdyYXBoJywgKCkgPT4ge1xuICAgICAgZWRpdG9yLmluc2VydFBhcmFncmFwaCgpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPmhlbGxvPC9wPjxwPjxicj48L3A+Jyk7XG5cbiAgICAgIGVkaXRvci5pbnNlcnRQYXJhZ3JhcGgoKTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbzwvcD48cD48YnI+PC9wPjxwPjxicj48L3A+Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGlmIChlbnYuaXNXZWJraXQpIHtcbiAgICBkZXNjcmliZSgnaW5zZXJ0SW1hZ2UnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGluc2VydCBpbWFnZScsICgpID0+IHtcbiAgICAgICAgdmFyIHNvdXJjZSA9ICdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUFZQUFBQUdDQVlBQUFEZ3pPOUlBQUFBRjBsRVFWUVlHV1A4Ly8vL2Z3WXNnQW1MR0ZpSUhoSUFUK29FQ0dIdU4yVUFBQUFBU1VWT1JLNUNZSUk9JztcbiAgICAgICAgcmV0dXJuIGVkaXRvci5pbnNlcnRJbWFnZShzb3VyY2UsICdpbWFnZScpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbzxpbWcgc3JjPVwiJyArIHNvdXJjZSArICdcIiBkYXRhLWZpbGVuYW1lPVwiaW1hZ2VcIiBzdHlsZT1cIndpZHRoOiAwcHg7XCI+PC9wPicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVzY3JpYmUoJ2luc2VydE9yZGVyZWRMaXN0IGFuZCBpbnNlcnRVbm9yZGVyZWRMaXN0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdG9nZ2xlIHBhcmFncmFwaCB0byBsaXN0JywgKCkgPT4ge1xuICAgICAgZWRpdG9yLmluc2VydE9yZGVyZWRMaXN0KCk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPG9sPjxsaT5oZWxsbzwvbGk+PC9vbD4nKTtcblxuICAgICAgZWRpdG9yLmluc2VydFVub3JkZXJlZExpc3QoKTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8dWw+PGxpPmhlbGxvPC9saT48L3VsPicpO1xuXG4gICAgICBlZGl0b3IuaW5zZXJ0VW5vcmRlcmVkTGlzdCgpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPmhlbGxvPC9wPicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5kZW50IGFuZCBvdXRkZW50JywgKCkgPT4ge1xuICAgIC8vIFt3b3JrYXJvdW5kXSBzdHlsZSBpcyBkaWZmZXJlbnQgYnkgYnJvd3NlclxuICAgIGlmIChlbnYuaXNQaGFudG9tKSB7XG4gICAgICBpdCgnc2hvdWxkIGluZGVudCBhbmQgb3V0ZGVudCBwYXJhZ3JhcGgnLCAoKSA9PiB7XG4gICAgICAgIGVkaXRvci5pbmRlbnQoKTtcbiAgICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDI1cHg7XCI+aGVsbG88L3A+Jyk7XG5cbiAgICAgICAgZWRpdG9yLm91dGRlbnQoKTtcbiAgICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwIHN0eWxlPVwiXCI+aGVsbG88L3A+Jyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIGluZGVudCBhbmQgb3V0ZGVudCBsaXN0JywgKCkgPT4ge1xuICAgICAgZWRpdG9yLmluc2VydE9yZGVyZWRMaXN0KCk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPG9sPjxsaT5oZWxsbzwvbGk+PC9vbD4nKTtcblxuICAgICAgZWRpdG9yLmluZGVudCgpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxvbD48bGk+PG9sPjxsaT5oZWxsbzwvbGk+PC9vbD48L2xpPjwvb2w+Jyk7XG5cbiAgICAgIGVkaXRvci5pbmRlbnQoKTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8b2w+PGxpPjxvbD48bGk+PG9sPjxsaT5oZWxsbzwvbGk+PC9vbD48L2xpPjwvb2w+PC9saT48L29sPicpO1xuXG4gICAgICBlZGl0b3Iub3V0ZGVudCgpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxvbD48bGk+PG9sPjxsaT5oZWxsbzwvbGk+PC9vbD48L2xpPjwvb2w+Jyk7XG5cbiAgICAgIGVkaXRvci5vdXRkZW50KCk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPG9sPjxsaT5oZWxsbzwvbGk+PC9vbD4nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luc2VydE5vZGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBpbnNlcnQgbm9kZScsICgpID0+IHtcbiAgICAgIGVkaXRvci5pbnNlcnROb2RlKCQoJzxzcGFuPiB3b3JsZDwvc3Bhbj4nKVswXSk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG88c3Bhbj4gd29ybGQ8L3NwYW4+PC9wPicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBsaW1pdGVkJywgKCkgPT4ge1xuICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJC5zdW1tZXJub3RlLm9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5tYXhUZXh0TGVuZ3RoID0gNTtcbiAgICAgIGNvbnRleHQgPSBuZXcgQ29udGV4dCgkKCc8ZGl2PjxwPmhlbGxvPC9wPjwvZGl2PicpLCBvcHRpb25zKTtcbiAgICAgIGVkaXRvciA9IGNvbnRleHQubW9kdWxlcy5lZGl0b3I7XG5cbiAgICAgIGVkaXRvci5pbnNlcnROb2RlKCQoJzxzcGFuPiB3b3JsZDwvc3Bhbj4nKVswXSk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG88L3A+Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGluc2VydCBub2RlIGluIGxhc3QgZm9jdXMnLCAoKSA9PiB7XG4gICAgICAkZWRpdGFibGUuYXBwZW5kVG8oJ2JvZHknKTtcbiAgICAgIGNvbnRleHQuaW52b2tlKCdlZGl0b3IuZm9jdXMnKTtcbiAgICAgIGVkaXRvci5pbnNlcnROb2RlKCQoJzxzcGFuPiB3b3JsZDwvc3Bhbj4nKVswXSk7XG4gICAgICAkKCdib2R5JykuZm9jdXMoKTtcbiAgICAgIGVkaXRvci5pbnNlcnROb2RlKCQoJzxzcGFuPiBoZWxsbzwvc3Bhbj4nKVswXSk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+PHNwYW4+IHdvcmxkPC9zcGFuPjxzcGFuPiBoZWxsbzwvc3Bhbj5oZWxsbzwvcD4nKTtcblxuICAgICAgJGVkaXRhYmxlLnJlbW92ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5zZXJ0VGV4dCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGluc2VydCB0ZXh0JywgKCkgPT4ge1xuICAgICAgZWRpdG9yLmluc2VydFRleHQoJyB3b3JsZCcpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPmhlbGxvIHdvcmxkPC9wPicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBsaW1pdGVkJywgKCkgPT4ge1xuICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJC5zdW1tZXJub3RlLm9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5tYXhUZXh0TGVuZ3RoID0gNTtcbiAgICAgIGNvbnRleHQgPSBuZXcgQ29udGV4dCgkKCc8ZGl2PjxwPmhlbGxvPC9wPjwvZGl2PicpLCBvcHRpb25zKTtcbiAgICAgIGVkaXRvciA9IGNvbnRleHQubW9kdWxlcy5lZGl0b3I7XG5cbiAgICAgIGVkaXRvci5pbnNlcnRUZXh0KCcgd29ybGQnKTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbzwvcD4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaW5zZXJ0IHRleHQgaW4gbGFzdCBmb2N1cycsICgpID0+IHtcbiAgICAgICRlZGl0YWJsZS5hcHBlbmRUbygnYm9keScpO1xuICAgICAgY29udGV4dC5pbnZva2UoJ2VkaXRvci5mb2N1cycpO1xuICAgICAgZWRpdG9yLmluc2VydFRleHQoJyB3b3JsZCcpO1xuICAgICAgJCgnYm9keScpLmZvY3VzKCk7XG4gICAgICBlZGl0b3IuaW5zZXJ0VGV4dCgnIHN1bW1lcm5vdGUgJyk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+IHdvcmxkIHN1bW1lcm5vdGUgaGVsbG88L3A+Jyk7XG5cbiAgICAgICRlZGl0YWJsZS5yZW1vdmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Bhc3RlSFRNTCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHBhc3RlIGh0bWwnLCAoKSA9PiB7XG4gICAgICBlZGl0b3IucGFzdGVIVE1MKCc8c3Bhbj4gd29ybGQ8L3NwYW4+Jyk7XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG88c3Bhbj4gd29ybGQ8L3NwYW4+PC9wPicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgY2FsbCBjaGFuZ2UgY2hhbmdlIGV2ZW50IG1vcmUgdGhhbiBvbmNlIHBlciBwYXN0ZSBldmVudCcsICgpID0+IHtcbiAgICAgIHZhciBnZW5lcmF0ZUxhcmdlSHRtbCA9ICgpID0+IHtcbiAgICAgICAgdmFyIGh0bWwgPSAnPGRpdj4nO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDEwMDA7IGkrKykge1xuICAgICAgICAgIGh0bWwgKz0gJzxwPkhUTUwgZWxlbWVudCAjJyArIGkgKyAnPC9wPic7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICB9O1xuICAgICAgdmFyICRub3RlID0gY29udGV4dC5sYXlvdXRJbmZvLm5vdGU7XG4gICAgICB2YXIgc3B5ID0gY2hhaS5zcHkoKTtcbiAgICAgICRub3RlLm9uKCdzdW1tZXJub3RlLmNoYW5nZScsIHNweSk7XG4gICAgICB2YXIgaHRtbCA9IGdlbmVyYXRlTGFyZ2VIdG1sKCk7XG4gICAgICBlZGl0b3IucGFzdGVIVE1MKGh0bWwpO1xuICAgICAgZXhwZWN0KHNweSkudG8uaGF2ZS5iZWVuLmNhbGxlZC5vbmNlO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBsaW1pdGVkJywgKCkgPT4ge1xuICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJC5zdW1tZXJub3RlLm9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5tYXhUZXh0TGVuZ3RoID0gNTtcbiAgICAgIGNvbnRleHQgPSBuZXcgQ29udGV4dCgkKCc8ZGl2PjxwPmhlbGxvPC9wPjwvZGl2PicpLCBvcHRpb25zKTtcbiAgICAgIGVkaXRvciA9IGNvbnRleHQubW9kdWxlcy5lZGl0b3I7XG5cbiAgICAgIGVkaXRvci5wYXN0ZUhUTUwoJzxzcGFuPiB3b3JsZDwvc3Bhbj4nKTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbzwvcD4nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luc2VydEhvcml6b250YWxSdWxlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgaW5zZXJ0IGhvcml6b250YWwgcnVsZScsICgpID0+IHtcbiAgICAgIGVkaXRvci5pbnNlcnRIb3Jpem9udGFsUnVsZSgpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPmhlbGxvPC9wPjxocj48cD48YnI+PC9wPicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5zZXJ0VGFibGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBpbnNlcnQgdGFibGUnLCAoKSA9PiB7XG4gICAgICB2YXIgbWFya3VwID0gW1xuICAgICAgICAnPHA+aGVsbG88L3A+JyxcbiAgICAgICAgJzx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWJvcmRlcmVkXCI+PHRib2R5PicsXG4gICAgICAgICc8dHI+PHRkPjxicj48L3RkPjx0ZD48YnI+PC90ZD48L3RyPicsXG4gICAgICAgICc8dHI+PHRkPjxicj48L3RkPjx0ZD48YnI+PC90ZD48L3RyPicsXG4gICAgICAgICc8L3Rib2R5PjwvdGFibGU+JyxcbiAgICAgICAgJzxwPjxicj48L3A+JyxcbiAgICAgIF0uam9pbignJyk7XG4gICAgICBlZGl0b3IuaW5zZXJ0VGFibGUoJzJ4MicpO1xuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgbWFya3VwKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2VtcHR5JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgbWFrZSBjb250ZW50cyBlbXB0eScsICgpID0+IHtcbiAgICAgIGVkaXRvci5lbXB0eSgpO1xuICAgICAgZXhwZWN0KGVkaXRvci5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmb3JtYXRCbG9jaycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGFwcGx5IGZvcm1hdEJsb2NrJywgKCkgPT4ge1xuICAgICAgJGVkaXRhYmxlLmFwcGVuZFRvKCdib2R5Jyk7XG4gICAgICBlZGl0b3IuZm9ybWF0QmxvY2soJ2Jsb2NrcXVvdGUnKTtcblxuICAgICAgLy8gc3RhcnQgPHA+aGVsbG88L3A+ID0+IDxibG9ja3F1b3RlPmhlbGxvPC9ibG9ja3F1b3RlPlxuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxibG9ja3F1b3RlPmhlbGxvPC9ibG9ja3F1b3RlPicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhcHBseSBtdWx0aSBmb3JtYXRCbG9jaycsICgpID0+IHtcbiAgICAgIC8vIHNldCBtdWx0aSBibG9jayBodG1sXG4gICAgICB2YXIgY29kZXMgPSBbXG4gICAgICAgICc8cD48YSBocmVmPVwiaHR0cDovL3N1bW1lcm5vdGUub3JnXCI+aGVsbG8gd29ybGQ8L2E+PC9wPicsXG4gICAgICAgICc8cD48YSBocmVmPVwiaHR0cDovL3N1bW1lcm5vdGUub3JnXCI+aGVsbG8gd29ybGQ8L2E+PC9wPicsXG4gICAgICAgICc8cD48YSBocmVmPVwiaHR0cDovL3N1bW1lcm5vdGUub3JnXCI+aGVsbG8gd29ybGQ8L2E+PC9wPicsXG4gICAgICBdO1xuXG4gICAgICBjb250ZXh0Lmludm9rZSgnY29kZScsIGNvZGVzLmpvaW4oJycpKTtcblxuICAgICAgLy8gcnVuIGZvcm1hdEJsb2NrXG4gICAgICAkZWRpdGFibGUuYXBwZW5kVG8oJ2JvZHknKTtcbiAgICAgIGVkaXRvci5mb3JtYXRCbG9jaygnYmxvY2txdW90ZScpO1xuXG4gICAgICAvLyBjaGVjayBjdXJyZW50IHJhbmdlIHBvc2l0aW9uIGluIGJsb2NrcXVvdGUgZWxlbWVudFxuXG4gICAgICB2YXIgbm9kZU5hbWUgPSAkZWRpdGFibGUuY2hpbGRyZW4oKVswXS5ub2RlTmFtZTtcbiAgICAgIGV4cGVjdChub2RlTmFtZSkudG8uZXF1YWxzSWdub3JlQ2FzZSgnYmxvY2txdW90ZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhcHBseSBtdWx0aSB0ZXN0IDIgLSBmb3JtYXRCbG9jaycsICgpID0+IHtcbiAgICAgIHZhciBjb2RlcyA9IFtcbiAgICAgICAgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5oZWxsbyB3b3JsZDwvYT48L3A+JyxcbiAgICAgICAgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5oZWxsbyB3b3JsZDwvYT48L3A+JyxcbiAgICAgICAgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5oZWxsbyB3b3JsZDwvYT48L3A+JyxcbiAgICAgIF07XG5cbiAgICAgIGNvbnRleHQuaW52b2tlKCdjb2RlJywgY29kZXMuam9pbignJykpO1xuICAgICAgJGVkaXRhYmxlLmFwcGVuZFRvKCdib2R5Jyk7XG5cbiAgICAgIHZhciBzdGFydE5vZGUgPSAkZWRpdGFibGUuZmluZCgncCcpLmZpcnN0KClbMF07XG4gICAgICB2YXIgZW5kTm9kZSA9ICRlZGl0YWJsZS5maW5kKCdwJykubGFzdCgpWzBdO1xuXG4gICAgICAvLyBhbGwgcCB0YWdzIGlzIHdyYXBwZWRcbiAgICAgIHJhbmdlLmNyZWF0ZShzdGFydE5vZGUsIDEsIGVuZE5vZGUsIDEpLm5vcm1hbGl6ZSgpLnNlbGVjdCgpO1xuXG4gICAgICBlZGl0b3IuZm9ybWF0QmxvY2soJ2Jsb2NrcXVvdGUnKTtcblxuICAgICAgdmFyIG5vZGVOYW1lID0gJGVkaXRhYmxlLmNoaWxkcmVuKClbMF0ubm9kZU5hbWU7XG4gICAgICBleHBlY3Qobm9kZU5hbWUpLnRvLmVxdWFsc0lnbm9yZUNhc2UoJ2Jsb2NrcXVvdGUnKTtcblxuICAgICAgLy8gcCAtPiBibG9ja3F1b3RlLCBwIGlzIG5vbmVcbiAgICAgIGV4cGVjdCgkZWRpdGFibGUuZmluZCgncCcpLmxlbmd0aCkudG8uZXF1YWxzKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhcHBseSBjdXN0b20gY2xhc3NOYW1lIGluIGZvcm1hdEJsb2NrJywgKCkgPT4ge1xuICAgICAgdmFyICR0YXJnZXQgPSAkKCc8YmxvY2txdW90ZSBjbGFzcz1cImJsb2NrcXVvdGVcIiAvPicpO1xuICAgICAgJGVkaXRhYmxlLmFwcGVuZFRvKCdib2R5Jyk7XG4gICAgICBlZGl0b3IuZm9ybWF0QmxvY2soJ2Jsb2NrcXVvdGUnLCAkdGFyZ2V0KTtcblxuICAgICAgLy8gc3RhcnQgPHA+aGVsbG88L3A+ID0+IDxibG9ja3F1b3RlIGNsYXNzPVwiYmxvY2txdW90ZVwiPmhlbGxvPC9ibG9ja3F1b3RlPlxuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxibG9ja3F1b3RlIGNsYXNzPVwiYmxvY2txdW90ZVwiPmhlbGxvPC9ibG9ja3F1b3RlPicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmaW5kIGV4YWN0IHRhcmdldCBpbiBmb3JtYXRCbG9jaycsICgpID0+IHtcbiAgICAgIHZhciAkdGFyZ2V0ID0gJCgnPGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIiBkYXRhLXZhbHVlPVwiYmxvY2txdW90ZVwiIHJvbGU9XCJsaXN0aXRlbVwiIGFyaWEtbGFiZWw9XCJibG9ja3F1b3RlXCI+PGJsb2NrcXVvdGUgY2xhc3M9XCJibG9ja3F1b3RlXCI+QmxvY2txdW90ZTwvYmxvY2txdW90ZT48L2E+Jyk7XG4gICAgICAkZWRpdGFibGUuYXBwZW5kVG8oJ2JvZHknKTtcbiAgICAgIGVkaXRvci5mb3JtYXRCbG9jaygnYmxvY2txdW90ZScsICR0YXJnZXQpO1xuXG4gICAgICAvLyBzdGFydCA8cD5oZWxsbzwvcD4gPT4gPGJsb2NrcXVvdGUgY2xhc3M9XCJibG9ja3F1b3RlXCI+aGVsbG88L2Jsb2NrcXVvdGU+XG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPGJsb2NrcXVvdGUgY2xhc3M9XCJibG9ja3F1b3RlXCI+aGVsbG88L2Jsb2NrcXVvdGU+Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVMaW5rJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIG5vcm1hbCBsaW5rJywgKCkgPT4ge1xuICAgICAgdmFyIHRleHQgPSAnaGVsbG8nO1xuICAgICAgdmFyIHBOb2RlID0gJGVkaXRhYmxlLmZpbmQoJ3AnKVswXTtcbiAgICAgIHZhciB0ZXh0Tm9kZSA9IHBOb2RlLmNoaWxkTm9kZXNbMF07XG4gICAgICB2YXIgc3RhcnRJbmRleCA9IHRleHROb2RlLndob2xlVGV4dC5pbmRleE9mKHRleHQpO1xuICAgICAgdmFyIGVuZEluZGV4ID0gc3RhcnRJbmRleCArIHRleHQubGVuZ3RoO1xuXG4gICAgICByYW5nZS5jcmVhdGUodGV4dE5vZGUsIHN0YXJ0SW5kZXgsIHRleHROb2RlLCBlbmRJbmRleCkubm9ybWFsaXplKCkuc2VsZWN0KCk7XG5cbiAgICAgIC8vIGNoZWNrIGNyZWF0aW9uIG5vcm1hbCBsaW5rXG4gICAgICBlZGl0b3IuY3JlYXRlTGluayh7XG4gICAgICAgIHVybDogJ2h0dHA6Ly9zdW1tZXJub3RlLm9yZycsXG4gICAgICAgIHRleHQ6ICdzdW1tZXJub3RlJyxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+aGVsbG88YSBocmVmPVwiaHR0cDovL3N1bW1lcm5vdGUub3JnXCI+c3VtbWVybm90ZTwvYT48L3A+Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIGxpbmsgd2l0aCByYW5nZScsICgpID0+IHtcbiAgICAgIHZhciB0ZXh0ID0gJ2hlbGxvJztcbiAgICAgIHZhciBwTm9kZSA9ICRlZGl0YWJsZS5maW5kKCdwJylbMF07XG4gICAgICB2YXIgdGV4dE5vZGUgPSBwTm9kZS5jaGlsZE5vZGVzWzBdO1xuICAgICAgdmFyIHN0YXJ0SW5kZXggPSB0ZXh0Tm9kZS53aG9sZVRleHQuaW5kZXhPZih0ZXh0KTtcbiAgICAgIHZhciBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyB0ZXh0Lmxlbmd0aDtcblxuICAgICAgdmFyIHJuZyA9IHJhbmdlLmNyZWF0ZSh0ZXh0Tm9kZSwgc3RhcnRJbmRleCwgdGV4dE5vZGUsIGVuZEluZGV4KTtcblxuICAgICAgZWRpdG9yLmNyZWF0ZUxpbmsoe1xuICAgICAgICB1cmw6ICdodHRwOi8vc3VtbWVybm90ZS5vcmcnLFxuICAgICAgICB0ZXh0OiAnc3VtbWVybm90ZScsXG4gICAgICAgIHJhbmdlOiBybmcsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5zdW1tZXJub3RlPC9hPjwvcD4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbGluayB3aXRoIGlzTmV3V2luZG93JywgKCkgPT4ge1xuICAgICAgdmFyIHRleHQgPSAnaGVsbG8nO1xuICAgICAgdmFyIHBOb2RlID0gJGVkaXRhYmxlLmZpbmQoJ3AnKVswXTtcbiAgICAgIHZhciB0ZXh0Tm9kZSA9IHBOb2RlLmNoaWxkTm9kZXNbMF07XG4gICAgICB2YXIgc3RhcnRJbmRleCA9IHRleHROb2RlLndob2xlVGV4dC5pbmRleE9mKHRleHQpO1xuICAgICAgdmFyIGVuZEluZGV4ID0gc3RhcnRJbmRleCArIHRleHQubGVuZ3RoO1xuXG4gICAgICB2YXIgcm5nID0gcmFuZ2UuY3JlYXRlKHRleHROb2RlLCBzdGFydEluZGV4LCB0ZXh0Tm9kZSwgZW5kSW5kZXgpO1xuXG4gICAgICBlZGl0b3IuY3JlYXRlTGluayh7XG4gICAgICAgIHVybDogJ2h0dHA6Ly9zdW1tZXJub3RlLm9yZycsXG4gICAgICAgIHRleHQ6ICdzdW1tZXJub3RlJyxcbiAgICAgICAgcmFuZ2U6IHJuZyxcbiAgICAgICAgaXNOZXdXaW5kb3c6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0Q29udGVudHMoY29udGV4dCwgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIiB0YXJnZXQ9XCJfYmxhbmtcIj5zdW1tZXJub3RlPC9hPjwvcD4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgcmVsYXRpdmUgbGluayB3aXRob3V0IHNjaGVtZScsICgpID0+IHtcbiAgICAgIHZhciB0ZXh0ID0gJ2hlbGxvJztcbiAgICAgIHZhciBwTm9kZSA9ICRlZGl0YWJsZS5maW5kKCdwJylbMF07XG4gICAgICB2YXIgdGV4dE5vZGUgPSBwTm9kZS5jaGlsZE5vZGVzWzBdO1xuICAgICAgdmFyIHN0YXJ0SW5kZXggPSB0ZXh0Tm9kZS53aG9sZVRleHQuaW5kZXhPZih0ZXh0KTtcbiAgICAgIHZhciBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyB0ZXh0Lmxlbmd0aDtcblxuICAgICAgdmFyIHJuZyA9IHJhbmdlLmNyZWF0ZSh0ZXh0Tm9kZSwgc3RhcnRJbmRleCwgdGV4dE5vZGUsIGVuZEluZGV4KTtcblxuICAgICAgZWRpdG9yLmNyZWF0ZUxpbmsoe1xuICAgICAgICB1cmw6ICcvcmVsYXRpdmUvdXJsJyxcbiAgICAgICAgdGV4dDogJ3N1bW1lcm5vdGUnLFxuICAgICAgICByYW5nZTogcm5nLFxuICAgICAgICBpc05ld1dpbmRvdzogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+PGEgaHJlZj1cIi9yZWxhdGl2ZS91cmxcIiB0YXJnZXQ9XCJfYmxhbmtcIj5zdW1tZXJub3RlPC9hPjwvcD4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbW9kaWZ5IGEgbGluaycsICgpID0+IHtcbiAgICAgIGNvbnRleHQuaW52b2tlKCdjb2RlJywgJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5oZWxsbyB3b3JsZDwvYT48L3A+Jyk7XG5cbiAgICAgIHZhciBhbmNob3JOb2RlID0gJGVkaXRhYmxlLmZpbmQoJ2EnKVswXTtcbiAgICAgIHZhciBybmcgPSByYW5nZS5jcmVhdGVGcm9tTm9kZShhbmNob3JOb2RlKTtcblxuICAgICAgZWRpdG9yLmNyZWF0ZUxpbmsoe1xuICAgICAgICB1cmw6ICdodHRwOi8vd293LnN1bW1lcm5vdGUub3JnJyxcbiAgICAgICAgdGV4dDogJ3N1bW1lcm5vdGUgd293JyxcbiAgICAgICAgcmFuZ2U6IHJuZyxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPHA+PGEgaHJlZj1cImh0dHA6Ly93b3cuc3VtbWVybm90ZS5vcmdcIj5zdW1tZXJub3RlIHdvdzwvYT48L3A+Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGxpbWl0ZWQgd2hlbiBjcmVhdGluZyBhIGxpbmsnLCAoKSA9PiB7XG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCAkLnN1bW1lcm5vdGUub3B0aW9ucyk7XG4gICAgICBvcHRpb25zLm1heFRleHRMZW5ndGggPSA1O1xuICAgICAgY29udGV4dCA9IG5ldyBDb250ZXh0KCQoJzxkaXY+PHA+aGVsbG88L3A+PC9kaXY+JyksIG9wdGlvbnMpO1xuICAgICAgZWRpdG9yID0gY29udGV4dC5tb2R1bGVzLmVkaXRvcjtcblxuICAgICAgZWRpdG9yLmNyZWF0ZUxpbmsoe1xuICAgICAgICB1cmw6ICdodHRwOi8vc3VtbWVybm90ZS5vcmcnLFxuICAgICAgICB0ZXh0OiAnc3VtbWVybm90ZScsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdENvbnRlbnRzKGNvbnRleHQsICc8cD5oZWxsbzwvcD4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgbGltaXRlZCB3aGVuIG1vZGlmeWluZyBhIGxpbmsnLCAoKSA9PiB7XG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCAkLnN1bW1lcm5vdGUub3B0aW9ucyk7XG4gICAgICBvcHRpb25zLm1heFRleHRMZW5ndGggPSA1O1xuICAgICAgY29udGV4dCA9IG5ldyBDb250ZXh0KCQoJzxwPjxhIGhyZWY9XCJodHRwOi8vc3VtbWVybm90ZS5vcmdcIj5oZWxsbzwvYT48L3A+JyksIG9wdGlvbnMpO1xuXG4gICAgICB2YXIgZWRpdGFibGUgPSBjb250ZXh0LmxheW91dEluZm8uZWRpdGFibGU7XG4gICAgICB2YXIgYW5jaG9yTm9kZSA9IGVkaXRhYmxlLmZpbmQoJ2EnKVswXTtcbiAgICAgIHZhciBybmcgPSByYW5nZS5jcmVhdGVGcm9tTm9kZShhbmNob3JOb2RlKTtcbiAgICAgIGVkaXRvciA9IGNvbnRleHQubW9kdWxlcy5lZGl0b3I7XG5cbiAgICAgIGVkaXRvci5jcmVhdGVMaW5rKHtcbiAgICAgICAgdXJsOiAnaHR0cDovL3N1bW1lcm5vdGUub3JnJyxcbiAgICAgICAgdGV4dDogJ2hlbGxvIHdvcmxkJyxcbiAgICAgICAgcmFuZ2U6IHJuZyxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3RDb250ZW50cyhjb250ZXh0LCAnPGEgaHJlZj1cImh0dHA6Ly9zdW1tZXJub3RlLm9yZ1wiPmhlbGxvPC9hPicpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19