all files / src/js/base/module/ Buttons.js

85.42% Statements 252/295
58.62% Branches 51/87
90.91% Functions 80/88
85.37% Lines 251/294
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 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 97× 97× 97× 97× 97× 97×   1188× 1188×     1188× 1188×   1188×       1188×   4080×     4080× 4080×   97× 97× 97× 97× 97×     1162× 1089×     1162×   87× 87× 87×   167× 167×                                               167× 167× 127× 127×   167× 127× 127×     40×                                                                                                 167× 254× 254×                 167×     167× 254× 254×               167× 254×                                                             97× 97× 87×                           783× 696×   783× 783× 783× 783× 783×           97× 873× 873×                 97× 97× 873×   97× 87×             97× 40×             97× 87×             97× 87×           97× 40×             97× 40×             97× 40×             97× 87×   87× 87× 87× 43×       87×                             1038×           97× 40×                                   97× 87×   97× 40×   97× 40×   97× 87×           97× 87×           97×         97×         97×         97×         97×         97×         97× 97× 97× 97× 97× 97× 97× 87×                                         97×                                     97× 87×                                             87× 87×               97× 91×           97× 87×           97× 93×           97×             97× 87×             97× 87×             97×             97×             97× 87×                           97×   97× 97×           97× 97×           97× 97×           97× 97×             97× 97×           97× 97×           97× 97×             97× 97×             97× 97× 97×           97× 97×                         97× 97× 97×             97× 97×             97× 97×             97× 97×             97× 97×             97× 97×             97× 97×               388× 1288× 1288× 1288× 1288×     1288× 3331× 3331× 3331×     1288×           175× 175× 175× 175×   175×     175×     175×     175×     175×     175×     175× 81× 81×       81× 81× 876×   876× 876×   81×   175× 81× 81× 549×   549× 549×   81×   175× 81× 81×             175× 175× 1050×                                                                                    
(function(global){global.wrappers['/Users/lqez/Dev/summernote/src/js/base/module/Buttons.js']=[function(require,module,exports,__dirname,__filename){ "use strict";
exports.__esModule = true;
var jquery_1 = require("jquery");
var func_1 = require("../core/func");
var lists_1 = require("../core/lists");
var env_1 = require("../core/env");
var Buttons = /** @class */ (function () {
    function Buttons(context) {
        this.ui = jquery_1["default"].summernote.ui;
        this.context = context;
        this.$toolbar = context.layoutInfo.toolbar;
        this.options = context.options;
        this.lang = this.options.langInfo;
        this.invertedKeyMap = func_1["default"].invertObject(this.options.keyMap[env_1["default"].isMac ? 'mac' : 'pc']);
    }
    Buttons.prototype.representShortcut = function (editorMethod) {
        var shortcut = this.invertedKeyMap[editorMethod];
        Iif (!this.options.shortcuts || !shortcut) {
            return '';
        }
        Eif (env_1["default"].isMac) {
            shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');
        }
        shortcut = shortcut.replace('BACKSLASH', '\\')
            .replace('SLASH', '/')
            .replace('LEFTBRACKET', '[')
            .replace('RIGHTBRACKET', ']');
        return ' (' + shortcut + ')';
    };
    Buttons.prototype.button = function (o) {
        Iif (!this.options.tooltip && o.tooltip) {
            delete o.tooltip;
        }
        o.container = this.options.container;
        return this.ui.button(o);
    };
    Buttons.prototype.initialize = function () {
        this.addToolbarButtons();
        this.addImagePopoverButtons();
        this.addLinkPopoverButtons();
        this.addTablePopoverButtons();
        this.fontInstalledMap = {};
    };
    Buttons.prototype.destroy = function () {
        delete this.fontInstalledMap;
    };
    Buttons.prototype.isFontInstalled = function (name) {
        if (!this.fontInstalledMap.hasOwnProperty(name)) {
            this.fontInstalledMap[name] = env_1["default"].isFontInstalled(name) ||
                lists_1["default"].contains(this.options.fontNamesIgnoreCheck, name);
        }
        return this.fontInstalledMap[name];
    };
    Buttons.prototype.isFontDeservedToAdd = function (name) {
        var genericFamilies = ['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy'];
        name = name.toLowerCase();
        return ((name !== '') && this.isFontInstalled(name) && (jquery_1["default"].inArray(name, genericFamilies) === -1));
    };
    Buttons.prototype.colorPalette = function (className, tooltip, backColor, foreColor) {
        var _this = this;
        return this.ui.buttonGroup({
            className: 'note-color ' + className,
            children: [
                this.button({
                    className: 'note-current-color-button',
                    contents: this.ui.icon(this.options.icons.font + ' note-recent-color'),
                    tooltip: tooltip,
                    click: function (e) {
                        var $button = jquery_1["default"](e.currentTarget);
                        Eif (backColor && foreColor) {
                            _this.context.invoke('editor.color', {
                                backColor: $button.attr('data-backColor'),
                                foreColor: $button.attr('data-foreColor')
                            });
                        }
                        else if (backColor) {
                            _this.context.invoke('editor.color', {
                                backColor: $button.attr('data-backColor')
                            });
                        }
                        else if (foreColor) {
                            _this.context.invoke('editor.color', {
                                foreColor: $button.attr('data-foreColor')
                            });
                        }
                    },
                    callback: function ($button) {
                        var $recentColor = $button.find('.note-recent-color');
                        if (backColor) {
                            $recentColor.css('background-color', _this.options.colorButton.backColor);
                            $button.attr('data-backColor', _this.options.colorButton.backColor);
                        }
                        if (foreColor) {
                            $recentColor.css('color', _this.options.colorButton.foreColor);
                            $button.attr('data-foreColor', _this.options.colorButton.foreColor);
                        }
                        else {
                            $recentColor.css('color', 'transparent');
                        }
                    }
                }),
                this.button({
                    className: 'dropdown-toggle',
                    contents: this.ui.dropdownButtonContents('', this.options),
                    tooltip: this.lang.color.more,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                this.ui.dropdown({
                    items: (backColor ? [
                        '<div class="note-palette">',
                        '  <div class="note-palette-title">' + this.lang.color.background + '</div>',
                        '  <div>',
                        '    <button type="button" class="note-color-reset btn btn-light" data-event="backColor" data-value="inherit">',
                        this.lang.color.transparent,
                        '    </button>',
                        '  </div>',
                        '  <div class="note-holder" data-event="backColor"/>',
                        '  <div>',
                        '    <button type="button" class="note-color-select btn" data-event="openPalette" data-value="backColorPicker">',
                        this.lang.color.cpSelect,
                        '    </button>',
                        '    <input type="color" id="backColorPicker" class="note-btn note-color-select-btn" value="' + this.options.colorButton.backColor + '" data-event="backColorPalette">',
                        '  </div>',
                        '  <div class="note-holder-custom" id="backColorPalette" data-event="backColor"/>',
                        '</div>',
                    ].join('') : '') +
                        (foreColor ? [
                            '<div class="note-palette">',
                            '  <div class="note-palette-title">' + this.lang.color.foreground + '</div>',
                            '  <div>',
                            '    <button type="button" class="note-color-reset btn btn-light" data-event="removeFormat" data-value="foreColor">',
                            this.lang.color.resetToDefault,
                            '    </button>',
                            '  </div>',
                            '  <div class="note-holder" data-event="foreColor"/>',
                            '  <div>',
                            '    <button type="button" class="note-color-select btn" data-event="openPalette" data-value="foreColorPicker">',
                            this.lang.color.cpSelect,
                            '    </button>',
                            '    <input type="color" id="foreColorPicker" class="note-btn note-color-select-btn" value="' + this.options.colorButton.foreColor + '" data-event="foreColorPalette">',
                            '  <div class="note-holder-custom" id="foreColorPalette" data-event="foreColor"/>',
                            '</div>',
                        ].join('') : ''),
                    callback: function ($dropdown) {
                        $dropdown.find('.note-holder').each(function (idx, item) {
                            var $holder = jquery_1["default"](item);
                            $holder.append(_this.ui.palette({
                                colors: _this.options.colors,
                                colorsName: _this.options.colorsName,
                                eventName: $holder.data('event'),
                                container: _this.options.container,
                                tooltip: _this.options.tooltip
                            }).render());
                        });
                        /* TODO: do we have to record recent custom colors within cookies? */
                        var customColors = [
                            ['#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF'],
                        ];
                        $dropdown.find('.note-holder-custom').each(function (idx, item) {
                            var $holder = jquery_1["default"](item);
                            $holder.append(_this.ui.palette({
                                colors: customColors,
                                colorsName: customColors,
                                eventName: $holder.data('event'),
                                container: _this.options.container,
                                tooltip: _this.options.tooltip
                            }).render());
                        });
                        $dropdown.find('input[type=color]').each(function (idx, item) {
                            jquery_1["default"](item).change(function () {
                                var $chip = $dropdown.find('#' + jquery_1["default"](this).data('event')).find('.note-color-btn').first();
                                var color = this.value.toUpperCase();
                                $chip.css('background-color', color)
                                    .attr('aria-label', color)
                                    .attr('data-value', color)
                                    .attr('data-original-title', color);
                                $chip.click();
                            });
                        });
                    },
                    click: function (event) {
                        event.stopPropagation();
                        var $parent = jquery_1["default"]('.' + className);
                        var $button = jquery_1["default"](event.target);
                        var eventName = $button.data('event');
                        var value = $button.attr('data-value');
                        Iif (eventName === 'openPalette') {
                            var $picker = $parent.find('#' + value);
                            var $palette = jquery_1["default"]($parent.find('#' + $picker.data('event')).find('.note-color-row')[0]);
                            // Shift palette chips
                            var $chip = $palette.find('.note-color-btn').last().detach();
                            // Set chip attributes
                            var color = $picker.val();
                            $chip.css('background-color', color)
                                .attr('aria-label', color)
                                .attr('data-value', color)
                                .attr('data-original-title', color);
                            $palette.prepend($chip);
                            $picker.click();
                        }
                        else Eif (lists_1["default"].contains(['backColor', 'foreColor'], eventName)) {
                            var key = eventName === 'backColor' ? 'background-color' : 'color';
                            var $color = $button.closest('.note-color').find('.note-recent-color');
                            var $currentButton = $button.closest('.note-color').find('.note-current-color-button');
                            $color.css(key, value);
                            $currentButton.attr('data-' + eventName, value);
                            _this.context.invoke('editor.' + eventName, value);
                        }
                    }
                }),
            ]
        }).render();
    };
    Buttons.prototype.addToolbarButtons = function () {
        var _this = this;
        this.context.memo('button.style', function () {
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.magic), _this.options),
                    tooltip: _this.lang.style.style,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdown({
                    className: 'dropdown-style',
                    items: _this.options.styleTags,
                    title: _this.lang.style.style,
                    template: function (item) {
                        if (typeof item === 'string') {
                            item = { tag: item, title: (_this.lang.style.hasOwnProperty(item) ? _this.lang.style[item] : item) };
                        }
                        var tag = item.tag;
                        var title = item.title;
                        var style = item.style ? ' style="' + item.style + '" ' : '';
                        var className = item.className ? ' class="' + item.className + '"' : '';
                        return '<' + tag + style + className + '>' + title + '</' + tag + '>';
                    },
                    click: _this.context.createInvokeHandler('editor.formatBlock')
                }),
            ]).render();
        });
        var _loop_1 = function (styleIdx, styleLen) {
            var item = this_1.options.styleTags[styleIdx];
            this_1.context.memo('button.style.' + item, function () {
                return _this.button({
                    className: 'note-btn-style-' + item,
                    contents: '<div data-value="' + item + '">' + item.toUpperCase() + '</div>',
                    tooltip: _this.lang.style[item],
                    click: _this.context.createInvokeHandler('editor.formatBlock')
                }).render();
            });
        };
        var this_1 = this;
        for (var styleIdx = 0, styleLen = this.options.styleTags.length; styleIdx < styleLen; styleIdx++) {
            _loop_1(styleIdx, styleLen);
        }
        this.context.memo('button.bold', function () {
            return _this.button({
                className: 'note-btn-bold',
                contents: _this.ui.icon(_this.options.icons.bold),
                tooltip: _this.lang.font.bold + _this.representShortcut('bold'),
                click: _this.context.createInvokeHandlerAndUpdateState('editor.bold')
            }).render();
        });
        this.context.memo('button.italic', function () {
            return _this.button({
                className: 'note-btn-italic',
                contents: _this.ui.icon(_this.options.icons.italic),
                tooltip: _this.lang.font.italic + _this.representShortcut('italic'),
                click: _this.context.createInvokeHandlerAndUpdateState('editor.italic')
            }).render();
        });
        this.context.memo('button.underline', function () {
            return _this.button({
                className: 'note-btn-underline',
                contents: _this.ui.icon(_this.options.icons.underline),
                tooltip: _this.lang.font.underline + _this.representShortcut('underline'),
                click: _this.context.createInvokeHandlerAndUpdateState('editor.underline')
            }).render();
        });
        this.context.memo('button.clear', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.eraser),
                tooltip: _this.lang.font.clear + _this.representShortcut('removeFormat'),
                click: _this.context.createInvokeHandler('editor.removeFormat')
            }).render();
        });
        this.context.memo('button.strikethrough', function () {
            return _this.button({
                className: 'note-btn-strikethrough',
                contents: _this.ui.icon(_this.options.icons.strikethrough),
                tooltip: _this.lang.font.strikethrough + _this.representShortcut('strikethrough'),
                click: _this.context.createInvokeHandlerAndUpdateState('editor.strikethrough')
            }).render();
        });
        this.context.memo('button.superscript', function () {
            return _this.button({
                className: 'note-btn-superscript',
                contents: _this.ui.icon(_this.options.icons.superscript),
                tooltip: _this.lang.font.superscript,
                click: _this.context.createInvokeHandlerAndUpdateState('editor.superscript')
            }).render();
        });
        this.context.memo('button.subscript', function () {
            return _this.button({
                className: 'note-btn-subscript',
                contents: _this.ui.icon(_this.options.icons.subscript),
                tooltip: _this.lang.font.subscript,
                click: _this.context.createInvokeHandlerAndUpdateState('editor.subscript')
            }).render();
        });
        this.context.memo('button.fontname', function () {
            var styleInfo = _this.context.invoke('editor.currentStyle');
            // Add 'default' fonts into the fontnames array if not exist
            jquery_1["default"].each(styleInfo['font-family'].split(','), function (idx, fontname) {
                fontname = fontname.trim().replace(/['"]+/g, '');
                if (_this.isFontDeservedToAdd(fontname)) {
                    if (jquery_1["default"].inArray(fontname, _this.options.fontNames) === -1) {
                        _this.options.fontNames.push(fontname);
                    }
                }
            });
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents('<span class="note-current-fontname"/>', _this.options),
                    tooltip: _this.lang.font.name,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdownCheck({
                    className: 'dropdown-fontname',
                    checkClassName: _this.options.icons.menuCheck,
                    items: _this.options.fontNames.filter(_this.isFontInstalled.bind(_this)),
                    title: _this.lang.font.name,
                    template: function (item) {
                        return '<span style="font-family: \'' + item + '\'">' + item + '</span>';
                    },
                    click: _this.context.createInvokeHandlerAndUpdateState('editor.fontName')
                }),
            ]).render();
        });
        this.context.memo('button.fontsize', function () {
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents('<span class="note-current-fontsize"/>', _this.options),
                    tooltip: _this.lang.font.size,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdownCheck({
                    className: 'dropdown-fontsize',
                    checkClassName: _this.options.icons.menuCheck,
                    items: _this.options.fontSizes,
                    title: _this.lang.font.size,
                    click: _this.context.createInvokeHandlerAndUpdateState('editor.fontSize')
                }),
            ]).render();
        });
        this.context.memo('button.color', function () {
            return _this.colorPalette('note-color-all', _this.lang.color.recent, true, true);
        });
        this.context.memo('button.forecolor', function () {
            return _this.colorPalette('note-color-fore', _this.lang.color.foreground, false, true);
        });
        this.context.memo('button.backcolor', function () {
            return _this.colorPalette('note-color-back', _this.lang.color.background, true, false);
        });
        this.context.memo('button.ul', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.unorderedlist),
                tooltip: _this.lang.lists.unordered + _this.representShortcut('insertUnorderedList'),
                click: _this.context.createInvokeHandler('editor.insertUnorderedList')
            }).render();
        });
        this.context.memo('button.ol', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.orderedlist),
                tooltip: _this.lang.lists.ordered + _this.representShortcut('insertOrderedList'),
                click: _this.context.createInvokeHandler('editor.insertOrderedList')
            }).render();
        });
        var justifyLeft = this.button({
            contents: this.ui.icon(this.options.icons.alignLeft),
            tooltip: this.lang.paragraph.left + this.representShortcut('justifyLeft'),
            click: this.context.createInvokeHandler('editor.justifyLeft')
        });
        var justifyCenter = this.button({
            contents: this.ui.icon(this.options.icons.alignCenter),
            tooltip: this.lang.paragraph.center + this.representShortcut('justifyCenter'),
            click: this.context.createInvokeHandler('editor.justifyCenter')
        });
        var justifyRight = this.button({
            contents: this.ui.icon(this.options.icons.alignRight),
            tooltip: this.lang.paragraph.right + this.representShortcut('justifyRight'),
            click: this.context.createInvokeHandler('editor.justifyRight')
        });
        var justifyFull = this.button({
            contents: this.ui.icon(this.options.icons.alignJustify),
            tooltip: this.lang.paragraph.justify + this.representShortcut('justifyFull'),
            click: this.context.createInvokeHandler('editor.justifyFull')
        });
        var outdent = this.button({
            contents: this.ui.icon(this.options.icons.outdent),
            tooltip: this.lang.paragraph.outdent + this.representShortcut('outdent'),
            click: this.context.createInvokeHandler('editor.outdent')
        });
        var indent = this.button({
            contents: this.ui.icon(this.options.icons.indent),
            tooltip: this.lang.paragraph.indent + this.representShortcut('indent'),
            click: this.context.createInvokeHandler('editor.indent')
        });
        this.context.memo('button.justifyLeft', func_1["default"].invoke(justifyLeft, 'render'));
        this.context.memo('button.justifyCenter', func_1["default"].invoke(justifyCenter, 'render'));
        this.context.memo('button.justifyRight', func_1["default"].invoke(justifyRight, 'render'));
        this.context.memo('button.justifyFull', func_1["default"].invoke(justifyFull, 'render'));
        this.context.memo('button.outdent', func_1["default"].invoke(outdent, 'render'));
        this.context.memo('button.indent', func_1["default"].invoke(indent, 'render'));
        this.context.memo('button.paragraph', function () {
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.alignLeft), _this.options),
                    tooltip: _this.lang.paragraph.paragraph,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdown([
                    _this.ui.buttonGroup({
                        className: 'note-align',
                        children: [justifyLeft, justifyCenter, justifyRight, justifyFull]
                    }),
                    _this.ui.buttonGroup({
                        className: 'note-list',
                        children: [outdent, indent]
                    }),
                ]),
            ]).render();
        });
        this.context.memo('button.height', function () {
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.textHeight), _this.options),
                    tooltip: _this.lang.font.height,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdownCheck({
                    items: _this.options.lineHeights,
                    checkClassName: _this.options.icons.menuCheck,
                    className: 'dropdown-line-height',
                    title: _this.lang.font.height,
                    click: _this.context.createInvokeHandler('editor.lineHeight')
                }),
            ]).render();
        });
        this.context.memo('button.table', function () {
            return _this.ui.buttonGroup([
                _this.button({
                    className: 'dropdown-toggle',
                    contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.table), _this.options),
                    tooltip: _this.lang.table.table,
                    data: {
                        toggle: 'dropdown'
                    }
                }),
                _this.ui.dropdown({
                    title: _this.lang.table.table,
                    className: 'note-table',
                    items: [
                        '<div class="note-dimension-picker">',
                        '  <div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"/>',
                        '  <div class="note-dimension-picker-highlighted"/>',
                        '  <div class="note-dimension-picker-unhighlighted"/>',
                        '</div>',
                        '<div class="note-dimension-display">1 x 1</div>',
                    ].join('')
                }),
            ], {
                callback: function ($node) {
                    var $catcher = $node.find('.note-dimension-picker-mousecatcher');
                    $catcher.css({
                        width: _this.options.insertTableMaxSize.col + 'em',
                        height: _this.options.insertTableMaxSize.row + 'em'
                    }).mousedown(_this.context.createInvokeHandler('editor.insertTable'))
                        .on('mousemove', _this.tableMoveHandler.bind(_this));
                }
            }).render();
        });
        this.context.memo('button.link', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.link),
                tooltip: _this.lang.link.link + _this.representShortcut('linkDialog.show'),
                click: _this.context.createInvokeHandler('linkDialog.show')
            }).render();
        });
        this.context.memo('button.picture', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.picture),
                tooltip: _this.lang.image.image,
                click: _this.context.createInvokeHandler('imageDialog.show')
            }).render();
        });
        this.context.memo('button.video', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.video),
                tooltip: _this.lang.video.video,
                click: _this.context.createInvokeHandler('videoDialog.show')
            }).render();
        });
        this.context.memo('button.hr', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.minus),
                tooltip: _this.lang.hr.insert + _this.representShortcut('insertHorizontalRule'),
                click: _this.context.createInvokeHandler('editor.insertHorizontalRule')
            }).render();
        });
        this.context.memo('button.fullscreen', function () {
            return _this.button({
                className: 'btn-fullscreen',
                contents: _this.ui.icon(_this.options.icons.arrowsAlt),
                tooltip: _this.lang.options.fullscreen,
                click: _this.context.createInvokeHandler('fullscreen.toggle')
            }).render();
        });
        this.context.memo('button.codeview', function () {
            return _this.button({
                className: 'btn-codeview',
                contents: _this.ui.icon(_this.options.icons.code),
                tooltip: _this.lang.options.codeview,
                click: _this.context.createInvokeHandler('codeview.toggle')
            }).render();
        });
        this.context.memo('button.redo', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.redo),
                tooltip: _this.lang.history.redo + _this.representShortcut('redo'),
                click: _this.context.createInvokeHandler('editor.redo')
            }).render();
        });
        this.context.memo('button.undo', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.undo),
                tooltip: _this.lang.history.undo + _this.representShortcut('undo'),
                click: _this.context.createInvokeHandler('editor.undo')
            }).render();
        });
        this.context.memo('button.help', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.question),
                tooltip: _this.lang.options.help,
                click: _this.context.createInvokeHandler('helpDialog.show')
            }).render();
        });
    };
    /**
     * image: [
     *   ['imageResize', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
     *   ['float', ['floatLeft', 'floatRight', 'floatNone']],
     *   ['remove', ['removeMedia']],
     * ],
     */
    Buttons.prototype.addImagePopoverButtons = function () {
        var _this = this;
        // Image Size Buttons
        this.context.memo('button.resizeFull', function () {
            return _this.button({
                contents: '<span class="note-fontsize-10">100%</span>',
                tooltip: _this.lang.image.resizeFull,
                click: _this.context.createInvokeHandler('editor.resize', '1')
            }).render();
        });
        this.context.memo('button.resizeHalf', function () {
            return _this.button({
                contents: '<span class="note-fontsize-10">50%</span>',
                tooltip: _this.lang.image.resizeHalf,
                click: _this.context.createInvokeHandler('editor.resize', '0.5')
            }).render();
        });
        this.context.memo('button.resizeQuarter', function () {
            return _this.button({
                contents: '<span class="note-fontsize-10">25%</span>',
                tooltip: _this.lang.image.resizeQuarter,
                click: _this.context.createInvokeHandler('editor.resize', '0.25')
            }).render();
        });
        this.context.memo('button.resizeNone', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.rollback),
                tooltip: _this.lang.image.resizeNone,
                click: _this.context.createInvokeHandler('editor.resize', '0')
            }).render();
        });
        // Float Buttons
        this.context.memo('button.floatLeft', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.floatLeft),
                tooltip: _this.lang.image.floatLeft,
                click: _this.context.createInvokeHandler('editor.floatMe', 'left')
            }).render();
        });
        this.context.memo('button.floatRight', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.floatRight),
                tooltip: _this.lang.image.floatRight,
                click: _this.context.createInvokeHandler('editor.floatMe', 'right')
            }).render();
        });
        this.context.memo('button.floatNone', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.rollback),
                tooltip: _this.lang.image.floatNone,
                click: _this.context.createInvokeHandler('editor.floatMe', 'none')
            }).render();
        });
        // Remove Buttons
        this.context.memo('button.removeMedia', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.trash),
                tooltip: _this.lang.image.remove,
                click: _this.context.createInvokeHandler('editor.removeMedia')
            }).render();
        });
    };
    Buttons.prototype.addLinkPopoverButtons = function () {
        var _this = this;
        this.context.memo('button.linkDialogShow', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.link),
                tooltip: _this.lang.link.edit,
                click: _this.context.createInvokeHandler('linkDialog.show')
            }).render();
        });
        this.context.memo('button.unlink', function () {
            return _this.button({
                contents: _this.ui.icon(_this.options.icons.unlink),
                tooltip: _this.lang.link.unlink,
                click: _this.context.createInvokeHandler('editor.unlink')
            }).render();
        });
    };
    /**
     * table : [
     *  ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
     *  ['delete', ['deleteRow', 'deleteCol', 'deleteTable']]
     * ],
     */
    Buttons.prototype.addTablePopoverButtons = function () {
        var _this = this;
        this.context.memo('button.addRowUp', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.rowAbove),
                tooltip: _this.lang.table.addRowAbove,
                click: _this.context.createInvokeHandler('editor.addRow', 'top')
            }).render();
        });
        this.context.memo('button.addRowDown', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.rowBelow),
                tooltip: _this.lang.table.addRowBelow,
                click: _this.context.createInvokeHandler('editor.addRow', 'bottom')
            }).render();
        });
        this.context.memo('button.addColLeft', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.colBefore),
                tooltip: _this.lang.table.addColLeft,
                click: _this.context.createInvokeHandler('editor.addCol', 'left')
            }).render();
        });
        this.context.memo('button.addColRight', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.colAfter),
                tooltip: _this.lang.table.addColRight,
                click: _this.context.createInvokeHandler('editor.addCol', 'right')
            }).render();
        });
        this.context.memo('button.deleteRow', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.rowRemove),
                tooltip: _this.lang.table.delRow,
                click: _this.context.createInvokeHandler('editor.deleteRow')
            }).render();
        });
        this.context.memo('button.deleteCol', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.colRemove),
                tooltip: _this.lang.table.delCol,
                click: _this.context.createInvokeHandler('editor.deleteCol')
            }).render();
        });
        this.context.memo('button.deleteTable', function () {
            return _this.button({
                className: 'btn-md',
                contents: _this.ui.icon(_this.options.icons.trash),
                tooltip: _this.lang.table.delTable,
                click: _this.context.createInvokeHandler('editor.deleteTable')
            }).render();
        });
    };
    Buttons.prototype.build = function ($container, groups) {
        for (var groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) {
            var group = groups[groupIdx];
            var groupName = jquery_1["default"].isArray(group) ? group[0] : group;
            var buttons = jquery_1["default"].isArray(group) ? ((group.length === 1) ? [group[0]] : group[1]) : [group];
            var $group = this.ui.buttonGroup({
                className: 'note-' + groupName
            }).render();
            for (var idx = 0, len = buttons.length; idx < len; idx++) {
                var btn = this.context.memo('button.' + buttons[idx]);
                Eif (btn) {
                    $group.append(typeof btn === 'function' ? btn() : btn);
                }
            }
            $group.appendTo($container);
        }
    };
    /**
     * @param {jQuery} [$container]
     */
    Buttons.prototype.updateCurrentStyle = function ($container) {
        var _this = this;
        var $cont = $container || this.$toolbar;
        var styleInfo = this.context.invoke('editor.currentStyle');
        this.updateBtnStates($cont, {
            '.note-btn-bold': function () {
                return styleInfo['font-bold'] === 'bold';
            },
            '.note-btn-italic': function () {
                return styleInfo['font-italic'] === 'italic';
            },
            '.note-btn-underline': function () {
                return styleInfo['font-underline'] === 'underline';
            },
            '.note-btn-subscript': function () {
                return styleInfo['font-subscript'] === 'subscript';
            },
            '.note-btn-superscript': function () {
                return styleInfo['font-superscript'] === 'superscript';
            },
            '.note-btn-strikethrough': function () {
                return styleInfo['font-strikethrough'] === 'strikethrough';
            }
        });
        if (styleInfo['font-family']) {
            var fontNames = styleInfo['font-family'].split(',').map(function (name) {
                return name.replace(/[\'\"]/g, '')
                    .replace(/\s+$/, '')
                    .replace(/^\s+/, '');
            });
            var fontName_1 = lists_1["default"].find(fontNames, this.isFontInstalled.bind(this));
            $cont.find('.dropdown-fontname a').each(function (idx, item) {
                var $item = jquery_1["default"](item);
                // always compare string to avoid creating another func.
                var isChecked = ($item.data('value') + '') === (fontName_1 + '');
                $item.toggleClass('checked', isChecked);
            });
            $cont.find('.note-current-fontname').text(fontName_1).css('font-family', fontName_1);
        }
        if (styleInfo['font-size']) {
            var fontSize_1 = styleInfo['font-size'];
            $cont.find('.dropdown-fontsize a').each(function (idx, item) {
                var $item = jquery_1["default"](item);
                // always compare with string to avoid creating another func.
                var isChecked = ($item.data('value') + '') === (fontSize_1 + '');
                $item.toggleClass('checked', isChecked);
            });
            $cont.find('.note-current-fontsize').text(fontSize_1);
        }
        if (styleInfo['line-height']) {
            var lineHeight_1 = styleInfo['line-height'];
            $cont.find('.dropdown-line-height li a').each(function (idx, item) {
                // always compare with string to avoid creating another func.
                var isChecked = (jquery_1["default"](item).data('value') + '') === (lineHeight_1 + '');
                _this.className = isChecked ? 'checked' : '';
            });
        }
    };
    Buttons.prototype.updateBtnStates = function ($container, infos) {
        var _this = this;
        jquery_1["default"].each(infos, function (selector, pred) {
            _this.ui.toggleBtnActive($container.find(selector), pred());
        });
    };
    Buttons.prototype.tableMoveHandler = function (event) {
        var PX_PER_EM = 18;
        var $picker = jquery_1["default"](event.target.parentNode); // target is mousecatcher
        var $dimensionDisplay = $picker.next();
        var $catcher = $picker.find('.note-dimension-picker-mousecatcher');
        var $highlighted = $picker.find('.note-dimension-picker-highlighted');
        var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');
        var posOffset;
        // HTML5 with jQuery - e.offsetX is undefined in Firefox
        if (event.offsetX === undefined) {
            var posCatcher = jquery_1["default"](event.target).offset();
            posOffset = {
                x: event.pageX - posCatcher.left,
                y: event.pageY - posCatcher.top
            };
        }
        else {
            posOffset = {
                x: event.offsetX,
                y: event.offsetY
            };
        }
        var dim = {
            c: Math.ceil(posOffset.x / PX_PER_EM) || 1,
            r: Math.ceil(posOffset.y / PX_PER_EM) || 1
        };
        $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });
        $catcher.data('value', dim.c + 'x' + dim.r);
        if (dim.c > 3 && dim.c < this.options.insertTableMaxSize.col) {
            $unhighlighted.css({ width: dim.c + 1 + 'em' });
        }
        if (dim.r > 3 && dim.r < this.options.insertTableMaxSize.row) {
            $unhighlighted.css({ height: dim.r + 1 + 'em' });
        }
        $dimensionDisplay.html(dim.c + ' x ' + dim.r);
    };
    return Buttons;
}());
exports["default"] = Buttons;
 
},'src/js/base/module/Buttons.js',{"jquery":"/Users/lqez/Dev/summernote/node_modules/jquery/dist/jquery.js","../core/func":"/Users/lqez/Dev/summernote/src/js/base/core/func.js","../core/lists":"/Users/lqez/Dev/summernote/src/js/base/core/lists.js","../core/env":"/Users/lqez/Dev/summernote/src/js/base/core/env.js"}];})(this);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnV0dG9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkJ1dHRvbnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBdUI7QUFDdkIscUNBQWdDO0FBQ2hDLHVDQUFrQztBQUNsQyxtQ0FBOEI7QUFFOUI7SUFDRSxpQkFBWSxPQUFPO1FBQ2pCLElBQUksQ0FBQyxFQUFFLEdBQUcsbUJBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7UUFDM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxpQkFBSSxDQUFDLFlBQVksQ0FDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZ0JBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQsbUNBQWlCLEdBQWpCLFVBQWtCLFlBQVk7UUFDNUIsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDeEMsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELElBQUksZ0JBQUcsQ0FBQyxLQUFLLEVBQUU7WUFDYixRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztTQUMvRDtRQUVELFFBQVEsR0FB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QVMsQ0FBQyxJQUFJLENBQUM7U0FDM0MsQ0FBQztRQUVGLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFNUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsR0FBRyxFQUFFO1lBQzVELGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNqRDtRQUVELElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRTtZQUM1RCxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLENBQUM7U0FDbEQ7UUFFRCxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFDSCxjQUFDO0FBQUQsQ0FBQyxBQXQ0QkQsSUFzNEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcbmltcG9ydCBmdW5jIGZyb20gJy4uL2NvcmUvZnVuYyc7XG5pbXBvcnQgbGlzdHMgZnJvbSAnLi4vY29yZS9saXN0cyc7XG5pbXBvcnQgZW52IGZyb20gJy4uL2NvcmUvZW52JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9ucyB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQpIHtcbiAgICB0aGlzLnVpID0gJC5zdW1tZXJub3RlLnVpO1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgdGhpcy4kdG9vbGJhciA9IGNvbnRleHQubGF5b3V0SW5mby50b29sYmFyO1xuICAgIHRoaXMub3B0aW9ucyA9IGNvbnRleHQub3B0aW9ucztcbiAgICB0aGlzLmxhbmcgPSB0aGlzLm9wdGlvbnMubGFuZ0luZm87XG4gICAgdGhpcy5pbnZlcnRlZEtleU1hcCA9IGZ1bmMuaW52ZXJ0T2JqZWN0KFxuICAgICAgdGhpcy5vcHRpb25zLmtleU1hcFtlbnYuaXNNYWMgPyAnbWFjJyA6ICdwYyddXG4gICAgKTtcbiAgfVxuXG4gIHJlcHJlc2VudFNob3J0Y3V0KGVkaXRvck1ldGhvZCkge1xuICAgIGxldCBzaG9ydGN1dCA9IHRoaXMuaW52ZXJ0ZWRLZXlNYXBbZWRpdG9yTWV0aG9kXTtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG9ydGN1dHMgfHwgIXNob3J0Y3V0KSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgaWYgKGVudi5pc01hYykge1xuICAgICAgc2hvcnRjdXQgPSBzaG9ydGN1dC5yZXBsYWNlKCdDTUQnLCAn4oyYJykucmVwbGFjZSgnU0hJRlQnLCAn4oenJyk7XG4gICAgfVxuXG4gICAgc2hvcnRjdXQgPSBzaG9ydGN1dC5yZXBsYWNlKCdCQUNLU0xBU0gnLCAnXFxcXCcpXG4gICAgICAucmVwbGFjZSgnU0xBU0gnLCAnLycpXG4gICAgICAucmVwbGFjZSgnTEVGVEJSQUNLRVQnLCAnWycpXG4gICAgICAucmVwbGFjZSgnUklHSFRCUkFDS0VUJywgJ10nKTtcblxuICAgIHJldHVybiAnICgnICsgc2hvcnRjdXQgKyAnKSc7XG4gIH1cblxuICBidXR0b24obykge1xuICAgIGlmICghdGhpcy5vcHRpb25zLnRvb2x0aXAgJiYgby50b29sdGlwKSB7XG4gICAgICBkZWxldGUgby50b29sdGlwO1xuICAgIH1cbiAgICBvLmNvbnRhaW5lciA9IHRoaXMub3B0aW9ucy5jb250YWluZXI7XG4gICAgcmV0dXJuIHRoaXMudWkuYnV0dG9uKG8pO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSgpIHtcbiAgICB0aGlzLmFkZFRvb2xiYXJCdXR0b25zKCk7XG4gICAgdGhpcy5hZGRJbWFnZVBvcG92ZXJCdXR0b25zKCk7XG4gICAgdGhpcy5hZGRMaW5rUG9wb3ZlckJ1dHRvbnMoKTtcbiAgICB0aGlzLmFkZFRhYmxlUG9wb3ZlckJ1dHRvbnMoKTtcbiAgICB0aGlzLmZvbnRJbnN0YWxsZWRNYXAgPSB7fTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgZGVsZXRlIHRoaXMuZm9udEluc3RhbGxlZE1hcDtcbiAgfVxuXG4gIGlzRm9udEluc3RhbGxlZChuYW1lKSB7XG4gICAgaWYgKCF0aGlzLmZvbnRJbnN0YWxsZWRNYXAuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgIHRoaXMuZm9udEluc3RhbGxlZE1hcFtuYW1lXSA9IGVudi5pc0ZvbnRJbnN0YWxsZWQobmFtZSkgfHxcbiAgICAgICAgbGlzdHMuY29udGFpbnModGhpcy5vcHRpb25zLmZvbnROYW1lc0lnbm9yZUNoZWNrLCBuYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mb250SW5zdGFsbGVkTWFwW25hbWVdO1xuICB9XG5cbiAgaXNGb250RGVzZXJ2ZWRUb0FkZChuYW1lKSB7XG4gICAgY29uc3QgZ2VuZXJpY0ZhbWlsaWVzID0gWydzYW5zLXNlcmlmJywgJ3NlcmlmJywgJ21vbm9zcGFjZScsICdjdXJzaXZlJywgJ2ZhbnRhc3knXTtcbiAgICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgcmV0dXJuICgobmFtZSAhPT0gJycpICYmIHRoaXMuaXNGb250SW5zdGFsbGVkKG5hbWUpICYmICgkLmluQXJyYXkobmFtZSwgZ2VuZXJpY0ZhbWlsaWVzKSA9PT0gLTEpKTtcbiAgfVxuXG4gIGNvbG9yUGFsZXR0ZShjbGFzc05hbWUsIHRvb2x0aXAsIGJhY2tDb2xvciwgZm9yZUNvbG9yKSB7XG4gICAgcmV0dXJuIHRoaXMudWkuYnV0dG9uR3JvdXAoe1xuICAgICAgY2xhc3NOYW1lOiAnbm90ZS1jb2xvciAnICsgY2xhc3NOYW1lLFxuICAgICAgY2hpbGRyZW46IFtcbiAgICAgICAgdGhpcy5idXR0b24oe1xuICAgICAgICAgIGNsYXNzTmFtZTogJ25vdGUtY3VycmVudC1jb2xvci1idXR0b24nLFxuICAgICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLmZvbnQgKyAnIG5vdGUtcmVjZW50LWNvbG9yJyksXG4gICAgICAgICAgdG9vbHRpcDogdG9vbHRpcCxcbiAgICAgICAgICBjbGljazogKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRidXR0b24gPSAkKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgICAgICBpZiAoYmFja0NvbG9yICYmIGZvcmVDb2xvcikge1xuICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuaW52b2tlKCdlZGl0b3IuY29sb3InLCB7XG4gICAgICAgICAgICAgICAgYmFja0NvbG9yOiAkYnV0dG9uLmF0dHIoJ2RhdGEtYmFja0NvbG9yJyksXG4gICAgICAgICAgICAgICAgZm9yZUNvbG9yOiAkYnV0dG9uLmF0dHIoJ2RhdGEtZm9yZUNvbG9yJyksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChiYWNrQ29sb3IpIHtcbiAgICAgICAgICAgICAgdGhpcy5jb250ZXh0Lmludm9rZSgnZWRpdG9yLmNvbG9yJywge1xuICAgICAgICAgICAgICAgIGJhY2tDb2xvcjogJGJ1dHRvbi5hdHRyKCdkYXRhLWJhY2tDb2xvcicpLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9yZUNvbG9yKSB7XG4gICAgICAgICAgICAgIHRoaXMuY29udGV4dC5pbnZva2UoJ2VkaXRvci5jb2xvcicsIHtcbiAgICAgICAgICAgICAgICBmb3JlQ29sb3I6ICRidXR0b24uYXR0cignZGF0YS1mb3JlQ29sb3InKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBjYWxsYmFjazogKCRidXR0b24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRyZWNlbnRDb2xvciA9ICRidXR0b24uZmluZCgnLm5vdGUtcmVjZW50LWNvbG9yJyk7XG4gICAgICAgICAgICBpZiAoYmFja0NvbG9yKSB7XG4gICAgICAgICAgICAgICRyZWNlbnRDb2xvci5jc3MoJ2JhY2tncm91bmQtY29sb3InLCB0aGlzLm9wdGlvbnMuY29sb3JCdXR0b24uYmFja0NvbG9yKTtcbiAgICAgICAgICAgICAgJGJ1dHRvbi5hdHRyKCdkYXRhLWJhY2tDb2xvcicsIHRoaXMub3B0aW9ucy5jb2xvckJ1dHRvbi5iYWNrQ29sb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZvcmVDb2xvcikge1xuICAgICAgICAgICAgICAkcmVjZW50Q29sb3IuY3NzKCdjb2xvcicsIHRoaXMub3B0aW9ucy5jb2xvckJ1dHRvbi5mb3JlQ29sb3IpO1xuICAgICAgICAgICAgICAkYnV0dG9uLmF0dHIoJ2RhdGEtZm9yZUNvbG9yJywgdGhpcy5vcHRpb25zLmNvbG9yQnV0dG9uLmZvcmVDb2xvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAkcmVjZW50Q29sb3IuY3NzKCdjb2xvcicsICd0cmFuc3BhcmVudCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICB0aGlzLmJ1dHRvbih7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnZHJvcGRvd24tdG9nZ2xlJyxcbiAgICAgICAgICBjb250ZW50czogdGhpcy51aS5kcm9wZG93bkJ1dHRvbkNvbnRlbnRzKCcnLCB0aGlzLm9wdGlvbnMpLFxuICAgICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5jb2xvci5tb3JlLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHRvZ2dsZTogJ2Ryb3Bkb3duJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdGhpcy51aS5kcm9wZG93bih7XG4gICAgICAgICAgaXRlbXM6IChiYWNrQ29sb3IgPyBbXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cIm5vdGUtcGFsZXR0ZVwiPicsXG4gICAgICAgICAgICAnICA8ZGl2IGNsYXNzPVwibm90ZS1wYWxldHRlLXRpdGxlXCI+JyArIHRoaXMubGFuZy5jb2xvci5iYWNrZ3JvdW5kICsgJzwvZGl2PicsXG4gICAgICAgICAgICAnICA8ZGl2PicsXG4gICAgICAgICAgICAnICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibm90ZS1jb2xvci1yZXNldCBidG4gYnRuLWxpZ2h0XCIgZGF0YS1ldmVudD1cImJhY2tDb2xvclwiIGRhdGEtdmFsdWU9XCJpbmhlcml0XCI+JyxcbiAgICAgICAgICAgIHRoaXMubGFuZy5jb2xvci50cmFuc3BhcmVudCxcbiAgICAgICAgICAgICcgICAgPC9idXR0b24+JyxcbiAgICAgICAgICAgICcgIDwvZGl2PicsXG4gICAgICAgICAgICAnICA8ZGl2IGNsYXNzPVwibm90ZS1ob2xkZXJcIiBkYXRhLWV2ZW50PVwiYmFja0NvbG9yXCIvPicsXG4gICAgICAgICAgICAnICA8ZGl2PicsXG4gICAgICAgICAgICAnICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibm90ZS1jb2xvci1zZWxlY3QgYnRuXCIgZGF0YS1ldmVudD1cIm9wZW5QYWxldHRlXCIgZGF0YS12YWx1ZT1cImJhY2tDb2xvclBpY2tlclwiPicsXG4gICAgICAgICAgICB0aGlzLmxhbmcuY29sb3IuY3BTZWxlY3QsXG4gICAgICAgICAgICAnICAgIDwvYnV0dG9uPicsXG4gICAgICAgICAgICAnICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBpZD1cImJhY2tDb2xvclBpY2tlclwiIGNsYXNzPVwibm90ZS1idG4gbm90ZS1jb2xvci1zZWxlY3QtYnRuXCIgdmFsdWU9XCInICsgdGhpcy5vcHRpb25zLmNvbG9yQnV0dG9uLmJhY2tDb2xvciArICdcIiBkYXRhLWV2ZW50PVwiYmFja0NvbG9yUGFsZXR0ZVwiPicsXG4gICAgICAgICAgICAnICA8L2Rpdj4nLFxuICAgICAgICAgICAgJyAgPGRpdiBjbGFzcz1cIm5vdGUtaG9sZGVyLWN1c3RvbVwiIGlkPVwiYmFja0NvbG9yUGFsZXR0ZVwiIGRhdGEtZXZlbnQ9XCJiYWNrQ29sb3JcIi8+JyxcbiAgICAgICAgICAgICc8L2Rpdj4nLFxuICAgICAgICAgIF0uam9pbignJykgOiAnJykgK1xuICAgICAgICAgIChmb3JlQ29sb3IgPyBbXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cIm5vdGUtcGFsZXR0ZVwiPicsXG4gICAgICAgICAgICAnICA8ZGl2IGNsYXNzPVwibm90ZS1wYWxldHRlLXRpdGxlXCI+JyArIHRoaXMubGFuZy5jb2xvci5mb3JlZ3JvdW5kICsgJzwvZGl2PicsXG4gICAgICAgICAgICAnICA8ZGl2PicsXG4gICAgICAgICAgICAnICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibm90ZS1jb2xvci1yZXNldCBidG4gYnRuLWxpZ2h0XCIgZGF0YS1ldmVudD1cInJlbW92ZUZvcm1hdFwiIGRhdGEtdmFsdWU9XCJmb3JlQ29sb3JcIj4nLFxuICAgICAgICAgICAgdGhpcy5sYW5nLmNvbG9yLnJlc2V0VG9EZWZhdWx0LFxuICAgICAgICAgICAgJyAgICA8L2J1dHRvbj4nLFxuICAgICAgICAgICAgJyAgPC9kaXY+JyxcbiAgICAgICAgICAgICcgIDxkaXYgY2xhc3M9XCJub3RlLWhvbGRlclwiIGRhdGEtZXZlbnQ9XCJmb3JlQ29sb3JcIi8+JyxcbiAgICAgICAgICAgICcgIDxkaXY+JyxcbiAgICAgICAgICAgICcgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJub3RlLWNvbG9yLXNlbGVjdCBidG5cIiBkYXRhLWV2ZW50PVwib3BlblBhbGV0dGVcIiBkYXRhLXZhbHVlPVwiZm9yZUNvbG9yUGlja2VyXCI+JyxcbiAgICAgICAgICAgIHRoaXMubGFuZy5jb2xvci5jcFNlbGVjdCxcbiAgICAgICAgICAgICcgICAgPC9idXR0b24+JyxcbiAgICAgICAgICAgICcgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIGlkPVwiZm9yZUNvbG9yUGlja2VyXCIgY2xhc3M9XCJub3RlLWJ0biBub3RlLWNvbG9yLXNlbGVjdC1idG5cIiB2YWx1ZT1cIicgKyB0aGlzLm9wdGlvbnMuY29sb3JCdXR0b24uZm9yZUNvbG9yICsgJ1wiIGRhdGEtZXZlbnQ9XCJmb3JlQ29sb3JQYWxldHRlXCI+JyxcbiAgICAgICAgICAgICcgIDxkaXYgY2xhc3M9XCJub3RlLWhvbGRlci1jdXN0b21cIiBpZD1cImZvcmVDb2xvclBhbGV0dGVcIiBkYXRhLWV2ZW50PVwiZm9yZUNvbG9yXCIvPicsXG4gICAgICAgICAgICAnPC9kaXY+JyxcbiAgICAgICAgICBdLmpvaW4oJycpIDogJycpLFxuICAgICAgICAgIGNhbGxiYWNrOiAoJGRyb3Bkb3duKSA9PiB7XG4gICAgICAgICAgICAkZHJvcGRvd24uZmluZCgnLm5vdGUtaG9sZGVyJykuZWFjaCgoaWR4LCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0ICRob2xkZXIgPSAkKGl0ZW0pO1xuICAgICAgICAgICAgICAkaG9sZGVyLmFwcGVuZCh0aGlzLnVpLnBhbGV0dGUoe1xuICAgICAgICAgICAgICAgIGNvbG9yczogdGhpcy5vcHRpb25zLmNvbG9ycyxcbiAgICAgICAgICAgICAgICBjb2xvcnNOYW1lOiB0aGlzLm9wdGlvbnMuY29sb3JzTmFtZSxcbiAgICAgICAgICAgICAgICBldmVudE5hbWU6ICRob2xkZXIuZGF0YSgnZXZlbnQnKSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMub3B0aW9ucy5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgdG9vbHRpcDogdGhpcy5vcHRpb25zLnRvb2x0aXAsXG4gICAgICAgICAgICAgIH0pLnJlbmRlcigpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLyogVE9ETzogZG8gd2UgaGF2ZSB0byByZWNvcmQgcmVjZW50IGN1c3RvbSBjb2xvcnMgd2l0aGluIGNvb2tpZXM/ICovXG4gICAgICAgICAgICB2YXIgY3VzdG9tQ29sb3JzID0gW1xuICAgICAgICAgICAgICBbJyNGRkZGRkYnLCAnI0ZGRkZGRicsICcjRkZGRkZGJywgJyNGRkZGRkYnLCAnI0ZGRkZGRicsICcjRkZGRkZGJywgJyNGRkZGRkYnLCAnI0ZGRkZGRiddLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICRkcm9wZG93bi5maW5kKCcubm90ZS1ob2xkZXItY3VzdG9tJykuZWFjaCgoaWR4LCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0ICRob2xkZXIgPSAkKGl0ZW0pO1xuICAgICAgICAgICAgICAkaG9sZGVyLmFwcGVuZCh0aGlzLnVpLnBhbGV0dGUoe1xuICAgICAgICAgICAgICAgIGNvbG9yczogY3VzdG9tQ29sb3JzLFxuICAgICAgICAgICAgICAgIGNvbG9yc05hbWU6IGN1c3RvbUNvbG9ycyxcbiAgICAgICAgICAgICAgICBldmVudE5hbWU6ICRob2xkZXIuZGF0YSgnZXZlbnQnKSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMub3B0aW9ucy5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgdG9vbHRpcDogdGhpcy5vcHRpb25zLnRvb2x0aXAsXG4gICAgICAgICAgICAgIH0pLnJlbmRlcigpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJGRyb3Bkb3duLmZpbmQoJ2lucHV0W3R5cGU9Y29sb3JdJykuZWFjaCgoaWR4LCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICQoaXRlbSkuY2hhbmdlKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRjaGlwID0gJGRyb3Bkb3duLmZpbmQoJyMnICsgJCh0aGlzKS5kYXRhKCdldmVudCcpKS5maW5kKCcubm90ZS1jb2xvci1idG4nKS5maXJzdCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbG9yID0gdGhpcy52YWx1ZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgICAgICRjaGlwLmNzcygnYmFja2dyb3VuZC1jb2xvcicsIGNvbG9yKVxuICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtbGFiZWwnLCBjb2xvcilcbiAgICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXZhbHVlJywgY29sb3IpXG4gICAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1vcmlnaW5hbC10aXRsZScsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAkY2hpcC5jbGljaygpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgY2xpY2s6IChldmVudCkgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgIGNvbnN0ICRwYXJlbnQgPSAkKCcuJyArIGNsYXNzTmFtZSk7XG4gICAgICAgICAgICBjb25zdCAkYnV0dG9uID0gJChldmVudC50YXJnZXQpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnROYW1lID0gJGJ1dHRvbi5kYXRhKCdldmVudCcpO1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gJGJ1dHRvbi5hdHRyKCdkYXRhLXZhbHVlJyk7XG5cbiAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdvcGVuUGFsZXR0ZScpIHtcbiAgICAgICAgICAgICAgY29uc3QgJHBpY2tlciA9ICRwYXJlbnQuZmluZCgnIycgKyB2YWx1ZSk7XG4gICAgICAgICAgICAgIGNvbnN0ICRwYWxldHRlID0gJCgkcGFyZW50LmZpbmQoJyMnICsgJHBpY2tlci5kYXRhKCdldmVudCcpKS5maW5kKCcubm90ZS1jb2xvci1yb3cnKVswXSk7XG5cbiAgICAgICAgICAgICAgLy8gU2hpZnQgcGFsZXR0ZSBjaGlwc1xuICAgICAgICAgICAgICBjb25zdCAkY2hpcCA9ICRwYWxldHRlLmZpbmQoJy5ub3RlLWNvbG9yLWJ0bicpLmxhc3QoKS5kZXRhY2goKTtcblxuICAgICAgICAgICAgICAvLyBTZXQgY2hpcCBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgIGNvbnN0IGNvbG9yID0gJHBpY2tlci52YWwoKTtcbiAgICAgICAgICAgICAgJGNoaXAuY3NzKCdiYWNrZ3JvdW5kLWNvbG9yJywgY29sb3IpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtbGFiZWwnLCBjb2xvcilcbiAgICAgICAgICAgICAgICAuYXR0cignZGF0YS12YWx1ZScsIGNvbG9yKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLW9yaWdpbmFsLXRpdGxlJywgY29sb3IpO1xuICAgICAgICAgICAgICAkcGFsZXR0ZS5wcmVwZW5kKCRjaGlwKTtcbiAgICAgICAgICAgICAgJHBpY2tlci5jbGljaygpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChsaXN0cy5jb250YWlucyhbJ2JhY2tDb2xvcicsICdmb3JlQ29sb3InXSwgZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICBjb25zdCBrZXkgPSBldmVudE5hbWUgPT09ICdiYWNrQ29sb3InID8gJ2JhY2tncm91bmQtY29sb3InIDogJ2NvbG9yJztcbiAgICAgICAgICAgICAgY29uc3QgJGNvbG9yID0gJGJ1dHRvbi5jbG9zZXN0KCcubm90ZS1jb2xvcicpLmZpbmQoJy5ub3RlLXJlY2VudC1jb2xvcicpO1xuICAgICAgICAgICAgICBjb25zdCAkY3VycmVudEJ1dHRvbiA9ICRidXR0b24uY2xvc2VzdCgnLm5vdGUtY29sb3InKS5maW5kKCcubm90ZS1jdXJyZW50LWNvbG9yLWJ1dHRvbicpO1xuXG4gICAgICAgICAgICAgICRjb2xvci5jc3Moa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICRjdXJyZW50QnV0dG9uLmF0dHIoJ2RhdGEtJyArIGV2ZW50TmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuaW52b2tlKCdlZGl0b3IuJyArIGV2ZW50TmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICB9KS5yZW5kZXIoKTtcbiAgfVxuXG4gIGFkZFRvb2xiYXJCdXR0b25zKCkge1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uc3R5bGUnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy51aS5idXR0b25Hcm91cChbXG4gICAgICAgIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdkcm9wZG93bi10b2dnbGUnLFxuICAgICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmRyb3Bkb3duQnV0dG9uQ29udGVudHMoXG4gICAgICAgICAgICB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLm1hZ2ljKSwgdGhpcy5vcHRpb25zXG4gICAgICAgICAgKSxcbiAgICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuc3R5bGUuc3R5bGUsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgdG9nZ2xlOiAnZHJvcGRvd24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICB0aGlzLnVpLmRyb3Bkb3duKHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdkcm9wZG93bi1zdHlsZScsXG4gICAgICAgICAgaXRlbXM6IHRoaXMub3B0aW9ucy5zdHlsZVRhZ3MsXG4gICAgICAgICAgdGl0bGU6IHRoaXMubGFuZy5zdHlsZS5zdHlsZSxcbiAgICAgICAgICB0ZW1wbGF0ZTogKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgaXRlbSA9IHsgdGFnOiBpdGVtLCB0aXRsZTogKHRoaXMubGFuZy5zdHlsZS5oYXNPd25Qcm9wZXJ0eShpdGVtKSA/IHRoaXMubGFuZy5zdHlsZVtpdGVtXSA6IGl0ZW0pIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHRhZyA9IGl0ZW0udGFnO1xuICAgICAgICAgICAgY29uc3QgdGl0bGUgPSBpdGVtLnRpdGxlO1xuICAgICAgICAgICAgY29uc3Qgc3R5bGUgPSBpdGVtLnN0eWxlID8gJyBzdHlsZT1cIicgKyBpdGVtLnN0eWxlICsgJ1wiICcgOiAnJztcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGl0ZW0uY2xhc3NOYW1lID8gJyBjbGFzcz1cIicgKyBpdGVtLmNsYXNzTmFtZSArICdcIicgOiAnJztcblxuICAgICAgICAgICAgcmV0dXJuICc8JyArIHRhZyArIHN0eWxlICsgY2xhc3NOYW1lICsgJz4nICsgdGl0bGUgKyAnPC8nICsgdGFnICsgJz4nO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuZm9ybWF0QmxvY2snKSxcbiAgICAgICAgfSksXG4gICAgICBdKS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIGZvciAobGV0IHN0eWxlSWR4ID0gMCwgc3R5bGVMZW4gPSB0aGlzLm9wdGlvbnMuc3R5bGVUYWdzLmxlbmd0aDsgc3R5bGVJZHggPCBzdHlsZUxlbjsgc3R5bGVJZHgrKykge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMub3B0aW9ucy5zdHlsZVRhZ3Nbc3R5bGVJZHhdO1xuXG4gICAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnN0eWxlLicgKyBpdGVtLCAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnbm90ZS1idG4tc3R5bGUtJyArIGl0ZW0sXG4gICAgICAgICAgY29udGVudHM6ICc8ZGl2IGRhdGEtdmFsdWU9XCInICsgaXRlbSArICdcIj4nICsgaXRlbS50b1VwcGVyQ2FzZSgpICsgJzwvZGl2PicsXG4gICAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnN0eWxlW2l0ZW1dLFxuICAgICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmZvcm1hdEJsb2NrJyksXG4gICAgICAgIH0pLnJlbmRlcigpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5ib2xkJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnbm90ZS1idG4tYm9sZCcsXG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLmJvbGQpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuZm9udC5ib2xkICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgnYm9sZCcpLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXJBbmRVcGRhdGVTdGF0ZSgnZWRpdG9yLmJvbGQnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5pdGFsaWMnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjbGFzc05hbWU6ICdub3RlLWJ0bi1pdGFsaWMnLFxuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5pdGFsaWMpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuZm9udC5pdGFsaWMgKyB0aGlzLnJlcHJlc2VudFNob3J0Y3V0KCdpdGFsaWMnKSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyQW5kVXBkYXRlU3RhdGUoJ2VkaXRvci5pdGFsaWMnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi51bmRlcmxpbmUnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjbGFzc05hbWU6ICdub3RlLWJ0bi11bmRlcmxpbmUnLFxuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy51bmRlcmxpbmUpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuZm9udC51bmRlcmxpbmUgKyB0aGlzLnJlcHJlc2VudFNob3J0Y3V0KCd1bmRlcmxpbmUnKSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyQW5kVXBkYXRlU3RhdGUoJ2VkaXRvci51bmRlcmxpbmUnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5jbGVhcicsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLmVyYXNlciksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5mb250LmNsZWFyICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgncmVtb3ZlRm9ybWF0JyksXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLnJlbW92ZUZvcm1hdCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnN0cmlrZXRocm91Z2gnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjbGFzc05hbWU6ICdub3RlLWJ0bi1zdHJpa2V0aHJvdWdoJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuc3RyaWtldGhyb3VnaCksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5mb250LnN0cmlrZXRocm91Z2ggKyB0aGlzLnJlcHJlc2VudFNob3J0Y3V0KCdzdHJpa2V0aHJvdWdoJyksXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlckFuZFVwZGF0ZVN0YXRlKCdlZGl0b3Iuc3RyaWtldGhyb3VnaCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnN1cGVyc2NyaXB0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnbm90ZS1idG4tc3VwZXJzY3JpcHQnLFxuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5zdXBlcnNjcmlwdCksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5mb250LnN1cGVyc2NyaXB0LFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXJBbmRVcGRhdGVTdGF0ZSgnZWRpdG9yLnN1cGVyc2NyaXB0JyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uc3Vic2NyaXB0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnbm90ZS1idG4tc3Vic2NyaXB0JyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuc3Vic2NyaXB0KSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmZvbnQuc3Vic2NyaXB0LFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXJBbmRVcGRhdGVTdGF0ZSgnZWRpdG9yLnN1YnNjcmlwdCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmZvbnRuYW1lJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3R5bGVJbmZvID0gdGhpcy5jb250ZXh0Lmludm9rZSgnZWRpdG9yLmN1cnJlbnRTdHlsZScpO1xuXG4gICAgICAvLyBBZGQgJ2RlZmF1bHQnIGZvbnRzIGludG8gdGhlIGZvbnRuYW1lcyBhcnJheSBpZiBub3QgZXhpc3RcbiAgICAgICQuZWFjaChzdHlsZUluZm9bJ2ZvbnQtZmFtaWx5J10uc3BsaXQoJywnKSwgKGlkeCwgZm9udG5hbWUpID0+IHtcbiAgICAgICAgZm9udG5hbWUgPSBmb250bmFtZS50cmltKCkucmVwbGFjZSgvWydcIl0rL2csICcnKTtcbiAgICAgICAgaWYgKHRoaXMuaXNGb250RGVzZXJ2ZWRUb0FkZChmb250bmFtZSkpIHtcbiAgICAgICAgICBpZiAoJC5pbkFycmF5KGZvbnRuYW1lLCB0aGlzLm9wdGlvbnMuZm9udE5hbWVzKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5mb250TmFtZXMucHVzaChmb250bmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRoaXMudWkuYnV0dG9uR3JvdXAoW1xuICAgICAgICB0aGlzLmJ1dHRvbih7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnZHJvcGRvd24tdG9nZ2xlJyxcbiAgICAgICAgICBjb250ZW50czogdGhpcy51aS5kcm9wZG93bkJ1dHRvbkNvbnRlbnRzKFxuICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwibm90ZS1jdXJyZW50LWZvbnRuYW1lXCIvPicsIHRoaXMub3B0aW9uc1xuICAgICAgICAgICksXG4gICAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmZvbnQubmFtZSxcbiAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICB0b2dnbGU6ICdkcm9wZG93bicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICAgIHRoaXMudWkuZHJvcGRvd25DaGVjayh7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnZHJvcGRvd24tZm9udG5hbWUnLFxuICAgICAgICAgIGNoZWNrQ2xhc3NOYW1lOiB0aGlzLm9wdGlvbnMuaWNvbnMubWVudUNoZWNrLFxuICAgICAgICAgIGl0ZW1zOiB0aGlzLm9wdGlvbnMuZm9udE5hbWVzLmZpbHRlcih0aGlzLmlzRm9udEluc3RhbGxlZC5iaW5kKHRoaXMpKSxcbiAgICAgICAgICB0aXRsZTogdGhpcy5sYW5nLmZvbnQubmFtZSxcbiAgICAgICAgICB0ZW1wbGF0ZTogKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiAnPHNwYW4gc3R5bGU9XCJmb250LWZhbWlseTogXFwnJyArIGl0ZW0gKyAnXFwnXCI+JyArIGl0ZW0gKyAnPC9zcGFuPic7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXJBbmRVcGRhdGVTdGF0ZSgnZWRpdG9yLmZvbnROYW1lJyksXG4gICAgICAgIH0pLFxuICAgICAgXSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmZvbnRzaXplJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudWkuYnV0dG9uR3JvdXAoW1xuICAgICAgICB0aGlzLmJ1dHRvbih7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnZHJvcGRvd24tdG9nZ2xlJyxcbiAgICAgICAgICBjb250ZW50czogdGhpcy51aS5kcm9wZG93bkJ1dHRvbkNvbnRlbnRzKCc8c3BhbiBjbGFzcz1cIm5vdGUtY3VycmVudC1mb250c2l6ZVwiLz4nLCB0aGlzLm9wdGlvbnMpLFxuICAgICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5mb250LnNpemUsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgdG9nZ2xlOiAnZHJvcGRvd24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICB0aGlzLnVpLmRyb3Bkb3duQ2hlY2soe1xuICAgICAgICAgIGNsYXNzTmFtZTogJ2Ryb3Bkb3duLWZvbnRzaXplJyxcbiAgICAgICAgICBjaGVja0NsYXNzTmFtZTogdGhpcy5vcHRpb25zLmljb25zLm1lbnVDaGVjayxcbiAgICAgICAgICBpdGVtczogdGhpcy5vcHRpb25zLmZvbnRTaXplcyxcbiAgICAgICAgICB0aXRsZTogdGhpcy5sYW5nLmZvbnQuc2l6ZSxcbiAgICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXJBbmRVcGRhdGVTdGF0ZSgnZWRpdG9yLmZvbnRTaXplJyksXG4gICAgICAgIH0pLFxuICAgICAgXSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmNvbG9yJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY29sb3JQYWxldHRlKCdub3RlLWNvbG9yLWFsbCcsIHRoaXMubGFuZy5jb2xvci5yZWNlbnQsIHRydWUsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5mb3JlY29sb3InLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jb2xvclBhbGV0dGUoJ25vdGUtY29sb3ItZm9yZScsIHRoaXMubGFuZy5jb2xvci5mb3JlZ3JvdW5kLCBmYWxzZSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmJhY2tjb2xvcicsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNvbG9yUGFsZXR0ZSgnbm90ZS1jb2xvci1iYWNrJywgdGhpcy5sYW5nLmNvbG9yLmJhY2tncm91bmQsIHRydWUsIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24udWwnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy51bm9yZGVyZWRsaXN0KSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmxpc3RzLnVub3JkZXJlZCArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2luc2VydFVub3JkZXJlZExpc3QnKSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuaW5zZXJ0VW5vcmRlcmVkTGlzdCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLm9sJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMub3JkZXJlZGxpc3QpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcubGlzdHMub3JkZXJlZCArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2luc2VydE9yZGVyZWRMaXN0JyksXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmluc2VydE9yZGVyZWRMaXN0JyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGp1c3RpZnlMZWZ0ID0gdGhpcy5idXR0b24oe1xuICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuYWxpZ25MZWZ0KSxcbiAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5wYXJhZ3JhcGgubGVmdCArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2p1c3RpZnlMZWZ0JyksXG4gICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5qdXN0aWZ5TGVmdCcpLFxuICAgIH0pO1xuXG4gICAgY29uc3QganVzdGlmeUNlbnRlciA9IHRoaXMuYnV0dG9uKHtcbiAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLmFsaWduQ2VudGVyKSxcbiAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5wYXJhZ3JhcGguY2VudGVyICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgnanVzdGlmeUNlbnRlcicpLFxuICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuanVzdGlmeUNlbnRlcicpLFxuICAgIH0pO1xuXG4gICAgY29uc3QganVzdGlmeVJpZ2h0ID0gdGhpcy5idXR0b24oe1xuICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuYWxpZ25SaWdodCksXG4gICAgICB0b29sdGlwOiB0aGlzLmxhbmcucGFyYWdyYXBoLnJpZ2h0ICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgnanVzdGlmeVJpZ2h0JyksXG4gICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5qdXN0aWZ5UmlnaHQnKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGp1c3RpZnlGdWxsID0gdGhpcy5idXR0b24oe1xuICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuYWxpZ25KdXN0aWZ5KSxcbiAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5wYXJhZ3JhcGguanVzdGlmeSArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2p1c3RpZnlGdWxsJyksXG4gICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5qdXN0aWZ5RnVsbCcpLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0ZGVudCA9IHRoaXMuYnV0dG9uKHtcbiAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLm91dGRlbnQpLFxuICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnBhcmFncmFwaC5vdXRkZW50ICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgnb3V0ZGVudCcpLFxuICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3Iub3V0ZGVudCcpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5kZW50ID0gdGhpcy5idXR0b24oe1xuICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuaW5kZW50KSxcbiAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5wYXJhZ3JhcGguaW5kZW50ICsgdGhpcy5yZXByZXNlbnRTaG9ydGN1dCgnaW5kZW50JyksXG4gICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5pbmRlbnQnKSxcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uanVzdGlmeUxlZnQnLCBmdW5jLmludm9rZShqdXN0aWZ5TGVmdCwgJ3JlbmRlcicpKTtcbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmp1c3RpZnlDZW50ZXInLCBmdW5jLmludm9rZShqdXN0aWZ5Q2VudGVyLCAncmVuZGVyJykpO1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uanVzdGlmeVJpZ2h0JywgZnVuYy5pbnZva2UoanVzdGlmeVJpZ2h0LCAncmVuZGVyJykpO1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uanVzdGlmeUZ1bGwnLCBmdW5jLmludm9rZShqdXN0aWZ5RnVsbCwgJ3JlbmRlcicpKTtcbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLm91dGRlbnQnLCBmdW5jLmludm9rZShvdXRkZW50LCAncmVuZGVyJykpO1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uaW5kZW50JywgZnVuYy5pbnZva2UoaW5kZW50LCAncmVuZGVyJykpO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5wYXJhZ3JhcGgnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy51aS5idXR0b25Hcm91cChbXG4gICAgICAgIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdkcm9wZG93bi10b2dnbGUnLFxuICAgICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmRyb3Bkb3duQnV0dG9uQ29udGVudHModGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5hbGlnbkxlZnQpLCB0aGlzLm9wdGlvbnMpLFxuICAgICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5wYXJhZ3JhcGgucGFyYWdyYXBoLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHRvZ2dsZTogJ2Ryb3Bkb3duJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdGhpcy51aS5kcm9wZG93bihbXG4gICAgICAgICAgdGhpcy51aS5idXR0b25Hcm91cCh7XG4gICAgICAgICAgICBjbGFzc05hbWU6ICdub3RlLWFsaWduJyxcbiAgICAgICAgICAgIGNoaWxkcmVuOiBbanVzdGlmeUxlZnQsIGp1c3RpZnlDZW50ZXIsIGp1c3RpZnlSaWdodCwganVzdGlmeUZ1bGxdLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRoaXMudWkuYnV0dG9uR3JvdXAoe1xuICAgICAgICAgICAgY2xhc3NOYW1lOiAnbm90ZS1saXN0JyxcbiAgICAgICAgICAgIGNoaWxkcmVuOiBbb3V0ZGVudCwgaW5kZW50XSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICBdKS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uaGVpZ2h0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudWkuYnV0dG9uR3JvdXAoW1xuICAgICAgICB0aGlzLmJ1dHRvbih7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnZHJvcGRvd24tdG9nZ2xlJyxcbiAgICAgICAgICBjb250ZW50czogdGhpcy51aS5kcm9wZG93bkJ1dHRvbkNvbnRlbnRzKHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMudGV4dEhlaWdodCksIHRoaXMub3B0aW9ucyksXG4gICAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmZvbnQuaGVpZ2h0LFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHRvZ2dsZTogJ2Ryb3Bkb3duJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdGhpcy51aS5kcm9wZG93bkNoZWNrKHtcbiAgICAgICAgICBpdGVtczogdGhpcy5vcHRpb25zLmxpbmVIZWlnaHRzLFxuICAgICAgICAgIGNoZWNrQ2xhc3NOYW1lOiB0aGlzLm9wdGlvbnMuaWNvbnMubWVudUNoZWNrLFxuICAgICAgICAgIGNsYXNzTmFtZTogJ2Ryb3Bkb3duLWxpbmUtaGVpZ2h0JyxcbiAgICAgICAgICB0aXRsZTogdGhpcy5sYW5nLmZvbnQuaGVpZ2h0LFxuICAgICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmxpbmVIZWlnaHQnKSxcbiAgICAgICAgfSksXG4gICAgICBdKS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24udGFibGUnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy51aS5idXR0b25Hcm91cChbXG4gICAgICAgIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdkcm9wZG93bi10b2dnbGUnLFxuICAgICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmRyb3Bkb3duQnV0dG9uQ29udGVudHModGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy50YWJsZSksIHRoaXMub3B0aW9ucyksXG4gICAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnRhYmxlLnRhYmxlLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHRvZ2dsZTogJ2Ryb3Bkb3duJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdGhpcy51aS5kcm9wZG93bih7XG4gICAgICAgICAgdGl0bGU6IHRoaXMubGFuZy50YWJsZS50YWJsZSxcbiAgICAgICAgICBjbGFzc05hbWU6ICdub3RlLXRhYmxlJyxcbiAgICAgICAgICBpdGVtczogW1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJub3RlLWRpbWVuc2lvbi1waWNrZXJcIj4nLFxuICAgICAgICAgICAgJyAgPGRpdiBjbGFzcz1cIm5vdGUtZGltZW5zaW9uLXBpY2tlci1tb3VzZWNhdGNoZXJcIiBkYXRhLWV2ZW50PVwiaW5zZXJ0VGFibGVcIiBkYXRhLXZhbHVlPVwiMXgxXCIvPicsXG4gICAgICAgICAgICAnICA8ZGl2IGNsYXNzPVwibm90ZS1kaW1lbnNpb24tcGlja2VyLWhpZ2hsaWdodGVkXCIvPicsXG4gICAgICAgICAgICAnICA8ZGl2IGNsYXNzPVwibm90ZS1kaW1lbnNpb24tcGlja2VyLXVuaGlnaGxpZ2h0ZWRcIi8+JyxcbiAgICAgICAgICAgICc8L2Rpdj4nLFxuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJub3RlLWRpbWVuc2lvbi1kaXNwbGF5XCI+MSB4IDE8L2Rpdj4nLFxuICAgICAgICAgIF0uam9pbignJyksXG4gICAgICAgIH0pLFxuICAgICAgXSwge1xuICAgICAgICBjYWxsYmFjazogKCRub2RlKSA9PiB7XG4gICAgICAgICAgY29uc3QgJGNhdGNoZXIgPSAkbm9kZS5maW5kKCcubm90ZS1kaW1lbnNpb24tcGlja2VyLW1vdXNlY2F0Y2hlcicpO1xuICAgICAgICAgICRjYXRjaGVyLmNzcyh7XG4gICAgICAgICAgICB3aWR0aDogdGhpcy5vcHRpb25zLmluc2VydFRhYmxlTWF4U2l6ZS5jb2wgKyAnZW0nLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLm9wdGlvbnMuaW5zZXJ0VGFibGVNYXhTaXplLnJvdyArICdlbScsXG4gICAgICAgICAgfSkubW91c2Vkb3duKHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuaW5zZXJ0VGFibGUnKSlcbiAgICAgICAgICAgIC5vbignbW91c2Vtb3ZlJywgdGhpcy50YWJsZU1vdmVIYW5kbGVyLmJpbmQodGhpcykpO1xuICAgICAgICB9LFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmxpbmsnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5saW5rKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmxpbmsubGluayArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2xpbmtEaWFsb2cuc2hvdycpLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2xpbmtEaWFsb2cuc2hvdycpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnBpY3R1cmUnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5waWN0dXJlKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmltYWdlLmltYWdlLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2ltYWdlRGlhbG9nLnNob3cnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi52aWRlbycsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLnZpZGVvKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnZpZGVvLnZpZGVvLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ3ZpZGVvRGlhbG9nLnNob3cnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5ocicsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLm1pbnVzKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmhyLmluc2VydCArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ2luc2VydEhvcml6b250YWxSdWxlJyksXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmluc2VydEhvcml6b250YWxSdWxlJyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uZnVsbHNjcmVlbicsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNsYXNzTmFtZTogJ2J0bi1mdWxsc2NyZWVuJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuYXJyb3dzQWx0KSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLm9wdGlvbnMuZnVsbHNjcmVlbixcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdmdWxsc2NyZWVuLnRvZ2dsZScpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmNvZGV2aWV3JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnYnRuLWNvZGV2aWV3JyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuY29kZSksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5vcHRpb25zLmNvZGV2aWV3LFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2NvZGV2aWV3LnRvZ2dsZScpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnJlZG8nLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5yZWRvKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmhpc3RvcnkucmVkbyArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ3JlZG8nKSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IucmVkbycpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLnVuZG8nLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy51bmRvKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmhpc3RvcnkudW5kbyArIHRoaXMucmVwcmVzZW50U2hvcnRjdXQoJ3VuZG8nKSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IudW5kbycpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmhlbHAnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5xdWVzdGlvbiksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5vcHRpb25zLmhlbHAsXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignaGVscERpYWxvZy5zaG93JyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpbWFnZTogW1xuICAgKiAgIFsnaW1hZ2VSZXNpemUnLCBbJ3Jlc2l6ZUZ1bGwnLCAncmVzaXplSGFsZicsICdyZXNpemVRdWFydGVyJywgJ3Jlc2l6ZU5vbmUnXV0sXG4gICAqICAgWydmbG9hdCcsIFsnZmxvYXRMZWZ0JywgJ2Zsb2F0UmlnaHQnLCAnZmxvYXROb25lJ11dLFxuICAgKiAgIFsncmVtb3ZlJywgWydyZW1vdmVNZWRpYSddXSxcbiAgICogXSxcbiAgICovXG4gIGFkZEltYWdlUG9wb3ZlckJ1dHRvbnMoKSB7XG4gICAgLy8gSW1hZ2UgU2l6ZSBCdXR0b25zXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5yZXNpemVGdWxsJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY29udGVudHM6ICc8c3BhbiBjbGFzcz1cIm5vdGUtZm9udHNpemUtMTBcIj4xMDAlPC9zcGFuPicsXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5pbWFnZS5yZXNpemVGdWxsLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5yZXNpemUnLCAnMScpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5yZXNpemVIYWxmJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY29udGVudHM6ICc8c3BhbiBjbGFzcz1cIm5vdGUtZm9udHNpemUtMTBcIj41MCU8L3NwYW4+JyxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmltYWdlLnJlc2l6ZUhhbGYsXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLnJlc2l6ZScsICcwLjUnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24ucmVzaXplUXVhcnRlcicsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiAnPHNwYW4gY2xhc3M9XCJub3RlLWZvbnRzaXplLTEwXCI+MjUlPC9zcGFuPicsXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy5pbWFnZS5yZXNpemVRdWFydGVyLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5yZXNpemUnLCAnMC4yNScpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5yZXNpemVOb25lJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMucm9sbGJhY2spLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuaW1hZ2UucmVzaXplTm9uZSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IucmVzaXplJywgJzAnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgLy8gRmxvYXQgQnV0dG9uc1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uZmxvYXRMZWZ0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuZmxvYXRMZWZ0KSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmltYWdlLmZsb2F0TGVmdCxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuZmxvYXRNZScsICdsZWZ0JyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uZmxvYXRSaWdodCcsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLmZsb2F0UmlnaHQpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcuaW1hZ2UuZmxvYXRSaWdodCxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuZmxvYXRNZScsICdyaWdodCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmZsb2F0Tm9uZScsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLnJvbGxiYWNrKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmltYWdlLmZsb2F0Tm9uZSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuZmxvYXRNZScsICdub25lJyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIC8vIFJlbW92ZSBCdXR0b25zXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5yZW1vdmVNZWRpYScsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLnRyYXNoKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmltYWdlLnJlbW92ZSxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IucmVtb3ZlTWVkaWEnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkTGlua1BvcG92ZXJCdXR0b25zKCkge1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24ubGlua0RpYWxvZ1Nob3cnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5saW5rKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLmxpbmsuZWRpdCxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdsaW5rRGlhbG9nLnNob3cnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi51bmxpbmsnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy51bmxpbmspLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcubGluay51bmxpbmssXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLnVubGluaycpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogdGFibGUgOiBbXG4gICAqICBbJ2FkZCcsIFsnYWRkUm93RG93bicsICdhZGRSb3dVcCcsICdhZGRDb2xMZWZ0JywgJ2FkZENvbFJpZ2h0J11dLFxuICAgKiAgWydkZWxldGUnLCBbJ2RlbGV0ZVJvdycsICdkZWxldGVDb2wnLCAnZGVsZXRlVGFibGUnXV1cbiAgICogXSxcbiAgICovXG4gIGFkZFRhYmxlUG9wb3ZlckJ1dHRvbnMoKSB7XG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5hZGRSb3dVcCcsICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmJ1dHRvbih7XG4gICAgICAgIGNsYXNzTmFtZTogJ2J0bi1tZCcsXG4gICAgICAgIGNvbnRlbnRzOiB0aGlzLnVpLmljb24odGhpcy5vcHRpb25zLmljb25zLnJvd0Fib3ZlKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnRhYmxlLmFkZFJvd0Fib3ZlLFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5hZGRSb3cnLCAndG9wJyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmFkZFJvd0Rvd24nLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjbGFzc05hbWU6ICdidG4tbWQnLFxuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5yb3dCZWxvdyksXG4gICAgICAgIHRvb2x0aXA6IHRoaXMubGFuZy50YWJsZS5hZGRSb3dCZWxvdyxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuYWRkUm93JywgJ2JvdHRvbScpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5hZGRDb2xMZWZ0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnYnRuLW1kJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuY29sQmVmb3JlKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnRhYmxlLmFkZENvbExlZnQsXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmFkZENvbCcsICdsZWZ0JyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmFkZENvbFJpZ2h0JywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnYnRuLW1kJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuY29sQWZ0ZXIpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcudGFibGUuYWRkQ29sUmlnaHQsXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmFkZENvbCcsICdyaWdodCcpLFxuICAgICAgfSkucmVuZGVyKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi5kZWxldGVSb3cnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idXR0b24oe1xuICAgICAgICBjbGFzc05hbWU6ICdidG4tbWQnLFxuICAgICAgICBjb250ZW50czogdGhpcy51aS5pY29uKHRoaXMub3B0aW9ucy5pY29ucy5yb3dSZW1vdmUpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcudGFibGUuZGVsUm93LFxuICAgICAgICBjbGljazogdGhpcy5jb250ZXh0LmNyZWF0ZUludm9rZUhhbmRsZXIoJ2VkaXRvci5kZWxldGVSb3cnKSxcbiAgICAgIH0pLnJlbmRlcigpO1xuICAgIH0pO1xuICAgIHRoaXMuY29udGV4dC5tZW1vKCdidXR0b24uZGVsZXRlQ29sJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnYnRuLW1kJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMuY29sUmVtb3ZlKSxcbiAgICAgICAgdG9vbHRpcDogdGhpcy5sYW5nLnRhYmxlLmRlbENvbCxcbiAgICAgICAgY2xpY2s6IHRoaXMuY29udGV4dC5jcmVhdGVJbnZva2VIYW5kbGVyKCdlZGl0b3IuZGVsZXRlQ29sJyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRleHQubWVtbygnYnV0dG9uLmRlbGV0ZVRhYmxlJywgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uKHtcbiAgICAgICAgY2xhc3NOYW1lOiAnYnRuLW1kJyxcbiAgICAgICAgY29udGVudHM6IHRoaXMudWkuaWNvbih0aGlzLm9wdGlvbnMuaWNvbnMudHJhc2gpLFxuICAgICAgICB0b29sdGlwOiB0aGlzLmxhbmcudGFibGUuZGVsVGFibGUsXG4gICAgICAgIGNsaWNrOiB0aGlzLmNvbnRleHQuY3JlYXRlSW52b2tlSGFuZGxlcignZWRpdG9yLmRlbGV0ZVRhYmxlJyksXG4gICAgICB9KS5yZW5kZXIoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGJ1aWxkKCRjb250YWluZXIsIGdyb3Vwcykge1xuICAgIGZvciAobGV0IGdyb3VwSWR4ID0gMCwgZ3JvdXBMZW4gPSBncm91cHMubGVuZ3RoOyBncm91cElkeCA8IGdyb3VwTGVuOyBncm91cElkeCsrKSB7XG4gICAgICBjb25zdCBncm91cCA9IGdyb3Vwc1tncm91cElkeF07XG4gICAgICBjb25zdCBncm91cE5hbWUgPSAkLmlzQXJyYXkoZ3JvdXApID8gZ3JvdXBbMF0gOiBncm91cDtcbiAgICAgIGNvbnN0IGJ1dHRvbnMgPSAkLmlzQXJyYXkoZ3JvdXApID8gKChncm91cC5sZW5ndGggPT09IDEpID8gW2dyb3VwWzBdXSA6IGdyb3VwWzFdKSA6IFtncm91cF07XG5cbiAgICAgIGNvbnN0ICRncm91cCA9IHRoaXMudWkuYnV0dG9uR3JvdXAoe1xuICAgICAgICBjbGFzc05hbWU6ICdub3RlLScgKyBncm91cE5hbWUsXG4gICAgICB9KS5yZW5kZXIoKTtcblxuICAgICAgZm9yIChsZXQgaWR4ID0gMCwgbGVuID0gYnV0dG9ucy5sZW5ndGg7IGlkeCA8IGxlbjsgaWR4KyspIHtcbiAgICAgICAgY29uc3QgYnRuID0gdGhpcy5jb250ZXh0Lm1lbW8oJ2J1dHRvbi4nICsgYnV0dG9uc1tpZHhdKTtcbiAgICAgICAgaWYgKGJ0bikge1xuICAgICAgICAgICRncm91cC5hcHBlbmQodHlwZW9mIGJ0biA9PT0gJ2Z1bmN0aW9uJyA/IGJ0bigpIDogYnRuKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgJGdyb3VwLmFwcGVuZFRvKCRjb250YWluZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2pRdWVyeX0gWyRjb250YWluZXJdXG4gICAqL1xuICB1cGRhdGVDdXJyZW50U3R5bGUoJGNvbnRhaW5lcikge1xuICAgIGNvbnN0ICRjb250ID0gJGNvbnRhaW5lciB8fCB0aGlzLiR0b29sYmFyO1xuXG4gICAgY29uc3Qgc3R5bGVJbmZvID0gdGhpcy5jb250ZXh0Lmludm9rZSgnZWRpdG9yLmN1cnJlbnRTdHlsZScpO1xuICAgIHRoaXMudXBkYXRlQnRuU3RhdGVzKCRjb250LCB7XG4gICAgICAnLm5vdGUtYnRuLWJvbGQnOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBzdHlsZUluZm9bJ2ZvbnQtYm9sZCddID09PSAnYm9sZCc7XG4gICAgICB9LFxuICAgICAgJy5ub3RlLWJ0bi1pdGFsaWMnOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBzdHlsZUluZm9bJ2ZvbnQtaXRhbGljJ10gPT09ICdpdGFsaWMnO1xuICAgICAgfSxcbiAgICAgICcubm90ZS1idG4tdW5kZXJsaW5lJzogKCkgPT4ge1xuICAgICAgICByZXR1cm4gc3R5bGVJbmZvWydmb250LXVuZGVybGluZSddID09PSAndW5kZXJsaW5lJztcbiAgICAgIH0sXG4gICAgICAnLm5vdGUtYnRuLXN1YnNjcmlwdCc6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN0eWxlSW5mb1snZm9udC1zdWJzY3JpcHQnXSA9PT0gJ3N1YnNjcmlwdCc7XG4gICAgICB9LFxuICAgICAgJy5ub3RlLWJ0bi1zdXBlcnNjcmlwdCc6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN0eWxlSW5mb1snZm9udC1zdXBlcnNjcmlwdCddID09PSAnc3VwZXJzY3JpcHQnO1xuICAgICAgfSxcbiAgICAgICcubm90ZS1idG4tc3RyaWtldGhyb3VnaCc6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN0eWxlSW5mb1snZm9udC1zdHJpa2V0aHJvdWdoJ10gPT09ICdzdHJpa2V0aHJvdWdoJztcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoc3R5bGVJbmZvWydmb250LWZhbWlseSddKSB7XG4gICAgICBjb25zdCBmb250TmFtZXMgPSBzdHlsZUluZm9bJ2ZvbnQtZmFtaWx5J10uc3BsaXQoJywnKS5tYXAoKG5hbWUpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hbWUucmVwbGFjZSgvW1xcJ1xcXCJdL2csICcnKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXHMrJC8sICcnKVxuICAgICAgICAgIC5yZXBsYWNlKC9eXFxzKy8sICcnKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZm9udE5hbWUgPSBsaXN0cy5maW5kKGZvbnROYW1lcywgdGhpcy5pc0ZvbnRJbnN0YWxsZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICRjb250LmZpbmQoJy5kcm9wZG93bi1mb250bmFtZSBhJykuZWFjaCgoaWR4LCBpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0ICRpdGVtID0gJChpdGVtKTtcbiAgICAgICAgLy8gYWx3YXlzIGNvbXBhcmUgc3RyaW5nIHRvIGF2b2lkIGNyZWF0aW5nIGFub3RoZXIgZnVuYy5cbiAgICAgICAgY29uc3QgaXNDaGVja2VkID0gKCRpdGVtLmRhdGEoJ3ZhbHVlJykgKyAnJykgPT09IChmb250TmFtZSArICcnKTtcbiAgICAgICAgJGl0ZW0udG9nZ2xlQ2xhc3MoJ2NoZWNrZWQnLCBpc0NoZWNrZWQpO1xuICAgICAgfSk7XG4gICAgICAkY29udC5maW5kKCcubm90ZS1jdXJyZW50LWZvbnRuYW1lJykudGV4dChmb250TmFtZSkuY3NzKCdmb250LWZhbWlseScsIGZvbnROYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGVJbmZvWydmb250LXNpemUnXSkge1xuICAgICAgY29uc3QgZm9udFNpemUgPSBzdHlsZUluZm9bJ2ZvbnQtc2l6ZSddO1xuICAgICAgJGNvbnQuZmluZCgnLmRyb3Bkb3duLWZvbnRzaXplIGEnKS5lYWNoKChpZHgsIGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgJGl0ZW0gPSAkKGl0ZW0pO1xuICAgICAgICAvLyBhbHdheXMgY29tcGFyZSB3aXRoIHN0cmluZyB0byBhdm9pZCBjcmVhdGluZyBhbm90aGVyIGZ1bmMuXG4gICAgICAgIGNvbnN0IGlzQ2hlY2tlZCA9ICgkaXRlbS5kYXRhKCd2YWx1ZScpICsgJycpID09PSAoZm9udFNpemUgKyAnJyk7XG4gICAgICAgICRpdGVtLnRvZ2dsZUNsYXNzKCdjaGVja2VkJywgaXNDaGVja2VkKTtcbiAgICAgIH0pO1xuICAgICAgJGNvbnQuZmluZCgnLm5vdGUtY3VycmVudC1mb250c2l6ZScpLnRleHQoZm9udFNpemUpO1xuICAgIH1cblxuICAgIGlmIChzdHlsZUluZm9bJ2xpbmUtaGVpZ2h0J10pIHtcbiAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBzdHlsZUluZm9bJ2xpbmUtaGVpZ2h0J107XG4gICAgICAkY29udC5maW5kKCcuZHJvcGRvd24tbGluZS1oZWlnaHQgbGkgYScpLmVhY2goKGlkeCwgaXRlbSkgPT4ge1xuICAgICAgICAvLyBhbHdheXMgY29tcGFyZSB3aXRoIHN0cmluZyB0byBhdm9pZCBjcmVhdGluZyBhbm90aGVyIGZ1bmMuXG4gICAgICAgIGNvbnN0IGlzQ2hlY2tlZCA9ICgkKGl0ZW0pLmRhdGEoJ3ZhbHVlJykgKyAnJykgPT09IChsaW5lSGVpZ2h0ICsgJycpO1xuICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IGlzQ2hlY2tlZCA/ICdjaGVja2VkJyA6ICcnO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQnRuU3RhdGVzKCRjb250YWluZXIsIGluZm9zKSB7XG4gICAgJC5lYWNoKGluZm9zLCAoc2VsZWN0b3IsIHByZWQpID0+IHtcbiAgICAgIHRoaXMudWkudG9nZ2xlQnRuQWN0aXZlKCRjb250YWluZXIuZmluZChzZWxlY3RvciksIHByZWQoKSk7XG4gICAgfSk7XG4gIH1cblxuICB0YWJsZU1vdmVIYW5kbGVyKGV2ZW50KSB7XG4gICAgY29uc3QgUFhfUEVSX0VNID0gMTg7XG4gICAgY29uc3QgJHBpY2tlciA9ICQoZXZlbnQudGFyZ2V0LnBhcmVudE5vZGUpOyAvLyB0YXJnZXQgaXMgbW91c2VjYXRjaGVyXG4gICAgY29uc3QgJGRpbWVuc2lvbkRpc3BsYXkgPSAkcGlja2VyLm5leHQoKTtcbiAgICBjb25zdCAkY2F0Y2hlciA9ICRwaWNrZXIuZmluZCgnLm5vdGUtZGltZW5zaW9uLXBpY2tlci1tb3VzZWNhdGNoZXInKTtcbiAgICBjb25zdCAkaGlnaGxpZ2h0ZWQgPSAkcGlja2VyLmZpbmQoJy5ub3RlLWRpbWVuc2lvbi1waWNrZXItaGlnaGxpZ2h0ZWQnKTtcbiAgICBjb25zdCAkdW5oaWdobGlnaHRlZCA9ICRwaWNrZXIuZmluZCgnLm5vdGUtZGltZW5zaW9uLXBpY2tlci11bmhpZ2hsaWdodGVkJyk7XG5cbiAgICBsZXQgcG9zT2Zmc2V0O1xuICAgIC8vIEhUTUw1IHdpdGggalF1ZXJ5IC0gZS5vZmZzZXRYIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94XG4gICAgaWYgKGV2ZW50Lm9mZnNldFggPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcG9zQ2F0Y2hlciA9ICQoZXZlbnQudGFyZ2V0KS5vZmZzZXQoKTtcbiAgICAgIHBvc09mZnNldCA9IHtcbiAgICAgICAgeDogZXZlbnQucGFnZVggLSBwb3NDYXRjaGVyLmxlZnQsXG4gICAgICAgIHk6IGV2ZW50LnBhZ2VZIC0gcG9zQ2F0Y2hlci50b3AsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3NPZmZzZXQgPSB7XG4gICAgICAgIHg6IGV2ZW50Lm9mZnNldFgsXG4gICAgICAgIHk6IGV2ZW50Lm9mZnNldFksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGRpbSA9IHtcbiAgICAgIGM6IE1hdGguY2VpbChwb3NPZmZzZXQueCAvIFBYX1BFUl9FTSkgfHwgMSxcbiAgICAgIHI6IE1hdGguY2VpbChwb3NPZmZzZXQueSAvIFBYX1BFUl9FTSkgfHwgMSxcbiAgICB9O1xuXG4gICAgJGhpZ2hsaWdodGVkLmNzcyh7IHdpZHRoOiBkaW0uYyArICdlbScsIGhlaWdodDogZGltLnIgKyAnZW0nIH0pO1xuICAgICRjYXRjaGVyLmRhdGEoJ3ZhbHVlJywgZGltLmMgKyAneCcgKyBkaW0ucik7XG5cbiAgICBpZiAoZGltLmMgPiAzICYmIGRpbS5jIDwgdGhpcy5vcHRpb25zLmluc2VydFRhYmxlTWF4U2l6ZS5jb2wpIHtcbiAgICAgICR1bmhpZ2hsaWdodGVkLmNzcyh7IHdpZHRoOiBkaW0uYyArIDEgKyAnZW0nIH0pO1xuICAgIH1cblxuICAgIGlmIChkaW0uciA+IDMgJiYgZGltLnIgPCB0aGlzLm9wdGlvbnMuaW5zZXJ0VGFibGVNYXhTaXplLnJvdykge1xuICAgICAgJHVuaGlnaGxpZ2h0ZWQuY3NzKHsgaGVpZ2h0OiBkaW0uciArIDEgKyAnZW0nIH0pO1xuICAgIH1cblxuICAgICRkaW1lbnNpb25EaXNwbGF5Lmh0bWwoZGltLmMgKyAnIHggJyArIGRpbS5yKTtcbiAgfVxufVxuIl19