github.com/qubitproducts/logspray@v0.2.14/server/swagger-ui/dist/swagger-ui.js (about)

     1  /**
     2   * swagger-ui - Swagger UI is a dependency-free collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API
     3   * @version v2.2.8
     4   * @link http://swagger.io
     5   * @license Apache-2.0
     6   */
     7  (function(){/* jshint ignore:start */ 
     8   {(function() {
     9    var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
    10  templates['apikey_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
    11      var stack1;
    12  
    13    return "                <span class=\"key_auth__value\">"
    14      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
    15      + "</span>\n";
    16  },"3":function(container,depth0,helpers,partials,data) {
    17      return "                <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n";
    18  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
    19      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
    20  
    21    return "<div class=\"key_input_container\">\n    <h3 class=\"auth__title\">Api key authorization</h3>\n    <div class=\"auth__description\">"
    22      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
    23      + "</div>\n    <div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">name:</span>\n            <span class=\"key_auth__value\">"
    24      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
    25      + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">in:</span>\n            <span class=\"key_auth__value\">"
    26      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["in"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
    27      + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">value:</span>\n"
    28      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
    29      + "        </div>\n    </div>\n</div>\n";
    30  },"useData":true});
    31  templates['auth_button'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
    32      return "<a class='authorize__btn' href=\"#\">Authorize</a>\n";
    33  },"useData":true});
    34  templates['auth_button_operation'] = template({"1":function(container,depth0,helpers,partials,data) {
    35      return "        authorize__btn_operation_login\n";
    36  },"3":function(container,depth0,helpers,partials,data) {
    37      return "        authorize__btn_operation_logout\n";
    38  },"5":function(container,depth0,helpers,partials,data) {
    39      var stack1;
    40  
    41    return "        <ul class=\"authorize-scopes\">\n"
    42      + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    43      + "        </ul>\n";
    44  },"6":function(container,depth0,helpers,partials,data) {
    45      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
    46  
    47    return "                <li class=\"authorize__scope\" title=\""
    48      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
    49      + "\">"
    50      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
    51      + "</li>\n";
    52  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
    53      var stack1, alias1=depth0 != null ? depth0 : {};
    54  
    55    return "<div class=\"authorize__btn authorize__btn_operation\n"
    56      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
    57      + "\">\n"
    58      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    59      + "</div>\n";
    60  },"useData":true});
    61  templates['auth_view'] = template({"1":function(container,depth0,helpers,partials,data) {
    62      return "            <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n";
    63  },"3":function(container,depth0,helpers,partials,data) {
    64      return "            <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n";
    65  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
    66      var stack1, alias1=depth0 != null ? depth0 : {};
    67  
    68    return "<div class=\"auth_container\">\n\n    <div class=\"auth_inner\"></div>\n    <div class=\"auth_submit\">\n"
    69      + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    70      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isAuthorized : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    71      + "    </div>\n\n</div>\n";
    72  },"useData":true});
    73  templates['basic_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
    74      return " - authorized";
    75  },"3":function(container,depth0,helpers,partials,data) {
    76      var stack1;
    77  
    78    return "                <span class=\"basic_auth__value\">"
    79      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.username : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
    80      + "</span>\n";
    81  },"5":function(container,depth0,helpers,partials,data) {
    82      return "                <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n";
    83  },"7":function(container,depth0,helpers,partials,data) {
    84      return "            <div class=\"auth_label\">\n                <span class=\"basic_auth__label\" data-sw-translate>password:</span>\n                <input required placeholder=\"password\" class=\"basic_auth__password auth_input\" name=\"password\" type=\"password\"/></label>\n            </div>\n";
    85  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
    86      var stack1, alias1=depth0 != null ? depth0 : {};
    87  
    88    return "<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication"
    89      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    90      + "</h3>\n    <form class=\"basic_input_container\">\n        <div class=\"auth__description\">"
    91      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
    92      + "</div>\n        <div class=\"auth_label\">\n            <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n"
    93      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.program(5, data, 0),"data":data})) != null ? stack1 : "")
    94      + "        </div>\n"
    95      + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
    96      + "    </form>\n</div>\n";
    97  },"useData":true});
    98  templates['content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
    99      var stack1;
   100  
   101    return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
   102  },"2":function(container,depth0,helpers,partials,data) {
   103      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   104  
   105    return "	<option value=\""
   106      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   107      + "\">"
   108      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   109      + "</option>\n";
   110  },"4":function(container,depth0,helpers,partials,data) {
   111      return "  <option value=\"application/json\">application/json</option>\n";
   112  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   113      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   114  
   115    return "<label data-sw-translate for=\""
   116      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   117      + "\">Response Content Type</label>\n<select name=\"contentType\" id=\""
   118      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   119      + "\">\n"
   120      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
   121      + "</select>\n";
   122  },"useData":true});
   123  templates['main'] = template({"1":function(container,depth0,helpers,partials,data) {
   124      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   125  
   126    return "  <div class=\"info_title\">"
   127      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   128      + "</div>\n  <div class=\"info_description markdown\">"
   129      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   130      + "</div>\n"
   131      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.externalDocs : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   132      + "  "
   133      + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   134      + "\n  "
   135      + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   136      + "\n  "
   137      + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   138      + "\n  "
   139      + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   140      + "\n  "
   141      + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   142      + "\n";
   143  },"2":function(container,depth0,helpers,partials,data) {
   144      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   145  
   146    return "  <p>"
   147      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   148      + "</p>\n  <a href=\""
   149      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   150      + "\" target=\"_blank\">"
   151      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   152      + "</a>\n";
   153  },"4":function(container,depth0,helpers,partials,data) {
   154      var stack1;
   155  
   156    return "<div class=\"info_tos\"><a target=\"_blank\" href=\""
   157      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   158      + "\" data-sw-translate>Terms of service</a></div>";
   159  },"6":function(container,depth0,helpers,partials,data) {
   160      var stack1;
   161  
   162    return "<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "
   163      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   164      + "</div>";
   165  },"8":function(container,depth0,helpers,partials,data) {
   166      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   167  
   168    return "<div class='info_url' data-sw-translate>See more at <a href=\""
   169      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   170      + "\">"
   171      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   172      + "</a></div>";
   173  },"10":function(container,depth0,helpers,partials,data) {
   174      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   175  
   176    return "<div class='info_email'><a target=\"_parent\" href=\"mailto:"
   177      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   178      + "?subject="
   179      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   180      + "\" data-sw-translate>Contact the developer</a></div>";
   181  },"12":function(container,depth0,helpers,partials,data) {
   182      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   183  
   184    return "<div class='info_license'><a target=\"_blank\" href='"
   185      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   186      + "'>"
   187      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   188      + "</a></div>";
   189  },"14":function(container,depth0,helpers,partials,data) {
   190      var stack1;
   191  
   192    return "  , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: "
   193      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   194      + "\n    ";
   195  },"16":function(container,depth0,helpers,partials,data) {
   196      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   197  
   198    return "    <span style=\"float:right\"><a target=\"_blank\" href=\""
   199      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   200      + "/debug?url="
   201      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   202      + "\"><img id=\"validator\" src=\""
   203      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   204      + "?url="
   205      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   206      + "\"></a>\n    </span>\n";
   207  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   208      var stack1, alias1=depth0 != null ? depth0 : {};
   209  
   210    return "<div class='info' id='api_info'>\n"
   211      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.info : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   212      + "</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "
   213      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.basePath : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   214      + "\n"
   215      + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"if","hash":{},"fn":container.program(14, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   216      + "]\n"
   217      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"if","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   218      + "    </h4>\n    </div>\n</div>\n";
   219  },"useData":true});
   220  templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,data) {
   221      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   222  
   223    return "            <li>\n                <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""
   224      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   225      + "\" oauthtype=\""
   226      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   227      + "\"/>\n                <label>"
   228      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   229      + "</label><br/>\n                <span class=\"api-scope-desc\">"
   230      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   231      + "\n"
   232      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   233      + "                </span>\n            </li>\n";
   234  },"2":function(container,depth0,helpers,partials,data) {
   235      var stack1;
   236  
   237    return "                        ("
   238      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   239      + ")\n";
   240  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   241      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   242  
   243    return "<div>\n    <h3 class=\"auth__title\">Select OAuth2.0 Scopes</h3>\n    <p>"
   244      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   245      + "</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href=\"#\">Learn how to use</a>\n    </p>\n    <p><strong> "
   246      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.appName : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   247      + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Authorization URL: "
   248      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   249      + "</p>\n    <p>flow: "
   250      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.flow : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   251      + "</p>\n    <ul class=\"api-popup-scopes\">\n"
   252      + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   253      + "    </ul>\n</div>";
   254  },"useData":true});
   255  templates['operation'] = template({"1":function(container,depth0,helpers,partials,data) {
   256      return "deprecated";
   257  },"3":function(container,depth0,helpers,partials,data) {
   258      return "            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n";
   259  },"5":function(container,depth0,helpers,partials,data) {
   260      var stack1;
   261  
   262    return "        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class=\"markdown\">"
   263      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   264      + "</div>\n";
   265  },"7":function(container,depth0,helpers,partials,data) {
   266      return "            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n";
   267  },"9":function(container,depth0,helpers,partials,data) {
   268      var stack1, alias1=depth0 != null ? depth0 : {};
   269  
   270    return "          <div class=\"response-class\">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> "
   271      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.successCode : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   272      + ")</h4>\n              "
   273      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.successDescription : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   274      + "\n            <p><span class=\"model-signature\" /></p>\n            <br/>\n            <div class=\"response-content-type\" />\n            </div>\n";
   275  },"10":function(container,depth0,helpers,partials,data) {
   276      var stack1;
   277  
   278    return "<div class=\"markdown\">"
   279      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.successDescription : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   280      + "</div>";
   281  },"12":function(container,depth0,helpers,partials,data) {
   282      var stack1;
   283  
   284    return "          <h4 data-sw-translate>Headers</h4>\n          <table class=\"headers\">\n            <thead>\n              <tr>\n                <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Header</th>\n                <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Description</th>\n                <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Type</th>\n                <th style=\"width: 320px; max-width: 320px\" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n"
   285      + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   286      + "            </tbody>\n          </table>\n";
   287  },"13":function(container,depth0,helpers,partials,data) {
   288      var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   289  
   290    return "              <tr>\n                <td>"
   291      + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
   292      + "</td>\n                <td>"
   293      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   294      + "</td>\n                <td>"
   295      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   296      + "</td>\n                <td>"
   297      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.other : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   298      + "</td>\n              </tr>\n";
   299  },"15":function(container,depth0,helpers,partials,data) {
   300      return "          <h4 data-sw-translate>Parameters</h4>\n          <table class='fullwidth parameters'>\n          <thead>\n            <tr>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter</th>\n            <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Value</th>\n            <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Description</th>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter Type</th>\n            <th style=\"width: 220px; max-width: 230px\" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class=\"operation-params\">\n\n          </tbody>\n          </table>\n";
   301  },"17":function(container,depth0,helpers,partials,data) {
   302      return "          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth response-messages'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n";
   303  },"19":function(container,depth0,helpers,partials,data) {
   304      return "";
   305  },"21":function(container,depth0,helpers,partials,data) {
   306      return "          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n";
   307  },"23":function(container,depth0,helpers,partials,data) {
   308      return "          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n";
   309  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   310      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3=container.escapeExpression;
   311  
   312    return "  <ul class='operations' >\n    <li class='"
   313      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   314      + " operation' id='"
   315      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.parentId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   316      + "_"
   317      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   318      + "'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"
   319      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
   320      + "/"
   321      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
   322      + "' class=\"toggleOperation\">"
   323      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   324      + "</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"
   325      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
   326      + "/"
   327      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
   328      + "' class=\"toggleOperation "
   329      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   330      + "\">"
   331      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.path : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   332      + "</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"
   333      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
   334      + "/"
   335      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
   336      + "' class=\"toggleOperation\"><span class=\"markdown\">"
   337      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   338      + "</span></a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"
   339      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
   340      + "_"
   341      + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
   342      + "_content' style='display:none'>\n"
   343      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   344      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   345      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.security : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   346      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   347      + "\n"
   348      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   349      + "\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n"
   350      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.parameters : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   351      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.responseMessages : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   352      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isReadOnly : depth0),{"name":"if","hash":{},"fn":container.program(19, data, 0),"inverse":container.program(21, data, 0),"data":data})) != null ? stack1 : "")
   353      + "        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n"
   354      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showRequestHeaders : depth0),{"name":"if","hash":{},"fn":container.program(23, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   355      + "          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n";
   356  },"useData":true});
   357  templates['param'] = template({"1":function(container,depth0,helpers,partials,data) {
   358      var stack1;
   359  
   360    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "");
   361  },"2":function(container,depth0,helpers,partials,data) {
   362      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   363  
   364    return "			<input type=\"file\" name='"
   365      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   366      + "' id='"
   367      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   368      + "'/>\n			<div class=\"parameter-content-type\" />\n";
   369  },"4":function(container,depth0,helpers,partials,data) {
   370      var stack1;
   371  
   372    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
   373  },"5":function(container,depth0,helpers,partials,data) {
   374      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   375  
   376    return "				<div class=\"editor_holder\"></div>\n				<textarea class='body-textarea' name='"
   377      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   378      + "' id='"
   379      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   380      + "'>"
   381      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   382      + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
   383  },"7":function(container,depth0,helpers,partials,data) {
   384      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   385  
   386    return "				<textarea class='body-textarea' name='"
   387      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   388      + "' id='"
   389      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   390      + "'></textarea>\n				<div class=\"editor_holder\"></div>\n				<br />\n				<div class=\"parameter-content-type\" />\n";
   391  },"9":function(container,depth0,helpers,partials,data) {
   392      var stack1;
   393  
   394    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : "");
   395  },"10":function(container,depth0,helpers,partials,data) {
   396      var stack1;
   397  
   398    return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
   399  },"11":function(container,depth0,helpers,partials,data) {
   400      return "";
   401  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   402      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   403  
   404    return "<td class='code'><label for='"
   405      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   406      + "'>"
   407      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   408      + "</label></td>\n<td>\n\n"
   409      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "")
   410      + "\n</td>\n<td class=\"markdown\">"
   411      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   412      + "</td>\n<td>"
   413      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   414      + "</td>\n<td>\n	<span class=\"model-signature\"></span>\n</td>\n";
   415  },"useData":true});
   416  templates['param_list'] = template({"1":function(container,depth0,helpers,partials,data) {
   417      return " required";
   418  },"3":function(container,depth0,helpers,partials,data) {
   419      return " multiple=\"multiple\"";
   420  },"5":function(container,depth0,helpers,partials,data) {
   421      return " required ";
   422  },"7":function(container,depth0,helpers,partials,data) {
   423      var stack1;
   424  
   425    return "      <option "
   426      + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.hasDefault : depth0),{"name":"unless","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   427      + " value=''></option>\n";
   428  },"8":function(container,depth0,helpers,partials,data) {
   429      return "  selected=\"\" ";
   430  },"10":function(container,depth0,helpers,partials,data) {
   431      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   432  
   433    return "\n      <option "
   434      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   435      + "  value='"
   436      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   437      + "'> "
   438      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   439      + " "
   440      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   441      + " </option>\n\n";
   442  },"11":function(container,depth0,helpers,partials,data) {
   443      return " selected=\"\"  ";
   444  },"13":function(container,depth0,helpers,partials,data) {
   445      return " (default) ";
   446  },"15":function(container,depth0,helpers,partials,data) {
   447      return "<strong>";
   448  },"17":function(container,depth0,helpers,partials,data) {
   449      return "</strong>";
   450  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   451      var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   452  
   453    return "<td class='code"
   454      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   455      + "'><label for='"
   456      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   457      + "'>"
   458      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   459      + "</label></td>\n<td>\n  <select "
   460      + ((stack1 = (helpers.isArray || (depth0 && depth0.isArray) || alias2).call(alias1,depth0,{"name":"isArray","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   461      + " class=\"parameter "
   462      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   463      + "\" name=\""
   464      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   465      + "\" id=\""
   466      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   467      + "\">\n\n"
   468      + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   469      + "\n"
   470      + ((stack1 = helpers.each.call(alias1,((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   471      + "\n  </select>\n</td>\n<td class=\"markdown\">"
   472      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   473      + ((stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"description","hash":{},"data":data}) : helper))) != null ? stack1 : "")
   474      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   475      + "</td>\n<td>"
   476      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   477      + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
   478  },"useData":true});
   479  templates['param_readonly'] = template({"1":function(container,depth0,helpers,partials,data) {
   480      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   481  
   482    return "        <textarea class='body-textarea' readonly='readonly' name='"
   483      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   484      + "' id='"
   485      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   486      + "'>"
   487      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   488      + "</textarea>\n        <div class=\"parameter-content-type\" />\n";
   489  },"3":function(container,depth0,helpers,partials,data) {
   490      var stack1;
   491  
   492    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : "");
   493  },"4":function(container,depth0,helpers,partials,data) {
   494      var stack1;
   495  
   496    return "            "
   497      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   498      + "\n";
   499  },"6":function(container,depth0,helpers,partials,data) {
   500      return "            (empty)\n";
   501  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   502      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   503  
   504    return "<td class='code'><label for='"
   505      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   506      + "'>"
   507      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   508      + "</label></td>\n<td>\n"
   509      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
   510      + "</td>\n<td class=\"markdown\">"
   511      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   512      + "</td>\n<td>"
   513      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   514      + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
   515  },"useData":true});
   516  templates['param_readonly_required'] = template({"1":function(container,depth0,helpers,partials,data) {
   517      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   518  
   519    return "        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"
   520      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   521      + "' id='"
   522      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   523      + "'>"
   524      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   525      + "</textarea>\n";
   526  },"3":function(container,depth0,helpers,partials,data) {
   527      var stack1;
   528  
   529    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : "");
   530  },"4":function(container,depth0,helpers,partials,data) {
   531      var stack1;
   532  
   533    return "            "
   534      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   535      + "\n";
   536  },"6":function(container,depth0,helpers,partials,data) {
   537      return "            (empty)\n";
   538  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   539      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   540  
   541    return "<td class='code required'><label for='"
   542      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   543      + "'>"
   544      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   545      + "</label></td>\n<td>\n"
   546      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
   547      + "</td>\n<td class=\"markdown\">"
   548      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   549      + "</td>\n<td>"
   550      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   551      + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
   552  },"useData":true});
   553  templates['param_required'] = template({"1":function(container,depth0,helpers,partials,data) {
   554      var stack1;
   555  
   556    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "");
   557  },"2":function(container,depth0,helpers,partials,data) {
   558      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   559  
   560    return "			<input type=\"file\" name='"
   561      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   562      + "' id='"
   563      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   564      + "'/>\n";
   565  },"4":function(container,depth0,helpers,partials,data) {
   566      var stack1;
   567  
   568    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
   569  },"5":function(container,depth0,helpers,partials,data) {
   570      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   571  
   572    return "				<div class=\"editor_holder\"></div>\n				<textarea class='body-textarea required' placeholder='(required)' name='"
   573      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   574      + "' id=\""
   575      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   576      + "\">"
   577      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   578      + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
   579  },"7":function(container,depth0,helpers,partials,data) {
   580      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   581  
   582    return "				<textarea class='body-textarea required' placeholder='(required)' name='"
   583      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   584      + "' id='"
   585      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   586      + "'></textarea>\n				<div class=\"editor_holder\"></div>\n				<br />\n				<div class=\"parameter-content-type\" />\n";
   587  },"9":function(container,depth0,helpers,partials,data) {
   588      var stack1;
   589  
   590    return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.program(12, data, 0),"data":data})) != null ? stack1 : "");
   591  },"10":function(container,depth0,helpers,partials,data) {
   592      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   593  
   594    return "			<input class='parameter' class='required' type='file' name='"
   595      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   596      + "' id='"
   597      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   598      + "'/>\n";
   599  },"12":function(container,depth0,helpers,partials,data) {
   600      var stack1;
   601  
   602    return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
   603  },"13":function(container,depth0,helpers,partials,data) {
   604      return "";
   605  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   606      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   607  
   608    return "<td class='code required'><label for='"
   609      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   610      + "'>"
   611      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   612      + "</label></td>\n<td>\n"
   613      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "")
   614      + "</td>\n<td>\n	<strong><span class=\"markdown\">"
   615      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   616      + "</span></strong>\n</td>\n<td>"
   617      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   618      + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
   619  },"useData":true});
   620  templates['parameter_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
   621      var stack1;
   622  
   623    return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.consumes : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
   624  },"2":function(container,depth0,helpers,partials,data) {
   625      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   626  
   627    return "  <option value=\""
   628      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   629      + "\">"
   630      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   631      + "</option>\n";
   632  },"4":function(container,depth0,helpers,partials,data) {
   633      return "  <option value=\"application/json\">application/json</option>\n";
   634  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   635      var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   636  
   637    return "<label for=\""
   638      + container.escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"parameterContentTypeId","hash":{},"data":data}) : helper)))
   639      + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\""
   640      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.parameterContentTypeId : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   641      + "\">\n"
   642      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.consumes : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
   643      + "</select>\n";
   644  },"useData":true});
   645  templates['popup'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   646      var helper;
   647  
   648    return "<div class=\"api-popup-dialog-wrapper\">\n    <div class=\"api-popup-title\">"
   649      + container.escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"title","hash":{},"data":data}) : helper)))
   650      + "</div>\n    <div class=\"api-popup-content\"></div>\n    <p class=\"error-msg\"></p>\n    <div class=\"api-popup-actions\">\n        <button class=\"api-popup-cancel api-button gray\" type=\"button\">Cancel</button>\n    </div>\n</div>\n<div class=\"api-popup-dialog-shadow\"></div>";
   651  },"useData":true});
   652  templates['resource'] = template({"1":function(container,depth0,helpers,partials,data) {
   653      return " : ";
   654  },"3":function(container,depth0,helpers,partials,data) {
   655      var stack1;
   656  
   657    return "    <li>\n      <a href='"
   658      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.url : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   659      + "' data-sw-translate>Raw</a>\n    </li>\n";
   660  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   661      var stack1, helper, options, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, buffer = 
   662    "<div class='heading'>\n  <h2>\n    <a href='#!/"
   663      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   664      + "' class=\"toggleEndpointList\" data-id=\""
   665      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   666      + "\">"
   667      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   668      + "</a> ";
   669    stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : alias2),(options={"name":"summary","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(alias1,options) : helper));
   670    if (!helpers.summary) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)}
   671    if (stack1 != null) { buffer += stack1; }
   672    return buffer + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   673      + "\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"
   674      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   675      + "' id='endpointListTogger_"
   676      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   677      + "' class=\"toggleEndpointList\" data-id=\""
   678      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   679      + "\" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href='#' class=\"collapseResource\" data-id=\""
   680      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   681      + "\" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href='#' class=\"expandResource\" data-id=\""
   682      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   683      + "\" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n"
   684      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   685      + "  </ul>\n</div>\n<ul class='endpoints' id='"
   686      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   687      + "_endpoint_list' style='display:none'>\n\n</ul>\n";
   688  },"useData":true});
   689  templates['response_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
   690      var stack1;
   691  
   692    return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
   693  },"2":function(container,depth0,helpers,partials,data) {
   694      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   695  
   696    return "  <option value=\""
   697      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   698      + "\">"
   699      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   700      + "</option>\n";
   701  },"4":function(container,depth0,helpers,partials,data) {
   702      return "  <option value=\"application/json\">application/json</option>\n";
   703  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   704      var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
   705  
   706    return "<label data-sw-translate for=\""
   707      + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
   708      + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\""
   709      + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
   710      + "\">\n"
   711      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
   712      + "</select>\n";
   713  },"useData":true});
   714  templates['signature'] = template({"1":function(container,depth0,helpers,partials,data) {
   715      var stack1, alias1=depth0 != null ? depth0 : {};
   716  
   717    return "\n<div>\n<ul class=\"signature-nav\">\n  <li><a class=\"description-link\" href=\"#\" data-sw-translate>Model</a></li>\n  <li><a class=\"snippet-link\" href=\"#\" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n  <div class=\"description\">\n      "
   718      + container.escapeExpression((helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.signature : depth0),{"name":"sanitize","hash":{},"data":data}))
   719      + "\n  </div>\n\n  <div class=\"snippet\">\n"
   720      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   721      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   722      + "  </div>\n</div>\n";
   723  },"2":function(container,depth0,helpers,partials,data) {
   724      var stack1, alias1=depth0 != null ? depth0 : {};
   725  
   726    return "      <div class=\"snippet_json\">\n        <pre><code>"
   727      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   728      + "</code></pre>\n        "
   729      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   730      + "\n      </div>\n";
   731  },"3":function(container,depth0,helpers,partials,data) {
   732      return "<small class=\"notice\" data-sw-translate></small>";
   733  },"5":function(container,depth0,helpers,partials,data) {
   734      var stack1, alias1=depth0 != null ? depth0 : {};
   735  
   736    return "    <div class=\"snippet_xml\">\n      <pre><code>"
   737      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   738      + "</code></pre>\n      "
   739      + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   740      + "\n    </div>\n";
   741  },"7":function(container,depth0,helpers,partials,data) {
   742      var stack1;
   743  
   744    return "    "
   745      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.signature : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   746      + "\n";
   747  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   748      var stack1;
   749  
   750    return ((stack1 = (helpers.ifCond || (depth0 && depth0.ifCond) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.sampleJSON : depth0),"||",(depth0 != null ? depth0.sampleXML : depth0),{"name":"ifCond","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
   751  },"useData":true});
   752  templates['status_code'] = template({"1":function(container,depth0,helpers,partials,data) {
   753      var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   754  
   755    return "      <tr>\n        <td>"
   756      + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
   757      + "</td>\n        <td>"
   758      + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
   759      + "</td>\n        <td>"
   760      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   761      + "</td>\n      </tr>\n";
   762  },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
   763      var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
   764  
   765    return "<td width='15%' class='code'>"
   766      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.code : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   767      + "</td>\n<td class=\"markdown\">"
   768      + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.message : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
   769      + "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n  <table>\n    <tbody>\n"
   770      + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
   771      + "    </tbody>\n  </table>\n</td>";
   772  },"useData":true});
   773  })();} 
   774   /* jshint ignore:end */
   775  'use strict';
   776  
   777  
   778  $(function() {
   779  
   780  	// Helper function for vertically aligning DOM elements
   781  	// http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/
   782  	$.fn.vAlign = function() {
   783  		return this.each(function(){
   784  			var ah = $(this).height();
   785  			var ph = $(this).parent().height();
   786  			var mh = (ph - ah) / 2;
   787  			$(this).css('margin-top', mh);
   788  		});
   789  	};
   790  
   791  	$.fn.stretchFormtasticInputWidthToParent = function() {
   792  		return this.each(function(){
   793  			var p_width = $(this).closest("form").innerWidth();
   794  			var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10);
   795  			var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10);
   796  			$(this).css('width', p_width - p_padding - this_padding);
   797  		});
   798  	};
   799  
   800  	$('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent();
   801  
   802  	// Vertically center these paragraphs
   803  	// Parent may need a min-height for this to work..
   804  	$('ul.downplayed li div.content p').vAlign();
   805  
   806  	// When a sandbox form is submitted..
   807  	$("form.sandbox").submit(function(){
   808  
   809  		var error_free = true;
   810  
   811  		// Cycle through the forms required inputs
   812   		$(this).find("input.required").each(function() {
   813  
   814  			// Remove any existing error styles from the input
   815  			$(this).removeClass('error');
   816  
   817  			// Tack the error style on if the input is empty..
   818  			if ($(this).val() === '') {
   819  				$(this).addClass('error');
   820  				$(this).wiggle();
   821  				error_free = false;
   822  			}
   823  
   824  		});
   825  
   826  		return error_free;
   827  	});
   828  
   829  });
   830  
   831  function clippyCopiedCallback() {
   832    $('#api_key_copied').fadeIn().delay(1000).fadeOut();
   833  
   834    // var b = $("#clippy_tooltip_" + a);
   835    // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() {
   836    //   b.attr("title", "copy to clipboard")
   837    // },
   838    // 500))
   839  }
   840  
   841  // Logging function that accounts for browsers that don't have window.console
   842  function log(){
   843    log.history = log.history || [];
   844    log.history.push(arguments);
   845    if(this.console){
   846      console.log( Array.prototype.slice.call(arguments)[0] );
   847    }
   848  }
   849  
   850  // Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)
   851  if (Function.prototype.bind && console && typeof console.log === "object") {
   852      [
   853        "log","info","warn","error","assert","dir","clear","profile","profileEnd"
   854      ].forEach(function (method) {
   855          console[method] = this.bind(console[method], console);
   856      }, Function.prototype.call);
   857  }
   858  
   859  window.Docs = {
   860  
   861  	shebang: function() {
   862  
   863  		// If shebang has an operation nickname in it..
   864  		// e.g. /docs/#!/words/get_search
   865  		var fragments = $.param.fragment().split('/');
   866  		fragments.shift(); // get rid of the bang
   867  
   868  		switch (fragments.length) {
   869  			case 1:
   870          if (fragments[0].length > 0) { // prevent matching "#/"
   871            // Expand all operations for the resource and scroll to it
   872            var dom_id = 'resource_' + fragments[0];
   873  
   874            Docs.expandEndpointListForResource(fragments[0]);
   875            $("#"+dom_id).slideto({highlight: false});
   876          }
   877  				break;
   878  			case 2:
   879  				// Refer to the endpoint DOM element, e.g. #words_get_search
   880  
   881          // Expand Resource
   882          Docs.expandEndpointListForResource(fragments[0]);
   883          $("#"+dom_id).slideto({highlight: false});
   884  
   885              // Expand operation
   886              var li_dom_id = fragments.join('_');
   887              var li_content_dom_id = li_dom_id + "_content";
   888  
   889  
   890              Docs.expandOperation($('#'+li_content_dom_id));
   891              $('#'+li_dom_id).slideto({highlight: false});
   892              break;
   893  		}
   894  	},
   895  
   896  	toggleEndpointListForResource: function(resource) {
   897  		var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints');
   898  		if (elem.is(':visible')) {
   899  			$.bbq.pushState('#/', 2);
   900  			Docs.collapseEndpointListForResource(resource);
   901  		} else {
   902              $.bbq.pushState('#/' + resource, 2);
   903  			Docs.expandEndpointListForResource(resource);
   904  		}
   905  	},
   906  
   907  	// Expand resource
   908  	expandEndpointListForResource: function(resource) {
   909  		var resource = Docs.escapeResourceName(resource);
   910  		if (resource == '') {
   911  			$('.resource ul.endpoints').slideDown();
   912  			return;
   913  		}
   914  
   915  		$('li#resource_' + resource).addClass('active');
   916  
   917  		var elem = $('li#resource_' + resource + ' ul.endpoints');
   918  		elem.slideDown();
   919  	},
   920  
   921  	// Collapse resource and mark as explicitly closed
   922  	collapseEndpointListForResource: function(resource) {
   923  		var resource = Docs.escapeResourceName(resource);
   924  		if (resource == '') {
   925  			$('.resource ul.endpoints').slideUp();
   926  			return;
   927  		}
   928  
   929  		$('li#resource_' + resource).removeClass('active');
   930  
   931  		var elem = $('li#resource_' + resource + ' ul.endpoints');
   932  		elem.slideUp();
   933  	},
   934  
   935  	expandOperationsForResource: function(resource) {
   936  		// Make sure the resource container is open..
   937  		Docs.expandEndpointListForResource(resource);
   938  
   939  		if (resource == '') {
   940  			$('.resource ul.endpoints li.operation div.content').slideDown();
   941  			return;
   942  		}
   943  
   944  		$('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
   945  			Docs.expandOperation($(this));
   946  		});
   947  	},
   948  
   949  	collapseOperationsForResource: function(resource) {
   950  		// Make sure the resource container is open..
   951  		Docs.expandEndpointListForResource(resource);
   952  
   953  		if (resource == '') {
   954  			$('.resource ul.endpoints li.operation div.content').slideUp();
   955  			return;
   956  		}
   957  
   958  		$('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
   959  			Docs.collapseOperation($(this));
   960  		});
   961  	},
   962  
   963  	escapeResourceName: function(resource) {
   964  		return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&");
   965  	},
   966  
   967  	expandOperation: function(elem) {
   968  		elem.slideDown();
   969  	},
   970  
   971  	collapseOperation: function(elem) {
   972  		elem.slideUp();
   973  	}
   974  };
   975  
   976  /*!
   977   * https://github.com/es-shims/es5-shim
   978   * @license es5-shim Copyright 2009-2015 by contributors, MIT License
   979   * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
   980   */
   981  
   982  // vim: ts=4 sts=4 sw=4 expandtab
   983  
   984  // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
   985  ;
   986  
   987  // UMD (Universal Module Definition)
   988  // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
   989  (function (root, factory) {
   990      'use strict';
   991  
   992      /* global define, exports, module */
   993      if (typeof define === 'function' && define.amd) {
   994          // AMD. Register as an anonymous module.
   995          define(factory);
   996      } else if (typeof exports === 'object') {
   997          // Node. Does not work with strict CommonJS, but
   998          // only CommonJS-like enviroments that support module.exports,
   999          // like Node.
  1000          module.exports = factory();
  1001      } else {
  1002          // Browser globals (root is window)
  1003          root.returnExports = factory();
  1004      }
  1005  }(this, function () {
  1006      /**
  1007       * Brings an environment as close to ECMAScript 5 compliance
  1008       * as is possible with the facilities of erstwhile engines.
  1009       *
  1010       * Annotated ES5: http://es5.github.com/ (specific links below)
  1011       * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  1012       * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
  1013       */
  1014  
  1015      // Shortcut to an often accessed properties, in order to avoid multiple
  1016      // dereference that costs universally. This also holds a reference to known-good
  1017      // functions.
  1018      var $Array = Array;
  1019      var ArrayPrototype = $Array.prototype;
  1020      var $Object = Object;
  1021      var ObjectPrototype = $Object.prototype;
  1022      var $Function = Function;
  1023      var FunctionPrototype = $Function.prototype;
  1024      var $String = String;
  1025      var StringPrototype = $String.prototype;
  1026      var $Number = Number;
  1027      var NumberPrototype = $Number.prototype;
  1028      var array_slice = ArrayPrototype.slice;
  1029      var array_splice = ArrayPrototype.splice;
  1030      var array_push = ArrayPrototype.push;
  1031      var array_unshift = ArrayPrototype.unshift;
  1032      var array_concat = ArrayPrototype.concat;
  1033      var array_join = ArrayPrototype.join;
  1034      var call = FunctionPrototype.call;
  1035      var apply = FunctionPrototype.apply;
  1036      var max = Math.max;
  1037      var min = Math.min;
  1038  
  1039      // Having a toString local variable name breaks in Opera so use to_string.
  1040      var to_string = ObjectPrototype.toString;
  1041  
  1042      /* global Symbol */
  1043      /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
  1044      var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
  1045      var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
  1046  
  1047      var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
  1048      var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
  1049      /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
  1050  
  1051      /* inlined from http://npmjs.com/define-properties */
  1052      var supportsDescriptors = $Object.defineProperty && (function () {
  1053          try {
  1054              var obj = {};
  1055              $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
  1056              for (var _ in obj) { // jscs:ignore disallowUnusedVariables
  1057                  return false;
  1058              }
  1059              return obj.x === obj;
  1060          } catch (e) { /* this is ES3 */
  1061              return false;
  1062          }
  1063      }());
  1064      var defineProperties = (function (has) {
  1065          // Define configurable, writable, and non-enumerable props
  1066          // if they don't exist.
  1067          var defineProperty;
  1068          if (supportsDescriptors) {
  1069              defineProperty = function (object, name, method, forceAssign) {
  1070                  if (!forceAssign && (name in object)) {
  1071                      return;
  1072                  }
  1073                  $Object.defineProperty(object, name, {
  1074                      configurable: true,
  1075                      enumerable: false,
  1076                      writable: true,
  1077                      value: method
  1078                  });
  1079              };
  1080          } else {
  1081              defineProperty = function (object, name, method, forceAssign) {
  1082                  if (!forceAssign && (name in object)) {
  1083                      return;
  1084                  }
  1085                  object[name] = method;
  1086              };
  1087          }
  1088          return function defineProperties(object, map, forceAssign) {
  1089              for (var name in map) {
  1090                  if (has.call(map, name)) {
  1091                      defineProperty(object, name, map[name], forceAssign);
  1092                  }
  1093              }
  1094          };
  1095      }(ObjectPrototype.hasOwnProperty));
  1096  
  1097      //
  1098      // Util
  1099      // ======
  1100      //
  1101  
  1102      /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
  1103      var isPrimitive = function isPrimitive(input) {
  1104          var type = typeof input;
  1105          return input === null || (type !== 'object' && type !== 'function');
  1106      };
  1107  
  1108      var isActualNaN = $Number.isNaN || function isActualNaN(x) {
  1109          return x !== x;
  1110      };
  1111  
  1112      var ES = {
  1113          // ES5 9.4
  1114          // http://es5.github.com/#x9.4
  1115          // http://jsperf.com/to-integer
  1116          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
  1117          ToInteger: function ToInteger(num) {
  1118              var n = +num;
  1119              if (isActualNaN(n)) {
  1120                  n = 0;
  1121              } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
  1122                  n = (n > 0 || -1) * Math.floor(Math.abs(n));
  1123              }
  1124              return n;
  1125          },
  1126  
  1127          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
  1128          ToPrimitive: function ToPrimitive(input) {
  1129              var val, valueOf, toStr;
  1130              if (isPrimitive(input)) {
  1131                  return input;
  1132              }
  1133              valueOf = input.valueOf;
  1134              if (isCallable(valueOf)) {
  1135                  val = valueOf.call(input);
  1136                  if (isPrimitive(val)) {
  1137                      return val;
  1138                  }
  1139              }
  1140              toStr = input.toString;
  1141              if (isCallable(toStr)) {
  1142                  val = toStr.call(input);
  1143                  if (isPrimitive(val)) {
  1144                      return val;
  1145                  }
  1146              }
  1147              throw new TypeError();
  1148          },
  1149  
  1150          // ES5 9.9
  1151          // http://es5.github.com/#x9.9
  1152          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
  1153          ToObject: function (o) {
  1154              if (o == null) { // this matches both null and undefined
  1155                  throw new TypeError("can't convert " + o + ' to object');
  1156              }
  1157              return $Object(o);
  1158          },
  1159  
  1160          /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
  1161          ToUint32: function ToUint32(x) {
  1162              return x >>> 0;
  1163          }
  1164      };
  1165  
  1166      //
  1167      // Function
  1168      // ========
  1169      //
  1170  
  1171      // ES-5 15.3.4.5
  1172      // http://es5.github.com/#x15.3.4.5
  1173  
  1174      var Empty = function Empty() {};
  1175  
  1176      defineProperties(FunctionPrototype, {
  1177          bind: function bind(that) { // .length is 1
  1178              // 1. Let Target be the this value.
  1179              var target = this;
  1180              // 2. If IsCallable(Target) is false, throw a TypeError exception.
  1181              if (!isCallable(target)) {
  1182                  throw new TypeError('Function.prototype.bind called on incompatible ' + target);
  1183              }
  1184              // 3. Let A be a new (possibly empty) internal list of all of the
  1185              //   argument values provided after thisArg (arg1, arg2 etc), in order.
  1186              // XXX slicedArgs will stand in for "A" if used
  1187              var args = array_slice.call(arguments, 1); // for normal call
  1188              // 4. Let F be a new native ECMAScript object.
  1189              // 11. Set the [[Prototype]] internal property of F to the standard
  1190              //   built-in Function prototype object as specified in 15.3.3.1.
  1191              // 12. Set the [[Call]] internal property of F as described in
  1192              //   15.3.4.5.1.
  1193              // 13. Set the [[Construct]] internal property of F as described in
  1194              //   15.3.4.5.2.
  1195              // 14. Set the [[HasInstance]] internal property of F as described in
  1196              //   15.3.4.5.3.
  1197              var bound;
  1198              var binder = function () {
  1199  
  1200                  if (this instanceof bound) {
  1201                      // 15.3.4.5.2 [[Construct]]
  1202                      // When the [[Construct]] internal method of a function object,
  1203                      // F that was created using the bind function is called with a
  1204                      // list of arguments ExtraArgs, the following steps are taken:
  1205                      // 1. Let target be the value of F's [[TargetFunction]]
  1206                      //   internal property.
  1207                      // 2. If target has no [[Construct]] internal method, a
  1208                      //   TypeError exception is thrown.
  1209                      // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  1210                      //   property.
  1211                      // 4. Let args be a new list containing the same values as the
  1212                      //   list boundArgs in the same order followed by the same
  1213                      //   values as the list ExtraArgs in the same order.
  1214                      // 5. Return the result of calling the [[Construct]] internal
  1215                      //   method of target providing args as the arguments.
  1216  
  1217                      var result = apply.call(
  1218                          target,
  1219                          this,
  1220                          array_concat.call(args, array_slice.call(arguments))
  1221                      );
  1222                      if ($Object(result) === result) {
  1223                          return result;
  1224                      }
  1225                      return this;
  1226  
  1227                  } else {
  1228                      // 15.3.4.5.1 [[Call]]
  1229                      // When the [[Call]] internal method of a function object, F,
  1230                      // which was created using the bind function is called with a
  1231                      // this value and a list of arguments ExtraArgs, the following
  1232                      // steps are taken:
  1233                      // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  1234                      //   property.
  1235                      // 2. Let boundThis be the value of F's [[BoundThis]] internal
  1236                      //   property.
  1237                      // 3. Let target be the value of F's [[TargetFunction]] internal
  1238                      //   property.
  1239                      // 4. Let args be a new list containing the same values as the
  1240                      //   list boundArgs in the same order followed by the same
  1241                      //   values as the list ExtraArgs in the same order.
  1242                      // 5. Return the result of calling the [[Call]] internal method
  1243                      //   of target providing boundThis as the this value and
  1244                      //   providing args as the arguments.
  1245  
  1246                      // equiv: target.call(this, ...boundArgs, ...args)
  1247                      return apply.call(
  1248                          target,
  1249                          that,
  1250                          array_concat.call(args, array_slice.call(arguments))
  1251                      );
  1252  
  1253                  }
  1254  
  1255              };
  1256  
  1257              // 15. If the [[Class]] internal property of Target is "Function", then
  1258              //     a. Let L be the length property of Target minus the length of A.
  1259              //     b. Set the length own property of F to either 0 or L, whichever is
  1260              //       larger.
  1261              // 16. Else set the length own property of F to 0.
  1262  
  1263              var boundLength = max(0, target.length - args.length);
  1264  
  1265              // 17. Set the attributes of the length own property of F to the values
  1266              //   specified in 15.3.5.1.
  1267              var boundArgs = [];
  1268              for (var i = 0; i < boundLength; i++) {
  1269                  array_push.call(boundArgs, '$' + i);
  1270              }
  1271  
  1272              // XXX Build a dynamic function with desired amount of arguments is the only
  1273              // way to set the length property of a function.
  1274              // In environments where Content Security Policies enabled (Chrome extensions,
  1275              // for ex.) all use of eval or Function costructor throws an exception.
  1276              // However in all of these environments Function.prototype.bind exists
  1277              // and so this code will never be executed.
  1278              bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
  1279  
  1280              if (target.prototype) {
  1281                  Empty.prototype = target.prototype;
  1282                  bound.prototype = new Empty();
  1283                  // Clean up dangling references.
  1284                  Empty.prototype = null;
  1285              }
  1286  
  1287              // TODO
  1288              // 18. Set the [[Extensible]] internal property of F to true.
  1289  
  1290              // TODO
  1291              // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  1292              // 20. Call the [[DefineOwnProperty]] internal method of F with
  1293              //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  1294              //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  1295              //   false.
  1296              // 21. Call the [[DefineOwnProperty]] internal method of F with
  1297              //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  1298              //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  1299              //   and false.
  1300  
  1301              // TODO
  1302              // NOTE Function objects created using Function.prototype.bind do not
  1303              // have a prototype property or the [[Code]], [[FormalParameters]], and
  1304              // [[Scope]] internal properties.
  1305              // XXX can't delete prototype in pure-js.
  1306  
  1307              // 22. Return F.
  1308              return bound;
  1309          }
  1310      });
  1311  
  1312      // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  1313      // use it in defining shortcuts.
  1314      var owns = call.bind(ObjectPrototype.hasOwnProperty);
  1315      var toStr = call.bind(ObjectPrototype.toString);
  1316      var arraySlice = call.bind(array_slice);
  1317      var arraySliceApply = apply.bind(array_slice);
  1318      var strSlice = call.bind(StringPrototype.slice);
  1319      var strSplit = call.bind(StringPrototype.split);
  1320      var strIndexOf = call.bind(StringPrototype.indexOf);
  1321      var pushCall = call.bind(array_push);
  1322      var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
  1323      var arraySort = call.bind(ArrayPrototype.sort);
  1324  
  1325      //
  1326      // Array
  1327      // =====
  1328      //
  1329  
  1330      var isArray = $Array.isArray || function isArray(obj) {
  1331          return toStr(obj) === '[object Array]';
  1332      };
  1333  
  1334      // ES5 15.4.4.12
  1335      // http://es5.github.com/#x15.4.4.13
  1336      // Return len+argCount.
  1337      // [bugfix, ielt8]
  1338      // IE < 8 bug: [].unshift(0) === undefined but should be "1"
  1339      var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
  1340      defineProperties(ArrayPrototype, {
  1341          unshift: function () {
  1342              array_unshift.apply(this, arguments);
  1343              return this.length;
  1344          }
  1345      }, hasUnshiftReturnValueBug);
  1346  
  1347      // ES5 15.4.3.2
  1348      // http://es5.github.com/#x15.4.3.2
  1349      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  1350      defineProperties($Array, { isArray: isArray });
  1351  
  1352      // The IsCallable() check in the Array functions
  1353      // has been replaced with a strict check on the
  1354      // internal class of the object to trap cases where
  1355      // the provided function was actually a regular
  1356      // expression literal, which in V8 and
  1357      // JavaScriptCore is a typeof "function".  Only in
  1358      // V8 are regular expression literals permitted as
  1359      // reduce parameters, so it is desirable in the
  1360      // general case for the shim to match the more
  1361      // strict and common behavior of rejecting regular
  1362      // expressions.
  1363  
  1364      // ES5 15.4.4.18
  1365      // http://es5.github.com/#x15.4.4.18
  1366      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  1367  
  1368      // Check failure of by-index access of string characters (IE < 9)
  1369      // and failure of `0 in boxedString` (Rhino)
  1370      var boxedString = $Object('a');
  1371      var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
  1372  
  1373      var properlyBoxesContext = function properlyBoxed(method) {
  1374          // Check node 0.6.21 bug where third parameter is not boxed
  1375          var properlyBoxesNonStrict = true;
  1376          var properlyBoxesStrict = true;
  1377          var threwException = false;
  1378          if (method) {
  1379              try {
  1380                  method.call('foo', function (_, __, context) {
  1381                      if (typeof context !== 'object') {
  1382                          properlyBoxesNonStrict = false;
  1383                      }
  1384                  });
  1385  
  1386                  method.call([1], function () {
  1387                      'use strict';
  1388  
  1389                      properlyBoxesStrict = typeof this === 'string';
  1390                  }, 'x');
  1391              } catch (e) {
  1392                  threwException = true;
  1393              }
  1394          }
  1395          return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
  1396      };
  1397  
  1398      defineProperties(ArrayPrototype, {
  1399          forEach: function forEach(callbackfn/*, thisArg*/) {
  1400              var object = ES.ToObject(this);
  1401              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1402              var i = -1;
  1403              var length = ES.ToUint32(self.length);
  1404              var T;
  1405              if (arguments.length > 1) {
  1406                  T = arguments[1];
  1407              }
  1408  
  1409              // If no callback function or if callback is not a callable function
  1410              if (!isCallable(callbackfn)) {
  1411                  throw new TypeError('Array.prototype.forEach callback must be a function');
  1412              }
  1413  
  1414              while (++i < length) {
  1415                  if (i in self) {
  1416                      // Invoke the callback function with call, passing arguments:
  1417                      // context, property value, property key, thisArg object
  1418                      if (typeof T === 'undefined') {
  1419                          callbackfn(self[i], i, object);
  1420                      } else {
  1421                          callbackfn.call(T, self[i], i, object);
  1422                      }
  1423                  }
  1424              }
  1425          }
  1426      }, !properlyBoxesContext(ArrayPrototype.forEach));
  1427  
  1428      // ES5 15.4.4.19
  1429      // http://es5.github.com/#x15.4.4.19
  1430      // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  1431      defineProperties(ArrayPrototype, {
  1432          map: function map(callbackfn/*, thisArg*/) {
  1433              var object = ES.ToObject(this);
  1434              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1435              var length = ES.ToUint32(self.length);
  1436              var result = $Array(length);
  1437              var T;
  1438              if (arguments.length > 1) {
  1439                  T = arguments[1];
  1440              }
  1441  
  1442              // If no callback function or if callback is not a callable function
  1443              if (!isCallable(callbackfn)) {
  1444                  throw new TypeError('Array.prototype.map callback must be a function');
  1445              }
  1446  
  1447              for (var i = 0; i < length; i++) {
  1448                  if (i in self) {
  1449                      if (typeof T === 'undefined') {
  1450                          result[i] = callbackfn(self[i], i, object);
  1451                      } else {
  1452                          result[i] = callbackfn.call(T, self[i], i, object);
  1453                      }
  1454                  }
  1455              }
  1456              return result;
  1457          }
  1458      }, !properlyBoxesContext(ArrayPrototype.map));
  1459  
  1460      // ES5 15.4.4.20
  1461      // http://es5.github.com/#x15.4.4.20
  1462      // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  1463      defineProperties(ArrayPrototype, {
  1464          filter: function filter(callbackfn/*, thisArg*/) {
  1465              var object = ES.ToObject(this);
  1466              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1467              var length = ES.ToUint32(self.length);
  1468              var result = [];
  1469              var value;
  1470              var T;
  1471              if (arguments.length > 1) {
  1472                  T = arguments[1];
  1473              }
  1474  
  1475              // If no callback function or if callback is not a callable function
  1476              if (!isCallable(callbackfn)) {
  1477                  throw new TypeError('Array.prototype.filter callback must be a function');
  1478              }
  1479  
  1480              for (var i = 0; i < length; i++) {
  1481                  if (i in self) {
  1482                      value = self[i];
  1483                      if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
  1484                          pushCall(result, value);
  1485                      }
  1486                  }
  1487              }
  1488              return result;
  1489          }
  1490      }, !properlyBoxesContext(ArrayPrototype.filter));
  1491  
  1492      // ES5 15.4.4.16
  1493      // http://es5.github.com/#x15.4.4.16
  1494      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  1495      defineProperties(ArrayPrototype, {
  1496          every: function every(callbackfn/*, thisArg*/) {
  1497              var object = ES.ToObject(this);
  1498              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1499              var length = ES.ToUint32(self.length);
  1500              var T;
  1501              if (arguments.length > 1) {
  1502                  T = arguments[1];
  1503              }
  1504  
  1505              // If no callback function or if callback is not a callable function
  1506              if (!isCallable(callbackfn)) {
  1507                  throw new TypeError('Array.prototype.every callback must be a function');
  1508              }
  1509  
  1510              for (var i = 0; i < length; i++) {
  1511                  if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  1512                      return false;
  1513                  }
  1514              }
  1515              return true;
  1516          }
  1517      }, !properlyBoxesContext(ArrayPrototype.every));
  1518  
  1519      // ES5 15.4.4.17
  1520      // http://es5.github.com/#x15.4.4.17
  1521      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  1522      defineProperties(ArrayPrototype, {
  1523          some: function some(callbackfn/*, thisArg */) {
  1524              var object = ES.ToObject(this);
  1525              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1526              var length = ES.ToUint32(self.length);
  1527              var T;
  1528              if (arguments.length > 1) {
  1529                  T = arguments[1];
  1530              }
  1531  
  1532              // If no callback function or if callback is not a callable function
  1533              if (!isCallable(callbackfn)) {
  1534                  throw new TypeError('Array.prototype.some callback must be a function');
  1535              }
  1536  
  1537              for (var i = 0; i < length; i++) {
  1538                  if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  1539                      return true;
  1540                  }
  1541              }
  1542              return false;
  1543          }
  1544      }, !properlyBoxesContext(ArrayPrototype.some));
  1545  
  1546      // ES5 15.4.4.21
  1547      // http://es5.github.com/#x15.4.4.21
  1548      // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  1549      var reduceCoercesToObject = false;
  1550      if (ArrayPrototype.reduce) {
  1551          reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
  1552              return list;
  1553          }) === 'object';
  1554      }
  1555      defineProperties(ArrayPrototype, {
  1556          reduce: function reduce(callbackfn/*, initialValue*/) {
  1557              var object = ES.ToObject(this);
  1558              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1559              var length = ES.ToUint32(self.length);
  1560  
  1561              // If no callback function or if callback is not a callable function
  1562              if (!isCallable(callbackfn)) {
  1563                  throw new TypeError('Array.prototype.reduce callback must be a function');
  1564              }
  1565  
  1566              // no value to return if no initial value and an empty array
  1567              if (length === 0 && arguments.length === 1) {
  1568                  throw new TypeError('reduce of empty array with no initial value');
  1569              }
  1570  
  1571              var i = 0;
  1572              var result;
  1573              if (arguments.length >= 2) {
  1574                  result = arguments[1];
  1575              } else {
  1576                  do {
  1577                      if (i in self) {
  1578                          result = self[i++];
  1579                          break;
  1580                      }
  1581  
  1582                      // if array contains no values, no initial value to return
  1583                      if (++i >= length) {
  1584                          throw new TypeError('reduce of empty array with no initial value');
  1585                      }
  1586                  } while (true);
  1587              }
  1588  
  1589              for (; i < length; i++) {
  1590                  if (i in self) {
  1591                      result = callbackfn(result, self[i], i, object);
  1592                  }
  1593              }
  1594  
  1595              return result;
  1596          }
  1597      }, !reduceCoercesToObject);
  1598  
  1599      // ES5 15.4.4.22
  1600      // http://es5.github.com/#x15.4.4.22
  1601      // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  1602      var reduceRightCoercesToObject = false;
  1603      if (ArrayPrototype.reduceRight) {
  1604          reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
  1605              return list;
  1606          }) === 'object';
  1607      }
  1608      defineProperties(ArrayPrototype, {
  1609          reduceRight: function reduceRight(callbackfn/*, initial*/) {
  1610              var object = ES.ToObject(this);
  1611              var self = splitString && isString(this) ? strSplit(this, '') : object;
  1612              var length = ES.ToUint32(self.length);
  1613  
  1614              // If no callback function or if callback is not a callable function
  1615              if (!isCallable(callbackfn)) {
  1616                  throw new TypeError('Array.prototype.reduceRight callback must be a function');
  1617              }
  1618  
  1619              // no value to return if no initial value, empty array
  1620              if (length === 0 && arguments.length === 1) {
  1621                  throw new TypeError('reduceRight of empty array with no initial value');
  1622              }
  1623  
  1624              var result;
  1625              var i = length - 1;
  1626              if (arguments.length >= 2) {
  1627                  result = arguments[1];
  1628              } else {
  1629                  do {
  1630                      if (i in self) {
  1631                          result = self[i--];
  1632                          break;
  1633                      }
  1634  
  1635                      // if array contains no values, no initial value to return
  1636                      if (--i < 0) {
  1637                          throw new TypeError('reduceRight of empty array with no initial value');
  1638                      }
  1639                  } while (true);
  1640              }
  1641  
  1642              if (i < 0) {
  1643                  return result;
  1644              }
  1645  
  1646              do {
  1647                  if (i in self) {
  1648                      result = callbackfn(result, self[i], i, object);
  1649                  }
  1650              } while (i--);
  1651  
  1652              return result;
  1653          }
  1654      }, !reduceRightCoercesToObject);
  1655  
  1656      // ES5 15.4.4.14
  1657      // http://es5.github.com/#x15.4.4.14
  1658      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  1659      var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
  1660      defineProperties(ArrayPrototype, {
  1661          indexOf: function indexOf(searchElement/*, fromIndex */) {
  1662              var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
  1663              var length = ES.ToUint32(self.length);
  1664  
  1665              if (length === 0) {
  1666                  return -1;
  1667              }
  1668  
  1669              var i = 0;
  1670              if (arguments.length > 1) {
  1671                  i = ES.ToInteger(arguments[1]);
  1672              }
  1673  
  1674              // handle negative indices
  1675              i = i >= 0 ? i : max(0, length + i);
  1676              for (; i < length; i++) {
  1677                  if (i in self && self[i] === searchElement) {
  1678                      return i;
  1679                  }
  1680              }
  1681              return -1;
  1682          }
  1683      }, hasFirefox2IndexOfBug);
  1684  
  1685      // ES5 15.4.4.15
  1686      // http://es5.github.com/#x15.4.4.15
  1687      // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  1688      var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
  1689      defineProperties(ArrayPrototype, {
  1690          lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
  1691              var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
  1692              var length = ES.ToUint32(self.length);
  1693  
  1694              if (length === 0) {
  1695                  return -1;
  1696              }
  1697              var i = length - 1;
  1698              if (arguments.length > 1) {
  1699                  i = min(i, ES.ToInteger(arguments[1]));
  1700              }
  1701              // handle negative indices
  1702              i = i >= 0 ? i : length - Math.abs(i);
  1703              for (; i >= 0; i--) {
  1704                  if (i in self && searchElement === self[i]) {
  1705                      return i;
  1706                  }
  1707              }
  1708              return -1;
  1709          }
  1710      }, hasFirefox2LastIndexOfBug);
  1711  
  1712      // ES5 15.4.4.12
  1713      // http://es5.github.com/#x15.4.4.12
  1714      var spliceNoopReturnsEmptyArray = (function () {
  1715          var a = [1, 2];
  1716          var result = a.splice();
  1717          return a.length === 2 && isArray(result) && result.length === 0;
  1718      }());
  1719      defineProperties(ArrayPrototype, {
  1720          // Safari 5.0 bug where .splice() returns undefined
  1721          splice: function splice(start, deleteCount) {
  1722              if (arguments.length === 0) {
  1723                  return [];
  1724              } else {
  1725                  return array_splice.apply(this, arguments);
  1726              }
  1727          }
  1728      }, !spliceNoopReturnsEmptyArray);
  1729  
  1730      var spliceWorksWithEmptyObject = (function () {
  1731          var obj = {};
  1732          ArrayPrototype.splice.call(obj, 0, 0, 1);
  1733          return obj.length === 1;
  1734      }());
  1735      defineProperties(ArrayPrototype, {
  1736          splice: function splice(start, deleteCount) {
  1737              if (arguments.length === 0) {
  1738                  return [];
  1739              }
  1740              var args = arguments;
  1741              this.length = max(ES.ToInteger(this.length), 0);
  1742              if (arguments.length > 0 && typeof deleteCount !== 'number') {
  1743                  args = arraySlice(arguments);
  1744                  if (args.length < 2) {
  1745                      pushCall(args, this.length - start);
  1746                  } else {
  1747                      args[1] = ES.ToInteger(deleteCount);
  1748                  }
  1749              }
  1750              return array_splice.apply(this, args);
  1751          }
  1752      }, !spliceWorksWithEmptyObject);
  1753      var spliceWorksWithLargeSparseArrays = (function () {
  1754          // Per https://github.com/es-shims/es5-shim/issues/295
  1755          // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
  1756          var arr = new $Array(1e5);
  1757          // note: the index MUST be 8 or larger or the test will false pass
  1758          arr[8] = 'x';
  1759          arr.splice(1, 1);
  1760          // note: this test must be defined *after* the indexOf shim
  1761          // per https://github.com/es-shims/es5-shim/issues/313
  1762          return arr.indexOf('x') === 7;
  1763      }());
  1764      var spliceWorksWithSmallSparseArrays = (function () {
  1765          // Per https://github.com/es-shims/es5-shim/issues/295
  1766          // Opera 12.15 breaks on this, no idea why.
  1767          var n = 256;
  1768          var arr = [];
  1769          arr[n] = 'a';
  1770          arr.splice(n + 1, 0, 'b');
  1771          return arr[n] === 'a';
  1772      }());
  1773      defineProperties(ArrayPrototype, {
  1774          splice: function splice(start, deleteCount) {
  1775              var O = ES.ToObject(this);
  1776              var A = [];
  1777              var len = ES.ToUint32(O.length);
  1778              var relativeStart = ES.ToInteger(start);
  1779              var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
  1780              var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
  1781  
  1782              var k = 0;
  1783              var from;
  1784              while (k < actualDeleteCount) {
  1785                  from = $String(actualStart + k);
  1786                  if (owns(O, from)) {
  1787                      A[k] = O[from];
  1788                  }
  1789                  k += 1;
  1790              }
  1791  
  1792              var items = arraySlice(arguments, 2);
  1793              var itemCount = items.length;
  1794              var to;
  1795              if (itemCount < actualDeleteCount) {
  1796                  k = actualStart;
  1797                  var maxK = len - actualDeleteCount;
  1798                  while (k < maxK) {
  1799                      from = $String(k + actualDeleteCount);
  1800                      to = $String(k + itemCount);
  1801                      if (owns(O, from)) {
  1802                          O[to] = O[from];
  1803                      } else {
  1804                          delete O[to];
  1805                      }
  1806                      k += 1;
  1807                  }
  1808                  k = len;
  1809                  var minK = len - actualDeleteCount + itemCount;
  1810                  while (k > minK) {
  1811                      delete O[k - 1];
  1812                      k -= 1;
  1813                  }
  1814              } else if (itemCount > actualDeleteCount) {
  1815                  k = len - actualDeleteCount;
  1816                  while (k > actualStart) {
  1817                      from = $String(k + actualDeleteCount - 1);
  1818                      to = $String(k + itemCount - 1);
  1819                      if (owns(O, from)) {
  1820                          O[to] = O[from];
  1821                      } else {
  1822                          delete O[to];
  1823                      }
  1824                      k -= 1;
  1825                  }
  1826              }
  1827              k = actualStart;
  1828              for (var i = 0; i < items.length; ++i) {
  1829                  O[k] = items[i];
  1830                  k += 1;
  1831              }
  1832              O.length = len - actualDeleteCount + itemCount;
  1833  
  1834              return A;
  1835          }
  1836      }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
  1837  
  1838      var originalJoin = ArrayPrototype.join;
  1839      var hasStringJoinBug;
  1840      try {
  1841          hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
  1842      } catch (e) {
  1843          hasStringJoinBug = true;
  1844      }
  1845      if (hasStringJoinBug) {
  1846          defineProperties(ArrayPrototype, {
  1847              join: function join(separator) {
  1848                  var sep = typeof separator === 'undefined' ? ',' : separator;
  1849                  return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
  1850              }
  1851          }, hasStringJoinBug);
  1852      }
  1853  
  1854      var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
  1855      if (hasJoinUndefinedBug) {
  1856          defineProperties(ArrayPrototype, {
  1857              join: function join(separator) {
  1858                  var sep = typeof separator === 'undefined' ? ',' : separator;
  1859                  return originalJoin.call(this, sep);
  1860              }
  1861          }, hasJoinUndefinedBug);
  1862      }
  1863  
  1864      var pushShim = function push(item) {
  1865          var O = ES.ToObject(this);
  1866          var n = ES.ToUint32(O.length);
  1867          var i = 0;
  1868          while (i < arguments.length) {
  1869              O[n + i] = arguments[i];
  1870              i += 1;
  1871          }
  1872          O.length = n + i;
  1873          return n + i;
  1874      };
  1875  
  1876      var pushIsNotGeneric = (function () {
  1877          var obj = {};
  1878          var result = Array.prototype.push.call(obj, undefined);
  1879          return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
  1880      }());
  1881      defineProperties(ArrayPrototype, {
  1882          push: function push(item) {
  1883              if (isArray(this)) {
  1884                  return array_push.apply(this, arguments);
  1885              }
  1886              return pushShim.apply(this, arguments);
  1887          }
  1888      }, pushIsNotGeneric);
  1889  
  1890      // This fixes a very weird bug in Opera 10.6 when pushing `undefined
  1891      var pushUndefinedIsWeird = (function () {
  1892          var arr = [];
  1893          var result = arr.push(undefined);
  1894          return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
  1895      }());
  1896      defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
  1897  
  1898      // ES5 15.2.3.14
  1899      // http://es5.github.io/#x15.4.4.10
  1900      // Fix boxed string bug
  1901      defineProperties(ArrayPrototype, {
  1902          slice: function (start, end) {
  1903              var arr = isString(this) ? strSplit(this, '') : this;
  1904              return arraySliceApply(arr, arguments);
  1905          }
  1906      }, splitString);
  1907  
  1908      var sortIgnoresNonFunctions = (function () {
  1909          try {
  1910              [1, 2].sort(null);
  1911              [1, 2].sort({});
  1912              return true;
  1913          } catch (e) {}
  1914          return false;
  1915      }());
  1916      var sortThrowsOnRegex = (function () {
  1917          // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
  1918          try {
  1919              [1, 2].sort(/a/);
  1920              return false;
  1921          } catch (e) {}
  1922          return true;
  1923      }());
  1924      var sortIgnoresUndefined = (function () {
  1925          // applies in IE 8, for one.
  1926          try {
  1927              [1, 2].sort(undefined);
  1928              return true;
  1929          } catch (e) {}
  1930          return false;
  1931      }());
  1932      defineProperties(ArrayPrototype, {
  1933          sort: function sort(compareFn) {
  1934              if (typeof compareFn === 'undefined') {
  1935                  return arraySort(this);
  1936              }
  1937              if (!isCallable(compareFn)) {
  1938                  throw new TypeError('Array.prototype.sort callback must be a function');
  1939              }
  1940              return arraySort(this, compareFn);
  1941          }
  1942      }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
  1943  
  1944      //
  1945      // Object
  1946      // ======
  1947      //
  1948  
  1949      // ES5 15.2.3.14
  1950      // http://es5.github.com/#x15.2.3.14
  1951  
  1952      // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  1953      var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString');
  1954      var hasProtoEnumBug = isEnum(function () {}, 'prototype');
  1955      var hasStringEnumBug = !owns('x', '0');
  1956      var equalsConstructorPrototype = function (o) {
  1957          var ctor = o.constructor;
  1958          return ctor && ctor.prototype === o;
  1959      };
  1960      var blacklistedKeys = {
  1961          $window: true,
  1962          $console: true,
  1963          $parent: true,
  1964          $self: true,
  1965          $frame: true,
  1966          $frames: true,
  1967          $frameElement: true,
  1968          $webkitIndexedDB: true,
  1969          $webkitStorageInfo: true,
  1970          $external: true
  1971      };
  1972      var hasAutomationEqualityBug = (function () {
  1973          /* globals window */
  1974          if (typeof window === 'undefined') {
  1975              return false;
  1976          }
  1977          for (var k in window) {
  1978              try {
  1979                  if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
  1980                      equalsConstructorPrototype(window[k]);
  1981                  }
  1982              } catch (e) {
  1983                  return true;
  1984              }
  1985          }
  1986          return false;
  1987      }());
  1988      var equalsConstructorPrototypeIfNotBuggy = function (object) {
  1989          if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
  1990              return equalsConstructorPrototype(object);
  1991          }
  1992          try {
  1993              return equalsConstructorPrototype(object);
  1994          } catch (e) {
  1995              return false;
  1996          }
  1997      };
  1998      var dontEnums = [
  1999          'toString',
  2000          'toLocaleString',
  2001          'valueOf',
  2002          'hasOwnProperty',
  2003          'isPrototypeOf',
  2004          'propertyIsEnumerable',
  2005          'constructor'
  2006      ];
  2007      var dontEnumsLength = dontEnums.length;
  2008  
  2009      // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
  2010      // can be replaced with require('is-arguments') if we ever use a build process instead
  2011      var isStandardArguments = function isArguments(value) {
  2012          return toStr(value) === '[object Arguments]';
  2013      };
  2014      var isLegacyArguments = function isArguments(value) {
  2015          return value !== null &&
  2016              typeof value === 'object' &&
  2017              typeof value.length === 'number' &&
  2018              value.length >= 0 &&
  2019              !isArray(value) &&
  2020              isCallable(value.callee);
  2021      };
  2022      var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
  2023  
  2024      defineProperties($Object, {
  2025          keys: function keys(object) {
  2026              var isFn = isCallable(object);
  2027              var isArgs = isArguments(object);
  2028              var isObject = object !== null && typeof object === 'object';
  2029              var isStr = isObject && isString(object);
  2030  
  2031              if (!isObject && !isFn && !isArgs) {
  2032                  throw new TypeError('Object.keys called on a non-object');
  2033              }
  2034  
  2035              var theKeys = [];
  2036              var skipProto = hasProtoEnumBug && isFn;
  2037              if ((isStr && hasStringEnumBug) || isArgs) {
  2038                  for (var i = 0; i < object.length; ++i) {
  2039                      pushCall(theKeys, $String(i));
  2040                  }
  2041              }
  2042  
  2043              if (!isArgs) {
  2044                  for (var name in object) {
  2045                      if (!(skipProto && name === 'prototype') && owns(object, name)) {
  2046                          pushCall(theKeys, $String(name));
  2047                      }
  2048                  }
  2049              }
  2050  
  2051              if (hasDontEnumBug) {
  2052                  var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
  2053                  for (var j = 0; j < dontEnumsLength; j++) {
  2054                      var dontEnum = dontEnums[j];
  2055                      if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
  2056                          pushCall(theKeys, dontEnum);
  2057                      }
  2058                  }
  2059              }
  2060              return theKeys;
  2061          }
  2062      });
  2063  
  2064      var keysWorksWithArguments = $Object.keys && (function () {
  2065          // Safari 5.0 bug
  2066          return $Object.keys(arguments).length === 2;
  2067      }(1, 2));
  2068      var keysHasArgumentsLengthBug = $Object.keys && (function () {
  2069          var argKeys = $Object.keys(arguments);
  2070          return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
  2071      }(1));
  2072      var originalKeys = $Object.keys;
  2073      defineProperties($Object, {
  2074          keys: function keys(object) {
  2075              if (isArguments(object)) {
  2076                  return originalKeys(arraySlice(object));
  2077              } else {
  2078                  return originalKeys(object);
  2079              }
  2080          }
  2081      }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
  2082  
  2083      //
  2084      // Date
  2085      // ====
  2086      //
  2087  
  2088      var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
  2089      var aNegativeTestDate = new Date(-1509842289600292);
  2090      var aPositiveTestDate = new Date(1449662400000);
  2091      var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
  2092      var hasToDateStringFormatBug;
  2093      var hasToStringFormatBug;
  2094      var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
  2095      if (timeZoneOffset < -720) {
  2096          hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
  2097          hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
  2098      } else {
  2099          hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
  2100          hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
  2101      }
  2102  
  2103      var originalGetFullYear = call.bind(Date.prototype.getFullYear);
  2104      var originalGetMonth = call.bind(Date.prototype.getMonth);
  2105      var originalGetDate = call.bind(Date.prototype.getDate);
  2106      var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
  2107      var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
  2108      var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
  2109      var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
  2110      var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
  2111      var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
  2112      var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
  2113      var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
  2114      var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  2115      var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  2116      var daysInMonth = function daysInMonth(month, year) {
  2117          return originalGetDate(new Date(year, month, 0));
  2118      };
  2119  
  2120      defineProperties(Date.prototype, {
  2121          getFullYear: function getFullYear() {
  2122              if (!this || !(this instanceof Date)) {
  2123                  throw new TypeError('this is not a Date object.');
  2124              }
  2125              var year = originalGetFullYear(this);
  2126              if (year < 0 && originalGetMonth(this) > 11) {
  2127                  return year + 1;
  2128              }
  2129              return year;
  2130          },
  2131          getMonth: function getMonth() {
  2132              if (!this || !(this instanceof Date)) {
  2133                  throw new TypeError('this is not a Date object.');
  2134              }
  2135              var year = originalGetFullYear(this);
  2136              var month = originalGetMonth(this);
  2137              if (year < 0 && month > 11) {
  2138                  return 0;
  2139              }
  2140              return month;
  2141          },
  2142          getDate: function getDate() {
  2143              if (!this || !(this instanceof Date)) {
  2144                  throw new TypeError('this is not a Date object.');
  2145              }
  2146              var year = originalGetFullYear(this);
  2147              var month = originalGetMonth(this);
  2148              var date = originalGetDate(this);
  2149              if (year < 0 && month > 11) {
  2150                  if (month === 12) {
  2151                      return date;
  2152                  }
  2153                  var days = daysInMonth(0, year + 1);
  2154                  return (days - date) + 1;
  2155              }
  2156              return date;
  2157          },
  2158          getUTCFullYear: function getUTCFullYear() {
  2159              if (!this || !(this instanceof Date)) {
  2160                  throw new TypeError('this is not a Date object.');
  2161              }
  2162              var year = originalGetUTCFullYear(this);
  2163              if (year < 0 && originalGetUTCMonth(this) > 11) {
  2164                  return year + 1;
  2165              }
  2166              return year;
  2167          },
  2168          getUTCMonth: function getUTCMonth() {
  2169              if (!this || !(this instanceof Date)) {
  2170                  throw new TypeError('this is not a Date object.');
  2171              }
  2172              var year = originalGetUTCFullYear(this);
  2173              var month = originalGetUTCMonth(this);
  2174              if (year < 0 && month > 11) {
  2175                  return 0;
  2176              }
  2177              return month;
  2178          },
  2179          getUTCDate: function getUTCDate() {
  2180              if (!this || !(this instanceof Date)) {
  2181                  throw new TypeError('this is not a Date object.');
  2182              }
  2183              var year = originalGetUTCFullYear(this);
  2184              var month = originalGetUTCMonth(this);
  2185              var date = originalGetUTCDate(this);
  2186              if (year < 0 && month > 11) {
  2187                  if (month === 12) {
  2188                      return date;
  2189                  }
  2190                  var days = daysInMonth(0, year + 1);
  2191                  return (days - date) + 1;
  2192              }
  2193              return date;
  2194          }
  2195      }, hasNegativeMonthYearBug);
  2196  
  2197      defineProperties(Date.prototype, {
  2198          toUTCString: function toUTCString() {
  2199              if (!this || !(this instanceof Date)) {
  2200                  throw new TypeError('this is not a Date object.');
  2201              }
  2202              var day = originalGetUTCDay(this);
  2203              var date = originalGetUTCDate(this);
  2204              var month = originalGetUTCMonth(this);
  2205              var year = originalGetUTCFullYear(this);
  2206              var hour = originalGetUTCHours(this);
  2207              var minute = originalGetUTCMinutes(this);
  2208              var second = originalGetUTCSeconds(this);
  2209              return dayName[day] + ', ' +
  2210                  (date < 10 ? '0' + date : date) + ' ' +
  2211                  monthName[month] + ' ' +
  2212                  year + ' ' +
  2213                  (hour < 10 ? '0' + hour : hour) + ':' +
  2214                  (minute < 10 ? '0' + minute : minute) + ':' +
  2215                  (second < 10 ? '0' + second : second) + ' GMT';
  2216          }
  2217      }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
  2218  
  2219      // Opera 12 has `,`
  2220      defineProperties(Date.prototype, {
  2221          toDateString: function toDateString() {
  2222              if (!this || !(this instanceof Date)) {
  2223                  throw new TypeError('this is not a Date object.');
  2224              }
  2225              var day = this.getDay();
  2226              var date = this.getDate();
  2227              var month = this.getMonth();
  2228              var year = this.getFullYear();
  2229              return dayName[day] + ' ' +
  2230                  monthName[month] + ' ' +
  2231                  (date < 10 ? '0' + date : date) + ' ' +
  2232                  year;
  2233          }
  2234      }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
  2235  
  2236      // can't use defineProperties here because of toString enumeration issue in IE <= 8
  2237      if (hasNegativeMonthYearBug || hasToStringFormatBug) {
  2238          Date.prototype.toString = function toString() {
  2239              if (!this || !(this instanceof Date)) {
  2240                  throw new TypeError('this is not a Date object.');
  2241              }
  2242              var day = this.getDay();
  2243              var date = this.getDate();
  2244              var month = this.getMonth();
  2245              var year = this.getFullYear();
  2246              var hour = this.getHours();
  2247              var minute = this.getMinutes();
  2248              var second = this.getSeconds();
  2249              var timezoneOffset = this.getTimezoneOffset();
  2250              var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
  2251              var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
  2252              return dayName[day] + ' ' +
  2253                  monthName[month] + ' ' +
  2254                  (date < 10 ? '0' + date : date) + ' ' +
  2255                  year + ' ' +
  2256                  (hour < 10 ? '0' + hour : hour) + ':' +
  2257                  (minute < 10 ? '0' + minute : minute) + ':' +
  2258                  (second < 10 ? '0' + second : second) + ' GMT' +
  2259                  (timezoneOffset > 0 ? '-' : '+') +
  2260                  (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
  2261                  (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
  2262          };
  2263          if (supportsDescriptors) {
  2264              $Object.defineProperty(Date.prototype, 'toString', {
  2265                  configurable: true,
  2266                  enumerable: false,
  2267                  writable: true
  2268              });
  2269          }
  2270      }
  2271  
  2272      // ES5 15.9.5.43
  2273      // http://es5.github.com/#x15.9.5.43
  2274      // This function returns a String value represent the instance in time
  2275      // represented by this Date object. The format of the String is the Date Time
  2276      // string format defined in 15.9.1.15. All fields are present in the String.
  2277      // The time zone is always UTC, denoted by the suffix Z. If the time value of
  2278      // this object is not a finite Number a RangeError exception is thrown.
  2279      var negativeDate = -62198755200000;
  2280      var negativeYearString = '-000001';
  2281      var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
  2282      var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
  2283  
  2284      var getTime = call.bind(Date.prototype.getTime);
  2285  
  2286      defineProperties(Date.prototype, {
  2287          toISOString: function toISOString() {
  2288              if (!isFinite(this) || !isFinite(getTime(this))) {
  2289                  // Adope Photoshop requires the second check.
  2290                  throw new RangeError('Date.prototype.toISOString called on non-finite value.');
  2291              }
  2292  
  2293              var year = originalGetUTCFullYear(this);
  2294  
  2295              var month = originalGetUTCMonth(this);
  2296              // see https://github.com/es-shims/es5-shim/issues/111
  2297              year += Math.floor(month / 12);
  2298              month = (month % 12 + 12) % 12;
  2299  
  2300              // the date time string format is specified in 15.9.1.15.
  2301              var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
  2302              year = (
  2303                  (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
  2304                  strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
  2305              );
  2306  
  2307              for (var i = 0; i < result.length; ++i) {
  2308                  // pad months, days, hours, minutes, and seconds to have two digits.
  2309                  result[i] = strSlice('00' + result[i], -2);
  2310              }
  2311              // pad milliseconds to have three digits.
  2312              return (
  2313                  year + '-' + arraySlice(result, 0, 2).join('-') +
  2314                  'T' + arraySlice(result, 2).join(':') + '.' +
  2315                  strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
  2316              );
  2317          }
  2318      }, hasNegativeDateBug || hasSafari51DateBug);
  2319  
  2320      // ES5 15.9.5.44
  2321      // http://es5.github.com/#x15.9.5.44
  2322      // This function provides a String representation of a Date object for use by
  2323      // JSON.stringify (15.12.3).
  2324      var dateToJSONIsSupported = (function () {
  2325          try {
  2326              return Date.prototype.toJSON &&
  2327                  new Date(NaN).toJSON() === null &&
  2328                  new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
  2329                  Date.prototype.toJSON.call({ // generic
  2330                      toISOString: function () { return true; }
  2331                  });
  2332          } catch (e) {
  2333              return false;
  2334          }
  2335      }());
  2336      if (!dateToJSONIsSupported) {
  2337          Date.prototype.toJSON = function toJSON(key) {
  2338              // When the toJSON method is called with argument key, the following
  2339              // steps are taken:
  2340  
  2341              // 1.  Let O be the result of calling ToObject, giving it the this
  2342              // value as its argument.
  2343              // 2. Let tv be ES.ToPrimitive(O, hint Number).
  2344              var O = $Object(this);
  2345              var tv = ES.ToPrimitive(O);
  2346              // 3. If tv is a Number and is not finite, return null.
  2347              if (typeof tv === 'number' && !isFinite(tv)) {
  2348                  return null;
  2349              }
  2350              // 4. Let toISO be the result of calling the [[Get]] internal method of
  2351              // O with argument "toISOString".
  2352              var toISO = O.toISOString;
  2353              // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  2354              if (!isCallable(toISO)) {
  2355                  throw new TypeError('toISOString property is not callable');
  2356              }
  2357              // 6. Return the result of calling the [[Call]] internal method of
  2358              //  toISO with O as the this value and an empty argument list.
  2359              return toISO.call(O);
  2360  
  2361              // NOTE 1 The argument is ignored.
  2362  
  2363              // NOTE 2 The toJSON function is intentionally generic; it does not
  2364              // require that its this value be a Date object. Therefore, it can be
  2365              // transferred to other kinds of objects for use as a method. However,
  2366              // it does require that any such object have a toISOString method. An
  2367              // object is free to use the argument key to filter its
  2368              // stringification.
  2369          };
  2370      }
  2371  
  2372      // ES5 15.9.4.2
  2373      // http://es5.github.com/#x15.9.4.2
  2374      // based on work shared by Daniel Friesen (dantman)
  2375      // http://gist.github.com/303249
  2376      var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
  2377      var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
  2378      var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
  2379      if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
  2380          // XXX global assignment won't work in embeddings that use
  2381          // an alternate object for the context.
  2382          /* global Date: true */
  2383          /* eslint-disable no-undef */
  2384          var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
  2385          var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
  2386          /* eslint-disable no-implicit-globals */
  2387          Date = (function (NativeDate) {
  2388          /* eslint-enable no-implicit-globals */
  2389          /* eslint-enable no-undef */
  2390              // Date.length === 7
  2391              var DateShim = function Date(Y, M, D, h, m, s, ms) {
  2392                  var length = arguments.length;
  2393                  var date;
  2394                  if (this instanceof NativeDate) {
  2395                      var seconds = s;
  2396                      var millis = ms;
  2397                      if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
  2398                          // work around a Safari 8/9 bug where it treats the seconds as signed
  2399                          var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
  2400                          var sToShift = Math.floor(msToShift / 1e3);
  2401                          seconds += sToShift;
  2402                          millis -= sToShift * 1e3;
  2403                      }
  2404                      date = length === 1 && $String(Y) === Y ? // isString(Y)
  2405                          // We explicitly pass it through parse:
  2406                          new NativeDate(DateShim.parse(Y)) :
  2407                          // We have to manually make calls depending on argument
  2408                          // length here
  2409                          length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
  2410                          length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
  2411                          length >= 5 ? new NativeDate(Y, M, D, h, m) :
  2412                          length >= 4 ? new NativeDate(Y, M, D, h) :
  2413                          length >= 3 ? new NativeDate(Y, M, D) :
  2414                          length >= 2 ? new NativeDate(Y, M) :
  2415                          length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
  2416                                        new NativeDate();
  2417                  } else {
  2418                      date = NativeDate.apply(this, arguments);
  2419                  }
  2420                  if (!isPrimitive(date)) {
  2421                      // Prevent mixups with unfixed Date object
  2422                      defineProperties(date, { constructor: DateShim }, true);
  2423                  }
  2424                  return date;
  2425              };
  2426  
  2427              // 15.9.1.15 Date Time String Format.
  2428              var isoDateExpression = new RegExp('^' +
  2429                  '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
  2430                                            // 6-digit extended year
  2431                  '(?:-(\\d{2})' + // optional month capture
  2432                  '(?:-(\\d{2})' + // optional day capture
  2433                  '(?:' + // capture hours:minutes:seconds.milliseconds
  2434                      'T(\\d{2})' + // hours capture
  2435                      ':(\\d{2})' + // minutes capture
  2436                      '(?:' + // optional :seconds.milliseconds
  2437                          ':(\\d{2})' + // seconds capture
  2438                          '(?:(\\.\\d{1,}))?' + // milliseconds capture
  2439                      ')?' +
  2440                  '(' + // capture UTC offset component
  2441                      'Z|' + // UTC capture
  2442                      '(?:' + // offset specifier +/-hours:minutes
  2443                          '([-+])' + // sign capture
  2444                          '(\\d{2})' + // hours offset capture
  2445                          ':(\\d{2})' + // minutes offset capture
  2446                      ')' +
  2447                  ')?)?)?)?' +
  2448              '$');
  2449  
  2450              var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
  2451  
  2452              var dayFromMonth = function dayFromMonth(year, month) {
  2453                  var t = month > 1 ? 1 : 0;
  2454                  return (
  2455                      months[month] +
  2456                      Math.floor((year - 1969 + t) / 4) -
  2457                      Math.floor((year - 1901 + t) / 100) +
  2458                      Math.floor((year - 1601 + t) / 400) +
  2459                      365 * (year - 1970)
  2460                  );
  2461              };
  2462  
  2463              var toUTC = function toUTC(t) {
  2464                  var s = 0;
  2465                  var ms = t;
  2466                  if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
  2467                      // work around a Safari 8/9 bug where it treats the seconds as signed
  2468                      var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
  2469                      var sToShift = Math.floor(msToShift / 1e3);
  2470                      s += sToShift;
  2471                      ms -= sToShift * 1e3;
  2472                  }
  2473                  return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
  2474              };
  2475  
  2476              // Copy any custom methods a 3rd party library may have added
  2477              for (var key in NativeDate) {
  2478                  if (owns(NativeDate, key)) {
  2479                      DateShim[key] = NativeDate[key];
  2480                  }
  2481              }
  2482  
  2483              // Copy "native" methods explicitly; they may be non-enumerable
  2484              defineProperties(DateShim, {
  2485                  now: NativeDate.now,
  2486                  UTC: NativeDate.UTC
  2487              }, true);
  2488              DateShim.prototype = NativeDate.prototype;
  2489              defineProperties(DateShim.prototype, {
  2490                  constructor: DateShim
  2491              }, true);
  2492  
  2493              // Upgrade Date.parse to handle simplified ISO 8601 strings
  2494              var parseShim = function parse(string) {
  2495                  var match = isoDateExpression.exec(string);
  2496                  if (match) {
  2497                      // parse months, days, hours, minutes, seconds, and milliseconds
  2498                      // provide default values if necessary
  2499                      // parse the UTC offset component
  2500                      var year = $Number(match[1]),
  2501                          month = $Number(match[2] || 1) - 1,
  2502                          day = $Number(match[3] || 1) - 1,
  2503                          hour = $Number(match[4] || 0),
  2504                          minute = $Number(match[5] || 0),
  2505                          second = $Number(match[6] || 0),
  2506                          millisecond = Math.floor($Number(match[7] || 0) * 1000),
  2507                          // When time zone is missed, local offset should be used
  2508                          // (ES 5.1 bug)
  2509                          // see https://bugs.ecmascript.org/show_bug.cgi?id=112
  2510                          isLocalTime = Boolean(match[4] && !match[8]),
  2511                          signOffset = match[9] === '-' ? 1 : -1,
  2512                          hourOffset = $Number(match[10] || 0),
  2513                          minuteOffset = $Number(match[11] || 0),
  2514                          result;
  2515                      var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
  2516                      if (
  2517                          hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
  2518                          minute < 60 && second < 60 && millisecond < 1000 &&
  2519                          month > -1 && month < 12 && hourOffset < 24 &&
  2520                          minuteOffset < 60 && // detect invalid offsets
  2521                          day > -1 &&
  2522                          day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
  2523                      ) {
  2524                          result = (
  2525                              (dayFromMonth(year, month) + day) * 24 +
  2526                              hour +
  2527                              hourOffset * signOffset
  2528                          ) * 60;
  2529                          result = (
  2530                              (result + minute + minuteOffset * signOffset) * 60 +
  2531                              second
  2532                          ) * 1000 + millisecond;
  2533                          if (isLocalTime) {
  2534                              result = toUTC(result);
  2535                          }
  2536                          if (-8.64e15 <= result && result <= 8.64e15) {
  2537                              return result;
  2538                          }
  2539                      }
  2540                      return NaN;
  2541                  }
  2542                  return NativeDate.parse.apply(this, arguments);
  2543              };
  2544              defineProperties(DateShim, { parse: parseShim });
  2545  
  2546              return DateShim;
  2547          }(Date));
  2548          /* global Date: false */
  2549      }
  2550  
  2551      // ES5 15.9.4.4
  2552      // http://es5.github.com/#x15.9.4.4
  2553      if (!Date.now) {
  2554          Date.now = function now() {
  2555              return new Date().getTime();
  2556          };
  2557      }
  2558  
  2559      //
  2560      // Number
  2561      // ======
  2562      //
  2563  
  2564      // ES5.1 15.7.4.5
  2565      // http://es5.github.com/#x15.7.4.5
  2566      var hasToFixedBugs = NumberPrototype.toFixed && (
  2567        (0.00008).toFixed(3) !== '0.000' ||
  2568        (0.9).toFixed(0) !== '1' ||
  2569        (1.255).toFixed(2) !== '1.25' ||
  2570        (1000000000000000128).toFixed(0) !== '1000000000000000128'
  2571      );
  2572  
  2573      var toFixedHelpers = {
  2574          base: 1e7,
  2575          size: 6,
  2576          data: [0, 0, 0, 0, 0, 0],
  2577          multiply: function multiply(n, c) {
  2578              var i = -1;
  2579              var c2 = c;
  2580              while (++i < toFixedHelpers.size) {
  2581                  c2 += n * toFixedHelpers.data[i];
  2582                  toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
  2583                  c2 = Math.floor(c2 / toFixedHelpers.base);
  2584              }
  2585          },
  2586          divide: function divide(n) {
  2587              var i = toFixedHelpers.size;
  2588              var c = 0;
  2589              while (--i >= 0) {
  2590                  c += toFixedHelpers.data[i];
  2591                  toFixedHelpers.data[i] = Math.floor(c / n);
  2592                  c = (c % n) * toFixedHelpers.base;
  2593              }
  2594          },
  2595          numToString: function numToString() {
  2596              var i = toFixedHelpers.size;
  2597              var s = '';
  2598              while (--i >= 0) {
  2599                  if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
  2600                      var t = $String(toFixedHelpers.data[i]);
  2601                      if (s === '') {
  2602                          s = t;
  2603                      } else {
  2604                          s += strSlice('0000000', 0, 7 - t.length) + t;
  2605                      }
  2606                  }
  2607              }
  2608              return s;
  2609          },
  2610          pow: function pow(x, n, acc) {
  2611              return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
  2612          },
  2613          log: function log(x) {
  2614              var n = 0;
  2615              var x2 = x;
  2616              while (x2 >= 4096) {
  2617                  n += 12;
  2618                  x2 /= 4096;
  2619              }
  2620              while (x2 >= 2) {
  2621                  n += 1;
  2622                  x2 /= 2;
  2623              }
  2624              return n;
  2625          }
  2626      };
  2627  
  2628      var toFixedShim = function toFixed(fractionDigits) {
  2629          var f, x, s, m, e, z, j, k;
  2630  
  2631          // Test for NaN and round fractionDigits down
  2632          f = $Number(fractionDigits);
  2633          f = isActualNaN(f) ? 0 : Math.floor(f);
  2634  
  2635          if (f < 0 || f > 20) {
  2636              throw new RangeError('Number.toFixed called with invalid number of decimals');
  2637          }
  2638  
  2639          x = $Number(this);
  2640  
  2641          if (isActualNaN(x)) {
  2642              return 'NaN';
  2643          }
  2644  
  2645          // If it is too big or small, return the string value of the number
  2646          if (x <= -1e21 || x >= 1e21) {
  2647              return $String(x);
  2648          }
  2649  
  2650          s = '';
  2651  
  2652          if (x < 0) {
  2653              s = '-';
  2654              x = -x;
  2655          }
  2656  
  2657          m = '0';
  2658  
  2659          if (x > 1e-21) {
  2660              // 1e-21 < x < 1e21
  2661              // -70 < log2(x) < 70
  2662              e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
  2663              z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
  2664              z *= 0x10000000000000; // Math.pow(2, 52);
  2665              e = 52 - e;
  2666  
  2667              // -18 < e < 122
  2668              // x = z / 2 ^ e
  2669              if (e > 0) {
  2670                  toFixedHelpers.multiply(0, z);
  2671                  j = f;
  2672  
  2673                  while (j >= 7) {
  2674                      toFixedHelpers.multiply(1e7, 0);
  2675                      j -= 7;
  2676                  }
  2677  
  2678                  toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
  2679                  j = e - 1;
  2680  
  2681                  while (j >= 23) {
  2682                      toFixedHelpers.divide(1 << 23);
  2683                      j -= 23;
  2684                  }
  2685  
  2686                  toFixedHelpers.divide(1 << j);
  2687                  toFixedHelpers.multiply(1, 1);
  2688                  toFixedHelpers.divide(2);
  2689                  m = toFixedHelpers.numToString();
  2690              } else {
  2691                  toFixedHelpers.multiply(0, z);
  2692                  toFixedHelpers.multiply(1 << (-e), 0);
  2693                  m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
  2694              }
  2695          }
  2696  
  2697          if (f > 0) {
  2698              k = m.length;
  2699  
  2700              if (k <= f) {
  2701                  m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
  2702              } else {
  2703                  m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
  2704              }
  2705          } else {
  2706              m = s + m;
  2707          }
  2708  
  2709          return m;
  2710      };
  2711      defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
  2712  
  2713      var hasToPrecisionUndefinedBug = (function () {
  2714          try {
  2715              return 1.0.toPrecision(undefined) === '1';
  2716          } catch (e) {
  2717              return true;
  2718          }
  2719      }());
  2720      var originalToPrecision = NumberPrototype.toPrecision;
  2721      defineProperties(NumberPrototype, {
  2722          toPrecision: function toPrecision(precision) {
  2723              return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
  2724          }
  2725      }, hasToPrecisionUndefinedBug);
  2726  
  2727      //
  2728      // String
  2729      // ======
  2730      //
  2731  
  2732      // ES5 15.5.4.14
  2733      // http://es5.github.com/#x15.5.4.14
  2734  
  2735      // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
  2736      // Many browsers do not split properly with regular expressions or they
  2737      // do not perform the split correctly under obscure conditions.
  2738      // See http://blog.stevenlevithan.com/archives/cross-browser-split
  2739      // I've tested in many browsers and this seems to cover the deviant ones:
  2740      //    'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
  2741      //    '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
  2742      //    'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
  2743      //       [undefined, "t", undefined, "e", ...]
  2744      //    ''.split(/.?/) should be [], not [""]
  2745      //    '.'.split(/()()/) should be ["."], not ["", "", "."]
  2746  
  2747      if (
  2748          'ab'.split(/(?:ab)*/).length !== 2 ||
  2749          '.'.split(/(.?)(.?)/).length !== 4 ||
  2750          'tesst'.split(/(s)*/)[1] === 't' ||
  2751          'test'.split(/(?:)/, -1).length !== 4 ||
  2752          ''.split(/.?/).length ||
  2753          '.'.split(/()()/).length > 1
  2754      ) {
  2755          (function () {
  2756              var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
  2757              var maxSafe32BitInt = Math.pow(2, 32) - 1;
  2758  
  2759              StringPrototype.split = function (separator, limit) {
  2760                  var string = String(this);
  2761                  if (typeof separator === 'undefined' && limit === 0) {
  2762                      return [];
  2763                  }
  2764  
  2765                  // If `separator` is not a regex, use native split
  2766                  if (!isRegex(separator)) {
  2767                      return strSplit(this, separator, limit);
  2768                  }
  2769  
  2770                  var output = [];
  2771                  var flags = (separator.ignoreCase ? 'i' : '') +
  2772                              (separator.multiline ? 'm' : '') +
  2773                              (separator.unicode ? 'u' : '') + // in ES6
  2774                              (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
  2775                      lastLastIndex = 0,
  2776                      // Make `global` and avoid `lastIndex` issues by working with a copy
  2777                      separator2, match, lastIndex, lastLength;
  2778                  var separatorCopy = new RegExp(separator.source, flags + 'g');
  2779                  if (!compliantExecNpcg) {
  2780                      // Doesn't need flags gy, but they don't hurt
  2781                      separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
  2782                  }
  2783                  /* Values for `limit`, per the spec:
  2784                   * If undefined: 4294967295 // maxSafe32BitInt
  2785                   * If 0, Infinity, or NaN: 0
  2786                   * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
  2787                   * If negative number: 4294967296 - Math.floor(Math.abs(limit))
  2788                   * If other: Type-convert, then use the above rules
  2789                   */
  2790                  var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
  2791                  match = separatorCopy.exec(string);
  2792                  while (match) {
  2793                      // `separatorCopy.lastIndex` is not reliable cross-browser
  2794                      lastIndex = match.index + match[0].length;
  2795                      if (lastIndex > lastLastIndex) {
  2796                          pushCall(output, strSlice(string, lastLastIndex, match.index));
  2797                          // Fix browsers whose `exec` methods don't consistently return `undefined` for
  2798                          // nonparticipating capturing groups
  2799                          if (!compliantExecNpcg && match.length > 1) {
  2800                              /* eslint-disable no-loop-func */
  2801                              match[0].replace(separator2, function () {
  2802                                  for (var i = 1; i < arguments.length - 2; i++) {
  2803                                      if (typeof arguments[i] === 'undefined') {
  2804                                          match[i] = void 0;
  2805                                      }
  2806                                  }
  2807                              });
  2808                              /* eslint-enable no-loop-func */
  2809                          }
  2810                          if (match.length > 1 && match.index < string.length) {
  2811                              array_push.apply(output, arraySlice(match, 1));
  2812                          }
  2813                          lastLength = match[0].length;
  2814                          lastLastIndex = lastIndex;
  2815                          if (output.length >= splitLimit) {
  2816                              break;
  2817                          }
  2818                      }
  2819                      if (separatorCopy.lastIndex === match.index) {
  2820                          separatorCopy.lastIndex++; // Avoid an infinite loop
  2821                      }
  2822                      match = separatorCopy.exec(string);
  2823                  }
  2824                  if (lastLastIndex === string.length) {
  2825                      if (lastLength || !separatorCopy.test('')) {
  2826                          pushCall(output, '');
  2827                      }
  2828                  } else {
  2829                      pushCall(output, strSlice(string, lastLastIndex));
  2830                  }
  2831                  return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
  2832              };
  2833          }());
  2834  
  2835      // [bugfix, chrome]
  2836      // If separator is undefined, then the result array contains just one String,
  2837      // which is the this value (converted to a String). If limit is not undefined,
  2838      // then the output array is truncated so that it contains no more than limit
  2839      // elements.
  2840      // "0".split(undefined, 0) -> []
  2841      } else if ('0'.split(void 0, 0).length) {
  2842          StringPrototype.split = function split(separator, limit) {
  2843              if (typeof separator === 'undefined' && limit === 0) {
  2844                  return [];
  2845              }
  2846              return strSplit(this, separator, limit);
  2847          };
  2848      }
  2849  
  2850      var str_replace = StringPrototype.replace;
  2851      var replaceReportsGroupsCorrectly = (function () {
  2852          var groups = [];
  2853          'x'.replace(/x(.)?/g, function (match, group) {
  2854              pushCall(groups, group);
  2855          });
  2856          return groups.length === 1 && typeof groups[0] === 'undefined';
  2857      }());
  2858  
  2859      if (!replaceReportsGroupsCorrectly) {
  2860          StringPrototype.replace = function replace(searchValue, replaceValue) {
  2861              var isFn = isCallable(replaceValue);
  2862              var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
  2863              if (!isFn || !hasCapturingGroups) {
  2864                  return str_replace.call(this, searchValue, replaceValue);
  2865              } else {
  2866                  var wrappedReplaceValue = function (match) {
  2867                      var length = arguments.length;
  2868                      var originalLastIndex = searchValue.lastIndex;
  2869                      searchValue.lastIndex = 0;
  2870                      var args = searchValue.exec(match) || [];
  2871                      searchValue.lastIndex = originalLastIndex;
  2872                      pushCall(args, arguments[length - 2], arguments[length - 1]);
  2873                      return replaceValue.apply(this, args);
  2874                  };
  2875                  return str_replace.call(this, searchValue, wrappedReplaceValue);
  2876              }
  2877          };
  2878      }
  2879  
  2880      // ECMA-262, 3rd B.2.3
  2881      // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
  2882      // non-normative section suggesting uniform semantics and it should be
  2883      // normalized across all browsers
  2884      // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
  2885      var string_substr = StringPrototype.substr;
  2886      var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
  2887      defineProperties(StringPrototype, {
  2888          substr: function substr(start, length) {
  2889              var normalizedStart = start;
  2890              if (start < 0) {
  2891                  normalizedStart = max(this.length + start, 0);
  2892              }
  2893              return string_substr.call(this, normalizedStart, length);
  2894          }
  2895      }, hasNegativeSubstrBug);
  2896  
  2897      // ES5 15.5.4.20
  2898      // whitespace from: http://es5.github.io/#x15.5.4.20
  2899      var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  2900          '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
  2901          '\u2029\uFEFF';
  2902      var zeroWidth = '\u200b';
  2903      var wsRegexChars = '[' + ws + ']';
  2904      var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
  2905      var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
  2906      var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
  2907      defineProperties(StringPrototype, {
  2908          // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  2909          // http://perfectionkills.com/whitespace-deviations/
  2910          trim: function trim() {
  2911              if (typeof this === 'undefined' || this === null) {
  2912                  throw new TypeError("can't convert " + this + ' to object');
  2913              }
  2914              return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
  2915          }
  2916      }, hasTrimWhitespaceBug);
  2917      var trim = call.bind(String.prototype.trim);
  2918  
  2919      var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
  2920      defineProperties(StringPrototype, {
  2921          lastIndexOf: function lastIndexOf(searchString) {
  2922              if (typeof this === 'undefined' || this === null) {
  2923                  throw new TypeError("can't convert " + this + ' to object');
  2924              }
  2925              var S = $String(this);
  2926              var searchStr = $String(searchString);
  2927              var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
  2928              var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
  2929              var start = min(max(pos, 0), S.length);
  2930              var searchLen = searchStr.length;
  2931              var k = start + searchLen;
  2932              while (k > 0) {
  2933                  k = max(0, k - searchLen);
  2934                  var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
  2935                  if (index !== -1) {
  2936                      return k + index;
  2937                  }
  2938              }
  2939              return -1;
  2940          }
  2941      }, hasLastIndexBug);
  2942  
  2943      var originalLastIndexOf = StringPrototype.lastIndexOf;
  2944      defineProperties(StringPrototype, {
  2945          lastIndexOf: function lastIndexOf(searchString) {
  2946              return originalLastIndexOf.apply(this, arguments);
  2947          }
  2948      }, StringPrototype.lastIndexOf.length !== 1);
  2949  
  2950      // ES-5 15.1.2.2
  2951      /* eslint-disable radix */
  2952      if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
  2953      /* eslint-enable radix */
  2954          /* global parseInt: true */
  2955          parseInt = (function (origParseInt) {
  2956              var hexRegex = /^[\-+]?0[xX]/;
  2957              return function parseInt(str, radix) {
  2958                  var string = trim(String(str));
  2959                  var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
  2960                  return origParseInt(string, defaultedRadix);
  2961              };
  2962          }(parseInt));
  2963      }
  2964  
  2965      // https://es5.github.io/#x15.1.2.3
  2966      if (1 / parseFloat('-0') !== -Infinity) {
  2967          /* global parseFloat: true */
  2968          parseFloat = (function (origParseFloat) {
  2969              return function parseFloat(string) {
  2970                  var inputString = trim(String(string));
  2971                  var result = origParseFloat(inputString);
  2972                  return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
  2973              };
  2974          }(parseFloat));
  2975      }
  2976  
  2977      if (String(new RangeError('test')) !== 'RangeError: test') {
  2978          var errorToStringShim = function toString() {
  2979              if (typeof this === 'undefined' || this === null) {
  2980                  throw new TypeError("can't convert " + this + ' to object');
  2981              }
  2982              var name = this.name;
  2983              if (typeof name === 'undefined') {
  2984                  name = 'Error';
  2985              } else if (typeof name !== 'string') {
  2986                  name = $String(name);
  2987              }
  2988              var msg = this.message;
  2989              if (typeof msg === 'undefined') {
  2990                  msg = '';
  2991              } else if (typeof msg !== 'string') {
  2992                  msg = $String(msg);
  2993              }
  2994              if (!name) {
  2995                  return msg;
  2996              }
  2997              if (!msg) {
  2998                  return name;
  2999              }
  3000              return name + ': ' + msg;
  3001          };
  3002          // can't use defineProperties here because of toString enumeration issue in IE <= 8
  3003          Error.prototype.toString = errorToStringShim;
  3004      }
  3005  
  3006      if (supportsDescriptors) {
  3007          var ensureNonEnumerable = function (obj, prop) {
  3008              if (isEnum(obj, prop)) {
  3009                  var desc = Object.getOwnPropertyDescriptor(obj, prop);
  3010                  if (desc.configurable) {
  3011                      desc.enumerable = false;
  3012                      Object.defineProperty(obj, prop, desc);
  3013                  }
  3014              }
  3015          };
  3016          ensureNonEnumerable(Error.prototype, 'message');
  3017          if (Error.prototype.message !== '') {
  3018              Error.prototype.message = '';
  3019          }
  3020          ensureNonEnumerable(Error.prototype, 'name');
  3021      }
  3022  
  3023      if (String(/a/mig) !== '/a/gim') {
  3024          var regexToString = function toString() {
  3025              var str = '/' + this.source + '/';
  3026              if (this.global) {
  3027                  str += 'g';
  3028              }
  3029              if (this.ignoreCase) {
  3030                  str += 'i';
  3031              }
  3032              if (this.multiline) {
  3033                  str += 'm';
  3034              }
  3035              return str;
  3036          };
  3037          // can't use defineProperties here because of toString enumeration issue in IE <= 8
  3038          RegExp.prototype.toString = regexToString;
  3039      }
  3040  }));
  3041  
  3042  'use strict';
  3043  /*jslint eqeq: true*/
  3044  
  3045  Handlebars.registerHelper('sanitize', function (text) {
  3046      var result;
  3047  
  3048      if (text === undefined) { return ''; }
  3049  
  3050      result = sanitizeHtml(text, {
  3051          allowedTags: [ 'div', 'span', 'b', 'i', 'em', 'strong', 'a', 'br', 'table', 'tbody', 'tr', 'th', 'td' ],
  3052          allowedAttributes: {
  3053              'div': [ 'class' ],
  3054              'span': [ 'class' ],
  3055              'table': [ 'class' ],
  3056              'td': [ 'class' ],
  3057              'th': [ 'colspan' ],
  3058              'a': [ 'href' ]
  3059          }
  3060      });
  3061  
  3062      return new Handlebars.SafeString(result);
  3063  });
  3064  
  3065  Handlebars.registerHelper('renderTextParam', function(param) {
  3066      var result, type = 'text', idAtt = '';
  3067      var paramType = param.type || param.schema && param.schema.type || '';
  3068      var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple;
  3069      var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default;
  3070      var name = Handlebars.Utils.escapeExpression(param.name);
  3071      var valueId = Handlebars.Utils.escapeExpression(param.valueId);
  3072      paramType = Handlebars.Utils.escapeExpression(paramType);
  3073  
  3074      var dataVendorExtensions = Object.keys(param).filter(function(property) {
  3075          // filter X-data- properties
  3076          return property.match(/^X-data-/i) !== null;
  3077      }).reduce(function(result, property) {
  3078          // remove X- from property name, so it results in html attributes like data-foo='bar'
  3079          return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\'';
  3080      }, '');
  3081  
  3082      if(param.format && param.format === 'password') {
  3083          type = 'password';
  3084      }
  3085  
  3086      if(valueId) {
  3087          idAtt = ' id=\'' + valueId + '\'';
  3088      }
  3089  
  3090      if (defaultValue) {
  3091        defaultValue = sanitizeHtml(defaultValue);
  3092      } else {
  3093        defaultValue = '';
  3094      }
  3095  
  3096      if(isArray) {
  3097          result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + name + '\'' + idAtt + dataVendorExtensions;
  3098          result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>';
  3099          result += defaultValue + '</textarea>';
  3100      } else {
  3101          var parameterClass = 'parameter';
  3102          if(param.required) {
  3103            parameterClass += ' required';
  3104          }
  3105          result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\'';
  3106          result += ' name=\'' + name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions;
  3107          result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>';
  3108      }
  3109      return new Handlebars.SafeString(result);
  3110  });
  3111  
  3112  Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
  3113  
  3114      switch (operator) {
  3115          case '==':
  3116              return (v1 == v2) ? options.fn(this) : options.inverse(this);
  3117          case '===':
  3118              return (v1 === v2) ? options.fn(this) : options.inverse(this);
  3119          case '<':
  3120              return (v1 < v2) ? options.fn(this) : options.inverse(this);
  3121          case '<=':
  3122              return (v1 <= v2) ? options.fn(this) : options.inverse(this);
  3123          case '>':
  3124              return (v1 > v2) ? options.fn(this) : options.inverse(this);
  3125          case '>=':
  3126              return (v1 >= v2) ? options.fn(this) : options.inverse(this);
  3127          case '&&':
  3128              return (v1 && v2) ? options.fn(this) : options.inverse(this);
  3129          case '||':
  3130              return (v1 || v2) ? options.fn(this) : options.inverse(this);
  3131          default:
  3132              return options.inverse(this);
  3133      }
  3134  });
  3135  
  3136  Handlebars.registerHelper('escape', function (value) {
  3137      var text = Handlebars.Utils.escapeExpression(value);
  3138  
  3139      return new Handlebars.SafeString(text);
  3140  });
  3141  
  3142  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var htmlparser=require("htmlparser2");var extend=require("xtend");var quoteRegexp=require("regexp-quote");function each(obj,cb){if(obj)Object.keys(obj).forEach(function(key){cb(obj[key],key)})}function has(obj,key){return{}.hasOwnProperty.call(obj,key)}module.exports=sanitizeHtml;function sanitizeHtml(html,options,_recursing){var result="";function Frame(tag,attribs){var that=this;this.tag=tag;this.attribs=attribs||{};this.tagPosition=result.length;this.text="";this.updateParentNodeText=function(){if(stack.length){var parentFrame=stack[stack.length-1];parentFrame.text+=that.text}}}if(!options){options=sanitizeHtml.defaults;options.parser=htmlParserDefaults}else{options=extend(sanitizeHtml.defaults,options);if(options.parser){options.parser=extend(htmlParserDefaults,options.parser)}else{options.parser=htmlParserDefaults}}var nonTextTagsArray=options.nonTextTags||["script","style","textarea"];var allowedAttributesMap;var allowedAttributesGlobMap;if(options.allowedAttributes){allowedAttributesMap={};allowedAttributesGlobMap={};each(options.allowedAttributes,function(attributes,tag){allowedAttributesMap[tag]=[];var globRegex=[];attributes.forEach(function(name){if(name.indexOf("*")>=0){globRegex.push(quoteRegexp(name).replace(/\\\*/g,".*"))}else{allowedAttributesMap[tag].push(name)}});allowedAttributesGlobMap[tag]=new RegExp("^("+globRegex.join("|")+")$")})}var allowedClassesMap={};each(options.allowedClasses,function(classes,tag){if(allowedAttributesMap){if(!has(allowedAttributesMap,tag)){allowedAttributesMap[tag]=[]}allowedAttributesMap[tag].push("class")}allowedClassesMap[tag]=classes});var transformTagsMap={};var transformTagsAll;each(options.transformTags,function(transform,tag){var transFun;if(typeof transform==="function"){transFun=transform}else if(typeof transform==="string"){transFun=sanitizeHtml.simpleTransform(transform)}if(tag==="*"){transformTagsAll=transFun}else{transformTagsMap[tag]=transFun}});var depth=0;var stack=[];var skipMap={};var transformMap={};var skipText=false;var skipTextDepth=0;var parser=new htmlparser.Parser({onopentag:function(name,attribs){if(skipText){skipTextDepth++;return}var frame=new Frame(name,attribs);stack.push(frame);var skip=false;var hasText=frame.text?true:false;var transformedTag;if(has(transformTagsMap,name)){transformedTag=transformTagsMap[name](name,attribs);frame.attribs=attribs=transformedTag.attribs;if(transformedTag.text!==undefined){frame.innerText=transformedTag.text}if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(transformTagsAll){transformedTag=transformTagsAll(name,attribs);frame.attribs=attribs=transformedTag.attribs;if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(options.allowedTags&&options.allowedTags.indexOf(name)===-1){skip=true;if(nonTextTagsArray.indexOf(name)!==-1){skipText=true;skipTextDepth=1}skipMap[depth]=true}depth++;if(skip){return}result+="<"+name;if(!allowedAttributesMap||has(allowedAttributesMap,name)||allowedAttributesMap["*"]){each(attribs,function(value,a){if(!allowedAttributesMap||has(allowedAttributesMap,name)&&allowedAttributesMap[name].indexOf(a)!==-1||allowedAttributesMap["*"]&&allowedAttributesMap["*"].indexOf(a)!==-1||has(allowedAttributesGlobMap,name)&&allowedAttributesGlobMap[name].test(a)||allowedAttributesGlobMap["*"]&&allowedAttributesGlobMap["*"].test(a)){if(a==="href"||a==="src"){if(naughtyHref(name,value)){delete frame.attribs[a];return}}if(a==="class"){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return}}result+=" "+a;if(value.length){result+='="'+escapeHtml(value)+'"'}}else{delete frame.attribs[a]}})}if(options.selfClosing.indexOf(name)!==-1){result+=" />"}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText}}},ontext:function(text){if(skipText){return}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;text=lastFrame.innerText!==undefined?lastFrame.innerText:text}if(tag==="script"||tag==="style"){result+=text}else{var escaped=escapeHtml(text);if(options.textFilter){result+=options.textFilter(escaped)}else{result+=escaped}}if(stack.length){var frame=stack[stack.length-1];frame.text+=text}},onclosetag:function(name){if(skipText){skipTextDepth--;if(!skipTextDepth){skipText=false}else{return}}var frame=stack.pop();if(!frame){return}skipText=false;depth--;if(skipMap[depth]){delete skipMap[depth];frame.updateParentNodeText();return}if(transformMap[depth]){name=transformMap[depth];delete transformMap[depth]}if(options.exclusiveFilter&&options.exclusiveFilter(frame)){result=result.substr(0,frame.tagPosition);return}frame.updateParentNodeText();if(options.selfClosing.indexOf(name)!==-1){return}result+="</"+name+">"}},options.parser);parser.write(html);parser.end();return result;function escapeHtml(s){if(typeof s!=="string"){s=s+""}return s.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function naughtyHref(name,href){href=href.replace(/[\x00-\x20]+/g,"");href=href.replace(/<\!\-\-.*?\-\-\>/g,"");var matches=href.match(/^([a-zA-Z]+)\:/);if(!matches){return false}var scheme=matches[1].toLowerCase();if(has(options.allowedSchemesByTag,name)){return options.allowedSchemesByTag[name].indexOf(scheme)===-1}return!options.allowedSchemes||options.allowedSchemes.indexOf(scheme)===-1}function filterClasses(classes,allowed){if(!allowed){return classes}classes=classes.split(/\s+/);return classes.filter(function(clss){return allowed.indexOf(clss)!==-1}).join(" ")}}var htmlParserDefaults={decodeEntities:true};sanitizeHtml.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}};sanitizeHtml.simpleTransform=function(newTagName,newAttribs,merge){merge=merge===undefined?true:merge;newAttribs=newAttribs||{};return function(tagName,attribs){var attrib;if(merge){for(attrib in newAttribs){attribs[attrib]=newAttribs[attrib]}}else{attribs=newAttribs}return{tagName:newTagName,attribs:attribs}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(require,module,exports){"use strict";exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;function init(){var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i}revLookup["-".charCodeAt(0)]=62;revLookup["_".charCodeAt(0)]=63}init();function toByteArray(b64){var i,j,l,tmp,placeHolders,arr;var len=b64.length;if(len%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}placeHolders=b64[len-2]==="="?2:b64[len-1]==="="?1:0;arr=new Arr(len*3/4-placeHolders);l=placeHolders>0?len-4:len;var L=0;for(i=0,j=0;i<l;i+=4,j+=3){tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];arr[L++]=tmp>>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i=start;i<end;i+=3){tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];output.push(tripletToBase64(tmp))}return output.join("")}function fromByteArray(uint8){var tmp;var len=uint8.length;var extraBytes=len%3;var output="";var parts=[];var maxChunkLength=16383;for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength))}if(extraBytes===1){tmp=uint8[len-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len-2]<<8)+uint8[len-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(global){"use strict";var buffer=require("buffer");var Buffer=buffer.Buffer;var SlowBuffer=buffer.SlowBuffer;var MAX_LEN=buffer.kMaxLength||2147483647;exports.alloc=function alloc(size,fill,encoding){if(typeof Buffer.alloc==="function"){return Buffer.alloc(size,fill,encoding)}if(typeof encoding==="number"){throw new TypeError("encoding must not be number")}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===undefined){enc=undefined;_fill=0}var buf=new Buffer(size);if(typeof _fill==="string"){var fillBuf=new Buffer(_fill,enc);var flen=fillBuf.length;var i=-1;while(++i<size){buf[i]=fillBuf[i%flen]}}else{buf.fill(_fill)}return buf};exports.allocUnsafe=function allocUnsafe(size){if(typeof Buffer.allocUnsafe==="function"){return Buffer.allocUnsafe(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}return new Buffer(size)};exports.from=function from(value,encodingOrOffset,length){if(typeof Buffer.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){return Buffer.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer(value.slice(offset,offset+len))}if(Buffer.isBuffer(value)){var out=new Buffer(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer(value.data)}}throw new TypeError("First argument must be a string, Buffer, "+"ArrayBuffer, Array, or array-like object.")};exports.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer.allocUnsafeSlow==="function"){return Buffer.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{buffer:5}],5:[function(require,module,exports){(function(global){"use strict";var base64=require("base64-js");var ieee754=require("ieee754");var isArray=require("isarray");exports.Buffer=Buffer;exports.SlowBuffer=SlowBuffer;exports.INSPECT_MAX_BYTES=50;Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?global.TYPED_ARRAY_SUPPORT:typedArraySupport();exports.kMaxLength=kMaxLength();function typedArraySupport(){try{var arr=new Uint8Array(1);arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}};return arr.foo()===42&&typeof arr.subarray==="function"&&arr.subarray(1,1).byteLength===0}catch(e){return false}}function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(that,length){if(kMaxLength()<length){throw new RangeError("Invalid typed array length")}if(Buffer.TYPED_ARRAY_SUPPORT){that=new Uint8Array(length);that.__proto__=Buffer.prototype}else{if(that===null){that=new Buffer(length)}that.length=length}return that}function Buffer(arg,encodingOrOffset,length){if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){return new Buffer(arg,encodingOrOffset,length)}if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(this,arg)}return from(this,arg,encodingOrOffset,length)}Buffer.poolSize=8192;Buffer._augment=function(arr){arr.__proto__=Buffer.prototype;return arr};function from(that,value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){return fromArrayBuffer(that,value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(that,value,encodingOrOffset)}return fromObject(that,value)}Buffer.from=function(value,encodingOrOffset,length){return from(null,value,encodingOrOffset,length)};if(Buffer.TYPED_ARRAY_SUPPORT){Buffer.prototype.__proto__=Uint8Array.prototype;Buffer.__proto__=Uint8Array;if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer[Symbol.species]===Buffer){Object.defineProperty(Buffer,Symbol.species,{value:null,configurable:true})}}function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(that,size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(that,size)}if(fill!==undefined){return typeof encoding==="string"?createBuffer(that,size).fill(fill,encoding):createBuffer(that,size).fill(fill)}return createBuffer(that,size)}Buffer.alloc=function(size,fill,encoding){return alloc(null,size,fill,encoding)};function allocUnsafe(that,size){assertSize(size);that=createBuffer(that,size<0?0:checked(size)|0);if(!Buffer.TYPED_ARRAY_SUPPORT){for(var i=0;i<size;++i){that[i]=0}}return that}Buffer.allocUnsafe=function(size){return allocUnsafe(null,size)};Buffer.allocUnsafeSlow=function(size){return allocUnsafe(null,size)};function fromString(that,string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;that=createBuffer(that,length);var actual=that.write(string,encoding);if(actual!==length){that=that.slice(0,actual)}return that}function fromArrayLike(that,array){var length=array.length<0?0:checked(array.length)|0;that=createBuffer(that,length);for(var i=0;i<length;i+=1){that[i]=array[i]&255}return that}function fromArrayBuffer(that,array,byteOffset,length){array.byteLength;if(byteOffset<0||array.byteLength<byteOffset){throw new RangeError("'offset' is out of bounds")}if(array.byteLength<byteOffset+(length||0)){throw new RangeError("'length' is out of bounds")}if(byteOffset===undefined&&length===undefined){array=new Uint8Array(array)}else if(length===undefined){array=new Uint8Array(array,byteOffset)}else{array=new Uint8Array(array,byteOffset,length)}if(Buffer.TYPED_ARRAY_SUPPORT){that=array;that.__proto__=Buffer.prototype}else{that=fromArrayLike(that,array)}return that}function fromObject(that,obj){if(Buffer.isBuffer(obj)){var len=checked(obj.length)|0;that=createBuffer(that,len);if(that.length===0){return that}obj.copy(that,0,0,len);return that}if(obj){if(typeof ArrayBuffer!=="undefined"&&obj.buffer instanceof ArrayBuffer||"length"in obj){if(typeof obj.length!=="number"||isnan(obj.length)){return createBuffer(that,0)}return fromArrayLike(that,obj)}if(obj.type==="Buffer"&&isArray(obj.data)){return fromArrayLike(that,obj.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function checked(length){if(length>=kMaxLength()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+kMaxLength().toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer.alloc(+length)}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i<len;++i){if(a[i]!==b[i]){x=a[i];y=b[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};Buffer.isEncoding=function isEncoding(encoding){switch(String(encoding).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return true;default:return false}};Buffer.concat=function concat(list,length){if(!isArray(list)){throw new TypeError('"list" argument must be an Array of Buffers')}if(list.length===0){return Buffer.alloc(0)}var i;if(length===undefined){length=0;for(i=0;i<list.length;++i){length+=list[i].length}}var buffer=Buffer.allocUnsafe(length);var pos=0;for(i=0;i<list.length;++i){var buf=list[i];if(!Buffer.isBuffer(buf)){throw new TypeError('"list" argument must be an Array of Buffers')}buf.copy(buffer,pos);pos+=buf.length}return buffer};function byteLength(string,encoding){if(Buffer.isBuffer(string)){return string.length}if(typeof ArrayBuffer!=="undefined"&&typeof ArrayBuffer.isView==="function"&&(ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){return string.byteLength}if(typeof string!=="string"){string=""+string}var len=string.length;if(len===0)return 0;var loweredCase=false;for(;;){switch(encoding){case"ascii":case"latin1":case"binary":return len;case"utf8":case"utf-8":case undefined:return utf8ToBytes(string).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return len*2;case"hex":return len>>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===undefined||start<0){start=0}if(start>this.length){return""}if(end===undefined||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i<len;i+=2){swap(this,i,i+1)}return this};Buffer.prototype.swap32=function swap32(){var len=this.length;if(len%4!==0){throw new RangeError("Buffer size must be a multiple of 32-bits")}for(var i=0;i<len;i+=4){swap(this,i,i+3);swap(this,i+1,i+2)}return this};Buffer.prototype.swap64=function swap64(){var len=this.length;if(len%8!==0){throw new RangeError("Buffer size must be a multiple of 64-bits")}for(var i=0;i<len;i+=8){swap(this,i,i+7);swap(this,i+1,i+6);swap(this,i+2,i+5);swap(this,i+3,i+4)}return this};Buffer.prototype.toString=function toString(){var length=this.length|0;if(length===0)return"";if(arguments.length===0)return utf8Slice(this,0,length);return slowToString.apply(this,arguments)};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return"<Buffer "+str+">"};Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===undefined){start=0}if(end===undefined){end=target?target.length:0}if(thisStart===undefined){thisStart=0}if(thisEnd===undefined){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i<len;++i){if(thisCopy[i]!==targetCopy[i]){x=thisCopy[i];y=targetCopy[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){if(buffer.length===0)return-1;if(typeof byteOffset==="string"){encoding=byteOffset;byteOffset=0}else if(byteOffset>2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(isNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer.from(val,encoding)}if(Buffer.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==undefined){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i){if(indexSize===1){return buf[i]}else{return buf.readUInt16BE(i*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;i<arrLength;i++){if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){if(foundIndex===-1)foundIndex=i;if(i-foundIndex+1===valLength)return foundIndex*indexSize}else{if(foundIndex!==-1)i-=i-foundIndex;foundIndex=-1}}}else{if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;j<valLength;j++){if(read(arr,i+j)!==read(val,j)){found=false;break}}if(found)return i}}return-1}Buffer.prototype.includes=function includes(val,byteOffset,encoding){return this.indexOf(val,byteOffset,encoding)!==-1};Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,true)};Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,false)};function hexWrite(buf,string,offset,length){offset=Number(offset)||0;var remaining=buf.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i<length;++i){var parsed=parseInt(string.substr(i*2,2),16);if(isNaN(parsed))return i;buf[offset+i]=parsed}return i}function utf8Write(buf,string,offset,length){return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length)}function asciiWrite(buf,string,offset,length){return blitBuffer(asciiToBytes(string),buf,offset,length)}function latin1Write(buf,string,offset,length){return asciiWrite(buf,string,offset,length)}function base64Write(buf,string,offset,length){return blitBuffer(base64ToBytes(string),buf,offset,length)}function ucs2Write(buf,string,offset,length){return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length)}Buffer.prototype.write=function write(string,offset,length,encoding){if(offset===undefined){encoding="utf8";length=this.length;offset=0}else if(length===undefined&&typeof offset==="string"){encoding=offset;length=this.length;offset=0}else if(isFinite(offset)){offset=offset|0;if(isFinite(length)){length=length|0;if(encoding===undefined)encoding="utf8"}else{encoding=length;length=undefined}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===undefined||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i<end){var firstByte=buf[i];var codePoint=null;var bytesPerSequence=firstByte>239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(i<len){res+=String.fromCharCode.apply(String,codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH))}return res}function asciiSlice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i]&127)}return ret}function latin1Slice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i])}return ret}function hexSlice(buf,start,end){var len=buf.length;if(!start||start<0)start=0;if(!end||end<0||end>len)end=len;var out="";for(var i=start;i<end;++i){out+=toHex(buf[i])}return out}function utf16leSlice(buf,start,end){var bytes=buf.slice(start,end);var res="";for(var i=0;i<bytes.length;i+=2){res+=String.fromCharCode(bytes[i]+bytes[i+1]*256)}return res}Buffer.prototype.slice=function slice(start,end){var len=this.length;start=~~start;end=end===undefined?len:~~end;if(start<0){start+=len;if(start<0)start=0}else if(start>len){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(end<start)end=start;var newBuf;if(Buffer.TYPED_ARRAY_SUPPORT){newBuf=this.subarray(start,end);newBuf.__proto__=Buffer.prototype}else{var sliceLen=end-start;newBuf=new Buffer(sliceLen,undefined);for(var i=0;i<sliceLen;++i){newBuf[i]=this[i+start]}}return newBuf};function checkOffset(offset,ext,length){if(offset%1!==0||offset<0)throw new RangeError("offset is not uint");if(offset+ext>length)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}return val};Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);
  3143  var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');if(offset+ext>buf.length)throw new RangeError("Index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value&255;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){buf[offset+i]=(value&255<<8*(littleEndian?i:1-i))>>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){buf[offset+i]=value>>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){if(value<0&&sub===0&&this[offset+i-1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=byteLength-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end<start)end=start;if(end===start)return 0;if(target.length===0||this.length===0)return 0;if(targetStart<0){throw new RangeError("targetStart out of bounds")}if(start<0||start>=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart<end-start){end=target.length-targetStart+start}var len=end-start;var i;if(this===target&&start<targetStart&&targetStart<end){for(i=len-1;i>=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3||!Buffer.TYPED_ARRAY_SUPPORT){for(i=0;i<len;++i){target[i+targetStart]=this[i+start]}}else{Uint8Array.prototype.set.call(target,this.subarray(start,start+len),targetStart)}return len};Buffer.prototype.fill=function fill(val,start,end,encoding){if(typeof val==="string"){if(typeof start==="string"){encoding=start;start=0;end=this.length}else if(typeof end==="string"){encoding=end;end=this.length}if(val.length===1){var code=val.charCodeAt(0);if(code<256){val=code}}if(encoding!==undefined&&typeof encoding!=="string"){throw new TypeError("encoding must be a string")}if(typeof encoding==="string"&&!Buffer.isEncoding(encoding)){throw new TypeError("Unknown encoding: "+encoding)}}else if(typeof val==="number"){val=val&255}if(start<0||this.length<start||this.length<end){throw new RangeError("Out of range index")}if(end<=start){return this}start=start>>>0;end=end===undefined?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i<end;++i){this[i]=val}}else{var bytes=Buffer.isBuffer(val)?val:utf8ToBytes(new Buffer(val,encoding).toString());var len=bytes.length;for(i=0;i<end-start;++i){this[i+start]=bytes[i%len]}}return this};var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;function base64clean(str){str=stringtrim(str).replace(INVALID_BASE64_RE,"");if(str.length<2)return"";while(str.length%4!==0){str=str+"="}return str}function stringtrim(str){if(str.trim)return str.trim();return str.replace(/^\s+|\s+$/g,"")}function toHex(n){if(n<16)return"0"+n.toString(16);return n.toString(16)}function utf8ToBytes(string,units){units=units||Infinity;var codePoint;var length=string.length;var leadSurrogate=null;var bytes=[];for(var i=0;i<length;++i){codePoint=string.charCodeAt(i);if(codePoint>55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i<str.length;++i){byteArray.push(str.charCodeAt(i)&255)}return byteArray}function utf16leToBytes(str,units){var c,hi,lo;var byteArray=[];for(var i=0;i<str.length;++i){if((units-=2)<0)break;c=str.charCodeAt(i);hi=c>>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i<length;++i){if(i+offset>=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isnan(val){return val!==val}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(require,module,exports){(function(Buffer){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=Buffer.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(this,{isBuffer:require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){var ElementType=require("domelementtype");var entities=require("entities");var booleanAttributes={__proto__:null,allowfullscreen:true,async:true,autofocus:true,autoplay:true,checked:true,controls:true,default:true,defer:true,disabled:true,hidden:true,ismap:true,loop:true,multiple:true,muted:true,open:true,readonly:true,required:true,reversed:true,scoped:true,seamless:true,selected:true,typemustmatch:true};var unencodedElements={__proto__:null,style:true,script:true,xmp:true,iframe:true,noembed:true,noframes:true,plaintext:true,noscript:true};function formatAttrs(attributes,opts){if(!attributes)return;var output="",value;for(var key in attributes){value=attributes[key];if(output){output+=" "}if(!value&&booleanAttributes[key]){output+=key}else{output+=key+'="'+(opts.decodeEntities?entities.encodeXML(value):value)+'"'}}return output}var singleTag={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true};var render=module.exports=function(dom,opts){if(!Array.isArray(dom)&&!dom.cheerio)dom=[dom];opts=opts||{};var output="";for(var i=0;i<dom.length;i++){var elem=dom[i];if(elem.type==="root")output+=render(elem.children,opts);else if(ElementType.isTag(elem))output+=renderTag(elem,opts);else if(elem.type===ElementType.Directive)output+=renderDirective(elem);else if(elem.type===ElementType.Comment)output+=renderComment(elem);else if(elem.type===ElementType.CDATA)output+=renderCdata(elem);else output+=renderText(elem,opts)}return output};function renderTag(elem,opts){if(elem.name==="svg")opts={decodeEntities:opts.decodeEntities,xmlMode:true};var tag="<"+elem.name,attribs=formatAttrs(elem.attribs,opts);if(attribs){tag+=" "+attribs}if(opts.xmlMode&&(!elem.children||elem.children.length===0)){tag+="/>"}else{tag+=">";if(elem.children){tag+=render(elem.children,opts)}if(!singleTag[elem.name]||opts.xmlMode){tag+="</"+elem.name+">"}}return tag}function renderDirective(elem){return"<"+elem.data+">"}function renderText(elem,opts){var data=elem.data||"";if(opts.decodeEntities&&!(elem.parent&&elem.parent.name in unencodedElements)){data=entities.encodeXML(data)}return data}function renderCdata(elem){return"<![CDATA["+elem.children[0].data+"]]>"}function renderComment(elem){return"<!--"+elem.data+"-->"}},{domelementtype:8,entities:20}],8:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],9:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],10:[function(require,module,exports){var ElementType=require("domelementtype");var re_whitespace=/\s+/g;var NodePrototype=require("./lib/node");var ElementPrototype=require("./lib/element");function DomHandler(callback,options,elementCB){if(typeof callback==="object"){elementCB=options;options=callback;callback=null}else if(typeof options==="function"){elementCB=options;options=defaultOpts}this._callback=callback;this._options=options||defaultOpts;this._elementCB=elementCB;this.dom=[];this._done=false;this._tagStack=[];this._parser=this._parser||null}var defaultOpts={normalizeWhitespace:false,withStartIndices:false};DomHandler.prototype.onparserinit=function(parser){this._parser=parser};DomHandler.prototype.onreset=function(){DomHandler.call(this,this._callback,this._options,this._elementCB)};DomHandler.prototype.onend=function(){if(this._done)return;this._done=true;this._parser=null;this._handleCallback(null)};DomHandler.prototype._handleCallback=DomHandler.prototype.onerror=function(error){if(typeof this._callback==="function"){this._callback(error,this.dom)}else{if(error)throw error}};DomHandler.prototype.onclosetag=function(){var elem=this._tagStack.pop();if(this._elementCB)this._elementCB(elem)};DomHandler.prototype._addDomElement=function(element){var parent=this._tagStack[this._tagStack.length-1];var siblings=parent?parent.children:this.dom;var previousSibling=siblings[siblings.length-1];element.next=null;if(this._options.withStartIndices){element.startIndex=this._parser.startIndex}if(this._options.withDomLvl1){element.__proto__=element.type==="tag"?ElementPrototype:NodePrototype}if(previousSibling){element.prev=previousSibling;previousSibling.next=element}else{element.prev=null}siblings.push(element);element.parent=parent||null};DomHandler.prototype.onopentag=function(name,attribs){var element={type:name==="script"?ElementType.Script:name==="style"?ElementType.Style:ElementType.Tag,name:name,attribs:attribs,children:[]};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.ontext=function(data){var normalize=this._options.normalizeWhitespace||this._options.ignoreWhitespace;var lastTag;if(!this._tagStack.length&&this.dom.length&&(lastTag=this.dom[this.dom.length-1]).type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(this._tagStack.length&&(lastTag=this._tagStack[this._tagStack.length-1])&&(lastTag=lastTag.children[lastTag.children.length-1])&&lastTag.type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(normalize){data=data.replace(re_whitespace," ")}this._addDomElement({data:data,type:ElementType.Text})}}};DomHandler.prototype.oncomment=function(data){var lastTag=this._tagStack[this._tagStack.length-1];if(lastTag&&lastTag.type===ElementType.Comment){lastTag.data+=data;return}var element={data:data,type:ElementType.Comment};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncdatastart=function(){var element={children:[{data:"",type:ElementType.Text}],type:ElementType.CDATA};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncommentend=DomHandler.prototype.oncdataend=function(){this._tagStack.pop()};DomHandler.prototype.onprocessinginstruction=function(name,data){this._addDomElement({name:name,data:data,type:ElementType.Directive})};module.exports=DomHandler},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(require,module,exports){var NodePrototype=require("./node");var ElementPrototype=module.exports=Object.create(NodePrototype);var domLvl1={tagName:"name"};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(ElementPrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{"./node":12}],12:[function(require,module,exports){var NodePrototype=module.exports={get firstChild(){var children=this.children;return children&&children[0]||null},get lastChild(){var children=this.children;return children&&children[children.length-1]||null},get nodeType(){return nodeTypes[this.type]||nodeTypes.element}};var domLvl1={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"};var nodeTypes={element:1,text:3,cdata:4,comment:8};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(NodePrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{}],13:[function(require,module,exports){var DomUtils=module.exports;[require("./lib/stringify"),require("./lib/traversal"),require("./lib/manipulation"),require("./lib/querying"),require("./lib/legacy"),require("./lib/helpers")].forEach(function(ext){Object.keys(ext).forEach(function(key){DomUtils[key]=ext[key].bind(DomUtils)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(require,module,exports){exports.removeSubsets=function(nodes){var idx=nodes.length,node,ancestor,replace;while(--idx>-1){node=ancestor=nodes[idx];nodes[idx]=null;replace=true;while(ancestor){if(nodes.indexOf(ancestor)>-1){replace=false;nodes.splice(idx,1);break}ancestor=ancestor.parent}if(replace){nodes[idx]=node}}return nodes};var POSITION={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16};var comparePos=exports.compareDocumentPosition=function(nodeA,nodeB){var aParents=[];var bParents=[];var current,sharedParent,siblings,aSibling,bSibling,idx;if(nodeA===nodeB){return 0}current=nodeA;while(current){aParents.unshift(current);current=current.parent}current=nodeB;while(current){bParents.unshift(current);current=current.parent}idx=0;while(aParents[idx]===bParents[idx]){idx++}if(idx===0){return POSITION.DISCONNECTED}sharedParent=aParents[idx-1];siblings=sharedParent.children;aSibling=aParents[idx];bSibling=bParents[idx];if(siblings.indexOf(aSibling)>siblings.indexOf(bSibling)){if(sharedParent===nodeB){return POSITION.FOLLOWING|POSITION.CONTAINED_BY}return POSITION.FOLLOWING}else{if(sharedParent===nodeA){return POSITION.PRECEDING|POSITION.CONTAINS}return POSITION.PRECEDING}};exports.uniqueSort=function(nodes){var idx=nodes.length,node,position;nodes=nodes.slice();while(--idx>-1){node=nodes[idx];position=nodes.indexOf(node);if(position>-1&&position<idx){nodes.splice(idx,1)}}nodes.sort(function(a,b){var relative=comparePos(a,b);if(relative&POSITION.PRECEDING){return-1}else if(relative&POSITION.FOLLOWING){return 1}return 0});return nodes}},{}],15:[function(require,module,exports){var ElementType=require("domelementtype");var isTag=exports.isTag=ElementType.isTag;exports.testElement=function(options,element){for(var key in options){if(!options.hasOwnProperty(key));else if(key==="tag_name"){if(!isTag(element)||!options.tag_name(element.name)){return false}}else if(key==="tag_type"){if(!options.tag_type(element.type))return false}else if(key==="tag_contains"){if(isTag(element)||!options.tag_contains(element.data)){return false}}else if(!element.attribs||!options[key](element.attribs[key])){return false}}return true};var Checks={tag_name:function(name){if(typeof name==="function"){return function(elem){return isTag(elem)&&name(elem.name)}}else if(name==="*"){return isTag}else{return function(elem){return isTag(elem)&&elem.name===name}}},tag_type:function(type){if(typeof type==="function"){return function(elem){return type(elem.type)}}else{return function(elem){return elem.type===type}}},tag_contains:function(data){if(typeof data==="function"){return function(elem){return!isTag(elem)&&data(elem.data)}}else{return function(elem){return!isTag(elem)&&elem.data===data}}}};function getAttribCheck(attrib,value){if(typeof value==="function"){return function(elem){return elem.attribs&&value(elem.attribs[attrib])}}else{return function(elem){return elem.attribs&&elem.attribs[attrib]===value}}}function combineFuncs(a,b){return function(elem){return a(elem)||b(elem)}}exports.getElements=function(options,element,recurse,limit){var funcs=Object.keys(options).map(function(key){var value=options[key];return key in Checks?Checks[key](value):getAttribCheck(key,value)});return funcs.length===0?[]:this.filter(funcs.reduce(combineFuncs),element,recurse,limit)};exports.getElementById=function(id,element,recurse){if(!Array.isArray(element))element=[element];return this.findOne(getAttribCheck("id",id),element,recurse!==false)};exports.getElementsByTagName=function(name,element,recurse,limit){return this.filter(Checks.tag_name(name),element,recurse,limit)};exports.getElementsByTagType=function(type,element,recurse,limit){return this.filter(Checks.tag_type(type),element,recurse,limit)}},{domelementtype:9}],16:[function(require,module,exports){exports.removeElement=function(elem){if(elem.prev)elem.prev.next=elem.next;if(elem.next)elem.next.prev=elem.prev;if(elem.parent){var childs=elem.parent.children;childs.splice(childs.lastIndexOf(elem),1)}};exports.replaceElement=function(elem,replacement){var prev=replacement.prev=elem.prev;if(prev){prev.next=replacement}var next=replacement.next=elem.next;if(next){next.prev=replacement}var parent=replacement.parent=elem.parent;if(parent){var childs=parent.children;childs[childs.lastIndexOf(elem)]=replacement}};exports.appendChild=function(elem,child){child.parent=elem;if(elem.children.push(child)!==1){var sibling=elem.children[elem.children.length-2];sibling.next=child;child.prev=sibling;child.next=null}};exports.append=function(elem,next){var parent=elem.parent,currNext=elem.next;next.next=currNext;next.prev=elem;elem.next=next;next.parent=parent;if(currNext){currNext.prev=next;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(currNext),0,next)}}else if(parent){parent.children.push(next)}};exports.prepend=function(elem,prev){var parent=elem.parent;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(elem),0,prev)}if(elem.prev){elem.prev.next=prev}prev.parent=parent;prev.prev=elem.prev;prev.next=elem;elem.prev=prev}},{}],17:[function(require,module,exports){var isTag=require("domelementtype").isTag;module.exports={filter:filter,find:find,findOneChild:findOneChild,findOne:findOne,existsOne:existsOne,findAll:findAll};function filter(test,element,recurse,limit){if(!Array.isArray(element))element=[element];if(typeof limit!=="number"||!isFinite(limit)){limit=Infinity}return find(test,element,recurse!==false,limit)}function find(test,elems,recurse,limit){var result=[],childs;for(var i=0,j=elems.length;i<j;i++){if(test(elems[i])){result.push(elems[i]);if(--limit<=0)break}childs=elems[i].children;if(recurse&&childs&&childs.length>0){childs=find(test,childs,recurse,limit);result=result.concat(childs);limit-=childs.length;if(limit<=0)break}}return result}function findOneChild(test,elems){for(var i=0,l=elems.length;i<l;i++){if(test(elems[i]))return elems[i]}return null}function findOne(test,elems){var elem=null;for(var i=0,l=elems.length;i<l&&!elem;i++){if(!isTag(elems[i])){continue}else if(test(elems[i])){elem=elems[i]}else if(elems[i].children.length>0){elem=findOne(test,elems[i].children)}}return elem}function existsOne(test,elems){for(var i=0,l=elems.length;i<l;i++){if(isTag(elems[i])&&(test(elems[i])||elems[i].children.length>0&&existsOne(test,elems[i].children))){return true}}return false}function findAll(test,elems){var result=[];for(var i=0,j=elems.length;i<j;i++){if(!isTag(elems[i]))continue;if(test(elems[i]))result.push(elems[i]);if(elems[i].children.length>0){result=result.concat(findAll(test,elems[i].children))}}return result}},{domelementtype:9}],18:[function(require,module,exports){var ElementType=require("domelementtype"),getOuterHTML=require("dom-serializer"),isTag=ElementType.isTag;module.exports={getInnerHTML:getInnerHTML,getOuterHTML:getOuterHTML,getText:getText};function getInnerHTML(elem,opts){return elem.children?elem.children.map(function(elem){return getOuterHTML(elem,opts)}).join(""):""}function getText(elem){if(Array.isArray(elem))return elem.map(getText).join("");if(isTag(elem)||elem.type===ElementType.CDATA)return getText(elem.children);if(elem.type===ElementType.Text)return elem.data;return""}},{"dom-serializer":7,domelementtype:9}],19:[function(require,module,exports){var getChildren=exports.getChildren=function(elem){return elem.children};var getParent=exports.getParent=function(elem){return elem.parent};exports.getSiblings=function(elem){var parent=getParent(elem);return parent?getChildren(parent):[elem]};exports.getAttributeValue=function(elem,name){return elem.attribs&&elem.attribs[name]};exports.hasAttrib=function(elem,name){return!!elem.attribs&&hasOwnProperty.call(elem.attribs,name)};exports.getName=function(elem){return elem.name}},{}],20:[function(require,module,exports){var encode=require("./lib/encode.js"),decode=require("./lib/decode.js");exports.decode=function(data,level){return(!level||level<=0?decode.XML:decode.HTML)(data)};exports.decodeStrict=function(data,level){return(!level||level<=0?decode.XML:decode.HTMLStrict)(data)};exports.encode=function(data,level){return(!level||level<=0?encode.XML:encode.HTML)(data)};exports.encodeXML=encode.XML;exports.encodeHTML4=exports.encodeHTML5=exports.encodeHTML=encode.HTML;exports.decodeXML=exports.decodeXMLStrict=decode.XML;exports.decodeHTML4=exports.decodeHTML5=exports.decodeHTML=decode.HTML;exports.decodeHTML4Strict=exports.decodeHTML5Strict=exports.decodeHTMLStrict=decode.HTMLStrict;exports.escape=encode.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(require,module,exports){var entityMap=require("../maps/entities.json"),legacyMap=require("../maps/legacy.json"),xmlMap=require("../maps/xml.json"),decodeCodePoint=require("./decode_codepoint.js");var decodeXMLStrict=getStrictDecoder(xmlMap),decodeHTMLStrict=getStrictDecoder(entityMap);function getStrictDecoder(map){var keys=Object.keys(map).join("|"),replace=getReplacer(map);keys+="|#[xX][\\da-fA-F]+|#\\d+";var re=new RegExp("&(?:"+keys+");","g");return function(str){return String(str).replace(re,replace)}}var decodeHTML=function(){var legacy=Object.keys(legacyMap).sort(sorter);var keys=Object.keys(entityMap).sort(sorter);for(var i=0,j=0;i<keys.length;i++){if(legacy[j]===keys[i]){keys[i]+=";?";j++}else{keys[i]+=";"}}var re=new RegExp("&(?:"+keys.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),replace=getReplacer(entityMap);function replacer(str){if(str.substr(-1)!==";")str+=";";return replace(str)}return function(str){return String(str).replace(re,replacer)}}();function sorter(a,b){return a<b?1:-1}function getReplacer(map){return function replace(str){if(str.charAt(1)==="#"){if(str.charAt(2)==="X"||str.charAt(2)==="x"){return decodeCodePoint(parseInt(str.substr(3),16))}return decodeCodePoint(parseInt(str.substr(2),10))}return map[str.slice(1,-1)];
  3144  }}module.exports={XML:decodeXMLStrict,HTML:decodeHTML,HTMLStrict:decodeHTMLStrict}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(require,module,exports){var decodeMap=require("../maps/decode.json");module.exports=decodeCodePoint;function decodeCodePoint(codePoint){if(codePoint>=55296&&codePoint<=57343||codePoint>1114111){return"�"}if(codePoint in decodeMap){codePoint=decodeMap[codePoint]}var output="";if(codePoint>65535){codePoint-=65536;output+=String.fromCharCode(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}output+=String.fromCharCode(codePoint);return output}},{"../maps/decode.json":24}],23:[function(require,module,exports){var inverseXML=getInverseObj(require("../maps/xml.json")),xmlReplacer=getInverseReplacer(inverseXML);exports.XML=getInverse(inverseXML,xmlReplacer);var inverseHTML=getInverseObj(require("../maps/entities.json")),htmlReplacer=getInverseReplacer(inverseHTML);exports.HTML=getInverse(inverseHTML,htmlReplacer);function getInverseObj(obj){return Object.keys(obj).sort().reduce(function(inverse,name){inverse[obj[name]]="&"+name+";";return inverse},{})}function getInverseReplacer(inverse){var single=[],multiple=[];Object.keys(inverse).forEach(function(k){if(k.length===1){single.push("\\"+k)}else{multiple.push(k)}});multiple.unshift("["+single.join("")+"]");return new RegExp(multiple.join("|"),"g")}var re_nonASCII=/[^\0-\x7F]/g,re_astralSymbols=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;function singleCharReplacer(c){return"&#x"+c.charCodeAt(0).toString(16).toUpperCase()+";"}function astralReplacer(c){var high=c.charCodeAt(0);var low=c.charCodeAt(1);var codePoint=(high-55296)*1024+low-56320+65536;return"&#x"+codePoint.toString(16).toUpperCase()+";"}function getInverse(inverse,re){function func(name){return inverse[name]}return function(data){return data.replace(re,func).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}}var re_xmlChars=getInverseReplacer(inverseXML);function escapeXML(data){return data.replace(re_xmlChars,singleCharReplacer).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}exports.escape=escapeXML},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(require,module,exports){module.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(require,module,exports){module.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1);
  3145  }if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],29:[function(require,module,exports){module.exports=CollectingHandler;function CollectingHandler(cbs){this._cbs=cbs||{};this.events=[]}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;CollectingHandler.prototype[name]=function(){this.events.push([name]);if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;CollectingHandler.prototype[name]=function(a){this.events.push([name,a]);if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;CollectingHandler.prototype[name]=function(a,b){this.events.push([name,a,b]);if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}});CollectingHandler.prototype.onreset=function(){this.events=[];if(this._cbs.onreset)this._cbs.onreset()};CollectingHandler.prototype.restart=function(){if(this._cbs.onreset)this._cbs.onreset();for(var i=0,len=this.events.length;i<len;i++){if(this._cbs[this.events[i][0]]){var num=this.events[i].length;if(num===1){this._cbs[this.events[i][0]]()}else if(num===2){this._cbs[this.events[i][0]](this.events[i][1])}else{this._cbs[this.events[i][0]](this.events[i][1],this.events[i][2])}}}}},{"./":36}],30:[function(require,module,exports){var index=require("./index.js"),DomHandler=index.DomHandler,DomUtils=index.DomUtils;function FeedHandler(callback,options){this.init(callback,options)}require("inherits")(FeedHandler,DomHandler);FeedHandler.prototype.init=DomHandler;function getElements(what,where){return DomUtils.getElementsByTagName(what,where,true)}function getOneElement(what,where){return DomUtils.getElementsByTagName(what,where,true,1)[0]}function fetch(what,where,recurse){return DomUtils.getText(DomUtils.getElementsByTagName(what,where,recurse,1)).trim()}function addConditionally(obj,prop,what,where,recurse){var tmp=fetch(what,where,recurse);if(tmp)obj[prop]=tmp}var isValidFeed=function(value){return value==="rss"||value==="feed"||value==="rdf:RDF"};FeedHandler.prototype.onend=function(){var feed={},feedRoot=getOneElement(isValidFeed,this.dom),tmp,childs;if(feedRoot){if(feedRoot.name==="feed"){childs=feedRoot.children;feed.type="atom";addConditionally(feed,"id","id",childs);addConditionally(feed,"title","title",childs);if((tmp=getOneElement("link",childs))&&(tmp=tmp.attribs)&&(tmp=tmp.href))feed.link=tmp;addConditionally(feed,"description","subtitle",childs);if(tmp=fetch("updated",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","email",childs,true);feed.items=getElements("entry",childs).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","id",item);addConditionally(entry,"title","title",item);if((tmp=getOneElement("link",item))&&(tmp=tmp.attribs)&&(tmp=tmp.href))entry.link=tmp;if(tmp=fetch("summary",item)||fetch("content",item))entry.description=tmp;if(tmp=fetch("updated",item))entry.pubDate=new Date(tmp);return entry})}else{childs=getOneElement("channel",feedRoot.children).children;feed.type=feedRoot.name.substr(0,3);feed.id="";addConditionally(feed,"title","title",childs);addConditionally(feed,"link","link",childs);addConditionally(feed,"description","description",childs);if(tmp=fetch("lastBuildDate",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","managingEditor",childs,true);feed.items=getElements("item",feedRoot.children).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","guid",item);addConditionally(entry,"title","title",item);addConditionally(entry,"link","link",item);addConditionally(entry,"description","description",item);if(tmp=fetch("pubDate",item))entry.pubDate=new Date(tmp);return entry})}}this.dom=feed;DomHandler.prototype._handleCallback.call(this,feedRoot?null:Error("couldn't find root of feed"))};module.exports=FeedHandler},{"./index.js":36,inherits:38}],31:[function(require,module,exports){var Tokenizer=require("./Tokenizer.js");var formTags={input:true,option:true,optgroup:true,select:true,button:true,datalist:true,textarea:true};var openImpliesClose={tr:{tr:true,th:true,td:true},th:{th:true},td:{thead:true,th:true,td:true},body:{head:true,link:true,script:true},li:{li:true},p:{p:true},h1:{p:true},h2:{p:true},h3:{p:true},h4:{p:true},h5:{p:true},h6:{p:true},select:formTags,input:formTags,output:formTags,button:formTags,datalist:formTags,textarea:formTags,option:{option:true},optgroup:{optgroup:true}};var voidElements={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true,path:true,circle:true,ellipse:true,line:true,rect:true,use:true,stop:true,polyline:true,polygon:true};var re_nameEnd=/\s|\//;function Parser(cbs,options){this._options=options||{};this._cbs=cbs||{};this._tagname="";this._attribname="";this._attribvalue="";this._attribs=null;this._stack=[];this.startIndex=0;this.endIndex=null;this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode;this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode;if(this._options.Tokenizer){Tokenizer=this._options.Tokenizer}this._tokenizer=new Tokenizer(this._options,this);if(this._cbs.onparserinit)this._cbs.onparserinit(this)}require("inherits")(Parser,require("events").EventEmitter);Parser.prototype._updatePosition=function(initialOffset){if(this.endIndex===null){if(this._tokenizer._sectionStart<=initialOffset){this.startIndex=0}else{this.startIndex=this._tokenizer._sectionStart-initialOffset}}else this.startIndex=this.endIndex+1;this.endIndex=this._tokenizer.getAbsoluteIndex()};Parser.prototype.ontext=function(data){this._updatePosition(1);this.endIndex--;if(this._cbs.ontext)this._cbs.ontext(data)};Parser.prototype.onopentagname=function(name){if(this._lowerCaseTagNames){name=name.toLowerCase()}this._tagname=name;if(!this._options.xmlMode&&name in openImpliesClose){for(var el;(el=this._stack[this._stack.length-1])in openImpliesClose[name];this.onclosetag(el));}if(this._options.xmlMode||!(name in voidElements)){this._stack.push(name)}if(this._cbs.onopentagname)this._cbs.onopentagname(name);if(this._cbs.onopentag)this._attribs={}};Parser.prototype.onopentagend=function(){this._updatePosition(1);if(this._attribs){if(this._cbs.onopentag)this._cbs.onopentag(this._tagname,this._attribs);this._attribs=null}if(!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in voidElements){this._cbs.onclosetag(this._tagname)}this._tagname=""};Parser.prototype.onclosetag=function(name){this._updatePosition(1);if(this._lowerCaseTagNames){name=name.toLowerCase()}if(this._stack.length&&(!(name in voidElements)||this._options.xmlMode)){var pos=this._stack.lastIndexOf(name);if(pos!==-1){if(this._cbs.onclosetag){pos=this._stack.length-pos;while(pos--)this._cbs.onclosetag(this._stack.pop())}else this._stack.length=pos}else if(name==="p"&&!this._options.xmlMode){this.onopentagname(name);this._closeCurrentTag()}}else if(!this._options.xmlMode&&(name==="br"||name==="p")){this.onopentagname(name);this._closeCurrentTag()}};Parser.prototype.onselfclosingtag=function(){if(this._options.xmlMode||this._options.recognizeSelfClosing){this._closeCurrentTag()}else{this.onopentagend()}};Parser.prototype._closeCurrentTag=function(){var name=this._tagname;this.onopentagend();if(this._stack[this._stack.length-1]===name){if(this._cbs.onclosetag){this._cbs.onclosetag(name)}this._stack.pop()}};Parser.prototype.onattribname=function(name){if(this._lowerCaseAttributeNames){name=name.toLowerCase()}this._attribname=name};Parser.prototype.onattribdata=function(value){this._attribvalue+=value};Parser.prototype.onattribend=function(){if(this._cbs.onattribute)this._cbs.onattribute(this._attribname,this._attribvalue);if(this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)){this._attribs[this._attribname]=this._attribvalue}this._attribname="";this._attribvalue=""};Parser.prototype._getInstructionName=function(value){var idx=value.search(re_nameEnd),name=idx<0?value:value.substr(0,idx);if(this._lowerCaseTagNames){name=name.toLowerCase()}return name};Parser.prototype.ondeclaration=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("!"+name,"!"+value)}};Parser.prototype.onprocessinginstruction=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("?"+name,"?"+value)}};Parser.prototype.oncomment=function(value){this._updatePosition(4);if(this._cbs.oncomment)this._cbs.oncomment(value);if(this._cbs.oncommentend)this._cbs.oncommentend()};Parser.prototype.oncdata=function(value){this._updatePosition(1);if(this._options.xmlMode||this._options.recognizeCDATA){if(this._cbs.oncdatastart)this._cbs.oncdatastart();if(this._cbs.ontext)this._cbs.ontext(value);if(this._cbs.oncdataend)this._cbs.oncdataend()}else{this.oncomment("[CDATA["+value+"]]")}};Parser.prototype.onerror=function(err){if(this._cbs.onerror)this._cbs.onerror(err)};Parser.prototype.onend=function(){if(this._cbs.onclosetag){for(var i=this._stack.length;i>0;this._cbs.onclosetag(this._stack[--i]));}if(this._cbs.onend)this._cbs.onend()};Parser.prototype.reset=function(){if(this._cbs.onreset)this._cbs.onreset();this._tokenizer.reset();this._tagname="";this._attribname="";this._attribs=null;this._stack=[];if(this._cbs.onparserinit)this._cbs.onparserinit(this)};Parser.prototype.parseComplete=function(data){this.reset();this.end(data)};Parser.prototype.write=function(chunk){this._tokenizer.write(chunk)};Parser.prototype.end=function(chunk){this._tokenizer.end(chunk)};Parser.prototype.pause=function(){this._tokenizer.pause()};Parser.prototype.resume=function(){this._tokenizer.resume()};Parser.prototype.parseChunk=Parser.prototype.write;Parser.prototype.done=Parser.prototype.end;module.exports=Parser},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(require,module,exports){module.exports=ProxyHandler;function ProxyHandler(cbs){this._cbs=cbs||{}}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;ProxyHandler.prototype[name]=function(){if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;ProxyHandler.prototype[name]=function(a){if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;ProxyHandler.prototype[name]=function(a,b){if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}})},{"./":36}],33:[function(require,module,exports){module.exports=Stream;var Parser=require("./WritableStream.js");function Stream(options){Parser.call(this,new Cbs(this),options)}require("inherits")(Stream,Parser);Stream.prototype.readable=true;function Cbs(scope){this.scope=scope}var EVENTS=require("../").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){Cbs.prototype["on"+name]=function(){this.scope.emit(name)}}else if(EVENTS[name]===1){Cbs.prototype["on"+name]=function(a){this.scope.emit(name,a)}}else if(EVENTS[name]===2){Cbs.prototype["on"+name]=function(a,b){this.scope.emit(name,a,b)}}else{throw Error("wrong number of arguments!")}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(require,module,exports){module.exports=Tokenizer;var decodeCodePoint=require("entities/lib/decode_codepoint.js"),entityMap=require("entities/maps/entities.json"),legacyMap=require("entities/maps/legacy.json"),xmlMap=require("entities/maps/xml.json"),i=0,TEXT=i++,BEFORE_TAG_NAME=i++,IN_TAG_NAME=i++,IN_SELF_CLOSING_TAG=i++,BEFORE_CLOSING_TAG_NAME=i++,IN_CLOSING_TAG_NAME=i++,AFTER_CLOSING_TAG_NAME=i++,BEFORE_ATTRIBUTE_NAME=i++,IN_ATTRIBUTE_NAME=i++,AFTER_ATTRIBUTE_NAME=i++,BEFORE_ATTRIBUTE_VALUE=i++,IN_ATTRIBUTE_VALUE_DQ=i++,IN_ATTRIBUTE_VALUE_SQ=i++,IN_ATTRIBUTE_VALUE_NQ=i++,BEFORE_DECLARATION=i++,IN_DECLARATION=i++,IN_PROCESSING_INSTRUCTION=i++,BEFORE_COMMENT=i++,IN_COMMENT=i++,AFTER_COMMENT_1=i++,AFTER_COMMENT_2=i++,BEFORE_CDATA_1=i++,BEFORE_CDATA_2=i++,BEFORE_CDATA_3=i++,BEFORE_CDATA_4=i++,BEFORE_CDATA_5=i++,BEFORE_CDATA_6=i++,IN_CDATA=i++,AFTER_CDATA_1=i++,AFTER_CDATA_2=i++,BEFORE_SPECIAL=i++,BEFORE_SPECIAL_END=i++,BEFORE_SCRIPT_1=i++,BEFORE_SCRIPT_2=i++,BEFORE_SCRIPT_3=i++,BEFORE_SCRIPT_4=i++,BEFORE_SCRIPT_5=i++,AFTER_SCRIPT_1=i++,AFTER_SCRIPT_2=i++,AFTER_SCRIPT_3=i++,AFTER_SCRIPT_4=i++,AFTER_SCRIPT_5=i++,BEFORE_STYLE_1=i++,BEFORE_STYLE_2=i++,BEFORE_STYLE_3=i++,BEFORE_STYLE_4=i++,AFTER_STYLE_1=i++,AFTER_STYLE_2=i++,AFTER_STYLE_3=i++,AFTER_STYLE_4=i++,BEFORE_ENTITY=i++,BEFORE_NUMERIC_ENTITY=i++,IN_NAMED_ENTITY=i++,IN_NUMERIC_ENTITY=i++,IN_HEX_ENTITY=i++,j=0,SPECIAL_NONE=j++,SPECIAL_SCRIPT=j++,SPECIAL_STYLE=j++;function whitespace(c){return c===" "||c==="\n"||c==="\t"||c==="\f"||c==="\r"}function characterState(char,SUCCESS){return function(c){if(c===char)this._state=SUCCESS}}function ifElseState(upper,SUCCESS,FAILURE){var lower=upper.toLowerCase();if(upper===lower){return function(c){if(c===lower){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}else{return function(c){if(c===lower||c===upper){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}}function consumeSpecialNameChar(upper,NEXT_STATE){var lower=upper.toLowerCase();return function(c){if(c===lower||c===upper){this._state=NEXT_STATE}else{this._state=IN_TAG_NAME;this._index--}}}function Tokenizer(options,cbs){this._state=TEXT;this._buffer="";this._sectionStart=0;this._index=0;this._bufferOffset=0;this._baseState=TEXT;this._special=SPECIAL_NONE;this._cbs=cbs;this._running=true;this._ended=false;this._xmlMode=!!(options&&options.xmlMode);this._decodeEntities=!!(options&&options.decodeEntities)}Tokenizer.prototype._stateText=function(c){if(c==="<"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._state=BEFORE_TAG_NAME;this._sectionStart=this._index}else if(this._decodeEntities&&this._special===SPECIAL_NONE&&c==="&"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._baseState=TEXT;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeTagName=function(c){if(c==="/"){this._state=BEFORE_CLOSING_TAG_NAME}else if(c==="<"){this._cbs.ontext(this._getSection());this._sectionStart=this._index}else if(c===">"||this._special!==SPECIAL_NONE||whitespace(c)){this._state=TEXT}else if(c==="!"){this._state=BEFORE_DECLARATION;this._sectionStart=this._index+1}else if(c==="?"){this._state=IN_PROCESSING_INSTRUCTION;this._sectionStart=this._index+1}else{this._state=!this._xmlMode&&(c==="s"||c==="S")?BEFORE_SPECIAL:IN_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInTagName=function(c){if(c==="/"||c===">"||whitespace(c)){this._emitToken("onopentagname");this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateBeforeCloseingTagName=function(c){if(whitespace(c));else if(c===">"){this._state=TEXT}else if(this._special!==SPECIAL_NONE){if(c==="s"||c==="S"){this._state=BEFORE_SPECIAL_END}else{this._state=TEXT;this._index--}}else{this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInCloseingTagName=function(c){if(c===">"||whitespace(c)){this._emitToken("onclosetag");this._state=AFTER_CLOSING_TAG_NAME;this._index--}};Tokenizer.prototype._stateAfterCloseingTagName=function(c){if(c===">"){this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeAttributeName=function(c){if(c===">"){this._cbs.onopentagend();this._state=TEXT;this._sectionStart=this._index+1}else if(c==="/"){this._state=IN_SELF_CLOSING_TAG}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInSelfClosingTag=function(c){if(c===">"){this._cbs.onselfclosingtag();this._state=TEXT;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateInAttributeName=function(c){if(c==="="||c==="/"||c===">"||whitespace(c)){this._cbs.onattribname(this._getSection());this._sectionStart=-1;this._state=AFTER_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateAfterAttributeName=function(c){if(c==="="){this._state=BEFORE_ATTRIBUTE_VALUE}else if(c==="/"||c===">"){this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(!whitespace(c)){this._cbs.onattribend();this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeAttributeValue=function(c){if(c==='"'){this._state=IN_ATTRIBUTE_VALUE_DQ;this._sectionStart=this._index+1}else if(c==="'"){this._state=IN_ATTRIBUTE_VALUE_SQ;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_VALUE_NQ;this._sectionStart=this._index;this._index--}};Tokenizer.prototype._stateInAttributeValueDoubleQuotes=function(c){if(c==='"'){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueSingleQuotes=function(c){if(c==="'"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueNoQuotes=function(c){if(whitespace(c)||c===">"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeDeclaration=function(c){this._state=c==="["?BEFORE_CDATA_1:c==="-"?BEFORE_COMMENT:IN_DECLARATION};Tokenizer.prototype._stateInDeclaration=function(c){if(c===">"){this._cbs.ondeclaration(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateInProcessingInstruction=function(c){if(c===">"){this._cbs.onprocessinginstruction(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeComment=function(c){if(c==="-"){this._state=IN_COMMENT;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION}};Tokenizer.prototype._stateInComment=function(c){if(c==="-")this._state=AFTER_COMMENT_1};Tokenizer.prototype._stateAfterComment1=function(c){if(c==="-"){this._state=AFTER_COMMENT_2}else{this._state=IN_COMMENT}};Tokenizer.prototype._stateAfterComment2=function(c){if(c===">"){this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="-"){this._state=IN_COMMENT}};Tokenizer.prototype._stateBeforeCdata1=ifElseState("C",BEFORE_CDATA_2,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata2=ifElseState("D",BEFORE_CDATA_3,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata3=ifElseState("A",BEFORE_CDATA_4,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata4=ifElseState("T",BEFORE_CDATA_5,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata5=ifElseState("A",BEFORE_CDATA_6,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata6=function(c){if(c==="["){this._state=IN_CDATA;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION;this._index--}};Tokenizer.prototype._stateInCdata=function(c){if(c==="]")this._state=AFTER_CDATA_1};Tokenizer.prototype._stateAfterCdata1=characterState("]",AFTER_CDATA_2);Tokenizer.prototype._stateAfterCdata2=function(c){if(c===">"){this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="]"){this._state=IN_CDATA}};Tokenizer.prototype._stateBeforeSpecial=function(c){if(c==="c"||c==="C"){this._state=BEFORE_SCRIPT_1}else if(c==="t"||c==="T"){this._state=BEFORE_STYLE_1}else{this._state=IN_TAG_NAME;this._index--}};Tokenizer.prototype._stateBeforeSpecialEnd=function(c){if(this._special===SPECIAL_SCRIPT&&(c==="c"||c==="C")){this._state=AFTER_SCRIPT_1}else if(this._special===SPECIAL_STYLE&&(c==="t"||c==="T")){this._state=AFTER_STYLE_1}else this._state=TEXT};Tokenizer.prototype._stateBeforeScript1=consumeSpecialNameChar("R",BEFORE_SCRIPT_2);Tokenizer.prototype._stateBeforeScript2=consumeSpecialNameChar("I",BEFORE_SCRIPT_3);Tokenizer.prototype._stateBeforeScript3=consumeSpecialNameChar("P",BEFORE_SCRIPT_4);Tokenizer.prototype._stateBeforeScript4=consumeSpecialNameChar("T",BEFORE_SCRIPT_5);Tokenizer.prototype._stateBeforeScript5=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_SCRIPT}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterScript1=ifElseState("R",AFTER_SCRIPT_2,TEXT);Tokenizer.prototype._stateAfterScript2=ifElseState("I",AFTER_SCRIPT_3,TEXT);Tokenizer.prototype._stateAfterScript3=ifElseState("P",AFTER_SCRIPT_4,TEXT);Tokenizer.prototype._stateAfterScript4=ifElseState("T",AFTER_SCRIPT_5,TEXT);Tokenizer.prototype._stateAfterScript5=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-6;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeStyle1=consumeSpecialNameChar("Y",BEFORE_STYLE_2);Tokenizer.prototype._stateBeforeStyle2=consumeSpecialNameChar("L",BEFORE_STYLE_3);Tokenizer.prototype._stateBeforeStyle3=consumeSpecialNameChar("E",BEFORE_STYLE_4);Tokenizer.prototype._stateBeforeStyle4=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_STYLE}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterStyle1=ifElseState("Y",AFTER_STYLE_2,TEXT);Tokenizer.prototype._stateAfterStyle2=ifElseState("L",AFTER_STYLE_3,TEXT);Tokenizer.prototype._stateAfterStyle3=ifElseState("E",AFTER_STYLE_4,TEXT);Tokenizer.prototype._stateAfterStyle4=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-5;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeEntity=ifElseState("#",BEFORE_NUMERIC_ENTITY,IN_NAMED_ENTITY);Tokenizer.prototype._stateBeforeNumericEntity=ifElseState("X",IN_HEX_ENTITY,IN_NUMERIC_ENTITY);Tokenizer.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var entity=this._buffer.substring(this._sectionStart+1,this._index),map=this._xmlMode?xmlMap:entityMap;if(map.hasOwnProperty(entity)){this._emitPartial(map[entity]);this._sectionStart=this._index+1}}};Tokenizer.prototype._parseLegacyEntity=function(){var start=this._sectionStart+1,limit=this._index-start;if(limit>6)limit=6;while(limit>=2){var entity=this._buffer.substr(start,limit);if(legacyMap.hasOwnProperty(entity)){this._emitPartial(legacyMap[entity]);this._sectionStart+=limit+1;return}else{limit--}}};Tokenizer.prototype._stateInNamedEntity=function(c){if(c===";"){this._parseNamedEntityStrict();if(this._sectionStart+1<this._index&&!this._xmlMode){this._parseLegacyEntity()}this._state=this._baseState}else if((c<"a"||c>"z")&&(c<"A"||c>"Z")&&(c<"0"||c>"9")){if(this._xmlMode);else if(this._sectionStart+1===this._index);else if(this._baseState!==TEXT){if(c!=="="){this._parseNamedEntityStrict()}}else{this._parseLegacyEntity()}this._state=this._baseState;this._index--}};Tokenizer.prototype._decodeNumericEntity=function(offset,base){var sectionStart=this._sectionStart+offset;if(sectionStart!==this._index){var entity=this._buffer.substring(sectionStart,this._index);var parsed=parseInt(entity,base);this._emitPartial(decodeCodePoint(parsed));this._sectionStart=this._index}else{this._sectionStart--}this._state=this._baseState};Tokenizer.prototype._stateInNumericEntity=function(c){if(c===";"){this._decodeNumericEntity(2,10);this._sectionStart++}else if(c<"0"||c>"9"){if(!this._xmlMode){this._decodeNumericEntity(2,10)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._stateInHexEntity=function(c){if(c===";"){this._decodeNumericEntity(3,16);this._sectionStart++}else if((c<"a"||c>"f")&&(c<"A"||c>"F")&&(c<"0"||c>"9")){if(!this._xmlMode){this._decodeNumericEntity(3,16)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._cleanup=function(){if(this._sectionStart<0){this._buffer="";this._index=0;this._bufferOffset+=this._index}else if(this._running){if(this._state===TEXT){if(this._sectionStart!==this._index){this._cbs.ontext(this._buffer.substr(this._sectionStart))}this._buffer="";this._bufferOffset+=this._index;this._index=0}else if(this._sectionStart===this._index){this._buffer="";this._bufferOffset+=this._index;this._index=0}else{this._buffer=this._buffer.substr(this._sectionStart);this._index-=this._sectionStart;this._bufferOffset+=this._sectionStart}this._sectionStart=0}};Tokenizer.prototype.write=function(chunk){if(this._ended)this._cbs.onerror(Error(".write() after done!"));this._buffer+=chunk;this._parse()};Tokenizer.prototype._parse=function(){while(this._index<this._buffer.length&&this._running){var c=this._buffer.charAt(this._index);if(this._state===TEXT){this._stateText(c)}else if(this._state===BEFORE_TAG_NAME){this._stateBeforeTagName(c)}else if(this._state===IN_TAG_NAME){this._stateInTagName(c)}else if(this._state===BEFORE_CLOSING_TAG_NAME){this._stateBeforeCloseingTagName(c)}else if(this._state===IN_CLOSING_TAG_NAME){this._stateInCloseingTagName(c)}else if(this._state===AFTER_CLOSING_TAG_NAME){this._stateAfterCloseingTagName(c)}else if(this._state===IN_SELF_CLOSING_TAG){this._stateInSelfClosingTag(c)}else if(this._state===BEFORE_ATTRIBUTE_NAME){this._stateBeforeAttributeName(c)}else if(this._state===IN_ATTRIBUTE_NAME){this._stateInAttributeName(c)}else if(this._state===AFTER_ATTRIBUTE_NAME){this._stateAfterAttributeName(c)}else if(this._state===BEFORE_ATTRIBUTE_VALUE){this._stateBeforeAttributeValue(c)}else if(this._state===IN_ATTRIBUTE_VALUE_DQ){this._stateInAttributeValueDoubleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_SQ){this._stateInAttributeValueSingleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_NQ){this._stateInAttributeValueNoQuotes(c)}else if(this._state===BEFORE_DECLARATION){this._stateBeforeDeclaration(c)}else if(this._state===IN_DECLARATION){this._stateInDeclaration(c)}else if(this._state===IN_PROCESSING_INSTRUCTION){this._stateInProcessingInstruction(c)}else if(this._state===BEFORE_COMMENT){this._stateBeforeComment(c)}else if(this._state===IN_COMMENT){this._stateInComment(c)}else if(this._state===AFTER_COMMENT_1){this._stateAfterComment1(c)}else if(this._state===AFTER_COMMENT_2){this._stateAfterComment2(c)}else if(this._state===BEFORE_CDATA_1){this._stateBeforeCdata1(c)}else if(this._state===BEFORE_CDATA_2){this._stateBeforeCdata2(c)}else if(this._state===BEFORE_CDATA_3){this._stateBeforeCdata3(c)}else if(this._state===BEFORE_CDATA_4){this._stateBeforeCdata4(c)}else if(this._state===BEFORE_CDATA_5){this._stateBeforeCdata5(c)}else if(this._state===BEFORE_CDATA_6){this._stateBeforeCdata6(c)}else if(this._state===IN_CDATA){this._stateInCdata(c)}else if(this._state===AFTER_CDATA_1){this._stateAfterCdata1(c)}else if(this._state===AFTER_CDATA_2){this._stateAfterCdata2(c)}else if(this._state===BEFORE_SPECIAL){this._stateBeforeSpecial(c)}else if(this._state===BEFORE_SPECIAL_END){this._stateBeforeSpecialEnd(c)}else if(this._state===BEFORE_SCRIPT_1){this._stateBeforeScript1(c)}else if(this._state===BEFORE_SCRIPT_2){this._stateBeforeScript2(c)}else if(this._state===BEFORE_SCRIPT_3){this._stateBeforeScript3(c)}else if(this._state===BEFORE_SCRIPT_4){this._stateBeforeScript4(c)}else if(this._state===BEFORE_SCRIPT_5){this._stateBeforeScript5(c)}else if(this._state===AFTER_SCRIPT_1){this._stateAfterScript1(c)}else if(this._state===AFTER_SCRIPT_2){this._stateAfterScript2(c)}else if(this._state===AFTER_SCRIPT_3){this._stateAfterScript3(c)}else if(this._state===AFTER_SCRIPT_4){this._stateAfterScript4(c)}else if(this._state===AFTER_SCRIPT_5){this._stateAfterScript5(c)}else if(this._state===BEFORE_STYLE_1){this._stateBeforeStyle1(c)}else if(this._state===BEFORE_STYLE_2){this._stateBeforeStyle2(c)}else if(this._state===BEFORE_STYLE_3){this._stateBeforeStyle3(c)}else if(this._state===BEFORE_STYLE_4){this._stateBeforeStyle4(c)}else if(this._state===AFTER_STYLE_1){this._stateAfterStyle1(c)}else if(this._state===AFTER_STYLE_2){this._stateAfterStyle2(c)}else if(this._state===AFTER_STYLE_3){this._stateAfterStyle3(c)}else if(this._state===AFTER_STYLE_4){this._stateAfterStyle4(c)}else if(this._state===BEFORE_ENTITY){this._stateBeforeEntity(c)}else if(this._state===BEFORE_NUMERIC_ENTITY){this._stateBeforeNumericEntity(c)}else if(this._state===IN_NAMED_ENTITY){this._stateInNamedEntity(c)}else if(this._state===IN_NUMERIC_ENTITY){this._stateInNumericEntity(c)}else if(this._state===IN_HEX_ENTITY){this._stateInHexEntity(c)}else{this._cbs.onerror(Error("unknown _state"),this._state)}this._index++}this._cleanup()};Tokenizer.prototype.pause=function(){this._running=false};Tokenizer.prototype.resume=function(){this._running=true;if(this._index<this._buffer.length){this._parse()}if(this._ended){this._finish()}};Tokenizer.prototype.end=function(chunk){if(this._ended)this._cbs.onerror(Error(".end() after done!"));if(chunk)this.write(chunk);this._ended=true;if(this._running)this._finish()};Tokenizer.prototype._finish=function(){if(this._sectionStart<this._index){this._handleTrailingData()}this._cbs.onend()};Tokenizer.prototype._handleTrailingData=function(){var data=this._buffer.substr(this._sectionStart);if(this._state===IN_CDATA||this._state===AFTER_CDATA_1||this._state===AFTER_CDATA_2){this._cbs.oncdata(data)}else if(this._state===IN_COMMENT||this._state===AFTER_COMMENT_1||this._state===AFTER_COMMENT_2){this._cbs.oncomment(data)}else if(this._state===IN_NAMED_ENTITY&&!this._xmlMode){this._parseLegacyEntity();if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_NUMERIC_ENTITY&&!this._xmlMode){this._decodeNumericEntity(2,10);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_HEX_ENTITY&&!this._xmlMode){this._decodeNumericEntity(3,16);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state!==IN_TAG_NAME&&this._state!==BEFORE_ATTRIBUTE_NAME&&this._state!==BEFORE_ATTRIBUTE_VALUE&&this._state!==AFTER_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_VALUE_SQ&&this._state!==IN_ATTRIBUTE_VALUE_DQ&&this._state!==IN_ATTRIBUTE_VALUE_NQ&&this._state!==IN_CLOSING_TAG_NAME){
  3146  this._cbs.ontext(data)}};Tokenizer.prototype.reset=function(){Tokenizer.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)};Tokenizer.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index};Tokenizer.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)};Tokenizer.prototype._emitToken=function(name){this._cbs[name](this._getSection());this._sectionStart=-1};Tokenizer.prototype._emitPartial=function(value){if(this._baseState!==TEXT){this._cbs.onattribdata(value)}else{this._cbs.ontext(value)}}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(require,module,exports){module.exports=Stream;var Parser=require("./Parser.js"),WritableStream=require("stream").Writable||require("readable-stream").Writable,StringDecoder=require("string_decoder").StringDecoder,Buffer=require("buffer").Buffer;function Stream(cbs,options){var parser=this._parser=new Parser(cbs,options);var decoder=this._decoder=new StringDecoder;WritableStream.call(this,{decodeStrings:false});this.once("finish",function(){parser.end(decoder.end())})}require("inherits")(Stream,WritableStream);WritableStream.prototype._write=function(chunk,encoding,cb){if(chunk instanceof Buffer)chunk=this._decoder.write(chunk);this._parser.write(chunk);cb()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(require,module,exports){var Parser=require("./Parser.js"),DomHandler=require("domhandler");function defineProp(name,value){delete module.exports[name];module.exports[name]=value;return value}module.exports={Parser:Parser,Tokenizer:require("./Tokenizer.js"),ElementType:require("domelementtype"),DomHandler:DomHandler,get FeedHandler(){return defineProp("FeedHandler",require("./FeedHandler.js"))},get Stream(){return defineProp("Stream",require("./Stream.js"))},get WritableStream(){return defineProp("WritableStream",require("./WritableStream.js"))},get ProxyHandler(){return defineProp("ProxyHandler",require("./ProxyHandler.js"))},get DomUtils(){return defineProp("DomUtils",require("domutils"))},get CollectingHandler(){return defineProp("CollectingHandler",require("./CollectingHandler.js"))},DefaultHandler:DomHandler,get RssHandler(){return defineProp("RssHandler",this.FeedHandler)},parseDOM:function(data,options){var handler=new DomHandler(options);new Parser(handler,options).end(data);return handler.dom},parseFeed:function(feed,options){var handler=new module.exports.FeedHandler(options);new Parser(handler,options).end(feed);return handler.dom},createDomStream:function(cb,options,elementCb){var handler=new DomHandler(cb,options,elementCb);return new Parser(handler,options)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(require,module,exports){exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},{}],38:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],39:[function(require,module,exports){module.exports=function(obj){return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer)};function isBuffer(obj){return!!obj.constructor&&typeof obj.constructor.isBuffer==="function"&&obj.constructor.isBuffer(obj)}function isSlowBuffer(obj){return typeof obj.readFloatLE==="function"&&typeof obj.slice==="function"&&isBuffer(obj.slice(0,0))}},{}],40:[function(require,module,exports){var toString={}.toString;module.exports=Array.isArray||function(arr){return toString.call(arr)=="[object Array]"}},{}],41:[function(require,module,exports){(function(process){"use strict";if(!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){module.exports=nextTick}else{module.exports=process.nextTick}function nextTick(fn,arg1,arg2,arg3){if(typeof fn!=="function"){throw new TypeError('"callback" argument must be a function')}var len=arguments.length;var args,i;switch(len){case 0:case 1:return process.nextTick(fn);case 2:return process.nextTick(function afterTickOne(){fn.call(null,arg1)});case 3:return process.nextTick(function afterTickTwo(){fn.call(null,arg1,arg2)});case 4:return process.nextTick(function afterTickThree(){fn.call(null,arg1,arg2,arg3)});default:args=new Array(len-1);i=0;while(i<args.length){args[i++]=arguments[i]}return process.nextTick(function afterTick(){fn.apply(null,args)})}}}).call(this,require("_process"))},{_process:42}],42:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],43:[function(require,module,exports){module.exports=require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(require,module,exports){"use strict";var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key)}return keys};module.exports=Duplex;var processNextTick=require("process-nextick-args");var util=require("core-util-is");util.inherits=require("inherits");var Readable=require("./_stream_readable");var Writable=require("./_stream_writable");util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v<keys.length;v++){var method=keys[v];if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method]}function Duplex(options){if(!(this instanceof Duplex))return new Duplex(options);Readable.call(this,options);Writable.call(this,options);if(options&&options.readable===false)this.readable=false;if(options&&options.writable===false)this.writable=false;this.allowHalfOpen=true;if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;this.once("end",onend)}function onend(){if(this.allowHalfOpen||this._writableState.ended)return;processNextTick(onEndNT,this)}function onEndNT(self){self.end()}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(require,module,exports){"use strict";module.exports=PassThrough;var Transform=require("./_stream_transform");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options)}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(require,module,exports){(function(process){"use strict";module.exports=Readable;var processNextTick=require("process-nextick-args");var isArray=require("isarray");Readable.ReadableState=ReadableState;var EE=require("events").EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");var util=require("core-util-is");util.inherits=require("inherits");var debugUtil=require("util");var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=require("./internal/streams/BufferList");var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}var Duplex;function ReadableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}var Duplex;function Readable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0)}Readable.prototype.setEncoding=function(enc){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this._readableState.decoder=new StringDecoder(enc);this._readableState.encoding=enc;return this};var MAX_HWM=8388608;function computeNewHighWaterMark(n){if(n>=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n<state.highWaterMark){doRead=true;debug("length less than watermark",doRead)}if(state.ended||state.reading){doRead=false;debug("reading or ended",doRead)}else if(doRead){debug("do read");state.reading=true;state.sync=true;if(state.length===0)state.needReadable=true;this._read(state.highWaterMark);state.sync=false;if(!state.reading)n=howMuchToRead(nOrig,state)}var ret;if(n>0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){debug("maybeReadMore read 0");stream.read(0);if(len===state.length)break;else len=state.length}state.readingMore=false}Readable.prototype._read=function(n){this.emit("error",new Error("not implemented"))};Readable.prototype.pipe=function(dest,pipeOpts){var src=this;var state=this._readableState;switch(state.pipesCount){case 0:state.pipes=dest;break;case 1:state.pipes=[state.pipes,dest];break;default:state.pipes.push(dest);break}state.pipesCount+=1;debug("pipe count=%d opts=%j",state.pipesCount,pipeOpts);var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;var endFn=doEnd?onend:cleanup;if(state.endEmitted)processNextTick(endFn);else src.once("end",endFn);dest.on("unpipe",onunpipe);function onunpipe(readable){debug("onunpipe");if(readable===src){cleanup()}}function onend(){debug("onend");dest.end()}var ondrain=pipeOnDrain(src);dest.on("drain",ondrain);var cleanedUp=false;function cleanup(){debug("cleanup");dest.removeListener("close",onclose);dest.removeListener("finish",onfinish);dest.removeListener("drain",ondrain);dest.removeListener("error",onerror);dest.removeListener("unpipe",onunpipe);src.removeListener("end",onend);src.removeListener("end",cleanup);src.removeListener("data",ondata);cleanedUp=true;if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain()}var increasedAwaitDrain=false;src.on("data",ondata);function ondata(chunk){debug("ondata");increasedAwaitDrain=false;var ret=dest.write(chunk);if(false===ret&&!increasedAwaitDrain){if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var _i=0;_i<len;_i++){dests[_i].emit("unpipe",this)}return this}var i=indexOf(state.pipes,dest);if(i===-1)return this;state.pipes.splice(i,1);state.pipesCount-=1;if(state.pipesCount===1)state.pipes=state.pipes[0];dest.emit("unpipe",this);return this};Readable.prototype.on=function(ev,fn){var res=Stream.prototype.on.call(this,ev,fn);if(ev==="data"){if(this._readableState.flowing!==false)this.resume()}else if(ev==="readable"){var state=this._readableState;if(!state.endEmitted&&!state.readableListening){state.readableListening=state.needReadable=true;state.emittedReadable=false;if(!state.reading){processNextTick(nReadingNextTick,this)}else if(state.length){emitReadable(this,state)}}}return res};Readable.prototype.addListener=Readable.prototype.on;function nReadingNextTick(self){debug("readable nexttick read 0");self.read(0)}Readable.prototype.resume=function(){var state=this._readableState;if(!state.flowing){debug("resume");state.flowing=true;resume(this,state)}return this};function resume(stream,state){if(!state.resumeScheduled){state.resumeScheduled=true;processNextTick(resume_,stream,state)}}function resume_(stream,state){if(!state.reading){debug("resume read 0");stream.read(0)}state.resumeScheduled=false;state.awaitDrain=0;stream.emit("resume");flow(stream);if(state.flowing&&!state.reading)stream.read(0)}Readable.prototype.pause=function(){debug("call pause flowing=%j",this._readableState.flowing);if(false!==this._readableState.flowing){debug("pause");this._readableState.flowing=false;this.emit("pause")}return this};function flow(stream){var state=stream._readableState;debug("flow",state.flowing);while(state.flowing&&stream.read()!==null){}}Readable.prototype.wrap=function(stream){var state=this._readableState;var paused=false;var self=this;stream.on("end",function(){debug("wrapped end");if(state.decoder&&!state.ended){var chunk=state.decoder.end();if(chunk&&chunk.length)self.push(chunk)}self.push(null)});stream.on("data",function(chunk){debug("wrapped data");if(state.decoder)chunk=state.decoder.write(chunk);if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;var ret=self.push(chunk);if(!ret){paused=true;stream.pause()}});for(var i in stream){if(this[i]===undefined&&typeof stream[i]==="function"){this[i]=function(method){return function(){return stream[method].apply(stream,arguments)}}(i)}}var events=["error","close","destroy","pause","resume"];forEach(events,function(ev){stream.on(ev,self.emit.bind(self,ev))});self._read=function(n){debug("wrapped _read",n);if(paused){paused=false;stream.resume()}};return self};Readable._fromList=fromList;function fromList(n,state){if(state.length===0)return null;var ret;if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(n<list.head.data.length){ret=list.head.data.slice(0,n);list.head.data=list.head.data.slice(n)}else if(n===list.head.data.length){ret=list.shift()}else{ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list)}return ret}function copyFromBufferString(n,list){var p=list.head;var c=1;var ret=p.data;n-=ret.length;while(p=p.next){var str=p.data;var nb=n>str.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i}return-1}}).call(this,require("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(require,module,exports){"use strict";module.exports=Transform;var Duplex=require("./_stream_duplex");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length<rs.highWaterMark){stream._read(rs.highWaterMark)}}function Transform(options){if(!(this instanceof Transform))return new Transform(options);Duplex.call(this,options);this._transformState=new TransformState(this);var stream=this;this._readableState.needReadable=true;this._readableState.sync=false;if(options){if(typeof options.transform==="function")this._transform=options.transform;if(typeof options.flush==="function")this._flush=options.flush}this.once("prefinish",function(){if(typeof this._flush==="function")this._flush(function(er){done(stream,er)});else done(stream)})}Transform.prototype.push=function(chunk,encoding){this._transformState.needTransform=false;return Duplex.prototype.push.call(this,chunk,encoding)};Transform.prototype._transform=function(chunk,encoding,cb){throw new Error("Not implemented")};Transform.prototype._write=function(chunk,encoding,cb){var ts=this._transformState;ts.writecb=cb;ts.writechunk=chunk;ts.writeencoding=encoding;if(!ts.transforming){var rs=this._readableState;if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark)}};Transform.prototype._read=function(n){var ts=this._transformState;if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){ts.transforming=true;this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform)}else{ts.needTransform=true}};function done(stream,er){if(er)return stream.emit("error",er);var ws=stream._writableState;var ts=stream._transformState;if(ws.length)throw new Error("Calling transform done when ws.length != 0");if(ts.transforming)throw new Error("Calling transform done when still transforming");return stream.push(null)}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(require,module,exports){(function(process){"use strict";module.exports=Writable;var processNextTick=require("process-nextick-args");var asyncWrite=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}var Duplex;function WritableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function writableStateGetBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.")})}catch(_){}})();var Duplex;function Writable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Writable)&&!(this instanceof Duplex))return new Writable(options);this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;if(typeof encoding==="function"){cb=encoding;encoding=null}if(Buffer.isBuffer(chunk))encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){
  3147  state.pendingcb++;ret=writeOrBuffer(this,state,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,chunk,encoding,cb){chunk=decodeChunk(state,chunk,encoding);if(Buffer.isBuffer(chunk))encoding="buffer";var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length<state.highWaterMark;if(!ret)state.needDrain=true;if(state.writing||state.corked){var last=state.lastBufferedRequest;state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);if(last){last.next=state.lastBufferedRequest}else{state.bufferedRequest=state.lastBufferedRequest}state.bufferedRequestCount+=1}else{doWrite(stream,state,false,len,chunk,encoding,cb)}return ret}function doWrite(stream,state,writev,len,chunk,encoding,cb){state.writelen=len;state.writecb=cb;state.writing=true;state.sync=true;if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);state.sync=false}function onwriteError(stream,state,sync,er,cb){--state.pendingcb;if(sync)processNextTick(cb,er);else cb(er);stream._writableState.errorEmitted=true;stream.emit("error",er)}function onwriteStateUpdate(state){state.writing=false;state.writecb=null;state.length-=state.writelen;state.writelen=0}function onwrite(stream,er){var state=stream._writableState;var sync=state.sync;var cb=state.writecb;onwriteStateUpdate(state);if(er)onwriteError(stream,state,sync,er,cb);else{var finished=needFinish(state);if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){clearBuffer(stream,state)}if(sync){asyncWrite(afterWrite,stream,state,finished,cb)}else{afterWrite(stream,state,finished,cb)}}}function afterWrite(stream,state,finished,cb){if(!finished)onwriteDrain(stream,state);state.pendingcb--;cb();finishMaybe(stream,state)}function onwriteDrain(stream,state){if(state.length===0&&state.needDrain){state.needDrain=false;stream.emit("drain")}}function clearBuffer(stream,state){state.bufferProcessing=true;var entry=state.bufferedRequest;if(stream._writev&&entry&&entry.next){var l=state.bufferedRequestCount;var buffer=new Array(l);var holder=state.corkedRequestsFree;holder.entry=entry;var count=0;while(entry){buffer[count]=entry;entry=entry.next;count+=1}doWrite(stream,state,true,state.length,buffer,"",holder.finish);state.pendingcb++;state.lastBufferedRequest=null;if(holder.next){state.corkedRequestsFree=holder.next;holder.next=null}else{state.corkedRequestsFree=new CorkedRequest(state)}}else{while(entry){var chunk=entry.chunk;var encoding=entry.encoding;var cb=entry.callback;var len=state.objectMode?1:chunk.length;doWrite(stream,state,false,len,chunk,encoding,cb);entry=entry.next;if(state.writing){break}}if(entry===null)state.lastBufferedRequest=null}state.bufferedRequestCount=0;state.bufferedRequest=entry;state.bufferProcessing=false}Writable.prototype._write=function(chunk,encoding,cb){cb(new Error("not implemented"))};Writable.prototype._writev=null;Writable.prototype.end=function(chunk,encoding,cb){var state=this._writableState;if(typeof chunk==="function"){cb=chunk;chunk=null;encoding=null}else if(typeof encoding==="function"){cb=encoding;encoding=null}if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);if(state.corked){state.corked=1;this.uncork()}if(!state.ending&&!state.finished)endWritable(this,state,cb)};function needFinish(state){return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing}function prefinish(stream,state){if(!state.prefinished){state.prefinished=true;stream.emit("prefinish")}}function finishMaybe(stream,state){var need=needFinish(state);if(need){if(state.pendingcb===0){prefinish(stream,state);state.finished=true;stream.emit("finish")}else{prefinish(stream,state)}}return need}function endWritable(stream,state,cb){state.ending=true;finishMaybe(stream,state);if(cb){if(state.finished)processNextTick(cb);else stream.once("finish",cb)}state.ended=true;stream.writable=false}function CorkedRequest(state){var _this=this;this.next=null;this.entry=null;this.finish=function(err){var entry=_this.entry;_this.entry=null;while(entry){var cb=entry.callback;state.pendingcb--;cb(err);entry=entry.next}if(state.corkedRequestsFree){state.corkedRequestsFree.next=_this}else{state.corkedRequestsFree=_this}}}}).call(this,require("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(require,module,exports){"use strict";var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");module.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},{buffer:5,"buffer-shims":4}],50:[function(require,module,exports){module.exports=require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(require,module,exports){(function(process){var Stream=function(){try{return require("st"+"ream")}catch(_){}}();exports=module.exports=require("./lib/_stream_readable.js");exports.Stream=Stream||exports;exports.Readable=exports;exports.Writable=require("./lib/_stream_writable.js");exports.Duplex=require("./lib/_stream_duplex.js");exports.Transform=require("./lib/_stream_transform.js");exports.PassThrough=require("./lib/_stream_passthrough.js");if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module.exports=Stream}}).call(this,require("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(require,module,exports){module.exports=require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(require,module,exports){module.exports=require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(require,module,exports){module.exports=function(string){return string.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(require,module,exports){module.exports=Stream;var EE=require("events").EventEmitter;var inherits=require("inherits");inherits(Stream,EE);Stream.Readable=require("readable-stream/readable.js");Stream.Writable=require("readable-stream/writable.js");Stream.Duplex=require("readable-stream/duplex.js");Stream.Transform=require("readable-stream/transform.js");Stream.PassThrough=require("readable-stream/passthrough.js");Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(require,module,exports){var Buffer=require("buffer").Buffer;var isBufferEncoding=Buffer.isEncoding||function(encoding){switch(encoding&&encoding.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function assertEncoding(encoding){if(encoding&&!isBufferEncoding(encoding)){throw new Error("Unknown encoding: "+encoding)}}var StringDecoder=exports.StringDecoder=function(encoding){this.encoding=(encoding||"utf8").toLowerCase().replace(/[-_]/,"");assertEncoding(encoding);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=utf16DetectIncompleteChar;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=base64DetectIncompleteChar;break;default:this.write=passThroughWrite;return}this.charBuffer=new Buffer(6);this.charReceived=0;this.charLength=0};StringDecoder.prototype.write=function(buffer){var charStr="";while(this.charLength){var available=buffer.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived<this.charLength){return""}buffer=buffer.slice(available,buffer.length);charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var charCode=charStr.charCodeAt(charStr.length-1);if(charCode>=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},{buffer:5}],57:[function(require,module,exports){(function(global){module.exports=deprecate;function deprecate(fn,msg){if(config("noDeprecation")){return fn}var warned=false;function deprecated(){if(!warned){if(config("throwDeprecation")){throw new Error(msg)}else if(config("traceDeprecation")){console.trace(msg)}else{console.warn(msg)}warned=true}return fn.apply(this,arguments)}return deprecated}function config(name){try{if(!global.localStorage)return false}catch(_){return false}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==="true"}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],58:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target}},{}]},{},[1])(1)});
  3148  
  3149  /**
  3150   * swagger-client - swagger-client is a javascript client for use with swaggering APIs.
  3151   * @version v2.1.25
  3152   * @link http://swagger.io
  3153   * @license Apache-2.0
  3154   */
  3155  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SwaggerClient = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  3156  'use strict';
  3157  
  3158  var auth = require('./lib/auth');
  3159  var helpers = require('./lib/helpers');
  3160  var SwaggerClient = require('./lib/client');
  3161  var deprecationWrapper = function (url, options) {
  3162    helpers.log('This is deprecated, use "new SwaggerClient" instead.');
  3163  
  3164    return new SwaggerClient(url, options);
  3165  };
  3166  
  3167  /* Here for IE8 Support */
  3168  if (!Array.prototype.indexOf) {
  3169    Array.prototype.indexOf = function(obj, start) {
  3170      for (var i = (start || 0), j = this.length; i < j; i++) {
  3171        if (this[i] === obj) { return i; }
  3172      }
  3173      return -1;
  3174    };
  3175  }
  3176  
  3177  /* Here for IE8 Support */
  3178  if (!String.prototype.trim) {
  3179    String.prototype.trim = function () {
  3180      return this.replace(/^\s+|\s+$/g, '');
  3181    };
  3182  }
  3183  
  3184  /* Here for node 10.x support */
  3185  if (!String.prototype.endsWith) {
  3186    String.prototype.endsWith = function(suffix) {
  3187      return this.indexOf(suffix, this.length - suffix.length) !== -1;
  3188    };
  3189  }
  3190  
  3191  module.exports = SwaggerClient;
  3192  
  3193  SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization;
  3194  SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization;
  3195  SwaggerClient.CookieAuthorization = auth.CookieAuthorization;
  3196  SwaggerClient.SwaggerApi = deprecationWrapper;
  3197  SwaggerClient.SwaggerClient = deprecationWrapper;
  3198  SwaggerClient.SchemaMarkup = require('./lib/schema-markup');
  3199  
  3200  },{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){
  3201  'use strict';
  3202  
  3203  var helpers = require('./helpers');
  3204  var btoa = require('btoa'); // jshint ignore:line
  3205  var CookieJar = require('cookiejar').CookieJar;
  3206  var _ = {
  3207    each: require('lodash-compat/collection/each'),
  3208    includes: require('lodash-compat/collection/includes'),
  3209    isObject: require('lodash-compat/lang/isObject'),
  3210    isArray: require('lodash-compat/lang/isArray')
  3211  };
  3212  
  3213  /**
  3214   * SwaggerAuthorizations applies the correct authorization to an operation being executed
  3215   */
  3216  var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) {
  3217    this.authz = authz || {};
  3218  };
  3219  
  3220  /**
  3221   * Add auths to the hash
  3222   * Will overwrite any existing
  3223   *
  3224   */
  3225  SwaggerAuthorizations.prototype.add = function (name, auth) {
  3226    if(_.isObject(name)) {
  3227      for (var key in name) {
  3228        this.authz[key] = name[key];
  3229      }
  3230    } else if(typeof name === 'string' ){
  3231      this.authz[name] = auth;
  3232    }
  3233  
  3234    return auth;
  3235  };
  3236  
  3237  SwaggerAuthorizations.prototype.remove = function (name) {
  3238    return delete this.authz[name];
  3239  };
  3240  
  3241  SwaggerAuthorizations.prototype.apply = function (obj, securities) {
  3242    var status = true;
  3243    var applyAll = !securities;
  3244    var flattenedSecurities = [];
  3245  
  3246    // favor the object-level authorizations over global
  3247    var authz = obj.clientAuthorizations || this.authz;
  3248  
  3249    // Securities could be [ {} ]
  3250    _.each(securities, function (obj, key) {
  3251  
  3252      // Make sure we account for securities being [ str ]
  3253      if(typeof key === 'string') {
  3254        flattenedSecurities.push(key);
  3255      }
  3256  
  3257      // Flatten keys in to our array
  3258      _.each(obj, function (val, key) {
  3259        flattenedSecurities.push(key);
  3260      });
  3261    });
  3262  
  3263    _.each(authz, function (auth, authName) {
  3264      if(applyAll || _.includes(flattenedSecurities, authName)) {
  3265        var newStatus = auth.apply(obj);
  3266        status = status && !!newStatus; // logical ORs regarding status
  3267      }
  3268    });
  3269  
  3270    return status;
  3271  };
  3272  
  3273  /**
  3274   * ApiKeyAuthorization allows a query param or header to be injected
  3275   */
  3276  var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) {
  3277    this.name = name;
  3278    this.value = value;
  3279    this.type = type;
  3280  };
  3281  
  3282  ApiKeyAuthorization.prototype.apply = function (obj) {
  3283    if (this.type === 'query') {
  3284      // see if already applied.  If so, don't do it again
  3285  
  3286      var qp;
  3287      if (obj.url.indexOf('?') > 0) {
  3288        qp = obj.url.substring(obj.url.indexOf('?') + 1);
  3289        var parts = qp.split('&');
  3290        if(parts && parts.length > 0) {
  3291          for(var i = 0; i < parts.length; i++) {
  3292            var kv = parts[i].split('=');
  3293            if(kv && kv.length > 0) {
  3294              if (kv[0] === this.name) {
  3295                // skip it
  3296                return false;
  3297              }
  3298            }
  3299          }
  3300        }
  3301      }
  3302  
  3303      if (obj.url.indexOf('?') > 0) {
  3304        obj.url = obj.url + '&' + this.name + '=' + this.value;
  3305      } else {
  3306        obj.url = obj.url + '?' + this.name + '=' + this.value;
  3307      }
  3308  
  3309      return true;
  3310    } else if (this.type === 'header') {
  3311      if(typeof obj.headers[this.name] === 'undefined') {
  3312        obj.headers[this.name] = this.value;
  3313      }
  3314  
  3315      return true;
  3316    }
  3317  };
  3318  
  3319  var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) {
  3320    this.cookie = cookie;
  3321  };
  3322  
  3323  CookieAuthorization.prototype.apply = function (obj) {
  3324    obj.cookieJar = obj.cookieJar || new CookieJar();
  3325    obj.cookieJar.setCookie(this.cookie);
  3326  
  3327    return true;
  3328  };
  3329  
  3330  /**
  3331   * Password Authorization is a basic auth implementation
  3332   */
  3333  var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) {
  3334    if (arguments.length === 3) {
  3335      helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password');
  3336      username = arguments[1];
  3337      password = arguments[2];
  3338    }
  3339    this.username = username;
  3340    this.password = password;
  3341  };
  3342  
  3343  PasswordAuthorization.prototype.apply = function (obj) {
  3344    if(typeof obj.headers.Authorization === 'undefined') {
  3345      obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password);
  3346    }
  3347  
  3348    return true;
  3349  };
  3350  
  3351  },{"./helpers":4,"btoa":13,"cookiejar":18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(require,module,exports){
  3352  'use strict';
  3353  
  3354  var _ = {
  3355    bind: require('lodash-compat/function/bind'),
  3356    cloneDeep: require('lodash-compat/lang/cloneDeep'),
  3357    find: require('lodash-compat/collection/find'),
  3358    forEach: require('lodash-compat/collection/forEach'),
  3359    indexOf: require('lodash-compat/array/indexOf'),
  3360    isArray: require('lodash-compat/lang/isArray'),
  3361    isObject: require('lodash-compat/lang/isObject'),
  3362    isFunction: require('lodash-compat/lang/isFunction'),
  3363    isPlainObject: require('lodash-compat/lang/isPlainObject'),
  3364    isUndefined: require('lodash-compat/lang/isUndefined')
  3365  };
  3366  var auth = require('./auth');
  3367  var helpers = require('./helpers');
  3368  var Model = require('./types/model');
  3369  var Operation = require('./types/operation');
  3370  var OperationGroup = require('./types/operationGroup');
  3371  var Resolver = require('./resolver');
  3372  var SwaggerHttp = require('./http');
  3373  var SwaggerSpecConverter = require('./spec-converter');
  3374  var Q = require('q');
  3375  
  3376  // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
  3377  // following usage: 'client.{tagName}'
  3378  var reservedClientTags = [
  3379    'apis',
  3380    'authorizationScheme',
  3381    'authorizations',
  3382    'basePath',
  3383    'build',
  3384    'buildFrom1_1Spec',
  3385    'buildFrom1_2Spec',
  3386    'buildFromSpec',
  3387    'clientAuthorizations',
  3388    'convertInfo',
  3389    'debug',
  3390    'defaultErrorCallback',
  3391    'defaultSuccessCallback',
  3392    'enableCookies',
  3393    'fail',
  3394    'failure',
  3395    'finish',
  3396    'help',
  3397    'host',
  3398    'idFromOp',
  3399    'info',
  3400    'initialize',
  3401    'isBuilt',
  3402    'isValid',
  3403    'modelPropertyMacro',
  3404    'models',
  3405    'modelsArray',
  3406    'options',
  3407    'parameterMacro',
  3408    'parseUri',
  3409    'progress',
  3410    'resourceCount',
  3411    'sampleModels',
  3412    'selfReflect',
  3413    'setConsolidatedModels',
  3414    'spec',
  3415    'supportedSubmitMethods',
  3416    'swaggerRequestHeaders',
  3417    'tagFromLabel',
  3418    'title',
  3419    'url',
  3420    'useJQuery',
  3421    'jqueryAjaxCache'
  3422  ];
  3423  // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
  3424  // following usage: 'client.apis.{tagName}'
  3425  var reservedApiTags = [
  3426    'apis',
  3427    'asCurl',
  3428    'description',
  3429    'externalDocs',
  3430    'help',
  3431    'label',
  3432    'name',
  3433    'operation',
  3434    'operations',
  3435    'operationsArray',
  3436    'path',
  3437    'tag'
  3438  ];
  3439  var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];
  3440  var SwaggerClient = module.exports = function (url, options) {
  3441    this.authorizations = null;
  3442    this.authorizationScheme = null;
  3443    this.basePath = null;
  3444    this.debug = false;
  3445    this.enableCookies = false;
  3446    this.info = null;
  3447    this.isBuilt = false;
  3448    this.isValid = false;
  3449    this.modelsArray = [];
  3450    this.resourceCount = 0;
  3451    this.url = null;
  3452    this.useJQuery = false;
  3453    this.jqueryAjaxCache = false;
  3454    this.swaggerObject = {};
  3455    this.deferredClient = undefined;
  3456  
  3457    this.clientAuthorizations = new auth.SwaggerAuthorizations();
  3458  
  3459    if (typeof url !== 'undefined') {
  3460      return this.initialize(url, options);
  3461    } else {
  3462      return this;
  3463    }
  3464  };
  3465  
  3466  SwaggerClient.prototype.initialize = function (url, options) {
  3467    this.models = {};
  3468    this.sampleModels = {};
  3469  
  3470    if (typeof url === 'string') {
  3471      this.url = url;
  3472    } else if (_.isObject(url)) {
  3473      options = url;
  3474      this.url = options.url;
  3475    }
  3476  
  3477    if(this.url && this.url.indexOf('http:') === -1 && this.url.indexOf('https:') === -1) {
  3478      // no protocol, so we can only use window if it exists
  3479      if(typeof(window) !== 'undefined' && window && window.location) {
  3480        this.url = window.location.origin + this.url;
  3481      }
  3482    }
  3483  
  3484    options = options || {};
  3485    this.clientAuthorizations.add(options.authorizations);
  3486    this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*';
  3487    this.defaultSuccessCallback = options.defaultSuccessCallback || null;
  3488    this.defaultErrorCallback = options.defaultErrorCallback || null;
  3489    this.modelPropertyMacro = options.modelPropertyMacro || null;
  3490    this.connectionAgent = options.connectionAgent || null;
  3491    this.parameterMacro = options.parameterMacro || null;
  3492    this.usePromise = options.usePromise || null;
  3493  
  3494    // operation request timeout default
  3495    this.timeout = options.timeout || null;
  3496    // default to request timeout when not specified
  3497    this.fetchSpecTimeout = typeof options.fetchSpecTimeout !== 'undefined' ?
  3498        options.fetchSpecTimeout : options.timeout || null;
  3499  
  3500    if(this.usePromise) {
  3501      this.deferredClient = Q.defer();
  3502    }
  3503  
  3504    if (typeof options.success === 'function') {
  3505      this.success = options.success;
  3506    }
  3507    if (options.useJQuery) {
  3508      this.useJQuery = options.useJQuery;
  3509    }
  3510  
  3511    if (options.jqueryAjaxCache) {
  3512      this.jqueryAjaxCache = options.jqueryAjaxCache;
  3513    }
  3514  
  3515    if (options.enableCookies) {
  3516      this.enableCookies = options.enableCookies;
  3517    }
  3518  
  3519    this.options = options || {};
  3520  
  3521    // maybe don't need this?
  3522    this.options.timeout = this.timeout;
  3523    this.options.fetchSpecTimeout = this.fetchSpecTimeout;
  3524  
  3525    this.supportedSubmitMethods = options.supportedSubmitMethods || [];
  3526    this.failure = options.failure || function (err) { throw err; };
  3527    this.progress = options.progress || function () {};
  3528    this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document
  3529  
  3530    if (options.scheme) {
  3531      this.scheme = options.scheme;
  3532    }
  3533  
  3534    if (this.usePromise || typeof options.success === 'function') {
  3535      this.ready = true;
  3536      return this.build();
  3537    }
  3538  };
  3539  
  3540  SwaggerClient.prototype.build = function (mock) {
  3541    if (this.isBuilt) {
  3542      return this;
  3543    }
  3544  
  3545    var self = this;
  3546  
  3547    if (this.spec) {
  3548      this.progress('fetching resource list; Please wait.');
  3549    } else {
  3550      this.progress('fetching resource list: ' + this.url + '; Please wait.');
  3551    }
  3552  
  3553    var obj = {
  3554      useJQuery: this.useJQuery,
  3555      jqueryAjaxCache: this.jqueryAjaxCache,
  3556      connectionAgent: this.connectionAgent,
  3557      enableCookies: this.enableCookies,
  3558      url: this.url,
  3559      method: 'get',
  3560      headers: {
  3561        accept: this.swaggerRequestHeaders
  3562      },
  3563      on: {
  3564        error: function (response) {
  3565          if (self.url.substring(0, 4) !== 'http') {
  3566            return self.fail('Please specify the protocol for ' + self.url);
  3567          } else if (response.errObj && (response.errObj.code === 'ECONNABORTED' || response.errObj.message.indexOf('timeout') !== -1)) {
  3568            return self.fail('Request timed out after ' + self.fetchSpecTimeout + 'ms');
  3569          } else if (response.status === 0) {
  3570            return self.fail('Can\'t read from server.  It may not have the appropriate access-control-origin settings.');
  3571          } else if (response.status === 404) {
  3572            return self.fail('Can\'t read swagger JSON from ' + self.url);
  3573          } else {
  3574            return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);
  3575          }
  3576        },
  3577        response: function (resp) {
  3578  
  3579          var responseObj = resp.obj;
  3580          if(!responseObj) {
  3581            return self.fail('failed to parse JSON/YAML response');
  3582          }
  3583  
  3584          self.swaggerVersion = responseObj.swaggerVersion;
  3585          self.swaggerObject = responseObj;
  3586  
  3587          if (responseObj.swagger && parseInt(responseObj.swagger) === 2) {
  3588            self.swaggerVersion = responseObj.swagger;
  3589  
  3590            new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self);
  3591  
  3592            self.isValid = true;
  3593          } else {
  3594            var converter = new SwaggerSpecConverter();
  3595            self.oldSwaggerObject = self.swaggerObject;
  3596  
  3597            converter.setDocumentationLocation(self.url);
  3598            converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) {
  3599              self.swaggerObject = spec;
  3600              new Resolver().resolve(spec, self.url, self.buildFromSpec, self);
  3601              self.isValid = true;
  3602            });
  3603          }
  3604        }
  3605      }
  3606    };
  3607  
  3608    // only set timeout when specified
  3609    if (this.fetchSpecTimeout) {
  3610      obj.timeout = this.fetchSpecTimeout;
  3611    }
  3612  
  3613    if (this.spec) {
  3614      self.swaggerObject = this.spec;
  3615      setTimeout(function () {
  3616        new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self);
  3617      }, 10);
  3618    } else {
  3619      this.clientAuthorizations.apply(obj);
  3620  
  3621      if (mock) {
  3622        return obj;
  3623      }
  3624  
  3625      new SwaggerHttp().execute(obj, this.options);
  3626    }
  3627  
  3628    return (this.usePromise) ? this.deferredClient.promise : this;
  3629  };
  3630  
  3631  SwaggerClient.prototype.buildFromSpec = function (response) {
  3632    if (this.isBuilt) {
  3633      return this;
  3634    }
  3635  
  3636    this.apis = {};
  3637    this.apisArray = [];
  3638    this.basePath = response.basePath || '';
  3639    this.consumes = response.consumes;
  3640    this.host = response.host || '';
  3641    this.info = response.info || {};
  3642    this.produces = response.produces;
  3643    this.schemes = response.schemes || [];
  3644    this.securityDefinitions = _.cloneDeep(response.securityDefinitions);
  3645    this.security = response.security;
  3646    this.title = response.title || '';
  3647  
  3648    var key, definedTags = {}, k, location, self = this, i;
  3649  
  3650    if (response.externalDocs) {
  3651      this.externalDocs = response.externalDocs;
  3652    }
  3653  
  3654    // legacy support
  3655    this.authSchemes = this.securityDefinitions;
  3656  
  3657    if(this.securityDefinitions) {
  3658      for(key in this.securityDefinitions) {
  3659        var securityDefinition = this.securityDefinitions[key];
  3660        securityDefinition.vendorExtensions = {};
  3661        for(var ext in securityDefinition) {
  3662          helpers.extractExtensions(ext, securityDefinition);
  3663          if (ext === 'scopes') {
  3664            var scopes = securityDefinition[ext];
  3665            if(typeof scopes === 'object') {
  3666              scopes.vendorExtensions = {};
  3667              for (var s in scopes) {
  3668                helpers.extractExtensions(s, scopes);
  3669                if(s.indexOf('x-') === 0) {
  3670                  delete scopes[s];
  3671                }
  3672              }
  3673            }
  3674          }
  3675        }
  3676      }
  3677    }
  3678  
  3679    if (Array.isArray(response.tags)) {
  3680      definedTags = {};
  3681  
  3682      for (k = 0; k < response.tags.length; k++) {
  3683        var t = _.cloneDeep(response.tags[k]);
  3684        definedTags[t.name] = t;
  3685        for(i in t) {
  3686          if(i === 'externalDocs' && typeof t[i] === 'object') {
  3687            for(var j in t[i]) {
  3688              helpers.extractExtensions(j, t[i]);
  3689            }
  3690          }
  3691          helpers.extractExtensions(i, t);
  3692        }
  3693      }
  3694    }
  3695  
  3696  
  3697    if (typeof this.url === 'string') {
  3698      location = this.parseUri(this.url);
  3699      if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {
  3700        if(typeof window !== 'undefined') {
  3701          // use the window scheme
  3702          this.scheme = window.location.protocol.replace(':','');
  3703        }
  3704        else {
  3705          this.scheme = location.scheme || 'http';
  3706        }
  3707      } else if (typeof this.scheme === 'undefined') {
  3708        if(typeof window !== 'undefined') {
  3709          var scheme = window.location.protocol.replace(':','');
  3710          if(scheme === 'https' && this.schemes.indexOf(scheme) === -1) {
  3711            // can't call http from https served page in a browser!
  3712            helpers.log('Cannot call a http server from https inside a browser!');
  3713            this.scheme = 'http';
  3714          }
  3715          else if(this.schemes.indexOf(scheme) !== -1) {
  3716            this.scheme = scheme;
  3717          }
  3718          else {
  3719            if(this.schemes.indexOf('https') !== -1) {
  3720              this.scheme = 'https';
  3721            }
  3722            else {
  3723              this.scheme = 'http';
  3724            }
  3725          }
  3726        }
  3727        else {
  3728          this.scheme = this.schemes[0] || location.scheme;
  3729        }
  3730      }
  3731  
  3732      if (typeof this.host === 'undefined' || this.host === '') {
  3733        this.host = location.host;
  3734  
  3735        if (location.port) {
  3736          this.host = this.host + ':' + location.port;
  3737        }
  3738      }
  3739    }
  3740    else {
  3741      if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
  3742        this.scheme = 'http';
  3743      }
  3744      else if (typeof this.scheme === 'undefined') {
  3745        this.scheme = this.schemes[0];
  3746      }
  3747    }
  3748  
  3749    this.definitions = response.definitions;
  3750  
  3751    for (key in this.definitions) {
  3752      var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro);
  3753  
  3754      if (model) {
  3755        this.models[key] = model;
  3756      }
  3757    }
  3758  
  3759    // get paths, create functions for each operationId
  3760    
  3761    // Bind help to 'client.apis'
  3762    self.apis.help = _.bind(self.help, self);
  3763  
  3764    _.forEach(response.paths, function (pathObj, path) {
  3765      // Only process a path if it's an object
  3766      if (!_.isPlainObject(pathObj)) {
  3767        return;
  3768      }
  3769  
  3770      _.forEach(supportedOperationMethods, function (method) {
  3771        var operation = pathObj[method];
  3772  
  3773        if (_.isUndefined(operation)) {
  3774          // Operation does not exist
  3775          return;
  3776        } else if (!_.isPlainObject(operation)) {
  3777          // Operation exists but it is not an Operation Object.  Since this is invalid, log it.
  3778          helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object');
  3779  
  3780          return;
  3781        }
  3782  
  3783        var tags = operation.tags;
  3784  
  3785        if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) {
  3786          tags = operation.tags = [ 'default' ];
  3787        }
  3788  
  3789        var operationId = self.idFromOp(path, method, operation);
  3790  
  3791        var operationObject = new Operation(self,
  3792          operation.scheme,
  3793          operationId,
  3794          method,
  3795          path,
  3796          operation,
  3797          self.definitions,
  3798          self.models,
  3799          self.clientAuthorizations);
  3800  
  3801        operationObject.vendorExtensions = {};
  3802        for(i in operation) {
  3803          helpers.extractExtensions(i, operationObject, operation[i]);
  3804        }
  3805        operationObject.externalDocs = operation.externalDocs;
  3806        if(operationObject.externalDocs) {
  3807          operationObject.externalDocs = _.cloneDeep(operationObject.externalDocs);
  3808          operationObject.externalDocs.vendorExtensions = {};
  3809          for(i in operationObject.externalDocs) {
  3810            helpers.extractExtensions(i, operationObject.externalDocs);
  3811          }
  3812        }
  3813  
  3814        // bind self operation's execute command to the api
  3815        _.forEach(tags, function (tag) {
  3816          var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag;
  3817          var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag;
  3818          var operationGroup = self[clientProperty];
  3819  
  3820          if (clientProperty !== tag) {
  3821            helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name.  Use \'client.' +
  3822                        clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.');
  3823          }
  3824  
  3825          if (apiProperty !== tag) {
  3826            helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name.  Use ' +
  3827                        '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.');
  3828          }
  3829  
  3830          if (_.indexOf(reservedApiTags, operationId) > -1) {
  3831            helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' +
  3832                        'function/property name.  Use \'client.apis.' + apiProperty + '._' + operationId +
  3833                        '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.');
  3834  
  3835            operationId = '_' + operationId;
  3836            operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly
  3837          }
  3838  
  3839          if (_.isUndefined(operationGroup)) {
  3840            operationGroup = self[clientProperty] = self.apis[apiProperty] = {};
  3841  
  3842            operationGroup.operations = {};
  3843            operationGroup.label = apiProperty;
  3844            operationGroup.apis = {};
  3845  
  3846            var tagDef = definedTags[tag];
  3847  
  3848            if (!_.isUndefined(tagDef)) {
  3849              operationGroup.description = tagDef.description;
  3850              operationGroup.externalDocs = tagDef.externalDocs;
  3851              operationGroup.vendorExtensions = tagDef.vendorExtensions;
  3852            }
  3853  
  3854            self[clientProperty].help = _.bind(self.help, operationGroup);
  3855            self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));
  3856          }
  3857  
  3858          operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]);
  3859  
  3860          // Bind tag help
  3861          if (!_.isFunction(operationGroup.help)) {
  3862            operationGroup.help = _.bind(self.help, operationGroup);
  3863          }
  3864  
  3865          // bind to the apis object
  3866          self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute,
  3867                                                                                    operationObject);
  3868          self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help,
  3869                                                                                               operationObject);
  3870          self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl,
  3871                                                                                                   operationObject);
  3872  
  3873          operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject;
  3874  
  3875          // legacy UI feature
  3876          var api = _.find(self.apisArray, function (api) {
  3877            return api.tag === tag;
  3878          });
  3879  
  3880          if (api) {
  3881            api.operationsArray.push(operationObject);
  3882          }
  3883        });
  3884      });
  3885    });
  3886  
  3887    // sort the apisArray according to the tags
  3888    var sortedApis = [];
  3889    _.forEach(Object.keys(definedTags), function (tag) {
  3890      var pos;
  3891      for(pos in self.apisArray) {
  3892        var _api = self.apisArray[pos];
  3893        if(_api && tag === _api.name) {
  3894          sortedApis.push(_api);
  3895          self.apisArray[pos] = null;
  3896        }
  3897      }
  3898    });
  3899    // add anything left
  3900    _.forEach(self.apisArray, function (api) {
  3901      if(api) {
  3902        sortedApis.push(api);
  3903      }
  3904    });
  3905    self.apisArray = sortedApis;
  3906  
  3907    _.forEach(response.definitions, function (definitionObj, definition) {
  3908      definitionObj.id = definition.toLowerCase();
  3909      definitionObj.name = definition;
  3910      self.modelsArray.push(definitionObj);
  3911    });
  3912  
  3913    this.isBuilt = true;
  3914  
  3915    if (this.usePromise) {
  3916      this.isValid = true;
  3917      this.isBuilt = true;
  3918      this.deferredClient.resolve(this);
  3919  
  3920      return this.deferredClient.promise;
  3921    }
  3922  
  3923    if (this.success) {
  3924      this.success();
  3925    }
  3926  
  3927    return this;
  3928  };
  3929  
  3930  SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) {
  3931    var count = 0;
  3932    var name = operationId;
  3933  
  3934    // make unique across this operation group
  3935    while(true) {
  3936      var matched = false;
  3937      _.forEach(api.operations, function (operation) {
  3938        if(operation.nickname === name) {
  3939          matched = true;
  3940        }
  3941      });
  3942      if(!matched) {
  3943        return name;
  3944      }
  3945      name = operationId + '_' + count;
  3946      count ++;
  3947    }
  3948  
  3949    return operationId;
  3950  };
  3951  
  3952  SwaggerClient.prototype.parseUri = function (uri) {
  3953    var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;
  3954    var parts = urlParseRE.exec(uri);
  3955  
  3956    return {
  3957      scheme: parts[4] ? parts[4].replace(':','') : undefined,
  3958      host: parts[11],
  3959      port: parts[12],
  3960      path: parts[15]
  3961    };
  3962  };
  3963  
  3964  SwaggerClient.prototype.help = function (dontPrint) {
  3965    var output = '';
  3966  
  3967    if (this instanceof SwaggerClient) {
  3968      _.forEach(this.apis, function (api, name) {
  3969        if (_.isPlainObject(api)) {
  3970          output += 'operations for the \'' + name + '\' tag\n';
  3971  
  3972          _.forEach(api.operations, function (operation, name) {
  3973            output += '  * ' + name + ': ' + operation.summary + '\n';
  3974          });
  3975        }
  3976      });
  3977    } else if (this instanceof OperationGroup || _.isPlainObject(this)) {
  3978      output += 'operations for the \'' + this.label + '\' tag\n';
  3979  
  3980      _.forEach(this.apis, function (operation, name) {
  3981        output += '  * ' + name + ': ' + operation.summary + '\n';
  3982      });
  3983    }
  3984  
  3985    if (dontPrint) {
  3986      return output;
  3987    } else {
  3988      helpers.log(output);
  3989  
  3990      return output;
  3991    }
  3992  };
  3993  
  3994  SwaggerClient.prototype.tagFromLabel = function (label) {
  3995    return label;
  3996  };
  3997  
  3998  SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) {
  3999    if(!op || !op.operationId) {
  4000      op = op || {};
  4001      op.operationId = httpMethod + '_' + path;
  4002    }
  4003    var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod);
  4004  
  4005    opId = opId.replace(/((_){2,})/g, '_');
  4006    opId = opId.replace(/^(_)*/g, '');
  4007    opId = opId.replace(/([_])*$/g, '');
  4008  
  4009    return opId;
  4010  };
  4011  
  4012  SwaggerClient.prototype.setHost = function (host) {
  4013    this.host = host;
  4014  
  4015    if(this.apis) {
  4016      _.forEach(this.apis, function(api) {
  4017        if(api.operations) {
  4018          _.forEach(api.operations, function(operation) {
  4019            operation.host = host;
  4020          });
  4021        }
  4022      });
  4023    }
  4024  };
  4025  
  4026  SwaggerClient.prototype.setBasePath = function (basePath) {
  4027    this.basePath = basePath;
  4028  
  4029    if(this.apis) {
  4030      _.forEach(this.apis, function(api) {
  4031        if(api.operations) {
  4032          _.forEach(api.operations, function(operation) {
  4033            operation.basePath = basePath;
  4034          });
  4035        }
  4036      });
  4037    }
  4038  };
  4039  
  4040  SwaggerClient.prototype.setSchemes = function (schemes) {
  4041    this.schemes = schemes;
  4042  
  4043    if(schemes && schemes.length > 0) {
  4044      if(this.apis) {
  4045        _.forEach(this.apis, function (api) {
  4046          if (api.operations) {
  4047            _.forEach(api.operations, function (operation) {
  4048              operation.scheme = schemes[0];
  4049            });
  4050          }
  4051        });
  4052      }
  4053    }
  4054  };
  4055  
  4056  SwaggerClient.prototype.fail = function (message) {
  4057    if (this.usePromise) {
  4058      this.deferredClient.reject(message);
  4059      return this.deferredClient.promise;
  4060    } else {
  4061      if (this.failure) {
  4062        this.failure(message);
  4063      }
  4064      else {
  4065        this.failure(message);
  4066      }
  4067    }
  4068  };
  4069  
  4070  },{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"q":157}],4:[function(require,module,exports){
  4071  (function (process){
  4072  'use strict';
  4073  
  4074  var _ = {
  4075    isPlainObject: require('lodash-compat/lang/isPlainObject'),
  4076    indexOf: require('lodash-compat/array/indexOf')
  4077  };
  4078  
  4079  module.exports.__bind = function (fn, me) {
  4080    return function(){
  4081      return fn.apply(me, arguments);
  4082    };
  4083  };
  4084  
  4085  var log = module.exports.log = function() {
  4086    // Only log if available and we're not testing
  4087    if (console && process.env.NODE_ENV !== 'test') {
  4088      console.log(Array.prototype.slice.call(arguments)[0]);
  4089    }
  4090  };
  4091  
  4092  module.exports.fail = function (message) {
  4093    log(message);
  4094  };
  4095  
  4096  module.exports.optionHtml = function (label, value) {
  4097    return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
  4098  };
  4099  
  4100  var resolveSchema = module.exports.resolveSchema = function (schema) {
  4101    if (_.isPlainObject(schema.schema)) {
  4102      schema = resolveSchema(schema.schema);
  4103    }
  4104  
  4105    return schema;
  4106  };
  4107  
  4108  module.exports.simpleRef = function (name) {
  4109    if (typeof name === 'undefined') {
  4110      return null;
  4111    }
  4112  
  4113    if (name.indexOf('#/definitions/') === 0) {
  4114      return name.substring('#/definitions/'.length);
  4115    } else {
  4116      return name;
  4117    }
  4118  };
  4119  
  4120  /**
  4121   * helper to remove extensions and add them to an object
  4122   *
  4123   * @param keyname
  4124   * @param obj
  4125   */
  4126  module.exports.extractExtensions = function (keyname, obj, value) {
  4127    if(!keyname || !obj) {
  4128      return;
  4129    }
  4130  
  4131    if (typeof keyname === 'string' && keyname.indexOf('x-') === 0) {
  4132      obj.vendorExtensions = obj.vendorExtensions || {};
  4133      if(value) {
  4134        obj.vendorExtensions[keyname] = value;
  4135      }
  4136      else {
  4137        obj.vendorExtensions[keyname] = obj[keyname];
  4138      }
  4139    }
  4140  };
  4141  }).call(this,require('_process'))
  4142  
  4143  },{"_process":12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(require,module,exports){
  4144  (function (Buffer){
  4145  'use strict';
  4146  
  4147  var helpers = require('./helpers');
  4148  var request = require('superagent');
  4149  var jsyaml = require('js-yaml');
  4150  var _ = {
  4151    isObject: require('lodash-compat/lang/isObject'),
  4152    keys: require('lodash-compat/object/keys')
  4153  };
  4154  
  4155  /*
  4156   * JQueryHttpClient is a light-weight, node or browser HTTP client
  4157   */
  4158  var JQueryHttpClient = function () {
  4159    this.type = 'JQueryHttpClient';
  4160  };
  4161  
  4162  /*
  4163   * SuperagentHttpClient is a light-weight, node or browser HTTP client
  4164   */
  4165  var SuperagentHttpClient = function () {
  4166    this.type = 'SuperagentHttpClient';
  4167  };
  4168  
  4169  /**
  4170   * SwaggerHttp is a wrapper for executing requests
  4171   */
  4172  var SwaggerHttp = module.exports = function () {};
  4173  
  4174  SwaggerHttp.prototype.execute = function (obj, opts) {
  4175    var client;
  4176  
  4177    if(opts && opts.client) {
  4178      client = opts.client;
  4179    }
  4180    else {
  4181      client = new SuperagentHttpClient(opts);
  4182    }
  4183    client.opts = opts || {};
  4184  
  4185    if (opts && opts.requestAgent) {
  4186      request = opts.requestAgent;
  4187    }
  4188  
  4189    // legacy support
  4190    var hasJQuery = false;
  4191    if(typeof window !== 'undefined') {
  4192      if(typeof window.jQuery !== 'undefined') {
  4193        hasJQuery = true;
  4194      }
  4195    }
  4196    // OPTIONS support
  4197    if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') {
  4198      log('forcing jQuery as OPTIONS are not supported by SuperAgent');
  4199      obj.useJQuery = true;
  4200    }
  4201    if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) {
  4202      throw new Error('Unsupported configuration! JQuery is required but not available');
  4203    }
  4204    if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) {
  4205      client = new JQueryHttpClient(opts);
  4206    }
  4207  
  4208    var success = obj.on.response;
  4209    var error = obj.on.error;
  4210  
  4211    var requestInterceptor = function(data) {
  4212      if(opts && opts.requestInterceptor) {
  4213        data = opts.requestInterceptor.apply(data);
  4214      }
  4215      return data;
  4216    };
  4217  
  4218    var responseInterceptor = function(data) {
  4219      if(opts && opts.responseInterceptor) {
  4220        data = opts.responseInterceptor.apply(data);
  4221      }
  4222      return success(data);
  4223    };
  4224  
  4225    var errorInterceptor = function(data) {
  4226      if(opts && opts.responseInterceptor) {
  4227        data = opts.responseInterceptor.apply(data);
  4228      }
  4229      error(data);
  4230    };
  4231  
  4232    obj.on.error = function(data) {
  4233      errorInterceptor(data);
  4234    };
  4235  
  4236    obj.on.response = function(data) {
  4237      responseInterceptor(data);
  4238    };
  4239  
  4240    if (_.isObject(obj) && _.isObject(obj.body)) {
  4241      // special processing for file uploads via jquery
  4242      if (obj.body.type && obj.body.type === 'formData'){
  4243        if(opts.useJQuery) {
  4244          obj.contentType = false;
  4245          obj.processData = false;
  4246          delete obj.headers['Content-Type'];
  4247        }
  4248      }
  4249    }
  4250  
  4251    obj = requestInterceptor(obj) || obj;
  4252    if (obj.beforeSend) {
  4253      obj.beforeSend(function(_obj) {
  4254        client.execute(_obj || obj);
  4255      });
  4256    } else {
  4257      client.execute(obj);
  4258    }
  4259  
  4260    return (obj.deferred) ? obj.deferred.promise : obj;
  4261  };
  4262  
  4263  SwaggerHttp.prototype.isInternetExplorer = function () {
  4264    var detectedIE = false;
  4265  
  4266    if (typeof navigator !== 'undefined' && navigator.userAgent) {
  4267      var nav = navigator.userAgent.toLowerCase();
  4268  
  4269      if (nav.indexOf('msie') !== -1) {
  4270        var version = parseInt(nav.split('msie')[1]);
  4271  
  4272        if (version <= 8) {
  4273          detectedIE = true;
  4274        }
  4275      }
  4276    }
  4277  
  4278    return detectedIE;
  4279  };
  4280  
  4281  JQueryHttpClient.prototype.execute = function (obj) {
  4282    var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery);
  4283    var cb = obj.on;
  4284    var request = obj;
  4285  
  4286    if(typeof jq === 'undefined' || jq === false) {
  4287      throw new Error('Unsupported configuration! JQuery is required but not available');
  4288    }
  4289  
  4290    obj.type = obj.method;
  4291    obj.cache = obj.jqueryAjaxCache;
  4292    obj.data = obj.body;
  4293    delete obj.jqueryAjaxCache;
  4294    delete obj.useJQuery;
  4295    delete obj.body;
  4296  
  4297    obj.complete = function (response) {
  4298      var headers = {};
  4299      var headerArray = response.getAllResponseHeaders().split('\n');
  4300  
  4301      for (var i = 0; i < headerArray.length; i++) {
  4302        var toSplit = headerArray[i].trim();
  4303  
  4304        if (toSplit.length === 0) {
  4305          continue;
  4306        }
  4307  
  4308        var separator = toSplit.indexOf(':');
  4309  
  4310        if (separator === -1) {
  4311          // Name but no value in the header
  4312          headers[toSplit] = null;
  4313  
  4314          continue;
  4315        }
  4316  
  4317        var name = toSplit.substring(0, separator).trim();
  4318        var value = toSplit.substring(separator + 1).trim();
  4319  
  4320        headers[name] = value;
  4321      }
  4322  
  4323      var out = {
  4324        url: request.url,
  4325        method: request.method,
  4326        status: response.status,
  4327        statusText: response.statusText,
  4328        data: response.responseText,
  4329        headers: headers
  4330      };
  4331  
  4332      try {
  4333        var possibleObj =  response.responseJSON || jsyaml.safeLoad(response.responseText);
  4334        out.obj = (typeof possibleObj === 'string') ? {} : possibleObj;
  4335      } catch (ex) {
  4336        // do not set out.obj
  4337        helpers.log('unable to parse JSON/YAML content');
  4338      }
  4339  
  4340      // I can throw, or parse null?
  4341      out.obj = out.obj || null;
  4342  
  4343      if (response.status >= 200 && response.status < 300) {
  4344        cb.response(out);
  4345      } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) {
  4346        cb.error(out);
  4347      } else {
  4348        return cb.response(out);
  4349      }
  4350    };
  4351  
  4352    jq.support.cors = true;
  4353  
  4354    return jq.ajax(obj);
  4355  };
  4356  
  4357  SuperagentHttpClient.prototype.execute = function (obj) {
  4358    var connectionAgent = obj.connectionAgent;
  4359    var method = obj.method.toLowerCase();
  4360    var timeout = obj.timeout;
  4361  
  4362    if (method === 'delete') {
  4363      method = 'del';
  4364    }
  4365    var headers = obj.headers || {};
  4366  
  4367    if (connectionAgent) {
  4368        request = request.agent(connectionAgent);
  4369    }
  4370  
  4371    var r = request[method](obj.url);
  4372  
  4373    if (timeout) {
  4374      r.timeout(timeout);
  4375    }
  4376  
  4377    if (obj.enableCookies) {
  4378      r.withCredentials();
  4379    }
  4380  
  4381    var accept = obj.headers.Accept;
  4382  
  4383    if(this.binaryRequest(accept)) {
  4384      r.on('request', function () {
  4385        if(this.xhr) {
  4386          this.xhr.responseType = 'blob';
  4387        }
  4388      });
  4389    }
  4390  
  4391    if(obj.body) {
  4392      if(_.isObject(obj.body)) {
  4393        var contentType = obj.headers['Content-Type'] || '';
  4394        if (contentType.indexOf('multipart/form-data') === 0) {
  4395          delete headers['Content-Type'];
  4396          if({}.toString.apply(obj.body) === '[object FormData]') {
  4397            r.send(obj.body);
  4398          }
  4399          else {
  4400            var keyname, value, v;
  4401            for (keyname in obj.body) {
  4402              value = obj.body[keyname];
  4403              if(Array.isArray(value)) {
  4404                for(v in value) {
  4405                  r.field(keyname, v);
  4406                }
  4407              }
  4408              else {
  4409                r.field(keyname, value);
  4410              }
  4411            }
  4412          }
  4413        }
  4414        else if (_.isObject(obj.body)) {
  4415          // non multipart/form-data
  4416          obj.body = JSON.stringify(obj.body);
  4417          r.send(obj.body);
  4418        }
  4419      }
  4420      else {
  4421        r.send(obj.body);
  4422      }
  4423    }
  4424  
  4425    var name;
  4426    for (name in headers) {
  4427      r.set(name, headers[name]);
  4428    }
  4429  
  4430    if(typeof r.buffer === 'function') {
  4431      r.buffer(); // force superagent to populate res.text with the raw response data
  4432    }
  4433  
  4434    r.end(function (err, res) {
  4435      res = res || {
  4436        status: 0,
  4437        headers: {error: 'no response from server'}
  4438      };
  4439      var response = {
  4440        url: obj.url,
  4441        method: obj.method,
  4442        headers: res.headers
  4443      };
  4444      var cb;
  4445  
  4446      if (!err && res.error) {
  4447        err = res.error;
  4448      }
  4449  
  4450      if (err && obj.on && obj.on.error) {
  4451        response.errObj = err;
  4452        response.status = res ? res.status : 500;
  4453        response.statusText = res ? res.text : err.message;
  4454        if (res.headers && res.headers['content-type']) {
  4455          if (res.headers['content-type'].indexOf('application/json') >= 0) {
  4456            try {
  4457              response.obj = JSON.parse(response.statusText);
  4458            }
  4459            catch (e) {
  4460              response.obj = null;
  4461            }
  4462          }
  4463        }
  4464        cb = obj.on.error;
  4465      } else if (res && obj.on && obj.on.response) {
  4466        var possibleObj;
  4467  
  4468        // Already parsed by by superagent?
  4469        if (res.body && _.keys(res.body).length > 0) {
  4470          possibleObj = res.body;
  4471        } else {
  4472          try {
  4473            possibleObj = jsyaml.safeLoad(res.text);
  4474            // can parse into a string... which we don't need running around in the system
  4475            possibleObj = (typeof possibleObj === 'string') ? null : possibleObj;
  4476          } catch (e) {
  4477            helpers.log('cannot parse JSON/YAML content');
  4478          }
  4479        }
  4480  
  4481        // null means we can't parse into object
  4482        if(typeof Buffer === 'function' && Buffer.isBuffer(possibleObj)) {
  4483          response.data = possibleObj;
  4484        }
  4485        else {
  4486          response.obj = (typeof possibleObj === 'object') ? possibleObj : null;
  4487        }
  4488  
  4489        response.status = res.status;
  4490        response.statusText = res.text;
  4491        cb = obj.on.response;
  4492      }
  4493      if (res.xhr && res.xhr.response) {
  4494        response.data = res.xhr.response;
  4495      }
  4496      else if(!response.data) {
  4497        response.data = response.statusText;
  4498      }
  4499  
  4500      if (cb) {
  4501        cb(response);
  4502      }
  4503    });
  4504  };
  4505  
  4506  SuperagentHttpClient.prototype. binaryRequest = function (accept) {
  4507    if(!accept) {
  4508      return false;
  4509    }
  4510    return (/^image/i).test(accept)
  4511      || (/^application\/pdf/).test(accept)
  4512      || (/^application\/octet-stream/).test(accept);
  4513  };
  4514  
  4515  }).call(this,require("buffer").Buffer)
  4516  
  4517  },{"./helpers":4,"buffer":14,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,"superagent":158}],6:[function(require,module,exports){
  4518  'use strict';
  4519  
  4520  var SwaggerHttp = require('./http');
  4521  var _ = {
  4522    isObject: require('lodash-compat/lang/isObject'),
  4523    cloneDeep: require('lodash-compat/lang/cloneDeep'),
  4524    isArray: require('lodash-compat/lang/isArray'),
  4525    isString: require('lodash-compat/lang/isString')
  4526  };
  4527  
  4528  
  4529  /**
  4530   * Resolves a spec's remote references
  4531   */
  4532  var Resolver = module.exports = function () {
  4533    this.failedUrls = [];
  4534    this.resolverCache = {};
  4535    this.pendingUrls = {};
  4536  };
  4537  
  4538  Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) {
  4539    var i, location, property;
  4540  
  4541    definition['x-resolved-from'] = [ '#/definitions/' + name ];
  4542    var allOf = definition.allOf;
  4543    // the refs go first
  4544    allOf.sort(function(a, b) {
  4545      if(a.$ref && b.$ref) { return 0; }
  4546      else if(a.$ref) { return -1; }
  4547      else { return 1; }
  4548    });
  4549    for (i = 0; i < allOf.length; i++) {
  4550      property = allOf[i];
  4551      location = '/definitions/' + name + '/allOf';
  4552      this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location);
  4553    }
  4554  };
  4555  
  4556  Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
  4557    this.spec = spec;
  4558    var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i;
  4559    if(typeof arg1 === 'function') {
  4560      root = null;
  4561      callback = arg1;
  4562      scope = arg2;
  4563    }
  4564    var _root = root, modelName;
  4565    this.scope = (scope || this);
  4566    this.iteration = this.iteration || 0;
  4567  
  4568    if(this.scope.options && this.scope.options.requestInterceptor){
  4569      opts.requestInterceptor = this.scope.options.requestInterceptor;
  4570    }
  4571  
  4572    if(this.scope.options && this.scope.options.responseInterceptor){
  4573      opts.responseInterceptor = this.scope.options.responseInterceptor;
  4574    }
  4575  
  4576    var name, path, property, propertyName, parameter, done, counter;
  4577    var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};
  4578    var resolutionTable = []; // store objects for dereferencing
  4579  
  4580    spec.definitions = spec.definitions || {};
  4581    // definitions
  4582    for (name in spec.definitions) {
  4583      var definition = spec.definitions[name];
  4584      if(definition.$ref) {
  4585        this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition);
  4586      }
  4587      else {
  4588        for (propertyName in definition.properties) {
  4589          property = definition.properties[propertyName];
  4590          if (_.isArray(property.allOf)) {
  4591            this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec);
  4592          }
  4593          else {
  4594            this.resolveTo(root, property, resolutionTable, '/definitions');
  4595          }
  4596        }
  4597  
  4598        if (definition.allOf) {
  4599          this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec);
  4600        }
  4601      }
  4602    }
  4603  
  4604    // shared parameters
  4605    spec.parameters = spec.parameters || {};
  4606    for(name in spec.parameters) {
  4607      parameter = spec.parameters[name];
  4608      if (parameter.in === 'body' && parameter.schema) {
  4609        if(_.isArray(parameter.schema.allOf)) {
  4610          // move to a definition
  4611          modelName = 'inline_model';
  4612          var _name = modelName;
  4613          done = false; counter = 0;
  4614          while(!done) {
  4615            if(typeof spec.definitions[_name] === 'undefined') {
  4616              done = true;
  4617              break;
  4618            }
  4619            _name = modelName + '_' + counter;
  4620            counter ++;
  4621          }
  4622          spec.definitions[_name] = { allOf: parameter.schema.allOf };
  4623          delete parameter.schema.allOf;
  4624          parameter.schema.$ref = '#/definitions/' + _name;
  4625          this.processAllOf(root, _name, spec.definitions[_name], resolutionTable, unresolvedRefs, spec);
  4626        }
  4627        else {
  4628          this.resolveTo(root, parameter.schema, resolutionTable, location);
  4629        }
  4630      }
  4631  
  4632      if (parameter.$ref) {
  4633        // parameter reference
  4634        this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
  4635      }
  4636    }
  4637  
  4638    // operations
  4639    for (name in spec.paths) {
  4640      var method, operation, responseCode;
  4641      path = spec.paths[name];
  4642  
  4643      if(typeof path === 'object') {
  4644        for (method in path) {
  4645          // operation reference
  4646          if (method === '$ref') {
  4647            // location = path[method];
  4648            location = '/paths' + name;
  4649            this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location);
  4650          }
  4651          else {
  4652            operation = path[method];
  4653            var sharedParameters = path.parameters || [];
  4654            var parameters = operation.parameters || [];
  4655  
  4656            sharedParameters.forEach(function(parameter) {
  4657              parameters.unshift(parameter);
  4658            });
  4659  
  4660            if (method !== 'parameters' && _.isObject(operation)) {
  4661              operation.parameters = operation.parameters || parameters;
  4662            }
  4663  
  4664            for (i in parameters) {
  4665              parameter = parameters[i];
  4666              location = '/paths' + name + '/' + method + '/parameters';
  4667  
  4668              if (parameter.in === 'body' && parameter.schema) {
  4669                if (_.isArray(parameter.schema.allOf)) {
  4670                  // move to a definition
  4671                  modelName = 'inline_model';
  4672                  name = modelName;
  4673                  done = false;
  4674                  counter = 0;
  4675                  while (!done) {
  4676                    if (typeof spec.definitions[name] === 'undefined') {
  4677                      done = true;
  4678                      break;
  4679                    }
  4680                    name = modelName + '_' + counter;
  4681                    counter++;
  4682                  }
  4683                  spec.definitions[name] = {allOf: parameter.schema.allOf};
  4684                  delete parameter.schema.allOf;
  4685                  parameter.schema.$ref = '#/definitions/' + name;
  4686                  this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
  4687                }
  4688                else {
  4689                  this.resolveTo(root, parameter.schema, resolutionTable, location);
  4690                }
  4691              }
  4692  
  4693              if (parameter.$ref) {
  4694                // parameter reference
  4695                this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
  4696              }
  4697            }
  4698  
  4699            for (responseCode in operation.responses) {
  4700              var response = operation.responses[responseCode];
  4701              location = '/paths' + name + '/' + method + '/responses/' + responseCode;
  4702  
  4703              if (_.isObject(response)) {
  4704                if (response.$ref) {
  4705                  // response reference
  4706                  this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location);
  4707                }
  4708                if (response.schema) {
  4709                  var responseObj = response;
  4710                  if (_.isArray(responseObj.schema.allOf)) {
  4711                    // move to a definition
  4712                    modelName = 'inline_model';
  4713                    name = modelName;
  4714                    done = false;
  4715                    counter = 0;
  4716                    while (!done) {
  4717                      if (typeof spec.definitions[name] === 'undefined') {
  4718                        done = true;
  4719                        break;
  4720                      }
  4721                      name = modelName + '_' + counter;
  4722                      counter++;
  4723                    }
  4724                    spec.definitions[name] = {allOf: responseObj.schema.allOf};
  4725                    delete responseObj.schema.allOf;
  4726                    delete responseObj.schema.type;
  4727                    responseObj.schema.$ref = '#/definitions/' + name;
  4728                    this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
  4729                  }
  4730                  else if ('array' === responseObj.schema.type) {
  4731                    if (responseObj.schema.items && responseObj.schema.items.$ref) {
  4732                      // response reference
  4733                      this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location);
  4734                    }
  4735                  }
  4736                  else {
  4737                    this.resolveTo(root, response.schema, resolutionTable, location);
  4738                  }
  4739                }
  4740              }
  4741            }
  4742          }
  4743        }
  4744        // clear them out to avoid multiple resolutions
  4745        path.parameters = [];
  4746      }
  4747    }
  4748  
  4749    var expectedCalls = 0, toResolve = [];
  4750    // if the root is same as obj[i].root we can resolve locally
  4751    var all = resolutionTable;
  4752  
  4753    var parts;
  4754    for(i = 0; i < all.length; i++) {
  4755      var a = all[i];
  4756      if(root === a.root) {
  4757        if(a.resolveAs === 'ref') {
  4758          // resolve any path walking
  4759          var joined = ((a.root || '') + '/' + a.key).split('/');
  4760          var normalized = [];
  4761          var url = '';
  4762          var k;
  4763  
  4764          if(a.key.indexOf('../') >= 0) {
  4765            for(var j = 0; j < joined.length; j++) {
  4766              if(joined[j] === '..') {
  4767                normalized = normalized.slice(0, normalized.length-1);
  4768              }
  4769              else {
  4770                normalized.push(joined[j]);
  4771              }
  4772            }
  4773            for(k = 0; k < normalized.length; k ++) {
  4774              if(k > 0) {
  4775                url += '/';
  4776              }
  4777              url += normalized[k];
  4778            }
  4779            // we now have to remote resolve this because the path has changed
  4780            a.root = url;
  4781            toResolve.push(a);
  4782          }
  4783          else {
  4784            parts = a.key.split('#');
  4785            if(parts.length === 2) {
  4786              if(parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0) {
  4787                a.root = parts[0];
  4788              }
  4789              location = parts[1].split('/');
  4790              var r;
  4791              var s = spec;
  4792              for(k = 0; k < location.length; k++) {
  4793                var part = location[k];
  4794                if(part !== '') {
  4795                  s = s[part];
  4796                  if(typeof s !== 'undefined') {
  4797                    r = s;
  4798                  }
  4799                  else {
  4800                    r = null;
  4801                    break;
  4802                  }
  4803                }
  4804              }
  4805              if(r === null) {
  4806                // must resolve this too
  4807                toResolve.push(a);
  4808              }
  4809            }
  4810          }
  4811        }
  4812        else {
  4813          if (a.resolveAs === 'inline') {
  4814            if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') {
  4815              // handle relative schema
  4816              parts = a.root.split('/');
  4817              location = '';
  4818              for(i = 0; i < parts.length - 1; i++) {
  4819                location += parts[i] + '/';
  4820              }
  4821              location += a.key;
  4822              a.root = location;
  4823              a.location = '';
  4824            }
  4825            toResolve.push(a);
  4826          }
  4827        }
  4828      }
  4829      else {
  4830        toResolve.push(a);
  4831      }
  4832    }
  4833    expectedCalls = toResolve.length;
  4834  
  4835    // resolve anything that is local
  4836  
  4837    var lock = {};
  4838    for(var ii = 0; ii < toResolve.length; ii++) {
  4839      (function(item, spec, self, lock, ii) {
  4840        if(!item.root || item.root === root) {
  4841          // local resolve
  4842          self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item);
  4843          processedCalls += 1;
  4844  
  4845          if(processedCalls === expectedCalls) {
  4846            self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true);
  4847          }
  4848        }
  4849        else if(self.failedUrls.indexOf(item.root) === -1) {
  4850          var obj = {
  4851            useJQuery: false,  // TODO
  4852            url: item.root,
  4853            method: 'get',
  4854            headers: {
  4855              accept: self.scope.swaggerRequestHeaders || 'application/json'
  4856            },
  4857            on: {
  4858              error: function (error) {
  4859                processedCalls += 1;
  4860                console.log('failed url: ' + obj.url);
  4861                self.failedUrls.push(obj.url);
  4862                if (lock) {
  4863                  delete lock[item.root];
  4864                }
  4865                unresolvedRefs[item.key] = {
  4866                  root: item.root,
  4867                  location: item.location
  4868                };
  4869  
  4870                if (processedCalls === expectedCalls) {
  4871                  self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
  4872                }
  4873              },  // jshint ignore:line
  4874              response: function (response) {
  4875                var swagger = response.obj;
  4876                if (lock) {
  4877                  delete lock[item.root];
  4878                }
  4879                if (self.resolverCache) {
  4880                  self.resolverCache[item.root] = swagger;
  4881                }
  4882                self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item);
  4883                processedCalls += 1;
  4884  
  4885                if (processedCalls === expectedCalls) {
  4886                  self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
  4887                }
  4888              }
  4889            } // jshint ignore:line
  4890          };
  4891  
  4892          // apply timeout only when specified
  4893          if (scope && scope.fetchSpecTimeout) {
  4894            obj.timeout = scope.fetchSpecTimeout;
  4895          }
  4896  
  4897          if (scope && scope.clientAuthorizations) {
  4898            scope.clientAuthorizations.apply(obj);
  4899          }
  4900  
  4901          (function waitForUnlock() {
  4902            setTimeout(function() {
  4903              if (lock[obj.url]) {
  4904                waitForUnlock();
  4905              }
  4906              else {
  4907                var cached = self.resolverCache[obj.url];
  4908                if (_.isObject(cached)) {
  4909                  obj.on.response({obj: cached});
  4910                }
  4911                else {
  4912                  lock[obj.url] = true;
  4913                  new SwaggerHttp().execute(obj, opts);
  4914                }
  4915              }
  4916            }, 0);
  4917          })();
  4918        }
  4919  
  4920        else {
  4921          processedCalls += 1;
  4922          unresolvedRefs[item.key] = {
  4923            root: item.root,
  4924            location: item.location
  4925          };
  4926          if (processedCalls === expectedCalls) {
  4927            self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
  4928          }
  4929        }
  4930      }(toResolve[ii], spec, this, lock, ii));
  4931    }
  4932  
  4933    if (Object.keys(toResolve).length === 0) {
  4934      this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
  4935    }
  4936  };
  4937  
  4938  Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) {
  4939    var path = item.location;
  4940    var location = spec, parts = path.split('/');
  4941    if(path !== '') {
  4942      for (var j = 0; j < parts.length; j++) {
  4943        var segment = parts[j];
  4944        if (segment.indexOf('~1') !== -1) {
  4945          segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/');
  4946          if (segment.charAt(0) !== '/') {
  4947            segment = '/' + segment;
  4948          }
  4949        }
  4950        if (typeof location === 'undefined' || location === null) {
  4951          break;
  4952        }
  4953        if (segment === '' && j === (parts.length - 1) && parts.length > 1) {
  4954          location = null;
  4955          break;
  4956        }
  4957        if (segment.length > 0) {
  4958          location = location[segment];
  4959        }
  4960      }
  4961    }
  4962    var resolved = item.key;
  4963    parts = item.key.split('/');
  4964    var resolvedName = parts[parts.length-1];
  4965  
  4966    if(resolvedName.indexOf('#') >= 0) {
  4967      resolvedName = resolvedName.split('#')[1];
  4968    }
  4969  
  4970    if (location !== null && typeof location !== 'undefined') {
  4971      resolvedRefs[resolved] = {
  4972        name: resolvedName,
  4973        obj: location,
  4974        key: item.key,
  4975        root: item.root
  4976      };
  4977    } else {
  4978      unresolvedRefs[resolved] = {
  4979        root: item.root,
  4980        location: item.location
  4981      };
  4982    }
  4983  };
  4984  
  4985  Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) {
  4986    // walk resolution table and replace with resolved refs
  4987    var ref, abs;
  4988    for (ref in resolutionTable) {
  4989      var item = resolutionTable[ref];
  4990  
  4991      var key = item.key;
  4992      var resolvedTo = resolvedRefs[key];
  4993      if (resolvedTo) {
  4994        spec.definitions = spec.definitions || {};
  4995        if (item.resolveAs === 'ref') {
  4996          if (localResolve !== true) {
  4997            // don't retain root for local definitions
  4998            for (key in resolvedTo.obj) {
  4999              abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
  5000              resolvedTo.obj[key] = abs;
  5001            }
  5002          }
  5003          spec.definitions[resolvedTo.name] = resolvedTo.obj;
  5004          item.obj.$ref = '#/definitions/' + resolvedTo.name;
  5005        } else if (item.resolveAs === 'inline') {
  5006          var targetObj = item.obj;
  5007          targetObj['x-resolved-from'] = [ item.key ];
  5008          delete targetObj.$ref;
  5009  
  5010          for (key in resolvedTo.obj) {
  5011            abs = resolvedTo.obj[key];
  5012  
  5013            if (localResolve !== true) {
  5014              // don't retain root for local definitions
  5015              abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
  5016            }
  5017            targetObj[key] = abs;
  5018          }
  5019        }
  5020      }
  5021    }
  5022    var existingUnresolved = this.countUnresolvedRefs(spec);
  5023  
  5024    if(existingUnresolved === 0 || this.iteration > 5) {
  5025      this.resolveAllOf(spec.definitions);
  5026      this.resolverCache = null;
  5027      callback.call(this.scope, spec, unresolvedRefs);
  5028    }
  5029    else {
  5030      this.iteration += 1;
  5031      this.resolve(spec, root, callback, this.scope);
  5032    }
  5033  };
  5034  
  5035  Resolver.prototype.countUnresolvedRefs = function(spec) {
  5036    var i;
  5037    var refs = this.getRefs(spec);
  5038    var keys = [];
  5039    var unresolvedKeys = [];
  5040    for(i in refs) {
  5041      if(i.indexOf('#') === 0) {
  5042        keys.push(i.substring(1));
  5043      }
  5044      else {
  5045        unresolvedKeys.push(i);
  5046      }
  5047    }
  5048  
  5049    // verify possible keys
  5050    for (i = 0; i < keys.length; i++) {
  5051      var part = keys[i];
  5052      var parts = part.split('/');
  5053      var obj = spec;
  5054  
  5055      for (var k = 0; k < parts.length; k++) {
  5056        var key = parts[k];
  5057        if(key !== '') {
  5058          obj = obj[key];
  5059          if(typeof obj === 'undefined') {
  5060            unresolvedKeys.push(part);
  5061            break;
  5062          }
  5063        }
  5064      }
  5065    }
  5066    return unresolvedKeys.length;
  5067  };
  5068  
  5069  Resolver.prototype.getRefs = function(spec, obj) {
  5070    obj = obj || spec;
  5071    var output = {};
  5072    for(var key in obj) {
  5073      if (!obj.hasOwnProperty(key)) {
  5074        continue;
  5075      }
  5076      var item = obj[key];
  5077      if(key === '$ref' && typeof item === 'string') {
  5078        output[item] = null;
  5079      }
  5080      else if(_.isObject(item)) {
  5081        var o = this.getRefs(item);
  5082        for(var k in o) {
  5083          output[k] = null;
  5084        }
  5085      }
  5086    }
  5087    return output;
  5088  };
  5089  
  5090  function splitUrl(url) {
  5091    var result = {};
  5092    var proto = /[a-z]+:\/\//i.exec(url);
  5093    if (proto) {
  5094      result.proto = proto[0].slice(0, -3);
  5095      url = url.slice(result.proto.length + 1);
  5096    }
  5097    if (url.slice(0, 2) === '//') {
  5098      result.domain = url.slice(2).split('/')[0];
  5099      url = url.slice(2 + result.domain.length);
  5100    }
  5101    var p = url.split('#');
  5102    if (p[0].length) {
  5103      result.path = p[0];
  5104    }
  5105    if (p.length > 1) {
  5106      result.fragment = p.slice(1).join('#');
  5107    }
  5108    return result;
  5109  }
  5110  
  5111  function unsplitUrl(url) {
  5112    var result = url.path;
  5113    if (result === undefined) {
  5114      result = '';
  5115    }
  5116    if (url.fragment !== undefined) {
  5117      result += '#' + url.fragment;
  5118    }
  5119    if (url.domain !== undefined) {
  5120      if (result.slice(0, 1) === '/') {
  5121        result = result.slice(1);
  5122      }
  5123      result = '//' + url.domain + '/' + result;
  5124      if (url.proto !== undefined) {
  5125        result = url.proto + ':' + result;
  5126      }
  5127    }
  5128    return result;
  5129  }
  5130  
  5131  function joinUrl(base, rel) {
  5132    var relsp = splitUrl(rel);
  5133    if (relsp.domain !== undefined) {
  5134      return rel;
  5135    }
  5136    var result = splitUrl(base);
  5137    if (relsp.path === undefined) {
  5138      // change only fragment part
  5139      result.fragment = relsp.fragment;
  5140    } else if (relsp.path.slice(0, 1) === '/') {
  5141      // relative to domain
  5142      result.path = relsp.path;
  5143      result.fragment = relsp.fragment;
  5144    } else {
  5145      // relative to path
  5146      var path = result.path === undefined ? [] : result.path.split('/');
  5147      var relpath = relsp.path.split('/');
  5148      if (path.length) {
  5149        path.pop();
  5150      }
  5151      while (relpath[0] === '..' || relpath[0] === '.') {
  5152        if (relpath[0] === '..') {
  5153          path.pop();
  5154        }
  5155        relpath.shift();
  5156      }
  5157      result.path = path.concat(relpath).join('/');
  5158      result.fragment = relsp.fragment;
  5159    }
  5160    return unsplitUrl(result);
  5161  }
  5162  
  5163  Resolver.prototype.retainRoot = function(origKey, obj, root) {
  5164    // walk object and look for relative $refs
  5165    if(_.isObject(obj)) {
  5166      for(var key in obj) {
  5167        var item = obj[key];
  5168        if (key === '$ref' && typeof item === 'string') {
  5169          obj[key] = joinUrl(root, item);
  5170        }
  5171        else if (_.isObject(item)) {
  5172          this.retainRoot(key, item, root);
  5173        }
  5174      }
  5175    }
  5176    else if(_.isString(obj) && origKey === '$ref') {
  5177      obj = joinUrl(root, obj);
  5178    }
  5179    return obj;
  5180  };
  5181  
  5182  /**
  5183   * immediately in-lines local refs, queues remote refs
  5184   * for inline resolution
  5185   */
  5186  Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) {
  5187    var key = property.$ref, ref = property.$ref, i, p, p2, rs;
  5188    var rootTrimmed = false;
  5189  
  5190    root = root || ''; // Guard against .split. @fehguy, you'll need to check if this logic fits
  5191    // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ?
  5192  
  5193    if (ref) {
  5194      if(ref.indexOf('../') === 0) {
  5195        // reset root
  5196        p = ref.split('../');
  5197        p2 = root.split('/');
  5198        ref = '';
  5199        for(i = 0; i < p.length; i++) {
  5200          if(p[i] === '') {
  5201            p2 = p2.slice(0, p2.length-1);
  5202          }
  5203          else {
  5204            ref += p[i];
  5205          }
  5206        }
  5207        root = '';
  5208        for(i = 0; i < p2.length - 1; i++) {
  5209          if(i > 0) { root += '/'; }
  5210          root += p2[i];
  5211        }
  5212        rootTrimmed = true;
  5213      }
  5214      if(ref.indexOf('#') >= 0) {
  5215        if(ref.indexOf('/') === 0) {
  5216          rs = ref.split('#');
  5217          p  = root.split('//');
  5218          p2 = p[1].split('/');
  5219          root = p[0] + '//' + p2[0] + rs[0];
  5220          location = rs[1];
  5221        }
  5222        else {
  5223          rs = ref.split('#');
  5224          if(rs[0] !== '') {
  5225            p2 = root.split('/');
  5226            p2 = p2.slice(0, p2.length - 1);
  5227            if(!rootTrimmed) {
  5228              root = '';
  5229              for (var k = 0; k < p2.length; k++) {
  5230                if(k > 0) { root += '/'; }
  5231                root += p2[k];
  5232              }
  5233            }
  5234            root += '/' + ref.split('#')[0];
  5235          }
  5236          location = rs[1];
  5237        }
  5238      }
  5239      if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
  5240        if(ref.indexOf('#') >= 0) {
  5241          root = ref.split('#')[0];
  5242          location = ref.split('#')[1];
  5243        }
  5244        else {
  5245          root = ref;
  5246          location = '';
  5247        }
  5248        resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
  5249      } else if (ref.indexOf('#') === 0) {
  5250        location = ref.split('#')[1];
  5251        resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
  5252      } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) {
  5253        location = ref;
  5254        var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
  5255        if(matches) {
  5256          root = matches[0] + ref.substring(1);
  5257          location = '';
  5258        }
  5259        resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
  5260      }
  5261      else {
  5262        resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
  5263      }
  5264    }
  5265    else if (property.type === 'array') {
  5266      this.resolveTo(root, property.items, resolutionTable, location);
  5267    }
  5268  };
  5269  
  5270  Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {
  5271    var sp, i;
  5272    var ref = property.$ref;
  5273    var lroot = root;
  5274    if ((typeof ref !== 'undefined') && (ref !== null)) {
  5275      if(ref.indexOf('#') >= 0) {
  5276        var parts = ref.split('#');
  5277  
  5278        // #/definitions/foo
  5279        // foo.json#/bar
  5280        if(parts[0] && ref.indexOf('/') === 0) {
  5281  
  5282        }
  5283        else if(parts[0] && (parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0)) {
  5284          lroot = parts[0];
  5285          ref = parts[1];
  5286        }
  5287        else if(parts[0] && parts[0].length > 0) {
  5288          // relative file
  5289          sp = root.split('/');
  5290          lroot = '';
  5291          for(i = 0; i < sp.length - 1; i++) {
  5292            lroot += sp[i] + '/';
  5293          }
  5294          lroot += parts[0];
  5295        }
  5296        else {
  5297  
  5298        }
  5299  
  5300        location = parts[1];
  5301      }
  5302      else if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
  5303        lroot = ref;
  5304        location = '';
  5305      }
  5306      else {
  5307        // relative file
  5308        sp = root.split('/');
  5309        lroot = '';
  5310        for(i = 0; i < sp.length - 1; i++) {
  5311          lroot += sp[i] + '/';
  5312        }
  5313        lroot += ref;
  5314        location = '';
  5315      }
  5316      resolutionTable.push({
  5317        obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location
  5318      });
  5319    } else if (property.type === 'array') {
  5320      var items = property.items;
  5321      this.resolveTo(root, items, resolutionTable, location);
  5322    } else {
  5323      if(property && (property.properties || property.additionalProperties)) {
  5324        var name = this.uniqueName('inline_model');
  5325        if (property.title) {
  5326          name = this.uniqueName(property.title);
  5327        }
  5328        delete property.title;
  5329        this.spec.definitions[name] = _.cloneDeep(property);
  5330        property.$ref = '#/definitions/' + name;
  5331        delete property.type;
  5332        delete property.properties;
  5333      }
  5334    }
  5335  };
  5336  
  5337  Resolver.prototype.uniqueName = function(base) {
  5338    var name = base;
  5339    var count = 0;
  5340    while(true) {
  5341      if(!_.isObject(this.spec.definitions[name])) {
  5342        return name;
  5343      }
  5344      name = base + '_' + count;
  5345      count++;
  5346    }
  5347  };
  5348  
  5349  Resolver.prototype.resolveAllOf = function(spec, obj, depth) {
  5350    depth = depth || 0;
  5351    obj = obj || spec;
  5352    var name;
  5353    for(var key in obj) {
  5354      if (!obj.hasOwnProperty(key)) {
  5355        continue;
  5356      }
  5357      var item = obj[key];
  5358      if(item === null) {
  5359        throw new TypeError('Swagger 2.0 does not support null types (' + obj + ').  See https://github.com/swagger-api/swagger-spec/issues/229.');
  5360      }
  5361      if(typeof item === 'object') {
  5362        this.resolveAllOf(spec, item, depth + 1);
  5363      }
  5364      if(item && typeof item.allOf !== 'undefined') {
  5365        var allOf = item.allOf;
  5366        if(_.isArray(allOf)) {
  5367          var output = _.cloneDeep(item);
  5368          delete output.allOf;
  5369  
  5370          output['x-composed'] = true;
  5371          if (typeof item['x-resolved-from'] !== 'undefined') {
  5372            output['x-resolved-from'] = item['x-resolved-from'];
  5373          }
  5374  
  5375          for(var i = 0; i < allOf.length; i++) {
  5376            var component = allOf[i];
  5377            var source = 'self';
  5378            if(typeof component['x-resolved-from'] !== 'undefined') {
  5379              source = component['x-resolved-from'][0];
  5380            }
  5381  
  5382            for(var part in component) {
  5383              if(!output.hasOwnProperty(part)) {
  5384                output[part] = _.cloneDeep(component[part]);
  5385                if(part === 'properties') {
  5386                  for(name in output[part]) {
  5387                    output[part][name]['x-resolved-from'] = source;
  5388                  }
  5389                }
  5390              }
  5391              else {
  5392                if(part === 'properties') {
  5393                  var properties = component[part];
  5394                  for(name in properties) {
  5395                    output.properties[name] = _.cloneDeep(properties[name]);
  5396                    var resolvedFrom = properties[name]['x-resolved-from'];
  5397                    if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') {
  5398                      resolvedFrom = source;
  5399                    }
  5400                    output.properties[name]['x-resolved-from'] = resolvedFrom;
  5401                  }
  5402                }
  5403                else if(part === 'required') {
  5404                  // merge & dedup the required array
  5405                  var a = output.required.concat(component[part]);
  5406                  for(var k = 0; k < a.length; ++k) {
  5407                    for(var j = k + 1; j < a.length; ++j) {
  5408                      if(a[k] === a[j]) { a.splice(j--, 1); }
  5409                    }
  5410                  }
  5411                  output.required = a;
  5412                }
  5413                else if(part === 'x-resolved-from') {
  5414                  output['x-resolved-from'].push(source);
  5415                }
  5416                else {
  5417                  // TODO: need to merge this property
  5418                  // console.log('what to do with ' + part)
  5419                }
  5420              }
  5421            }
  5422          }
  5423          obj[key] = output;
  5424        }
  5425      }
  5426    }
  5427  };
  5428  
  5429  },{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(require,module,exports){
  5430  'use strict';
  5431  
  5432  var Helpers = require('./helpers');
  5433  
  5434  var _ = {
  5435    isPlainObject: require('lodash-compat/lang/isPlainObject'),
  5436    isUndefined: require('lodash-compat/lang/isUndefined'),
  5437    isArray: require('lodash-compat/lang/isArray'),
  5438    isObject: require('lodash-compat/lang/isObject'),
  5439    isEmpty: require('lodash-compat/lang/isEmpty'),
  5440    map: require('lodash-compat/collection/map'),
  5441    indexOf: require('lodash-compat/array/indexOf'),
  5442    cloneDeep: require('lodash-compat/lang/cloneDeep'),
  5443    keys: require('lodash-compat/object/keys'),
  5444    forEach: require('lodash-compat/collection/forEach')
  5445  };
  5446  
  5447  var optionHtml = module.exports.optionHtml = function  (label, value) {
  5448    return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
  5449  };
  5450  
  5451  module.exports.typeFromJsonSchema = function (type, format) {
  5452    var str;
  5453  
  5454    if (type === 'integer' && format === 'int32') {
  5455      str = 'integer';
  5456    } else if (type === 'integer' && format === 'int64') {
  5457      str = 'long';
  5458    } else if (type === 'integer' && typeof format === 'undefined') {
  5459      str = 'long';
  5460    } else if (type === 'string' && format === 'date-time') {
  5461      str = 'date-time';
  5462    } else if (type === 'string' && format === 'date') {
  5463      str = 'date';
  5464    } else if (type === 'number' && format === 'float') {
  5465      str = 'float';
  5466    } else if (type === 'number' && format === 'double') {
  5467      str = 'double';
  5468    } else if (type === 'number' && typeof format === 'undefined') {
  5469      str = 'double';
  5470    } else if (type === 'boolean') {
  5471      str = 'boolean';
  5472    } else if (type === 'string') {
  5473      str = 'string';
  5474    }
  5475  
  5476    return str;
  5477  };
  5478  
  5479  var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) {
  5480    var str = '';
  5481  
  5482    if (typeof obj.$ref !== 'undefined') {
  5483      str += Helpers.simpleRef(obj.$ref);
  5484    } else if (typeof obj.type === 'undefined') {
  5485      str += 'object';
  5486    } else if (obj.type === 'array') {
  5487      if (baseComponent) {
  5488        str += getStringSignature((obj.items || obj.$ref || {}));
  5489      } else {
  5490        str += 'Array[';
  5491        str += getStringSignature((obj.items || obj.$ref || {}));
  5492        str += ']';
  5493      }
  5494    } else if (obj.type === 'integer' && obj.format === 'int32') {
  5495      str += 'integer';
  5496    } else if (obj.type === 'integer' && obj.format === 'int64') {
  5497      str += 'long';
  5498    } else if (obj.type === 'integer' && typeof obj.format === 'undefined') {
  5499      str += 'long';
  5500    } else if (obj.type === 'string' && obj.format === 'date-time') {
  5501      str += 'date-time';
  5502    } else if (obj.type === 'string' && obj.format === 'date') {
  5503      str += 'date';
  5504    } else if (obj.type === 'string' && typeof obj.format === 'undefined') {
  5505      str += 'string';
  5506    } else if (obj.type === 'number' && obj.format === 'float') {
  5507      str += 'float';
  5508    } else if (obj.type === 'number' && obj.format === 'double') {
  5509      str += 'double';
  5510    } else if (obj.type === 'number' && typeof obj.format === 'undefined') {
  5511      str += 'double';
  5512    } else if (obj.type === 'boolean') {
  5513      str += 'boolean';
  5514    } else if (obj.$ref) {
  5515      str += Helpers.simpleRef(obj.$ref);
  5516    } else {
  5517      str += obj.type;
  5518    }
  5519  
  5520    return str;
  5521  };
  5522  
  5523  var schemaToJSON = module.exports.schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
  5524    // Resolve the schema (Handle nested schemas)
  5525    schema = Helpers.resolveSchema(schema);
  5526  
  5527    if(typeof modelPropertyMacro !== 'function') {
  5528      modelPropertyMacro = function(prop){
  5529        return (prop || {}).default;
  5530      };
  5531    }
  5532  
  5533    modelsToIgnore= modelsToIgnore || {};
  5534  
  5535    var type = schema.type || 'object';
  5536    var format = schema.format;
  5537    var model;
  5538    var output;
  5539  
  5540    if (!_.isUndefined(schema.example)) {
  5541      output = schema.example;
  5542    } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
  5543      output = schema.enum[0];
  5544    }
  5545  
  5546    if (_.isUndefined(output)) {
  5547      if (schema.$ref) {
  5548        model = models[Helpers.simpleRef(schema.$ref)];
  5549  
  5550        if (!_.isUndefined(model)) {
  5551          if (_.isUndefined(modelsToIgnore[model.name])) {
  5552            modelsToIgnore[model.name] = model;
  5553            output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
  5554            delete modelsToIgnore[model.name];
  5555          } else {
  5556            if (model.type === 'array') {
  5557              output = [];
  5558            } else {
  5559              output = {};
  5560            }
  5561          }
  5562        }
  5563      } else if (!_.isUndefined(schema.default)) {
  5564        output = schema.default;
  5565      } else if (type === 'string') {
  5566        if (format === 'date-time') {
  5567          output = new Date().toISOString();
  5568        } else if (format === 'date') {
  5569          output = new Date().toISOString().split('T')[0];
  5570        } else {
  5571          output = 'string';
  5572        }
  5573      } else if (type === 'integer') {
  5574        output = 0;
  5575      } else if (type === 'number') {
  5576        output = 0.0;
  5577      } else if (type === 'boolean') {
  5578        output = true;
  5579      } else if (type === 'object') {
  5580        output = {};
  5581  
  5582        _.forEach(schema.properties, function (property, name) {
  5583          var cProperty = _.cloneDeep(property);
  5584  
  5585          // Allow macro to set the default value
  5586          cProperty.default = modelPropertyMacro(property);
  5587  
  5588          output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
  5589        });
  5590      } else if (type === 'array') {
  5591        output = [];
  5592  
  5593        if (_.isArray(schema.items)) {
  5594          _.forEach(schema.items, function (item) {
  5595            output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
  5596          });
  5597        } else if (_.isPlainObject(schema.items)) {
  5598          output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
  5599        } else if (_.isUndefined(schema.items)) {
  5600          output.push({});
  5601        } else {
  5602          Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
  5603        }
  5604      }
  5605    }
  5606  
  5607    return output;
  5608  };
  5609  
  5610  module.exports.schemaToHTML =function (name, schema, models, modelPropertyMacro) {
  5611    var strongOpen = '<span class="strong">';
  5612    var strongClose = '</span>';
  5613  
  5614    // Allow for ignoring the 'name' argument.... shifting the rest
  5615    if(_.isObject(arguments[0])) {
  5616      name = void 0;
  5617      schema = arguments[0];
  5618      models = arguments[1];
  5619      modelPropertyMacro = arguments[2];
  5620    }
  5621  
  5622    models = models || {};
  5623  
  5624    // Resolve the schema (Handle nested schemas)
  5625    schema = Helpers.resolveSchema(schema);
  5626  
  5627    // Return for empty object
  5628    if(_.isEmpty(schema)) {
  5629      return strongOpen + 'Empty' + strongClose;
  5630    }
  5631  
  5632    // Dereference $ref from 'models'
  5633    if(typeof schema.$ref === 'string') {
  5634      name = Helpers.simpleRef(schema.$ref);
  5635      schema = models[name];
  5636      if(typeof schema === 'undefined')
  5637      {
  5638        return strongOpen + name + ' is not defined!' + strongClose;
  5639      }
  5640    }
  5641  
  5642    if(typeof name !== 'string') {
  5643      name = schema.title || 'Inline Model';
  5644    }
  5645  
  5646    // If we are a Model object... adjust accordingly
  5647    if(schema.definition) {
  5648      schema = schema.definition;
  5649    }
  5650  
  5651    if(typeof modelPropertyMacro !== 'function') {
  5652      modelPropertyMacro = function(prop){
  5653        return (prop || {}).default;
  5654      };
  5655    }
  5656  
  5657    var references = {};
  5658    var seenModels = [];
  5659    var inlineModels = 0;
  5660  
  5661  
  5662  
  5663    // Generate current HTML
  5664    var html = processModel(schema, name);
  5665  
  5666    // Generate references HTML
  5667    while (_.keys(references).length > 0) {
  5668      /* jshint ignore:start */
  5669      _.forEach(references, function (schema, name) {
  5670        var seenModel = _.indexOf(seenModels, name) > -1;
  5671  
  5672        delete references[name];
  5673  
  5674        if (!seenModel) {
  5675          seenModels.push(name);
  5676  
  5677          html += '<br />' + processModel(schema, name);
  5678        }
  5679      });
  5680      /* jshint ignore:end */
  5681    }
  5682  
  5683    return html;
  5684  
  5685    /////////////////////////////////
  5686  
  5687    function addReference(schema, name, skipRef) {
  5688      var modelName = name;
  5689      var model;
  5690  
  5691      if (schema.$ref) {
  5692        modelName = schema.title || Helpers.simpleRef(schema.$ref);
  5693        model = models[modelName];
  5694      } else if (_.isUndefined(name)) {
  5695        modelName = schema.title || 'Inline Model ' + (++inlineModels);
  5696        model = {definition: schema};
  5697      }
  5698  
  5699      if (skipRef !== true) {
  5700        references[modelName] = _.isUndefined(model) ? {} : model.definition;
  5701      }
  5702  
  5703      return modelName;
  5704    }
  5705  
  5706    function primitiveToHTML(schema) {
  5707      var html = '<span class="propType">';
  5708      var type = schema.type || 'object';
  5709  
  5710      if (schema.$ref) {
  5711        html += addReference(schema, Helpers.simpleRef(schema.$ref));
  5712      } else if (type === 'object') {
  5713        if (!_.isUndefined(schema.properties)) {
  5714          html += addReference(schema);
  5715        } else {
  5716          html += 'object';
  5717        }
  5718      } else if (type === 'array') {
  5719        html += 'Array[';
  5720  
  5721        if (_.isArray(schema.items)) {
  5722          html += _.map(schema.items, addReference).join(',');
  5723        } else if (_.isPlainObject(schema.items)) {
  5724          if (_.isUndefined(schema.items.$ref)) {
  5725            if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
  5726              html += schema.items.type;
  5727            } else {
  5728              html += addReference(schema.items);
  5729            }
  5730          } else {
  5731            html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref));
  5732          }
  5733        } else {
  5734          Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
  5735          html += 'object';
  5736        }
  5737  
  5738        html += ']';
  5739      } else {
  5740        html += schema.type;
  5741      }
  5742  
  5743      html += '</span>';
  5744  
  5745      return html;
  5746    }
  5747  
  5748    function primitiveToOptionsHTML(schema, html) {
  5749      var options = '';
  5750      var type = schema.type || 'object';
  5751      var isArray = type === 'array';
  5752  
  5753      if (isArray) {
  5754        if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
  5755          type = schema.items.type;
  5756        } else {
  5757          type = 'object';
  5758        }
  5759      }
  5760  
  5761      if (!_.isUndefined(schema.default)) {
  5762        options += optionHtml('Default', schema.default);
  5763      }
  5764  
  5765      switch (type) {
  5766      case 'string':
  5767        if (schema.minLength) {
  5768          options += optionHtml('Min. Length', schema.minLength);
  5769        }
  5770  
  5771        if (schema.maxLength) {
  5772          options += optionHtml('Max. Length', schema.maxLength);
  5773        }
  5774  
  5775        if (schema.pattern) {
  5776          options += optionHtml('Reg. Exp.', schema.pattern);
  5777        }
  5778        break;
  5779      case 'integer':
  5780      case 'number':
  5781        if (schema.minimum) {
  5782          options += optionHtml('Min. Value', schema.minimum);
  5783        }
  5784  
  5785        if (schema.exclusiveMinimum) {
  5786          options += optionHtml('Exclusive Min.', 'true');
  5787        }
  5788  
  5789        if (schema.maximum) {
  5790          options += optionHtml('Max. Value', schema.maximum);
  5791        }
  5792  
  5793        if (schema.exclusiveMaximum) {
  5794          options += optionHtml('Exclusive Max.', 'true');
  5795        }
  5796  
  5797        if (schema.multipleOf) {
  5798          options += optionHtml('Multiple Of', schema.multipleOf);
  5799        }
  5800  
  5801        break;
  5802      }
  5803  
  5804      if (isArray) {
  5805        if (schema.minItems) {
  5806          options += optionHtml('Min. Items', schema.minItems);
  5807        }
  5808  
  5809        if (schema.maxItems) {
  5810          options += optionHtml('Max. Items', schema.maxItems);
  5811        }
  5812  
  5813        if (schema.uniqueItems) {
  5814          options += optionHtml('Unique Items', 'true');
  5815        }
  5816  
  5817        if (schema.collectionFormat) {
  5818          options += optionHtml('Coll. Format', schema.collectionFormat);
  5819        }
  5820      }
  5821  
  5822      if (_.isUndefined(schema.items)) {
  5823        if (_.isArray(schema.enum)) {
  5824          var enumString;
  5825  
  5826          if (type === 'number' || type === 'integer') {
  5827            enumString = schema.enum.join(', ');
  5828          } else {
  5829            enumString = '"' + schema.enum.join('", "') + '"';
  5830          }
  5831  
  5832          options += optionHtml('Enum', enumString);
  5833        }
  5834      }
  5835  
  5836      if (options.length > 0) {
  5837        html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
  5838      }
  5839  
  5840      return html;
  5841    }
  5842  
  5843    function processModel(schema, name) {
  5844      var type = schema.type || 'object';
  5845      var isArray = schema.type === 'array';
  5846      var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
  5847  
  5848      if (name) {
  5849        seenModels.push(name);
  5850      }
  5851  
  5852      if (isArray) {
  5853        if (_.isArray(schema.items)) {
  5854          html += '<div>' + _.map(schema.items, function (item) {
  5855            var type = item.type || 'object';
  5856  
  5857            if (_.isUndefined(item.$ref)) {
  5858              if (_.indexOf(['array', 'object'], type) > -1) {
  5859                if (type === 'object' && _.isUndefined(item.properties)) {
  5860                  return 'object';
  5861                } else {
  5862                  return addReference(item);
  5863                }
  5864              } else {
  5865                return primitiveToOptionsHTML(item, type);
  5866              }
  5867            } else {
  5868              return addReference(item, Helpers.simpleRef(item.$ref));
  5869            }
  5870          }).join(',</div><div>');
  5871        } else if (_.isPlainObject(schema.items)) {
  5872          if (_.isUndefined(schema.items.$ref)) {
  5873            if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
  5874              if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
  5875                html += '<div>object</div>';
  5876              } else {
  5877                html += '<div>' + addReference(schema.items) + '</div>';
  5878              }
  5879            } else {
  5880              html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
  5881            }
  5882          } else {
  5883            html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>';
  5884          }
  5885        } else {
  5886          Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
  5887          html += '<div>object</div>';
  5888        }
  5889      } else {
  5890        if (schema.$ref) {
  5891          html += '<div>' + addReference(schema, name) + '</div>';
  5892        } else if (type === 'object') {
  5893          if (_.isPlainObject(schema.properties)) {
  5894            var contents = _.map(schema.properties, function (property, name) {
  5895              var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
  5896              var cProperty = _.cloneDeep(property);
  5897  
  5898              var requiredClass = propertyIsRequired ? 'required' : '';
  5899              var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
  5900              var model;
  5901              var propDescription;
  5902  
  5903              // Allow macro to set the default value
  5904              cProperty.default = modelPropertyMacro(cProperty);
  5905  
  5906              // Resolve the schema (Handle nested schemas)
  5907              cProperty = Helpers.resolveSchema(cProperty);
  5908  
  5909              propDescription = property.description || cProperty.description;
  5910  
  5911              // We need to handle property references to primitives (Issue 339)
  5912              if (!_.isUndefined(cProperty.$ref)) {
  5913                model = models[Helpers.simpleRef(cProperty.$ref)];
  5914  
  5915                if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
  5916                  // Use referenced schema
  5917                  cProperty = Helpers.resolveSchema(model.definition);
  5918                }
  5919              }
  5920  
  5921              html += primitiveToHTML(cProperty);
  5922  
  5923              if(!propertyIsRequired) {
  5924                html += ', <span class="propOptKey">optional</span>';
  5925              }
  5926  
  5927              if(property.readOnly) {
  5928                  html += ', <span class="propReadOnly">read only</span>';
  5929              }
  5930  
  5931              html += ')';
  5932  
  5933              if (!_.isUndefined(propDescription)) {
  5934                html += ': ' + '<span class="propDesc">' + propDescription + '</span>';
  5935              }
  5936  
  5937              if (cProperty.enum) {
  5938                html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';
  5939              }
  5940  
  5941              return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
  5942            }).join(',</div>');
  5943  
  5944            if (contents) {
  5945              html += contents + '</div>';
  5946            }
  5947          }
  5948        } else {
  5949          html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
  5950        }
  5951      }
  5952  
  5953      return html + strongOpen + (isArray ? ']' : '}') + strongClose;
  5954    }
  5955  };
  5956  },{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(require,module,exports){
  5957  'use strict';
  5958  
  5959  var SwaggerHttp = require('./http');
  5960  var _ = {
  5961    isObject: require('lodash-compat/lang/isObject')
  5962  };
  5963  
  5964  var SwaggerSpecConverter = module.exports = function () {
  5965    this.errors = [];
  5966    this.warnings = [];
  5967    this.modelMap = {};
  5968  };
  5969  
  5970  SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) {
  5971    this.docLocation = location;
  5972  };
  5973  
  5974  /**
  5975   * converts a resource listing OR api declaration
  5976   **/
  5977  SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) {
  5978    // not a valid spec
  5979    if(!obj || !Array.isArray(obj.apis)) {
  5980      return this.finish(callback, null);
  5981    }
  5982    this.clientAuthorizations = clientAuthorizations;
  5983  
  5984    // create a new swagger object to return
  5985    var swagger = { swagger: '2.0' };
  5986  
  5987    swagger.originalVersion = obj.swaggerVersion;
  5988  
  5989    // add the info
  5990    this.apiInfo(obj, swagger);
  5991  
  5992    // add security definitions
  5993    this.securityDefinitions(obj, swagger);
  5994  
  5995    // take basePath into account
  5996    if (obj.basePath) {
  5997      this.setDocumentationLocation(obj.basePath);
  5998    }
  5999  
  6000    // see if this is a single-file swagger definition
  6001    var isSingleFileSwagger = false;
  6002    var i;
  6003    for(i = 0; i < obj.apis.length; i++) {
  6004      var api = obj.apis[i];
  6005      if(Array.isArray(api.operations)) {
  6006        isSingleFileSwagger = true;
  6007      }
  6008    }
  6009    if(isSingleFileSwagger) {
  6010      this.declaration(obj, swagger);
  6011      this.finish(callback, swagger);
  6012    }
  6013    else {
  6014      this.resourceListing(obj, swagger, opts, callback);
  6015    }
  6016  };
  6017  
  6018  SwaggerSpecConverter.prototype.declaration = function(obj, swagger) {
  6019    var name, i, p, pos;
  6020    if(!obj.apis) {
  6021      return;
  6022    }
  6023  
  6024    if (obj.basePath.indexOf('http://') === 0) {
  6025      p = obj.basePath.substring('http://'.length);
  6026      pos = p.indexOf('/');
  6027      if (pos > 0) {
  6028        swagger.host = p.substring(0, pos);
  6029        swagger.basePath = p.substring(pos);
  6030      }
  6031      else {
  6032        swagger.host = p;
  6033        swagger.basePath = '/';
  6034      }
  6035    } else if (obj.basePath.indexOf('https://') === 0) {
  6036      p = obj.basePath.substring('https://'.length);
  6037      pos = p.indexOf('/');
  6038      if (pos > 0) {
  6039        swagger.host = p.substring(0, pos);
  6040        swagger.basePath = p.substring(pos);
  6041      }
  6042      else {
  6043        swagger.host = p;
  6044        swagger.basePath = '/';
  6045      }
  6046    } else {
  6047      swagger.basePath = obj.basePath;
  6048    }
  6049  
  6050    var resourceLevelAuth;
  6051    if(obj.authorizations) {
  6052      resourceLevelAuth = obj.authorizations;
  6053    }
  6054    if(obj.consumes) {
  6055      swagger.consumes = obj.consumes;
  6056    }
  6057    if(obj.produces) {
  6058      swagger.produces = obj.produces;
  6059    }
  6060  
  6061    // build a mapping of id to name for 1.0 model resolutions
  6062    if(_.isObject(obj)) {
  6063      for(name in obj.models) {
  6064        var existingModel = obj.models[name];
  6065        var key = (existingModel.id || name);
  6066        this.modelMap[key] = name;
  6067      }
  6068    }
  6069  
  6070    for(i = 0; i < obj.apis.length; i++) {
  6071      var api = obj.apis[i];
  6072      var path = api.path;
  6073      var operations = api.operations;
  6074      this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger);
  6075    }
  6076  
  6077    var models = obj.models || {};
  6078    this.models(models, swagger);
  6079  };
  6080  
  6081  SwaggerSpecConverter.prototype.models = function(obj, swagger) {
  6082    if(!_.isObject(obj)) {
  6083      return;
  6084    }
  6085    var name;
  6086  
  6087    swagger.definitions = swagger.definitions || {};
  6088    for(name in obj) {
  6089      var existingModel = obj[name];
  6090      var _required = [];
  6091      var schema = { properties: {}};
  6092      var propertyName;
  6093      for(propertyName in existingModel.properties) {
  6094        var existingProperty = existingModel.properties[propertyName];
  6095        var property = {};
  6096        this.dataType(existingProperty, property);
  6097        if(existingProperty.description) {
  6098          property.description = existingProperty.description;
  6099        }
  6100        if(existingProperty['enum']) {
  6101          property['enum'] = existingProperty['enum'];
  6102        }
  6103        if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) {
  6104          _required.push(propertyName);
  6105        }
  6106        if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') {
  6107          _required.push(propertyName);
  6108        }
  6109        schema.properties[propertyName] = property;
  6110      }
  6111      if(_required.length > 0) {
  6112        schema.required = _required;
  6113      } else {
  6114        schema.required = existingModel.required;
  6115      }
  6116      swagger.definitions[name] = schema;
  6117    }
  6118  };
  6119  
  6120  SwaggerSpecConverter.prototype.extractTag = function(resourcePath) {
  6121    var pathString = resourcePath || 'default';
  6122    if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) {
  6123      pathString = pathString.split(['/']);
  6124      pathString = pathString[pathString.length -1].substring();
  6125    }
  6126    if(pathString.endsWith('.json')) {
  6127      pathString = pathString.substring(0, pathString.length - '.json'.length);
  6128    }
  6129    return pathString.replace('/','');
  6130  };
  6131  
  6132  SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) {
  6133    if(!Array.isArray(obj)) {
  6134      return;
  6135    }
  6136    var i;
  6137  
  6138    if(!swagger.paths) {
  6139      swagger.paths = {};
  6140    }
  6141  
  6142    var pathObj = swagger.paths[path] || {};
  6143    var tag = this.extractTag(resourcePath);
  6144    swagger.tags = swagger.tags || [];
  6145    var matched = false;
  6146    for(i = 0; i < swagger.tags.length; i++) {
  6147      var tagObject = swagger.tags[i];
  6148      if(tagObject.name === tag) {
  6149        matched = true;
  6150      }
  6151    }
  6152    if(!matched) {
  6153      swagger.tags.push({name: tag});
  6154    }
  6155  
  6156    for(i = 0; i < obj.length; i++) {
  6157      var existingOperation = obj[i];
  6158      var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase();
  6159      var operation = {tags: [tag]};
  6160      var existingAuthorizations = existingOperation.authorizations;
  6161  
  6162      if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) {
  6163        existingAuthorizations = resourceLevelAuth;
  6164      }
  6165  
  6166      if(typeof existingAuthorizations !== 'undefined') {
  6167        var scopesObject;
  6168        for(var key in existingAuthorizations) {
  6169          operation.security = operation.security || [];
  6170          var scopes = existingAuthorizations[key];
  6171          if(scopes) {
  6172            var securityScopes = [];
  6173            for(var j in scopes) {
  6174              securityScopes.push(scopes[j].scope);
  6175            }
  6176            scopesObject = {};
  6177            scopesObject[key] = securityScopes;
  6178            operation.security.push(scopesObject);
  6179          }
  6180          else {
  6181            scopesObject = {};
  6182            scopesObject[key] = [];
  6183            operation.security.push(scopesObject);
  6184          }
  6185        }
  6186      }
  6187  
  6188      if(existingOperation.consumes) {
  6189        operation.consumes = existingOperation.consumes;
  6190      }
  6191      else if(swagger.consumes) {
  6192        operation.consumes = swagger.consumes;
  6193      }
  6194      if(existingOperation.produces) {
  6195        operation.produces = existingOperation.produces;
  6196      }
  6197      else if(swagger.produces) {
  6198        operation.produces = swagger.produces;
  6199      }
  6200      if(existingOperation.summary) {
  6201        operation.summary = existingOperation.summary;
  6202      }
  6203      if(existingOperation.notes) {
  6204        operation.description = existingOperation.notes;
  6205      }
  6206      if(existingOperation.nickname) {
  6207        operation.operationId = existingOperation.nickname;
  6208      }
  6209      if(existingOperation.deprecated) {
  6210        operation.deprecated = existingOperation.deprecated;
  6211      }
  6212  
  6213      this.authorizations(existingAuthorizations, swagger);
  6214      this.parameters(operation, existingOperation.parameters, swagger);
  6215      this.responseMessages(operation, existingOperation, swagger);
  6216  
  6217      pathObj[method] = operation;
  6218    }
  6219  
  6220    swagger.paths[path] = pathObj;
  6221  };
  6222  
  6223  SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) {
  6224    if(!_.isObject(existingOperation)) {
  6225      return;
  6226    }
  6227    // build default response from the operation (1.x)
  6228    var defaultResponse = {};
  6229    this.dataType(existingOperation, defaultResponse);
  6230    // TODO: look into the real problem of rendering responses in swagger-ui
  6231    // ....should reponseType have an implicit schema?
  6232    if(!defaultResponse.schema && defaultResponse.type) {
  6233      defaultResponse = {schema: defaultResponse};
  6234    }
  6235  
  6236    operation.responses = operation.responses || {};
  6237  
  6238    // grab from responseMessages (1.2)
  6239    var has200 = false;
  6240    if(Array.isArray(existingOperation.responseMessages)) {
  6241      var i;
  6242      var existingResponses = existingOperation.responseMessages;
  6243      for(i = 0; i < existingResponses.length; i++) {
  6244        var existingResponse = existingResponses[i];
  6245        var response = { description: existingResponse.message };
  6246        if(existingResponse.code === 200) {
  6247          has200 = true;
  6248        }
  6249        // Convert responseModel -> schema{$ref: responseModel}
  6250        if(existingResponse.responseModel) {
  6251          response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel};
  6252        }
  6253        operation.responses['' + existingResponse.code] = response;
  6254      }
  6255    }
  6256  
  6257    if(has200) {
  6258      operation.responses['default'] = defaultResponse;
  6259    }
  6260    else {
  6261      operation.responses['200'] = defaultResponse;
  6262    }
  6263  };
  6264  
  6265  SwaggerSpecConverter.prototype.authorizations = function(obj) {
  6266    // TODO
  6267    if(!_.isObject(obj)) {
  6268      return;
  6269    }
  6270  };
  6271  
  6272  SwaggerSpecConverter.prototype.parameters = function(operation, obj) {
  6273    if(!Array.isArray(obj)) {
  6274      return;
  6275    }
  6276    var i;
  6277    for(i = 0; i < obj.length; i++) {
  6278      var existingParameter = obj[i];
  6279      var parameter = {};
  6280      parameter.name = existingParameter.name;
  6281      parameter.description = existingParameter.description;
  6282      parameter.required = existingParameter.required;
  6283      parameter.in = existingParameter.paramType;
  6284  
  6285      // per #168
  6286      if(parameter.in === 'body') {
  6287        parameter.name = 'body';
  6288      }
  6289      if(parameter.in === 'form') {
  6290        parameter.in = 'formData';
  6291      }
  6292  
  6293      if(existingParameter.enum) {
  6294        parameter.enum = existingParameter.enum;
  6295      }
  6296  
  6297      if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') {
  6298        var innerType = {};
  6299        this.dataType(existingParameter, innerType);
  6300        parameter.type = 'array';
  6301        parameter.items = innerType;
  6302  
  6303        if(existingParameter.allowableValues) {
  6304          var av = existingParameter.allowableValues;
  6305          if(av.valueType === 'LIST') {
  6306            parameter['enum'] = av.values;
  6307          }
  6308        }
  6309      }
  6310      else {
  6311        this.dataType(existingParameter, parameter);
  6312      }
  6313      if(typeof existingParameter.defaultValue !== 'undefined') {
  6314        parameter.default = existingParameter.defaultValue;
  6315      }
  6316  
  6317      operation.parameters = operation.parameters || [];
  6318      operation.parameters.push(parameter);
  6319    }
  6320  };
  6321  
  6322  SwaggerSpecConverter.prototype.dataType = function(source, target) {
  6323    if(!_.isObject(source)) {
  6324      return;
  6325    }
  6326  
  6327    if(source.minimum) {
  6328      target.minimum = source.minimum;
  6329    }
  6330    if(source.maximum) {
  6331      target.maximum = source.maximum;
  6332    }
  6333    if (source.format) {
  6334      target.format = source.format;
  6335    }
  6336  
  6337    // default can be 'false'
  6338    if(typeof source.defaultValue !== 'undefined') {
  6339      target.default = source.defaultValue;
  6340    }
  6341  
  6342    var jsonSchemaType = this.toJsonSchema(source);
  6343    if(jsonSchemaType) {
  6344      target = target || {};
  6345      if(jsonSchemaType.type) {
  6346        target.type = jsonSchemaType.type;
  6347      }
  6348      if(jsonSchemaType.format) {
  6349        target.format = jsonSchemaType.format;
  6350      }
  6351      if(jsonSchemaType.$ref) {
  6352        target.schema = {$ref: jsonSchemaType.$ref};
  6353      }
  6354      if(jsonSchemaType.items) {
  6355        target.items = jsonSchemaType.items;
  6356      }
  6357    }
  6358  };
  6359  
  6360  SwaggerSpecConverter.prototype.toJsonSchema = function(source) {
  6361    if(!source) {
  6362      return 'object';
  6363    }
  6364    var detectedType = (source.type || source.dataType || source.responseClass || '');
  6365    var lcType = detectedType.toLowerCase();
  6366    var format = (source.format || '').toLowerCase();
  6367  
  6368    if(lcType.indexOf('list[') === 0) {
  6369      var innerType = detectedType.substring(5, detectedType.length - 1);
  6370      var jsonType = this.toJsonSchema({type: innerType});
  6371      return {type: 'array', items: jsonType};
  6372    } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) {
  6373      {return {type: 'integer', format: 'int32'};}
  6374    } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) {
  6375      {return {type: 'integer', format: 'int64'};}
  6376    } else if(lcType === 'integer') {
  6377      {return {type: 'integer', format: 'int64'};}
  6378    } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) {
  6379      {return {type: 'number', format: 'float'};}
  6380    } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) {
  6381      {return {type: 'number', format: 'double'};}
  6382    } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) {
  6383      {return {type: 'string', format: 'date-time'};}
  6384    } else if(lcType === 'string') {
  6385      {return {type: 'string'};}
  6386    } else if(lcType === 'file') {
  6387      {return {type: 'file'};}
  6388    } else if(lcType === 'boolean') {
  6389      {return {type: 'boolean'};}
  6390    } else if(lcType === 'boolean') {
  6391      {return {type: 'boolean'};}
  6392    } else if(lcType === 'array' || lcType === 'list') {
  6393      if(source.items) {
  6394        var it = this.toJsonSchema(source.items);
  6395        return {type: 'array', items: it};
  6396      }
  6397      else {
  6398        return {type: 'array', items: {type: 'object'}};
  6399      }
  6400    } else if(source.$ref) {
  6401      return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref};
  6402    } else if(lcType === 'void' || lcType === '') {
  6403      {return {};}
  6404    } else if (this.modelMap[source.type]) {
  6405      // If this a model using `type` instead of `$ref`, that's fine.
  6406      return {$ref: '#/definitions/' + this.modelMap[source.type]};
  6407    } else {
  6408      // Unknown model type or 'object', pass it along.
  6409      return {type: source.type};
  6410    }
  6411  };
  6412  
  6413  SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) {
  6414    var i;
  6415    var processedCount = 0;   // jshint ignore:line
  6416    var self = this;          // jshint ignore:line
  6417    var expectedCount = obj.apis.length;
  6418    var _swagger = swagger;   // jshint ignore:line
  6419    var _opts = {};
  6420  
  6421    if(opts && opts.requestInterceptor){
  6422      _opts.requestInterceptor = opts.requestInterceptor;
  6423    }
  6424  
  6425    if(opts && opts.responseInterceptor){
  6426      _opts.responseInterceptor = opts.responseInterceptor;
  6427    }
  6428  
  6429    var swaggerRequestHeaders = 'application/json';
  6430  
  6431    if(opts && opts.swaggerRequestHeaders) {
  6432      swaggerRequestHeaders = opts.swaggerRequestHeaders;
  6433    }
  6434  
  6435    if(expectedCount === 0) {
  6436      this.finish(callback, swagger);
  6437    }
  6438  
  6439    for(i = 0; i < expectedCount; i++) {
  6440      var api = obj.apis[i];
  6441      var path = api.path;
  6442      var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path);
  6443  
  6444      if(api.description) {
  6445        swagger.tags = swagger.tags || [];
  6446        swagger.tags.push({
  6447          name : this.extractTag(api.path),
  6448          description : api.description || ''
  6449        });
  6450      }
  6451      var http = {
  6452        url: absolutePath,
  6453        headers: { accept: swaggerRequestHeaders },
  6454        on: {},
  6455        method: 'get',
  6456        timeout: opts.timeout
  6457      };
  6458      /* jshint ignore:start */
  6459      http.on.response = function(data) {
  6460        processedCount += 1;
  6461        var obj = data.obj;
  6462        if(obj) {
  6463          self.declaration(obj, _swagger);
  6464        }
  6465        if(processedCount === expectedCount) {
  6466          self.finish(callback, _swagger);
  6467        }
  6468      };
  6469      http.on.error = function(data) {
  6470        console.error(data);
  6471        processedCount += 1;
  6472        if(processedCount === expectedCount) {
  6473          self.finish(callback, _swagger);
  6474        }
  6475      };
  6476      /* jshint ignore:end */
  6477  
  6478      if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') {
  6479        this.clientAuthorizations.apply(http);
  6480      }
  6481  
  6482      new SwaggerHttp().execute(http, _opts);
  6483    }
  6484  };
  6485  
  6486  SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path)  {
  6487    if(version === '1.0') {
  6488      if(docLocation.endsWith('.json')) {
  6489        // get root path
  6490        var pos = docLocation.lastIndexOf('/');
  6491        if(pos > 0) {
  6492          docLocation = docLocation.substring(0, pos);
  6493        }
  6494      }
  6495    }
  6496  
  6497    var location = docLocation;
  6498    if(path.indexOf('http:') === 0 || path.indexOf('https:') === 0) {
  6499      location = path;
  6500    }
  6501    else {
  6502      if(docLocation.endsWith('/')) {
  6503        location = docLocation.substring(0, docLocation.length - 1);
  6504      }
  6505      location += path;
  6506    }
  6507    location = location.replace('{format}', 'json');
  6508    return location;
  6509  };
  6510  
  6511  SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) {
  6512    if(obj.authorizations) {
  6513      var name;
  6514      for(name in obj.authorizations) {
  6515        var isValid = false;
  6516        var securityDefinition = {
  6517          vendorExtensions: {}
  6518        };
  6519        var definition = obj.authorizations[name];
  6520        if(definition.type === 'apiKey') {
  6521          securityDefinition.type = 'apiKey';
  6522          securityDefinition.in = definition.passAs;
  6523          securityDefinition.name = definition.keyname || name;
  6524          isValid = true;
  6525        }
  6526        else if(definition.type === 'basicAuth') {
  6527          securityDefinition.type = 'basicAuth';
  6528          isValid = true;
  6529        }
  6530        else if(definition.type === 'oauth2') {
  6531          var existingScopes = definition.scopes || [];
  6532          var scopes = {};
  6533          var i;
  6534          for(i in existingScopes) {
  6535            var scope = existingScopes[i];
  6536            scopes[scope.scope] = scope.description;
  6537          }
  6538          securityDefinition.type = 'oauth2';
  6539          if(i > 0) {
  6540            securityDefinition.scopes = scopes;
  6541          }
  6542          if(definition.grantTypes) {
  6543            if(definition.grantTypes.implicit) {
  6544              var implicit = definition.grantTypes.implicit;
  6545              securityDefinition.flow = 'implicit';
  6546              securityDefinition.authorizationUrl = implicit.loginEndpoint;
  6547              isValid = true;
  6548            }
  6549            /* jshint ignore:start */
  6550            if(definition.grantTypes['authorization_code']) {
  6551              if(!securityDefinition.flow) {
  6552                // cannot set if flow is already defined
  6553                var authCode = definition.grantTypes['authorization_code'];
  6554                securityDefinition.flow = 'accessCode';
  6555                securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url;
  6556                securityDefinition.tokenUrl = authCode.tokenEndpoint.url;
  6557                isValid = true;
  6558              }
  6559            }
  6560            /* jshint ignore:end */
  6561          }
  6562        }
  6563        if(isValid) {
  6564          swagger.securityDefinitions = swagger.securityDefinitions || {};
  6565          swagger.securityDefinitions[name] = securityDefinition;
  6566        }
  6567      }
  6568    }
  6569  };
  6570  
  6571  SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) {
  6572    // info section
  6573    if(obj.info) {
  6574      var info = obj.info;
  6575      swagger.info = {};
  6576  
  6577      if(info.contact) {
  6578        swagger.info.contact = {};
  6579        swagger.info.contact.email = info.contact;
  6580      }
  6581      if(info.description) {
  6582        swagger.info.description = info.description;
  6583      }
  6584      if(info.title) {
  6585        swagger.info.title = info.title;
  6586      }
  6587      if(info.termsOfServiceUrl) {
  6588        swagger.info.termsOfService = info.termsOfServiceUrl;
  6589      }
  6590      if(info.license || info.licenseUrl) {
  6591        swagger.license = {};
  6592        if(info.license) {
  6593          swagger.license.name = info.license;
  6594        }
  6595        if(info.licenseUrl) {
  6596          swagger.license.url = info.licenseUrl;
  6597        }
  6598      }
  6599    }
  6600    else {
  6601      this.warnings.push('missing info section');
  6602    }
  6603  };
  6604  
  6605  SwaggerSpecConverter.prototype.finish = function (callback, obj) {
  6606    callback(obj);
  6607  };
  6608  
  6609  },{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(require,module,exports){
  6610  'use strict';
  6611  
  6612  var log = require('../helpers').log;
  6613  var _ = {
  6614    isPlainObject: require('lodash-compat/lang/isPlainObject'),
  6615    isString: require('lodash-compat/lang/isString'),
  6616  };
  6617  
  6618  var SchemaMarkup = require('../schema-markup.js');
  6619  var jsyaml = require('js-yaml');
  6620  
  6621  var Model = module.exports = function (name, definition, models, modelPropertyMacro) {
  6622    this.definition = definition || {};
  6623    this.isArray = definition.type === 'array';
  6624    this.models = models || {};
  6625    this.name = name || definition.title || 'Inline Model';
  6626    this.modelPropertyMacro = modelPropertyMacro || function (property) {
  6627      return property.default;
  6628    };
  6629  
  6630    return this;
  6631  };
  6632  
  6633  // Note!  This function will be removed in 2.2.x!
  6634  Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) {
  6635    modelsToIgnore = modelsToIgnore || {};
  6636  
  6637    modelsToIgnore[this.name] = this;
  6638  
  6639    // Response support
  6640    if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) {
  6641      this.definition.example = this.examples['application/json'];
  6642  
  6643      if (_.isString(this.definition.example)) {
  6644        this.definition.example = jsyaml.safeLoad(this.definition.example);
  6645      }
  6646    } else if (!this.definition.example) {
  6647      this.definition.example = this.examples;
  6648    }
  6649  
  6650    return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro);
  6651  };
  6652  
  6653  Model.prototype.getMockSignature = function () {
  6654    return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro);
  6655  };
  6656  
  6657  },{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(require,module,exports){
  6658  'use strict';
  6659  
  6660  var _ = {
  6661    cloneDeep: require('lodash-compat/lang/cloneDeep'),
  6662    isUndefined: require('lodash-compat/lang/isUndefined'),
  6663    isEmpty: require('lodash-compat/lang/isEmpty'),
  6664    isObject: require('lodash-compat/lang/isObject')
  6665  };
  6666  var helpers = require('../helpers');
  6667  var Model = require('./model');
  6668  var SwaggerHttp = require('../http');
  6669  var Q = require('q');
  6670  
  6671  var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) {
  6672    var errors = [];
  6673  
  6674    parent = parent || {};
  6675    args = args || {};
  6676  
  6677    if(parent && parent.options) {
  6678      this.client = parent.options.client || null;
  6679      this.requestInterceptor = parent.options.requestInterceptor || null;
  6680      this.responseInterceptor = parent.options.responseInterceptor || null;
  6681      this.requestAgent = parent.options.requestAgent;
  6682    }
  6683    this.authorizations = args.security;
  6684    this.basePath = parent.basePath || '/';
  6685    this.clientAuthorizations = clientAuthorizations;
  6686    this.consumes = args.consumes || parent.consumes || ['application/json'];
  6687    this.produces = args.produces || parent.produces || ['application/json'];
  6688    this.deprecated = args.deprecated;
  6689    this.description = args.description;
  6690    this.host = parent.host;
  6691    this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.'));
  6692    this.models = models || {};
  6693    this.nickname = (operationId || errors.push('Operations must have a nickname.'));
  6694    this.operation = args;
  6695    this.operations = {};
  6696    this.parameters = args !== null ? (args.parameters || []) : {};
  6697    this.parent = parent;
  6698    this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.'));
  6699    this.responses = (args.responses || {});
  6700    this.scheme = scheme || parent.scheme || 'http';
  6701    this.schemes = args.schemes || parent.schemes;
  6702    this.security = args.security || parent.security;
  6703    this.summary = args.summary || '';
  6704    this.timeout = parent.timeout;
  6705    this.type = null;
  6706    this.useJQuery = parent.useJQuery;
  6707    this.jqueryAjaxCache = parent.jqueryAjaxCache;
  6708    this.enableCookies = parent.enableCookies;
  6709  
  6710    var key;
  6711  
  6712    if(!this.host) {
  6713      if(typeof window !== 'undefined') {
  6714        this.host = window.location.host;
  6715      }
  6716      else {
  6717        this.host = 'localhost';
  6718      }
  6719    }
  6720    this.parameterMacro = parent.parameterMacro || function (operation, parameter) {
  6721      return parameter.default;
  6722    };
  6723  
  6724    this.inlineModels = [];
  6725  
  6726    if(this.basePath !== '/' && this.basePath.slice(-1) === '/') {
  6727      this.basePath = this.basePath.slice(0, -1);
  6728    }
  6729  
  6730    if (typeof this.deprecated === 'string') {
  6731      switch(this.deprecated.toLowerCase()) {
  6732        case 'true': case 'yes': case '1': {
  6733          this.deprecated = true;
  6734          break;
  6735        }
  6736  
  6737        case 'false': case 'no': case '0': case null: {
  6738          this.deprecated = false;
  6739          break;
  6740        }
  6741  
  6742        default: this.deprecated = Boolean(this.deprecated);
  6743      }
  6744    }
  6745  
  6746    var i, model;
  6747  
  6748    if (definitions) {
  6749      // add to global models
  6750      for (key in definitions) {
  6751        model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro);
  6752  
  6753        if (model) {
  6754          this.models[key] = model;
  6755        }
  6756      }
  6757    }
  6758    else {
  6759      definitions = {};
  6760    }
  6761  
  6762    for (i = 0; i < this.parameters.length; i++) {
  6763      var d, param = this.parameters[i];
  6764  
  6765      // Allow macro to set the default value
  6766      param.default = this.parameterMacro(this, param);
  6767  
  6768      if (param.type === 'array') {
  6769        param.isList = true;
  6770        param.allowMultiple = true;
  6771      }
  6772  
  6773      var innerType = this.getType(param);
  6774  
  6775      if (innerType && innerType.toString().toLowerCase() === 'boolean') {
  6776        param.allowableValues = {};
  6777        param.isList = true;
  6778        param['enum'] = [true, false]; // use actual primitives
  6779      }
  6780  
  6781      for(key in param) {
  6782        helpers.extractExtensions(key, param);
  6783      }
  6784      if(typeof param['x-example'] !== 'undefined') {
  6785        d = param['x-example'];
  6786        param.default = d;
  6787      }
  6788      if(param['x-examples']) {
  6789        d = param['x-examples'].default;
  6790        if(typeof d !== 'undefined') {
  6791          param.default = d;
  6792        }
  6793      }
  6794  
  6795      var enumValues = param['enum'] || (param.items && param.items['enum']);
  6796  
  6797      if (typeof enumValues !== 'undefined') {
  6798        var id;
  6799  
  6800        param.allowableValues = {};
  6801        param.allowableValues.values = [];
  6802        param.allowableValues.descriptiveValues = [];
  6803  
  6804        for (id = 0; id < enumValues.length; id++) {
  6805          var value = enumValues[id];
  6806          var isDefault = (value === param.default || value+'' === param.default);
  6807  
  6808          param.allowableValues.values.push(value);
  6809          // Always have string for descriptive values....
  6810          param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault});
  6811        }
  6812      }
  6813  
  6814      if (param.type === 'array') {
  6815        innerType = [innerType];
  6816  
  6817        if (typeof param.allowableValues === 'undefined') {
  6818          // can't show as a list if no values to select from
  6819          delete param.isList;
  6820          delete param.allowMultiple;
  6821        }
  6822      }
  6823  
  6824      param.modelSignature = {type: innerType, definitions: this.models};
  6825      param.signature = this.getModelSignature(innerType, this.models).toString();
  6826      param.sampleJSON = this.getModelSampleJSON(innerType, this.models);
  6827      param.responseClassSignature = param.signature;
  6828    }
  6829  
  6830    var keyname, defaultResponseCode, response, responses = this.responses;
  6831  
  6832    if (responses['200']) {
  6833      response = responses['200'];
  6834      defaultResponseCode = '200';
  6835    } else if (responses['201']) {
  6836      response = responses['201'];
  6837      defaultResponseCode = '201';
  6838    } else if (responses['202']) {
  6839      response = responses['202'];
  6840      defaultResponseCode = '202';
  6841    } else if (responses['203']) {
  6842      response = responses['203'];
  6843      defaultResponseCode = '203';
  6844    } else if (responses['204']) {
  6845      response = responses['204'];
  6846      defaultResponseCode = '204';
  6847    } else if (responses['205']) {
  6848      response = responses['205'];
  6849      defaultResponseCode = '205';
  6850    } else if (responses['206']) {
  6851      response = responses['206'];
  6852      defaultResponseCode = '206';
  6853    } else if (responses['default']) {
  6854      response = responses['default'];
  6855      defaultResponseCode = 'default';
  6856    }
  6857  
  6858    for(keyname in responses) {
  6859      helpers.extractExtensions(keyname, responses);
  6860      if(typeof keyname === 'string' && keyname.indexOf('x-') === -1) {
  6861        var responseObject = responses[keyname];
  6862        if(typeof responseObject === 'object' && typeof responseObject.headers === 'object') {
  6863          var headers = responseObject.headers;
  6864          for(var headerName in headers) {
  6865            var header = headers[headerName];
  6866            if(typeof header === 'object') {
  6867              for(var headerKey in header) {
  6868                helpers.extractExtensions(headerKey, header);
  6869              }
  6870            }
  6871          }
  6872        }
  6873      }
  6874    }
  6875  
  6876    if (response) {
  6877      for(keyname in response) {
  6878        helpers.extractExtensions(keyname, response);
  6879      }
  6880    }
  6881  
  6882    if (response && response.schema) {
  6883      var resolvedModel = this.resolveModel(response.schema, definitions);
  6884      var successResponse;
  6885  
  6886      delete responses[defaultResponseCode];
  6887  
  6888      if (resolvedModel) {
  6889        this.successResponse = {};
  6890        successResponse = this.successResponse[defaultResponseCode] = resolvedModel;
  6891      } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') {
  6892        // Inline model
  6893        this.successResponse = {};
  6894        successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro);
  6895      } else {
  6896        // Primitive
  6897        this.successResponse = {};
  6898        successResponse = this.successResponse[defaultResponseCode] = response.schema;
  6899      }
  6900  
  6901      if (successResponse) {
  6902        successResponse.vendorExtensions = response.vendorExtensions;
  6903        // Attach response properties
  6904        if (response.description) {
  6905          successResponse.description = response.description;
  6906        }
  6907  
  6908        if (response.examples) {
  6909          successResponse.examples = response.examples;
  6910        }
  6911  
  6912        if (response.headers) {
  6913          successResponse.headers = response.headers;
  6914        }
  6915      }
  6916  
  6917      this.type = response;
  6918    }
  6919  
  6920    if (errors.length > 0) {
  6921      if (this.resource && this.resource.api && this.resource.api.fail) {
  6922        this.resource.api.fail(errors);
  6923      }
  6924    }
  6925  
  6926    return this;
  6927  };
  6928  
  6929  Operation.prototype.isDefaultArrayItemValue = function(value, param) {
  6930    if (param.default && Array.isArray(param.default)) {
  6931      return param.default.indexOf(value) !== -1;
  6932    }
  6933    return value === param.default;
  6934  };
  6935  
  6936  Operation.prototype.getType = function (param) {
  6937    var type = param.type;
  6938    var format = param.format;
  6939    var isArray = false;
  6940    var str;
  6941  
  6942    if (type === 'integer' && format === 'int32') {
  6943      str = 'integer';
  6944    } else if (type === 'integer' && format === 'int64') {
  6945      str = 'long';
  6946    } else if (type === 'integer') {
  6947      str = 'integer';
  6948    } else if (type === 'string') {
  6949      if (format === 'date-time') {
  6950        str = 'date-time';
  6951      } else if (format === 'date') {
  6952        str = 'date';
  6953      } else {
  6954        str = 'string';
  6955      }
  6956    } else if (type === 'number' && format === 'float') {
  6957      str = 'float';
  6958    } else if (type === 'number' && format === 'double') {
  6959      str = 'double';
  6960    } else if (type === 'number') {
  6961      str = 'double';
  6962    } else if (type === 'boolean') {
  6963      str = 'boolean';
  6964    } else if (type === 'array') {
  6965      isArray = true;
  6966  
  6967      if (param.items) {
  6968        str = this.getType(param.items);
  6969      }
  6970    } else if (type === 'file') {
  6971      str = 'file';
  6972    }
  6973  
  6974    if (param.$ref) {
  6975      str = helpers.simpleRef(param.$ref);
  6976    }
  6977  
  6978    var schema = param.schema;
  6979  
  6980    if (schema) {
  6981      var ref = schema.$ref;
  6982  
  6983      if (ref) {
  6984        ref = helpers.simpleRef(ref);
  6985  
  6986        if (isArray) {
  6987          return [ ref ];
  6988        } else {
  6989          return ref;
  6990        }
  6991      } else {
  6992        // If inline schema, we add it our interal hash -> which gives us it's ID (int)
  6993        if(schema.type === 'object') {
  6994          return this.addInlineModel(schema);
  6995        }
  6996        return this.getType(schema);
  6997      }
  6998    }
  6999    if (isArray) {
  7000      return [ str ];
  7001    } else {
  7002      return str;
  7003    }
  7004  };
  7005  
  7006  /**
  7007   * adds an inline schema (model) to a hash, where we can ref it later
  7008   * @param {object} schema a schema
  7009   * @return {number} the ID of the schema being added, or null
  7010   **/
  7011  Operation.prototype.addInlineModel = function (schema) {
  7012    var len = this.inlineModels.length;
  7013    var model = this.resolveModel(schema, {});
  7014    if(model) {
  7015      this.inlineModels.push(model);
  7016      return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel)
  7017    }
  7018    return null; // report errors?
  7019  };
  7020  
  7021  /**
  7022   * gets the internal ref to an inline model
  7023   * @param {string} inline_str a string reference to an inline model
  7024   * @return {Model} the model being referenced. Or null
  7025   **/
  7026  Operation.prototype.getInlineModel = function(inlineStr) {
  7027    if(/^Inline Model \d+$/.test(inlineStr)) {
  7028      var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
  7029      var model = this.inlineModels[id];
  7030      return model;
  7031    }
  7032    // I'm returning null here, should I rather throw an error?
  7033    return null;
  7034  };
  7035  
  7036  Operation.prototype.resolveModel = function (schema, definitions) {
  7037    if (typeof schema.$ref !== 'undefined') {
  7038      var ref = schema.$ref;
  7039  
  7040      if (ref.indexOf('#/definitions/') === 0) {
  7041        ref = ref.substring('#/definitions/'.length);
  7042      }
  7043  
  7044      if (definitions[ref]) {
  7045        return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro);
  7046      }
  7047    // schema must at least be an object to get resolved to an inline Model
  7048    } else if (schema && typeof schema === 'object' &&
  7049              (schema.type === 'object' || _.isUndefined(schema.type))) {
  7050      return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro);
  7051    }
  7052  
  7053    return null;
  7054  };
  7055  
  7056  Operation.prototype.help = function (dontPrint) {
  7057    var out = this.nickname + ': ' + this.summary + '\n';
  7058  
  7059    for (var i = 0; i < this.parameters.length; i++) {
  7060      var param = this.parameters[i];
  7061      var typeInfo = param.signature;
  7062  
  7063      out += '\n  * ' + param.name + ' (' + typeInfo + '): ' + param.description;
  7064    }
  7065  
  7066    if (typeof dontPrint === 'undefined') {
  7067      helpers.log(out);
  7068    }
  7069  
  7070    return out;
  7071  };
  7072  
  7073  Operation.prototype.getModelSignature = function (type, definitions) {
  7074    var isPrimitive, listType;
  7075  
  7076    if (type instanceof Array) {
  7077      listType = true;
  7078      type = type[0];
  7079    }
  7080  
  7081    // Convert undefined to string of 'undefined'
  7082    if (typeof type === 'undefined') {
  7083      type = 'undefined';
  7084      isPrimitive = true;
  7085  
  7086    } else if (definitions[type]){
  7087      // a model def exists?
  7088      type = definitions[type]; /* Model */
  7089      isPrimitive = false;
  7090  
  7091    } else if (this.getInlineModel(type)) {
  7092      type = this.getInlineModel(type); /* Model */
  7093      isPrimitive = false;
  7094  
  7095    } else {
  7096      // We default to primitive
  7097      isPrimitive = true;
  7098    }
  7099  
  7100    if (isPrimitive) {
  7101      if (listType) {
  7102        return 'Array[' + type + ']';
  7103      } else {
  7104        return type.toString();
  7105      }
  7106    } else {
  7107      if (listType) {
  7108        return 'Array[' + type.getMockSignature() + ']';
  7109      } else {
  7110        return type.getMockSignature();
  7111      }
  7112    }
  7113  };
  7114  
  7115  Operation.prototype.supportHeaderParams = function () {
  7116    return true;
  7117  };
  7118  
  7119  Operation.prototype.supportedSubmitMethods = function () {
  7120    return this.parent.supportedSubmitMethods;
  7121  };
  7122  
  7123  Operation.prototype.getHeaderParams = function (args) {
  7124    var headers = this.setContentTypes(args, {});
  7125    var headerParamsByLowerCase = {};
  7126  
  7127    for (var i = 0; i < this.parameters.length; i++) {
  7128      var param = this.parameters[i];
  7129  
  7130      if (param.in === 'header') {
  7131        headerParamsByLowerCase[param.name.toLowerCase()] = param;
  7132      }
  7133    }
  7134  
  7135    for (var arg in args) {
  7136      var headerParam = headerParamsByLowerCase[arg.toLowerCase()];
  7137      if (typeof headerParam !== 'undefined') {
  7138        var value = args[arg];
  7139  
  7140        if (Array.isArray(value)) {
  7141          value = value.toString();
  7142        }
  7143  
  7144        headers[headerParam.name] = value;
  7145      }
  7146    }
  7147  
  7148    return headers;
  7149  };
  7150  
  7151  Operation.prototype.urlify = function (args) {
  7152    var formParams = {};
  7153    var requestUrl = this.path.replace(/#.*/, ''); // remove URL fragment
  7154    var querystring = ''; // grab params from the args, build the querystring along the way
  7155  
  7156    for (var i = 0; i < this.parameters.length; i++) {
  7157      var param = this.parameters[i];
  7158  
  7159      if (typeof args[param.name] !== 'undefined') {
  7160        if (param.in === 'path') {
  7161          var reg = new RegExp('\{' + param.name + '\}', 'gi');
  7162          var value = args[param.name];
  7163  
  7164          if (Array.isArray(value)) {
  7165            value = this.encodePathCollection(param.collectionFormat, param.name, value);
  7166          } else {
  7167            value = this.encodePathParam(value);
  7168          }
  7169  
  7170          requestUrl = requestUrl.replace(reg, value);
  7171        } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
  7172          if (querystring === '' && requestUrl.indexOf('?') < 0) {
  7173            querystring += '?';
  7174          } else {
  7175            querystring += '&';
  7176          }
  7177  
  7178          if (typeof param.collectionFormat !== 'undefined') {
  7179            var qp = args[param.name];
  7180  
  7181            if (Array.isArray(qp)) {
  7182              querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);
  7183            } else {
  7184              querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name]);
  7185            }
  7186          } else {
  7187            querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name]);
  7188          }
  7189        } else if (param.in === 'formData') {
  7190          formParams[param.name] = args[param.name];
  7191        }
  7192      }
  7193    }
  7194    var url = this.scheme + '://' + this.host;
  7195  
  7196    if (this.basePath !== '/') {
  7197      url += this.basePath;
  7198    }
  7199    return url + requestUrl + querystring;
  7200  };
  7201  
  7202  Operation.prototype.getMissingParams = function (args) {
  7203    var missingParams = []; // check required params, track the ones that are missing
  7204    var i;
  7205  
  7206    for (i = 0; i < this.parameters.length; i++) {
  7207      var param = this.parameters[i];
  7208  
  7209      if (param.required === true) {
  7210        if (typeof args[param.name] === 'undefined') {
  7211          missingParams = param.name;
  7212        }
  7213      }
  7214    }
  7215  
  7216    return missingParams;
  7217  };
  7218  
  7219  Operation.prototype.getBody = function (headers, args) {
  7220    var formParams = {}, hasFormParams, param, body, key, value, hasBody = false;
  7221  
  7222    // look at each param and put form params in an object
  7223    for (var i = 0; i < this.parameters.length; i++) {
  7224      param = this.parameters[i];
  7225      if (typeof args[param.name] !== 'undefined') {
  7226        if (param.in === 'body') {
  7227          body = args[param.name];
  7228        } else if (param.in === 'formData') {
  7229          formParams[param.name] = {
  7230            param: param,
  7231            value: args[param.name]
  7232          };
  7233          hasFormParams = true;
  7234        }
  7235      }
  7236      else {
  7237        if(param.in === 'body') {
  7238          hasBody = true;
  7239        }
  7240      }
  7241    }
  7242  
  7243    // if body is null and hasBody is true, AND a JSON body is requested, send empty {}
  7244    if(hasBody && typeof body === 'undefined') {
  7245      var contentType = headers['Content-Type'];
  7246      if(contentType && contentType.indexOf('application/json') === 0) {
  7247        body = '{}';
  7248      }
  7249    }
  7250  
  7251    var isMultiPart = false;
  7252    if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {
  7253      isMultiPart = true;
  7254    }
  7255  
  7256    // handle form params
  7257    if (hasFormParams && !isMultiPart) {
  7258      var encoded = '';
  7259  
  7260      for (key in formParams) {
  7261        param = formParams[key].param;
  7262        value = formParams[key].value;
  7263  
  7264        if (typeof value !== 'undefined') {
  7265          if (Array.isArray(value)) {
  7266            if (encoded !== '') {
  7267              encoded += '&';
  7268            }
  7269            encoded += this.encodeQueryCollection(param.collectionFormat, key, value);
  7270          }
  7271          else {
  7272            if (encoded !== '') {
  7273              encoded += '&';
  7274            }
  7275  
  7276            encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
  7277          }
  7278        }
  7279      }
  7280  
  7281      body = encoded;
  7282    } else if (isMultiPart) {
  7283      var bodyParam;
  7284      if (typeof FormData === 'function') {
  7285        bodyParam = new FormData();
  7286  
  7287        bodyParam.type = 'formData';
  7288  
  7289        for (key in formParams) {
  7290          param = formParams[key].param;
  7291          value = args[key];
  7292  
  7293          if (typeof value !== 'undefined') {
  7294            if({}.toString.apply(value) === '[object File]') {
  7295              bodyParam.append(key, value);
  7296            }
  7297            else if (value.type === 'file' && value.value) {
  7298              bodyParam.append(key, value.value);
  7299            } else {
  7300              if (Array.isArray(value)) {
  7301                if(param.collectionFormat === 'multi') {
  7302                  bodyParam.delete(key);
  7303                  for(var v in value) {
  7304                    bodyParam.append(key, value[v]);
  7305                  }
  7306                }
  7307                else {
  7308                  bodyParam.append(key, this.encodeQueryCollection(param.collectionFormat, key, value).split('=').slice(1).join('='));
  7309                }
  7310              }
  7311              else {
  7312                bodyParam.append(key, value);
  7313              }
  7314            }
  7315          }
  7316        }
  7317        body = bodyParam;
  7318      }
  7319      else {
  7320        bodyParam = {};
  7321        for (key in formParams) {
  7322          value = args[key];
  7323          if (Array.isArray(value)) {
  7324            var delimeter;
  7325            var format = param.collectionFormat || 'multi';
  7326            if(format === 'ssv') {
  7327              delimeter = ' ';
  7328            }
  7329            else if(format === 'pipes') {
  7330              delimeter = '|';
  7331            }
  7332            else if(format === 'tsv') {
  7333              delimeter = '\t';
  7334            }
  7335            else if(format === 'multi') {
  7336              bodyParam[key] = value;
  7337              break;
  7338            }
  7339            else {
  7340              delimeter = ',';
  7341            }
  7342            var data;
  7343            value.forEach(function(v) {
  7344              if(data) {
  7345                data += delimeter;
  7346              }
  7347              else {
  7348                data = '';
  7349              }
  7350              data += v;
  7351            });
  7352            bodyParam[key] = data;
  7353          }
  7354          else {
  7355            bodyParam[key] = value;
  7356          }
  7357        }
  7358        body = bodyParam;
  7359      }
  7360      headers['Content-Type'] = 'multipart/form-data';
  7361    }
  7362  
  7363    return body;
  7364  };
  7365  
  7366  /**
  7367   * gets sample response for a single operation
  7368   **/
  7369  Operation.prototype.getModelSampleJSON = function (type, models) {
  7370    var listType, sampleJson, innerType;
  7371    models = models || {};
  7372  
  7373    listType = (type instanceof Array);
  7374    innerType = listType ? type[0] : type;
  7375  
  7376    if(models[innerType]) {
  7377      sampleJson = models[innerType].createJSONSample();
  7378    } else if (this.getInlineModel(innerType)){
  7379      sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct
  7380    }
  7381  
  7382  
  7383    if (sampleJson) {
  7384      sampleJson = listType ? [sampleJson] : sampleJson;
  7385  
  7386      if (typeof sampleJson === 'string') {
  7387        return sampleJson;
  7388      } else if (_.isObject(sampleJson)) {
  7389        var t = sampleJson;
  7390  
  7391        if (sampleJson instanceof Array && sampleJson.length > 0) {
  7392          t = sampleJson[0];
  7393        }
  7394  
  7395        if (t.nodeName && typeof t === 'Node') {
  7396          var xmlString = new XMLSerializer().serializeToString(t);
  7397  
  7398          return this.formatXml(xmlString);
  7399        } else {
  7400          return JSON.stringify(sampleJson, null, 2);
  7401        }
  7402      } else {
  7403        return sampleJson;
  7404      }
  7405    }
  7406  };
  7407  
  7408  /**
  7409   * legacy binding
  7410   **/
  7411  Operation.prototype.do = function (args, opts, callback, error, parent) {
  7412    return this.execute(args, opts, callback, error, parent);
  7413  };
  7414  
  7415  /**
  7416   * executes an operation
  7417   **/
  7418  Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) {
  7419    var args = arg1 || {};
  7420    var opts = {}, success, error, deferred, timeout;
  7421  
  7422    if (_.isObject(arg2)) {
  7423      opts = arg2;
  7424      success = arg3;
  7425      error = arg4;
  7426    }
  7427  
  7428    timeout = typeof opts.timeout !== 'undefined' ? opts.timeout : this.timeout;
  7429  
  7430    if(this.client) {
  7431      opts.client = this.client;
  7432    }
  7433  
  7434    if(this.requestAgent) {
  7435      opts.requestAgent = this.requestAgent;
  7436    }
  7437  
  7438    // add the request interceptor from parent, if none sent from client
  7439    if(!opts.requestInterceptor && this.requestInterceptor ) {
  7440      opts.requestInterceptor = this.requestInterceptor ;
  7441    }
  7442  
  7443    if(!opts.responseInterceptor && this.responseInterceptor) {
  7444      opts.responseInterceptor = this.responseInterceptor;
  7445    }
  7446  
  7447    if (typeof arg2 === 'function') {
  7448      success = arg2;
  7449      error = arg3;
  7450    }
  7451  
  7452    if (this.parent.usePromise) {
  7453      deferred = Q.defer();
  7454    } else {
  7455      success = (success || this.parent.defaultSuccessCallback || helpers.log);
  7456      error = (error || this.parent.defaultErrorCallback || helpers.log);
  7457    }
  7458  
  7459    if (typeof opts.useJQuery === 'undefined') {
  7460      opts.useJQuery = this.useJQuery;
  7461    }
  7462  
  7463    if (typeof opts.jqueryAjaxCache === 'undefined') {
  7464      opts.jqueryAjaxCache = this.jqueryAjaxCache;
  7465    }
  7466  
  7467    if (typeof opts.enableCookies === 'undefined') {
  7468      opts.enableCookies = this.enableCookies;
  7469    }
  7470  
  7471    var missingParams = this.getMissingParams(args);
  7472  
  7473    if (missingParams.length > 0) {
  7474      var message = 'missing required params: ' + missingParams;
  7475  
  7476      helpers.fail(message);
  7477  
  7478      if (this.parent.usePromise) {
  7479        deferred.reject(message);
  7480        return deferred.promise;
  7481      } else {
  7482        error(message, parent);
  7483        return {};
  7484      }
  7485    }
  7486  
  7487    var allHeaders = this.getHeaderParams(args);
  7488    var contentTypeHeaders = this.setContentTypes(args, opts);
  7489    var headers = {}, attrname;
  7490  
  7491    for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }
  7492    for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }
  7493  
  7494    var body = this.getBody(contentTypeHeaders, args, opts);
  7495    var url = this.urlify(args);
  7496  
  7497    if(url.indexOf('.{format}') > 0) {
  7498      if(headers) {
  7499        var format = headers.Accept || headers.accept;
  7500        if(format && format.indexOf('json') > 0) {
  7501          url = url.replace('.{format}', '.json');
  7502        }
  7503        else if(format && format.indexOf('xml') > 0) {
  7504          url = url.replace('.{format}', '.xml');
  7505        }
  7506      }
  7507    }
  7508  
  7509    var obj = {
  7510      url: url,
  7511      method: this.method.toUpperCase(),
  7512      body: body,
  7513      enableCookies: opts.enableCookies,
  7514      useJQuery: opts.useJQuery,
  7515      jqueryAjaxCache: opts.jqueryAjaxCache,
  7516      deferred: deferred,
  7517      headers: headers,
  7518      clientAuthorizations: opts.clientAuthorizations,
  7519      on: {
  7520        response: function (response) {
  7521          if (deferred) {
  7522            deferred.resolve(response);
  7523            return deferred.promise;
  7524          } else {
  7525            return success(response, parent);
  7526          }
  7527        },
  7528        error: function (response) {
  7529          if (deferred) {
  7530            deferred.reject(response);
  7531            return deferred.promise;
  7532          } else {
  7533            return error(response, parent);
  7534          }
  7535        }
  7536      }
  7537    };
  7538  
  7539    if (timeout) {
  7540      obj.timeout = timeout;
  7541    }
  7542  
  7543    this.clientAuthorizations.apply(obj, this.operation.security);
  7544    if (opts.mock === true) {
  7545      return obj;
  7546    } else {
  7547      return new SwaggerHttp().execute(obj, opts);
  7548    }
  7549  };
  7550  
  7551  function itemByPriority(col, itemPriority) {
  7552  
  7553    // No priorities? return first...
  7554    if(_.isEmpty(itemPriority)) {
  7555      return col[0];
  7556    }
  7557  
  7558    for (var i = 0, len = itemPriority.length; i < len; i++) {
  7559      if(col.indexOf(itemPriority[i]) > -1) {
  7560        return itemPriority[i];
  7561      }
  7562    }
  7563  
  7564    // Otherwise return first
  7565    return col[0];
  7566  }
  7567  
  7568  Operation.prototype.setContentTypes = function (args, opts) {
  7569    // default type
  7570    var allDefinedParams = this.parameters;
  7571    var body;
  7572    var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']);
  7573    var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']);
  7574    var definedFileParams = [];
  7575    var definedFormParams = [];
  7576    var headers = {};
  7577    var i;
  7578  
  7579    // get params from the operation and set them in definedFileParams, definedFormParams, headers
  7580    for (i = 0; i < allDefinedParams.length; i++) {
  7581      var param = allDefinedParams[i];
  7582  
  7583      if (param.in === 'formData') {
  7584        if (param.type === 'file') {
  7585          definedFileParams.push(param);
  7586        } else {
  7587          definedFormParams.push(param);
  7588        }
  7589      } else if (param.in === 'header' && opts) {
  7590        var key = param.name;
  7591        var headerValue = opts[param.name];
  7592  
  7593        if (typeof opts[param.name] !== 'undefined') {
  7594          headers[key] = headerValue;
  7595        }
  7596      } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') {
  7597        body = args[param.name];
  7598      }
  7599    }
  7600  
  7601    // if there's a body, need to set the consumes header via requestContentType
  7602    var hasBody = body || definedFileParams.length || definedFormParams.length;
  7603    if (this.method === 'post' || this.method === 'put' || this.method === 'patch' ||
  7604        ((this.method === 'delete' || this.method === 'get') && hasBody)) {
  7605      if (opts.requestContentType) {
  7606        consumes = opts.requestContentType;
  7607      }
  7608      // if any form params, content type must be set
  7609      if (definedFormParams.length > 0) {
  7610        consumes = undefined;
  7611        if (opts.requestContentType) {             // override if set
  7612          consumes = opts.requestContentType;
  7613        } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data
  7614          consumes = 'multipart/form-data';
  7615        } else {
  7616          if (this.consumes && this.consumes.length > 0) {
  7617            // use the consumes setting
  7618            for(var c in this.consumes) {
  7619              var chk = this.consumes[c];
  7620              if(chk.indexOf('application/x-www-form-urlencoded') === 0 || chk.indexOf('multipart/form-data') === 0) {
  7621                consumes = chk;
  7622              }
  7623            }
  7624          }
  7625        }
  7626        if(typeof consumes === 'undefined') {
  7627          // default to x-www-from-urlencoded
  7628          consumes = 'application/x-www-form-urlencoded';
  7629        }
  7630      }
  7631    }
  7632    else {
  7633      consumes = null;
  7634    }
  7635  
  7636    if (consumes && this.consumes) {
  7637      if (this.consumes.indexOf(consumes) === -1) {
  7638        helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));
  7639      }
  7640    }
  7641  
  7642    if (!this.matchesAccept(accepts)) {
  7643      helpers.log('server can\'t produce ' + accepts);
  7644    }
  7645  
  7646    if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) {
  7647      headers['Content-Type'] = consumes;
  7648    }
  7649    else if(this.consumes && this.consumes.length > 0 && this.consumes[0] === 'application/x-www-form-urlencoded') {
  7650      headers['Content-Type'] = this.consumes[0];
  7651    }
  7652  
  7653    if (accepts) {
  7654      headers.Accept = accepts;
  7655    }
  7656  
  7657    return headers;
  7658  };
  7659  
  7660  /**
  7661   * Returns true if the request accepts header matches anything in this.produces.
  7662   *  If this.produces contains * / *, ignore the accept header.
  7663   * @param {string=} accepts The client request accept header.
  7664   * @return {boolean}
  7665   */
  7666  Operation.prototype.matchesAccept = function(accepts) {
  7667    // no accepts or produces, no problem!
  7668    if (!accepts || !this.produces) {
  7669      return true;
  7670    }
  7671    return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1;
  7672  };
  7673  
  7674  Operation.prototype.asCurl = function (args1, args2) {
  7675    var opts = {mock: true};
  7676    if (typeof args2 === 'object') {
  7677      for (var argKey in args2) {
  7678        opts[argKey] = args2[argKey];
  7679      }
  7680    }
  7681    var obj = this.execute(args1, opts);
  7682  
  7683    this.clientAuthorizations.apply(obj, this.operation.security);
  7684  
  7685    var results = [];
  7686  
  7687    results.push('-X ' + this.method.toUpperCase());
  7688  
  7689    if (typeof obj.headers !== 'undefined') {
  7690      var key;
  7691  
  7692      for (key in obj.headers) {
  7693        var value = obj.headers[key];
  7694        if(typeof value === 'string'){
  7695          value = value.replace(/\'/g, '\\u0027');
  7696        }
  7697        results.push('--header \'' + key + ': ' + value + '\'');
  7698      }
  7699    }
  7700    var isFormData = false;
  7701    var isMultipart = false;
  7702  
  7703    var type = obj.headers['Content-Type'];
  7704    if(type && type.indexOf('application/x-www-form-urlencoded') === 0) {
  7705      isFormData = true;
  7706    }
  7707    else if (type && type.indexOf('multipart/form-data') === 0) {
  7708      isFormData = true;
  7709      isMultipart = true;
  7710    }
  7711  
  7712    if (obj.body) {
  7713      var body;
  7714      if (_.isObject(obj.body)) {
  7715        if(isMultipart) {
  7716          isMultipart = true;
  7717          // add the form data
  7718          for(var i = 0; i < this.parameters.length; i++) {
  7719            var parameter = this.parameters[i];
  7720            if(parameter.in === 'formData') {
  7721              if (!body) {
  7722                body = '';
  7723              }
  7724  
  7725              var paramValue;
  7726              if(typeof FormData === 'function' && obj.body instanceof FormData) {
  7727                paramValue = obj.body.getAll(parameter.name);
  7728              }
  7729              else {
  7730                paramValue = obj.body[parameter.name];
  7731              }
  7732              if (paramValue) {
  7733                if (parameter.type === 'file') {
  7734                  if(paramValue.name) {
  7735                    body += '-F ' + parameter.name + '=@"' + paramValue.name + '" ';
  7736                  }
  7737                }
  7738                else {
  7739                  if (Array.isArray(paramValue)) {
  7740                    if(parameter.collectionFormat === 'multi') {
  7741                      for(var v in paramValue) {
  7742                        body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + paramValue[v] + ' ';
  7743                      }
  7744                    }
  7745                    else {
  7746                      body += '-F ' + this.encodeQueryCollection(parameter.collectionFormat, parameter.name, paramValue) + ' ';
  7747                    }
  7748                  } else {
  7749                    body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + paramValue + ' ';
  7750                  }
  7751                }
  7752              }
  7753            }
  7754          }
  7755        }
  7756        if(!body) {
  7757          body = JSON.stringify(obj.body);
  7758        }
  7759      } else {
  7760        body = obj.body;
  7761      }
  7762      // escape @ => %40, ' => %27
  7763      body = body.replace(/\'/g, '%27').replace(/\n/g, ' \\ \n ');
  7764  
  7765      if(!isFormData) {
  7766        // escape & => %26
  7767        body = body.replace(/&/g, '%26');
  7768      }
  7769      if(isMultipart) {
  7770        results.push(body);
  7771      }
  7772      else {
  7773        results.push('-d \'' + body.replace(/@/g, '%40') + '\'');
  7774      }
  7775    }
  7776  
  7777    return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\'';
  7778  };
  7779  
  7780  Operation.prototype.encodePathCollection = function (type, name, value) {
  7781    var encoded = '';
  7782    var i;
  7783    var separator = '';
  7784  
  7785    if (type === 'ssv') {
  7786      separator = '%20';
  7787    } else if (type === 'tsv') {
  7788      separator = '%09';
  7789    } else if (type === 'pipes') {
  7790      separator = '|';
  7791    } else {
  7792      separator = ',';
  7793    }
  7794  
  7795    for (i = 0; i < value.length; i++) {
  7796      if (i === 0) {
  7797        encoded = this.encodeQueryParam(value[i]);
  7798      } else {
  7799        encoded += separator + this.encodeQueryParam(value[i]);
  7800      }
  7801    }
  7802  
  7803    return encoded;
  7804  };
  7805  
  7806  Operation.prototype.encodeQueryCollection = function (type, name, value) {
  7807    var encoded = '';
  7808    var i;
  7809  
  7810    type = type || 'default';
  7811    if (type === 'default' || type === 'multi') {
  7812      for (i = 0; i < value.length; i++) {
  7813        if (i > 0) {encoded += '&';}
  7814  
  7815        encoded += this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]);
  7816      }
  7817    } else {
  7818      var separator = '';
  7819  
  7820      if (type === 'csv') {
  7821        separator = ',';
  7822      } else if (type === 'ssv') {
  7823        separator = '%20';
  7824      } else if (type === 'tsv') {
  7825        separator = '%09';
  7826      } else if (type === 'pipes') {
  7827        separator = '|';
  7828      } else if (type === 'brackets') {
  7829        for (i = 0; i < value.length; i++) {
  7830          if (i !== 0) {
  7831            encoded += '&';
  7832          }
  7833  
  7834          encoded += this.encodeQueryKey(name) + '[]=' + this.encodeQueryParam(value[i]);
  7835        }
  7836      }
  7837  
  7838      if (separator !== '') {
  7839        for (i = 0; i < value.length; i++) {
  7840          if (i === 0) {
  7841            encoded = this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]);
  7842          } else {
  7843            encoded += separator + this.encodeQueryParam(value[i]);
  7844          }
  7845        }
  7846      }
  7847    }
  7848  
  7849    return encoded;
  7850  };
  7851  
  7852  Operation.prototype.encodeQueryKey = function (arg) {
  7853    return encodeURIComponent(arg)
  7854        .replace('%5B','[').replace('%5D', ']').replace('%24', '$');
  7855  };
  7856  
  7857  Operation.prototype.encodeQueryParam = function (arg) {
  7858    return encodeURIComponent(arg);
  7859  };
  7860  
  7861  /**
  7862   * TODO revisit, might not want to leave '/'
  7863   **/
  7864  Operation.prototype.encodePathParam = function (pathParam) {
  7865    return encodeURIComponent(pathParam);
  7866  };
  7867  
  7868  },{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,"q":157}],11:[function(require,module,exports){
  7869  'use strict';
  7870  
  7871  var OperationGroup = module.exports = function (tag, description, externalDocs, operation) {
  7872    this.description = description;
  7873    this.externalDocs = externalDocs;
  7874    this.name = tag;
  7875    this.operation = operation;
  7876    this.operationsArray = [];
  7877    this.path = tag;
  7878    this.tag = tag;
  7879  };
  7880  
  7881  OperationGroup.prototype.sort = function () {
  7882  
  7883  };
  7884  
  7885  
  7886  },{}],12:[function(require,module,exports){
  7887  // shim for using process in browser
  7888  
  7889  var process = module.exports = {};
  7890  var queue = [];
  7891  var draining = false;
  7892  
  7893  function drainQueue() {
  7894      if (draining) {
  7895          return;
  7896      }
  7897      draining = true;
  7898      var currentQueue;
  7899      var len = queue.length;
  7900      while(len) {
  7901          currentQueue = queue;
  7902          queue = [];
  7903          var i = -1;
  7904          while (++i < len) {
  7905              currentQueue[i]();
  7906          }
  7907          len = queue.length;
  7908      }
  7909      draining = false;
  7910  }
  7911  process.nextTick = function (fun) {
  7912      queue.push(fun);
  7913      if (!draining) {
  7914          setTimeout(drainQueue, 0);
  7915      }
  7916  };
  7917  
  7918  process.title = 'browser';
  7919  process.browser = true;
  7920  process.env = {};
  7921  process.argv = [];
  7922  process.version = ''; // empty string to avoid regexp issues
  7923  process.versions = {};
  7924  
  7925  function noop() {}
  7926  
  7927  process.on = noop;
  7928  process.addListener = noop;
  7929  process.once = noop;
  7930  process.off = noop;
  7931  process.removeListener = noop;
  7932  process.removeAllListeners = noop;
  7933  process.emit = noop;
  7934  
  7935  process.binding = function (name) {
  7936      throw new Error('process.binding is not supported');
  7937  };
  7938  
  7939  // TODO(shtylman)
  7940  process.cwd = function () { return '/' };
  7941  process.chdir = function (dir) {
  7942      throw new Error('process.chdir is not supported');
  7943  };
  7944  process.umask = function() { return 0; };
  7945  
  7946  },{}],13:[function(require,module,exports){
  7947  (function (Buffer){
  7948  (function () {
  7949    "use strict";
  7950  
  7951    function btoa(str) {
  7952      var buffer
  7953        ;
  7954  
  7955      if (str instanceof Buffer) {
  7956        buffer = str;
  7957      } else {
  7958        buffer = new Buffer(str.toString(), 'binary');
  7959      }
  7960  
  7961      return buffer.toString('base64');
  7962    }
  7963  
  7964    module.exports = btoa;
  7965  }());
  7966  
  7967  }).call(this,require("buffer").Buffer)
  7968  
  7969  },{"buffer":14}],14:[function(require,module,exports){
  7970  /*!
  7971   * The buffer module from node.js, for the browser.
  7972   *
  7973   * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
  7974   * @license  MIT
  7975   */
  7976  
  7977  var base64 = require('base64-js')
  7978  var ieee754 = require('ieee754')
  7979  var isArray = require('is-array')
  7980  
  7981  exports.Buffer = Buffer
  7982  exports.SlowBuffer = SlowBuffer
  7983  exports.INSPECT_MAX_BYTES = 50
  7984  Buffer.poolSize = 8192 // not used by this implementation
  7985  
  7986  var rootParent = {}
  7987  
  7988  /**
  7989   * If `Buffer.TYPED_ARRAY_SUPPORT`:
  7990   *   === true    Use Uint8Array implementation (fastest)
  7991   *   === false   Use Object implementation (most compatible, even IE6)
  7992   *
  7993   * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
  7994   * Opera 11.6+, iOS 4.2+.
  7995   *
  7996   * Due to various browser bugs, sometimes the Object implementation will be used even
  7997   * when the browser supports typed arrays.
  7998   *
  7999   * Note:
  8000   *
  8001   *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
  8002   *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
  8003   *
  8004   *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
  8005   *     on objects.
  8006   *
  8007   *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
  8008   *
  8009   *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
  8010   *     incorrect length in some situations.
  8011  
  8012   * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
  8013   * get the Object implementation, which is slower but behaves correctly.
  8014   */
  8015  Buffer.TYPED_ARRAY_SUPPORT = (function () {
  8016    function Bar () {}
  8017    try {
  8018      var arr = new Uint8Array(1)
  8019      arr.foo = function () { return 42 }
  8020      arr.constructor = Bar
  8021      return arr.foo() === 42 && // typed array instances can be augmented
  8022          arr.constructor === Bar && // constructor can be set
  8023          typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
  8024          arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
  8025    } catch (e) {
  8026      return false
  8027    }
  8028  })()
  8029  
  8030  function kMaxLength () {
  8031    return Buffer.TYPED_ARRAY_SUPPORT
  8032      ? 0x7fffffff
  8033      : 0x3fffffff
  8034  }
  8035  
  8036  /**
  8037   * Class: Buffer
  8038   * =============
  8039   *
  8040   * The Buffer constructor returns instances of `Uint8Array` that are augmented
  8041   * with function properties for all the node `Buffer` API functions. We use
  8042   * `Uint8Array` so that square bracket notation works as expected -- it returns
  8043   * a single octet.
  8044   *
  8045   * By augmenting the instances, we can avoid modifying the `Uint8Array`
  8046   * prototype.
  8047   */
  8048  function Buffer (arg) {
  8049    if (!(this instanceof Buffer)) {
  8050      // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
  8051      if (arguments.length > 1) return new Buffer(arg, arguments[1])
  8052      return new Buffer(arg)
  8053    }
  8054  
  8055    this.length = 0
  8056    this.parent = undefined
  8057  
  8058    // Common case.
  8059    if (typeof arg === 'number') {
  8060      return fromNumber(this, arg)
  8061    }
  8062  
  8063    // Slightly less common case.
  8064    if (typeof arg === 'string') {
  8065      return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
  8066    }
  8067  
  8068    // Unusual.
  8069    return fromObject(this, arg)
  8070  }
  8071  
  8072  function fromNumber (that, length) {
  8073    that = allocate(that, length < 0 ? 0 : checked(length) | 0)
  8074    if (!Buffer.TYPED_ARRAY_SUPPORT) {
  8075      for (var i = 0; i < length; i++) {
  8076        that[i] = 0
  8077      }
  8078    }
  8079    return that
  8080  }
  8081  
  8082  function fromString (that, string, encoding) {
  8083    if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
  8084  
  8085    // Assumption: byteLength() return value is always < kMaxLength.
  8086    var length = byteLength(string, encoding) | 0
  8087    that = allocate(that, length)
  8088  
  8089    that.write(string, encoding)
  8090    return that
  8091  }
  8092  
  8093  function fromObject (that, object) {
  8094    if (Buffer.isBuffer(object)) return fromBuffer(that, object)
  8095  
  8096    if (isArray(object)) return fromArray(that, object)
  8097  
  8098    if (object == null) {
  8099      throw new TypeError('must start with number, buffer, array or string')
  8100    }
  8101  
  8102    if (typeof ArrayBuffer !== 'undefined') {
  8103      if (object.buffer instanceof ArrayBuffer) {
  8104        return fromTypedArray(that, object)
  8105      }
  8106      if (object instanceof ArrayBuffer) {
  8107        return fromArrayBuffer(that, object)
  8108      }
  8109    }
  8110  
  8111    if (object.length) return fromArrayLike(that, object)
  8112  
  8113    return fromJsonObject(that, object)
  8114  }
  8115  
  8116  function fromBuffer (that, buffer) {
  8117    var length = checked(buffer.length) | 0
  8118    that = allocate(that, length)
  8119    buffer.copy(that, 0, 0, length)
  8120    return that
  8121  }
  8122  
  8123  function fromArray (that, array) {
  8124    var length = checked(array.length) | 0
  8125    that = allocate(that, length)
  8126    for (var i = 0; i < length; i += 1) {
  8127      that[i] = array[i] & 255
  8128    }
  8129    return that
  8130  }
  8131  
  8132  // Duplicate of fromArray() to keep fromArray() monomorphic.
  8133  function fromTypedArray (that, array) {
  8134    var length = checked(array.length) | 0
  8135    that = allocate(that, length)
  8136    // Truncating the elements is probably not what people expect from typed
  8137    // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
  8138    // of the old Buffer constructor.
  8139    for (var i = 0; i < length; i += 1) {
  8140      that[i] = array[i] & 255
  8141    }
  8142    return that
  8143  }
  8144  
  8145  function fromArrayBuffer (that, array) {
  8146    if (Buffer.TYPED_ARRAY_SUPPORT) {
  8147      // Return an augmented `Uint8Array` instance, for best performance
  8148      array.byteLength
  8149      that = Buffer._augment(new Uint8Array(array))
  8150    } else {
  8151      // Fallback: Return an object instance of the Buffer class
  8152      that = fromTypedArray(that, new Uint8Array(array))
  8153    }
  8154    return that
  8155  }
  8156  
  8157  function fromArrayLike (that, array) {
  8158    var length = checked(array.length) | 0
  8159    that = allocate(that, length)
  8160    for (var i = 0; i < length; i += 1) {
  8161      that[i] = array[i] & 255
  8162    }
  8163    return that
  8164  }
  8165  
  8166  // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
  8167  // Returns a zero-length buffer for inputs that don't conform to the spec.
  8168  function fromJsonObject (that, object) {
  8169    var array
  8170    var length = 0
  8171  
  8172    if (object.type === 'Buffer' && isArray(object.data)) {
  8173      array = object.data
  8174      length = checked(array.length) | 0
  8175    }
  8176    that = allocate(that, length)
  8177  
  8178    for (var i = 0; i < length; i += 1) {
  8179      that[i] = array[i] & 255
  8180    }
  8181    return that
  8182  }
  8183  
  8184  function allocate (that, length) {
  8185    if (Buffer.TYPED_ARRAY_SUPPORT) {
  8186      // Return an augmented `Uint8Array` instance, for best performance
  8187      that = Buffer._augment(new Uint8Array(length))
  8188    } else {
  8189      // Fallback: Return an object instance of the Buffer class
  8190      that.length = length
  8191      that._isBuffer = true
  8192    }
  8193  
  8194    var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
  8195    if (fromPool) that.parent = rootParent
  8196  
  8197    return that
  8198  }
  8199  
  8200  function checked (length) {
  8201    // Note: cannot use `length < kMaxLength` here because that fails when
  8202    // length is NaN (which is otherwise coerced to zero.)
  8203    if (length >= kMaxLength()) {
  8204      throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
  8205                           'size: 0x' + kMaxLength().toString(16) + ' bytes')
  8206    }
  8207    return length | 0
  8208  }
  8209  
  8210  function SlowBuffer (subject, encoding) {
  8211    if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
  8212  
  8213    var buf = new Buffer(subject, encoding)
  8214    delete buf.parent
  8215    return buf
  8216  }
  8217  
  8218  Buffer.isBuffer = function isBuffer (b) {
  8219    return !!(b != null && b._isBuffer)
  8220  }
  8221  
  8222  Buffer.compare = function compare (a, b) {
  8223    if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
  8224      throw new TypeError('Arguments must be Buffers')
  8225    }
  8226  
  8227    if (a === b) return 0
  8228  
  8229    var x = a.length
  8230    var y = b.length
  8231  
  8232    var i = 0
  8233    var len = Math.min(x, y)
  8234    while (i < len) {
  8235      if (a[i] !== b[i]) break
  8236  
  8237      ++i
  8238    }
  8239  
  8240    if (i !== len) {
  8241      x = a[i]
  8242      y = b[i]
  8243    }
  8244  
  8245    if (x < y) return -1
  8246    if (y < x) return 1
  8247    return 0
  8248  }
  8249  
  8250  Buffer.isEncoding = function isEncoding (encoding) {
  8251    switch (String(encoding).toLowerCase()) {
  8252      case 'hex':
  8253      case 'utf8':
  8254      case 'utf-8':
  8255      case 'ascii':
  8256      case 'binary':
  8257      case 'base64':
  8258      case 'raw':
  8259      case 'ucs2':
  8260      case 'ucs-2':
  8261      case 'utf16le':
  8262      case 'utf-16le':
  8263        return true
  8264      default:
  8265        return false
  8266    }
  8267  }
  8268  
  8269  Buffer.concat = function concat (list, length) {
  8270    if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
  8271  
  8272    if (list.length === 0) {
  8273      return new Buffer(0)
  8274    }
  8275  
  8276    var i
  8277    if (length === undefined) {
  8278      length = 0
  8279      for (i = 0; i < list.length; i++) {
  8280        length += list[i].length
  8281      }
  8282    }
  8283  
  8284    var buf = new Buffer(length)
  8285    var pos = 0
  8286    for (i = 0; i < list.length; i++) {
  8287      var item = list[i]
  8288      item.copy(buf, pos)
  8289      pos += item.length
  8290    }
  8291    return buf
  8292  }
  8293  
  8294  function byteLength (string, encoding) {
  8295    if (typeof string !== 'string') string = '' + string
  8296  
  8297    var len = string.length
  8298    if (len === 0) return 0
  8299  
  8300    // Use a for loop to avoid recursion
  8301    var loweredCase = false
  8302    for (;;) {
  8303      switch (encoding) {
  8304        case 'ascii':
  8305        case 'binary':
  8306        // Deprecated
  8307        case 'raw':
  8308        case 'raws':
  8309          return len
  8310        case 'utf8':
  8311        case 'utf-8':
  8312          return utf8ToBytes(string).length
  8313        case 'ucs2':
  8314        case 'ucs-2':
  8315        case 'utf16le':
  8316        case 'utf-16le':
  8317          return len * 2
  8318        case 'hex':
  8319          return len >>> 1
  8320        case 'base64':
  8321          return base64ToBytes(string).length
  8322        default:
  8323          if (loweredCase) return utf8ToBytes(string).length // assume utf8
  8324          encoding = ('' + encoding).toLowerCase()
  8325          loweredCase = true
  8326      }
  8327    }
  8328  }
  8329  Buffer.byteLength = byteLength
  8330  
  8331  // pre-set for values that may exist in the future
  8332  Buffer.prototype.length = undefined
  8333  Buffer.prototype.parent = undefined
  8334  
  8335  function slowToString (encoding, start, end) {
  8336    var loweredCase = false
  8337  
  8338    start = start | 0
  8339    end = end === undefined || end === Infinity ? this.length : end | 0
  8340  
  8341    if (!encoding) encoding = 'utf8'
  8342    if (start < 0) start = 0
  8343    if (end > this.length) end = this.length
  8344    if (end <= start) return ''
  8345  
  8346    while (true) {
  8347      switch (encoding) {
  8348        case 'hex':
  8349          return hexSlice(this, start, end)
  8350  
  8351        case 'utf8':
  8352        case 'utf-8':
  8353          return utf8Slice(this, start, end)
  8354  
  8355        case 'ascii':
  8356          return asciiSlice(this, start, end)
  8357  
  8358        case 'binary':
  8359          return binarySlice(this, start, end)
  8360  
  8361        case 'base64':
  8362          return base64Slice(this, start, end)
  8363  
  8364        case 'ucs2':
  8365        case 'ucs-2':
  8366        case 'utf16le':
  8367        case 'utf-16le':
  8368          return utf16leSlice(this, start, end)
  8369  
  8370        default:
  8371          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
  8372          encoding = (encoding + '').toLowerCase()
  8373          loweredCase = true
  8374      }
  8375    }
  8376  }
  8377  
  8378  Buffer.prototype.toString = function toString () {
  8379    var length = this.length | 0
  8380    if (length === 0) return ''
  8381    if (arguments.length === 0) return utf8Slice(this, 0, length)
  8382    return slowToString.apply(this, arguments)
  8383  }
  8384  
  8385  Buffer.prototype.equals = function equals (b) {
  8386    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  8387    if (this === b) return true
  8388    return Buffer.compare(this, b) === 0
  8389  }
  8390  
  8391  Buffer.prototype.inspect = function inspect () {
  8392    var str = ''
  8393    var max = exports.INSPECT_MAX_BYTES
  8394    if (this.length > 0) {
  8395      str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
  8396      if (this.length > max) str += ' ... '
  8397    }
  8398    return '<Buffer ' + str + '>'
  8399  }
  8400  
  8401  Buffer.prototype.compare = function compare (b) {
  8402    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  8403    if (this === b) return 0
  8404    return Buffer.compare(this, b)
  8405  }
  8406  
  8407  Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
  8408    if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
  8409    else if (byteOffset < -0x80000000) byteOffset = -0x80000000
  8410    byteOffset >>= 0
  8411  
  8412    if (this.length === 0) return -1
  8413    if (byteOffset >= this.length) return -1
  8414  
  8415    // Negative offsets start from the end of the buffer
  8416    if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
  8417  
  8418    if (typeof val === 'string') {
  8419      if (val.length === 0) return -1 // special case: looking for empty string always fails
  8420      return String.prototype.indexOf.call(this, val, byteOffset)
  8421    }
  8422    if (Buffer.isBuffer(val)) {
  8423      return arrayIndexOf(this, val, byteOffset)
  8424    }
  8425    if (typeof val === 'number') {
  8426      if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
  8427        return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
  8428      }
  8429      return arrayIndexOf(this, [ val ], byteOffset)
  8430    }
  8431  
  8432    function arrayIndexOf (arr, val, byteOffset) {
  8433      var foundIndex = -1
  8434      for (var i = 0; byteOffset + i < arr.length; i++) {
  8435        if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
  8436          if (foundIndex === -1) foundIndex = i
  8437          if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
  8438        } else {
  8439          foundIndex = -1
  8440        }
  8441      }
  8442      return -1
  8443    }
  8444  
  8445    throw new TypeError('val must be string, number or Buffer')
  8446  }
  8447  
  8448  // `get` is deprecated
  8449  Buffer.prototype.get = function get (offset) {
  8450    console.log('.get() is deprecated. Access using array indexes instead.')
  8451    return this.readUInt8(offset)
  8452  }
  8453  
  8454  // `set` is deprecated
  8455  Buffer.prototype.set = function set (v, offset) {
  8456    console.log('.set() is deprecated. Access using array indexes instead.')
  8457    return this.writeUInt8(v, offset)
  8458  }
  8459  
  8460  function hexWrite (buf, string, offset, length) {
  8461    offset = Number(offset) || 0
  8462    var remaining = buf.length - offset
  8463    if (!length) {
  8464      length = remaining
  8465    } else {
  8466      length = Number(length)
  8467      if (length > remaining) {
  8468        length = remaining
  8469      }
  8470    }
  8471  
  8472    // must be an even number of digits
  8473    var strLen = string.length
  8474    if (strLen % 2 !== 0) throw new Error('Invalid hex string')
  8475  
  8476    if (length > strLen / 2) {
  8477      length = strLen / 2
  8478    }
  8479    for (var i = 0; i < length; i++) {
  8480      var parsed = parseInt(string.substr(i * 2, 2), 16)
  8481      if (isNaN(parsed)) throw new Error('Invalid hex string')
  8482      buf[offset + i] = parsed
  8483    }
  8484    return i
  8485  }
  8486  
  8487  function utf8Write (buf, string, offset, length) {
  8488    return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  8489  }
  8490  
  8491  function asciiWrite (buf, string, offset, length) {
  8492    return blitBuffer(asciiToBytes(string), buf, offset, length)
  8493  }
  8494  
  8495  function binaryWrite (buf, string, offset, length) {
  8496    return asciiWrite(buf, string, offset, length)
  8497  }
  8498  
  8499  function base64Write (buf, string, offset, length) {
  8500    return blitBuffer(base64ToBytes(string), buf, offset, length)
  8501  }
  8502  
  8503  function ucs2Write (buf, string, offset, length) {
  8504    return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  8505  }
  8506  
  8507  Buffer.prototype.write = function write (string, offset, length, encoding) {
  8508    // Buffer#write(string)
  8509    if (offset === undefined) {
  8510      encoding = 'utf8'
  8511      length = this.length
  8512      offset = 0
  8513    // Buffer#write(string, encoding)
  8514    } else if (length === undefined && typeof offset === 'string') {
  8515      encoding = offset
  8516      length = this.length
  8517      offset = 0
  8518    // Buffer#write(string, offset[, length][, encoding])
  8519    } else if (isFinite(offset)) {
  8520      offset = offset | 0
  8521      if (isFinite(length)) {
  8522        length = length | 0
  8523        if (encoding === undefined) encoding = 'utf8'
  8524      } else {
  8525        encoding = length
  8526        length = undefined
  8527      }
  8528    // legacy write(string, encoding, offset, length) - remove in v0.13
  8529    } else {
  8530      var swap = encoding
  8531      encoding = offset
  8532      offset = length | 0
  8533      length = swap
  8534    }
  8535  
  8536    var remaining = this.length - offset
  8537    if (length === undefined || length > remaining) length = remaining
  8538  
  8539    if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
  8540      throw new RangeError('attempt to write outside buffer bounds')
  8541    }
  8542  
  8543    if (!encoding) encoding = 'utf8'
  8544  
  8545    var loweredCase = false
  8546    for (;;) {
  8547      switch (encoding) {
  8548        case 'hex':
  8549          return hexWrite(this, string, offset, length)
  8550  
  8551        case 'utf8':
  8552        case 'utf-8':
  8553          return utf8Write(this, string, offset, length)
  8554  
  8555        case 'ascii':
  8556          return asciiWrite(this, string, offset, length)
  8557  
  8558        case 'binary':
  8559          return binaryWrite(this, string, offset, length)
  8560  
  8561        case 'base64':
  8562          // Warning: maxLength not taken into account in base64Write
  8563          return base64Write(this, string, offset, length)
  8564  
  8565        case 'ucs2':
  8566        case 'ucs-2':
  8567        case 'utf16le':
  8568        case 'utf-16le':
  8569          return ucs2Write(this, string, offset, length)
  8570  
  8571        default:
  8572          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
  8573          encoding = ('' + encoding).toLowerCase()
  8574          loweredCase = true
  8575      }
  8576    }
  8577  }
  8578  
  8579  Buffer.prototype.toJSON = function toJSON () {
  8580    return {
  8581      type: 'Buffer',
  8582      data: Array.prototype.slice.call(this._arr || this, 0)
  8583    }
  8584  }
  8585  
  8586  function base64Slice (buf, start, end) {
  8587    if (start === 0 && end === buf.length) {
  8588      return base64.fromByteArray(buf)
  8589    } else {
  8590      return base64.fromByteArray(buf.slice(start, end))
  8591    }
  8592  }
  8593  
  8594  function utf8Slice (buf, start, end) {
  8595    end = Math.min(buf.length, end)
  8596    var res = []
  8597  
  8598    var i = start
  8599    while (i < end) {
  8600      var firstByte = buf[i]
  8601      var codePoint = null
  8602      var bytesPerSequence = (firstByte > 0xEF) ? 4
  8603        : (firstByte > 0xDF) ? 3
  8604        : (firstByte > 0xBF) ? 2
  8605        : 1
  8606  
  8607      if (i + bytesPerSequence <= end) {
  8608        var secondByte, thirdByte, fourthByte, tempCodePoint
  8609  
  8610        switch (bytesPerSequence) {
  8611          case 1:
  8612            if (firstByte < 0x80) {
  8613              codePoint = firstByte
  8614            }
  8615            break
  8616          case 2:
  8617            secondByte = buf[i + 1]
  8618            if ((secondByte & 0xC0) === 0x80) {
  8619              tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
  8620              if (tempCodePoint > 0x7F) {
  8621                codePoint = tempCodePoint
  8622              }
  8623            }
  8624            break
  8625          case 3:
  8626            secondByte = buf[i + 1]
  8627            thirdByte = buf[i + 2]
  8628            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
  8629              tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
  8630              if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
  8631                codePoint = tempCodePoint
  8632              }
  8633            }
  8634            break
  8635          case 4:
  8636            secondByte = buf[i + 1]
  8637            thirdByte = buf[i + 2]
  8638            fourthByte = buf[i + 3]
  8639            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
  8640              tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
  8641              if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
  8642                codePoint = tempCodePoint
  8643              }
  8644            }
  8645        }
  8646      }
  8647  
  8648      if (codePoint === null) {
  8649        // we did not generate a valid codePoint so insert a
  8650        // replacement char (U+FFFD) and advance only 1 byte
  8651        codePoint = 0xFFFD
  8652        bytesPerSequence = 1
  8653      } else if (codePoint > 0xFFFF) {
  8654        // encode to utf16 (surrogate pair dance)
  8655        codePoint -= 0x10000
  8656        res.push(codePoint >>> 10 & 0x3FF | 0xD800)
  8657        codePoint = 0xDC00 | codePoint & 0x3FF
  8658      }
  8659  
  8660      res.push(codePoint)
  8661      i += bytesPerSequence
  8662    }
  8663  
  8664    return decodeCodePointsArray(res)
  8665  }
  8666  
  8667  // Based on http://stackoverflow.com/a/22747272/680742, the browser with
  8668  // the lowest limit is Chrome, with 0x10000 args.
  8669  // We go 1 magnitude less, for safety
  8670  var MAX_ARGUMENTS_LENGTH = 0x1000
  8671  
  8672  function decodeCodePointsArray (codePoints) {
  8673    var len = codePoints.length
  8674    if (len <= MAX_ARGUMENTS_LENGTH) {
  8675      return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
  8676    }
  8677  
  8678    // Decode in chunks to avoid "call stack size exceeded".
  8679    var res = ''
  8680    var i = 0
  8681    while (i < len) {
  8682      res += String.fromCharCode.apply(
  8683        String,
  8684        codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
  8685      )
  8686    }
  8687    return res
  8688  }
  8689  
  8690  function asciiSlice (buf, start, end) {
  8691    var ret = ''
  8692    end = Math.min(buf.length, end)
  8693  
  8694    for (var i = start; i < end; i++) {
  8695      ret += String.fromCharCode(buf[i] & 0x7F)
  8696    }
  8697    return ret
  8698  }
  8699  
  8700  function binarySlice (buf, start, end) {
  8701    var ret = ''
  8702    end = Math.min(buf.length, end)
  8703  
  8704    for (var i = start; i < end; i++) {
  8705      ret += String.fromCharCode(buf[i])
  8706    }
  8707    return ret
  8708  }
  8709  
  8710  function hexSlice (buf, start, end) {
  8711    var len = buf.length
  8712  
  8713    if (!start || start < 0) start = 0
  8714    if (!end || end < 0 || end > len) end = len
  8715  
  8716    var out = ''
  8717    for (var i = start; i < end; i++) {
  8718      out += toHex(buf[i])
  8719    }
  8720    return out
  8721  }
  8722  
  8723  function utf16leSlice (buf, start, end) {
  8724    var bytes = buf.slice(start, end)
  8725    var res = ''
  8726    for (var i = 0; i < bytes.length; i += 2) {
  8727      res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
  8728    }
  8729    return res
  8730  }
  8731  
  8732  Buffer.prototype.slice = function slice (start, end) {
  8733    var len = this.length
  8734    start = ~~start
  8735    end = end === undefined ? len : ~~end
  8736  
  8737    if (start < 0) {
  8738      start += len
  8739      if (start < 0) start = 0
  8740    } else if (start > len) {
  8741      start = len
  8742    }
  8743  
  8744    if (end < 0) {
  8745      end += len
  8746      if (end < 0) end = 0
  8747    } else if (end > len) {
  8748      end = len
  8749    }
  8750  
  8751    if (end < start) end = start
  8752  
  8753    var newBuf
  8754    if (Buffer.TYPED_ARRAY_SUPPORT) {
  8755      newBuf = Buffer._augment(this.subarray(start, end))
  8756    } else {
  8757      var sliceLen = end - start
  8758      newBuf = new Buffer(sliceLen, undefined)
  8759      for (var i = 0; i < sliceLen; i++) {
  8760        newBuf[i] = this[i + start]
  8761      }
  8762    }
  8763  
  8764    if (newBuf.length) newBuf.parent = this.parent || this
  8765  
  8766    return newBuf
  8767  }
  8768  
  8769  /*
  8770   * Need to make sure that buffer isn't trying to write out of bounds.
  8771   */
  8772  function checkOffset (offset, ext, length) {
  8773    if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
  8774    if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
  8775  }
  8776  
  8777  Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
  8778    offset = offset | 0
  8779    byteLength = byteLength | 0
  8780    if (!noAssert) checkOffset(offset, byteLength, this.length)
  8781  
  8782    var val = this[offset]
  8783    var mul = 1
  8784    var i = 0
  8785    while (++i < byteLength && (mul *= 0x100)) {
  8786      val += this[offset + i] * mul
  8787    }
  8788  
  8789    return val
  8790  }
  8791  
  8792  Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
  8793    offset = offset | 0
  8794    byteLength = byteLength | 0
  8795    if (!noAssert) {
  8796      checkOffset(offset, byteLength, this.length)
  8797    }
  8798  
  8799    var val = this[offset + --byteLength]
  8800    var mul = 1
  8801    while (byteLength > 0 && (mul *= 0x100)) {
  8802      val += this[offset + --byteLength] * mul
  8803    }
  8804  
  8805    return val
  8806  }
  8807  
  8808  Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
  8809    if (!noAssert) checkOffset(offset, 1, this.length)
  8810    return this[offset]
  8811  }
  8812  
  8813  Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
  8814    if (!noAssert) checkOffset(offset, 2, this.length)
  8815    return this[offset] | (this[offset + 1] << 8)
  8816  }
  8817  
  8818  Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
  8819    if (!noAssert) checkOffset(offset, 2, this.length)
  8820    return (this[offset] << 8) | this[offset + 1]
  8821  }
  8822  
  8823  Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
  8824    if (!noAssert) checkOffset(offset, 4, this.length)
  8825  
  8826    return ((this[offset]) |
  8827        (this[offset + 1] << 8) |
  8828        (this[offset + 2] << 16)) +
  8829        (this[offset + 3] * 0x1000000)
  8830  }
  8831  
  8832  Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
  8833    if (!noAssert) checkOffset(offset, 4, this.length)
  8834  
  8835    return (this[offset] * 0x1000000) +
  8836      ((this[offset + 1] << 16) |
  8837      (this[offset + 2] << 8) |
  8838      this[offset + 3])
  8839  }
  8840  
  8841  Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
  8842    offset = offset | 0
  8843    byteLength = byteLength | 0
  8844    if (!noAssert) checkOffset(offset, byteLength, this.length)
  8845  
  8846    var val = this[offset]
  8847    var mul = 1
  8848    var i = 0
  8849    while (++i < byteLength && (mul *= 0x100)) {
  8850      val += this[offset + i] * mul
  8851    }
  8852    mul *= 0x80
  8853  
  8854    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  8855  
  8856    return val
  8857  }
  8858  
  8859  Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
  8860    offset = offset | 0
  8861    byteLength = byteLength | 0
  8862    if (!noAssert) checkOffset(offset, byteLength, this.length)
  8863  
  8864    var i = byteLength
  8865    var mul = 1
  8866    var val = this[offset + --i]
  8867    while (i > 0 && (mul *= 0x100)) {
  8868      val += this[offset + --i] * mul
  8869    }
  8870    mul *= 0x80
  8871  
  8872    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  8873  
  8874    return val
  8875  }
  8876  
  8877  Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
  8878    if (!noAssert) checkOffset(offset, 1, this.length)
  8879    if (!(this[offset] & 0x80)) return (this[offset])
  8880    return ((0xff - this[offset] + 1) * -1)
  8881  }
  8882  
  8883  Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
  8884    if (!noAssert) checkOffset(offset, 2, this.length)
  8885    var val = this[offset] | (this[offset + 1] << 8)
  8886    return (val & 0x8000) ? val | 0xFFFF0000 : val
  8887  }
  8888  
  8889  Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
  8890    if (!noAssert) checkOffset(offset, 2, this.length)
  8891    var val = this[offset + 1] | (this[offset] << 8)
  8892    return (val & 0x8000) ? val | 0xFFFF0000 : val
  8893  }
  8894  
  8895  Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
  8896    if (!noAssert) checkOffset(offset, 4, this.length)
  8897  
  8898    return (this[offset]) |
  8899      (this[offset + 1] << 8) |
  8900      (this[offset + 2] << 16) |
  8901      (this[offset + 3] << 24)
  8902  }
  8903  
  8904  Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
  8905    if (!noAssert) checkOffset(offset, 4, this.length)
  8906  
  8907    return (this[offset] << 24) |
  8908      (this[offset + 1] << 16) |
  8909      (this[offset + 2] << 8) |
  8910      (this[offset + 3])
  8911  }
  8912  
  8913  Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
  8914    if (!noAssert) checkOffset(offset, 4, this.length)
  8915    return ieee754.read(this, offset, true, 23, 4)
  8916  }
  8917  
  8918  Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
  8919    if (!noAssert) checkOffset(offset, 4, this.length)
  8920    return ieee754.read(this, offset, false, 23, 4)
  8921  }
  8922  
  8923  Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
  8924    if (!noAssert) checkOffset(offset, 8, this.length)
  8925    return ieee754.read(this, offset, true, 52, 8)
  8926  }
  8927  
  8928  Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
  8929    if (!noAssert) checkOffset(offset, 8, this.length)
  8930    return ieee754.read(this, offset, false, 52, 8)
  8931  }
  8932  
  8933  function checkInt (buf, value, offset, ext, max, min) {
  8934    if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
  8935    if (value > max || value < min) throw new RangeError('value is out of bounds')
  8936    if (offset + ext > buf.length) throw new RangeError('index out of range')
  8937  }
  8938  
  8939  Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
  8940    value = +value
  8941    offset = offset | 0
  8942    byteLength = byteLength | 0
  8943    if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
  8944  
  8945    var mul = 1
  8946    var i = 0
  8947    this[offset] = value & 0xFF
  8948    while (++i < byteLength && (mul *= 0x100)) {
  8949      this[offset + i] = (value / mul) & 0xFF
  8950    }
  8951  
  8952    return offset + byteLength
  8953  }
  8954  
  8955  Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
  8956    value = +value
  8957    offset = offset | 0
  8958    byteLength = byteLength | 0
  8959    if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
  8960  
  8961    var i = byteLength - 1
  8962    var mul = 1
  8963    this[offset + i] = value & 0xFF
  8964    while (--i >= 0 && (mul *= 0x100)) {
  8965      this[offset + i] = (value / mul) & 0xFF
  8966    }
  8967  
  8968    return offset + byteLength
  8969  }
  8970  
  8971  Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
  8972    value = +value
  8973    offset = offset | 0
  8974    if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
  8975    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  8976    this[offset] = value
  8977    return offset + 1
  8978  }
  8979  
  8980  function objectWriteUInt16 (buf, value, offset, littleEndian) {
  8981    if (value < 0) value = 0xffff + value + 1
  8982    for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
  8983      buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
  8984        (littleEndian ? i : 1 - i) * 8
  8985    }
  8986  }
  8987  
  8988  Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
  8989    value = +value
  8990    offset = offset | 0
  8991    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  8992    if (Buffer.TYPED_ARRAY_SUPPORT) {
  8993      this[offset] = value
  8994      this[offset + 1] = (value >>> 8)
  8995    } else {
  8996      objectWriteUInt16(this, value, offset, true)
  8997    }
  8998    return offset + 2
  8999  }
  9000  
  9001  Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
  9002    value = +value
  9003    offset = offset | 0
  9004    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  9005    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9006      this[offset] = (value >>> 8)
  9007      this[offset + 1] = value
  9008    } else {
  9009      objectWriteUInt16(this, value, offset, false)
  9010    }
  9011    return offset + 2
  9012  }
  9013  
  9014  function objectWriteUInt32 (buf, value, offset, littleEndian) {
  9015    if (value < 0) value = 0xffffffff + value + 1
  9016    for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
  9017      buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
  9018    }
  9019  }
  9020  
  9021  Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
  9022    value = +value
  9023    offset = offset | 0
  9024    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  9025    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9026      this[offset + 3] = (value >>> 24)
  9027      this[offset + 2] = (value >>> 16)
  9028      this[offset + 1] = (value >>> 8)
  9029      this[offset] = value
  9030    } else {
  9031      objectWriteUInt32(this, value, offset, true)
  9032    }
  9033    return offset + 4
  9034  }
  9035  
  9036  Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
  9037    value = +value
  9038    offset = offset | 0
  9039    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  9040    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9041      this[offset] = (value >>> 24)
  9042      this[offset + 1] = (value >>> 16)
  9043      this[offset + 2] = (value >>> 8)
  9044      this[offset + 3] = value
  9045    } else {
  9046      objectWriteUInt32(this, value, offset, false)
  9047    }
  9048    return offset + 4
  9049  }
  9050  
  9051  Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
  9052    value = +value
  9053    offset = offset | 0
  9054    if (!noAssert) {
  9055      var limit = Math.pow(2, 8 * byteLength - 1)
  9056  
  9057      checkInt(this, value, offset, byteLength, limit - 1, -limit)
  9058    }
  9059  
  9060    var i = 0
  9061    var mul = 1
  9062    var sub = value < 0 ? 1 : 0
  9063    this[offset] = value & 0xFF
  9064    while (++i < byteLength && (mul *= 0x100)) {
  9065      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  9066    }
  9067  
  9068    return offset + byteLength
  9069  }
  9070  
  9071  Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
  9072    value = +value
  9073    offset = offset | 0
  9074    if (!noAssert) {
  9075      var limit = Math.pow(2, 8 * byteLength - 1)
  9076  
  9077      checkInt(this, value, offset, byteLength, limit - 1, -limit)
  9078    }
  9079  
  9080    var i = byteLength - 1
  9081    var mul = 1
  9082    var sub = value < 0 ? 1 : 0
  9083    this[offset + i] = value & 0xFF
  9084    while (--i >= 0 && (mul *= 0x100)) {
  9085      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  9086    }
  9087  
  9088    return offset + byteLength
  9089  }
  9090  
  9091  Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
  9092    value = +value
  9093    offset = offset | 0
  9094    if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
  9095    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  9096    if (value < 0) value = 0xff + value + 1
  9097    this[offset] = value
  9098    return offset + 1
  9099  }
  9100  
  9101  Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
  9102    value = +value
  9103    offset = offset | 0
  9104    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  9105    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9106      this[offset] = value
  9107      this[offset + 1] = (value >>> 8)
  9108    } else {
  9109      objectWriteUInt16(this, value, offset, true)
  9110    }
  9111    return offset + 2
  9112  }
  9113  
  9114  Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
  9115    value = +value
  9116    offset = offset | 0
  9117    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  9118    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9119      this[offset] = (value >>> 8)
  9120      this[offset + 1] = value
  9121    } else {
  9122      objectWriteUInt16(this, value, offset, false)
  9123    }
  9124    return offset + 2
  9125  }
  9126  
  9127  Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
  9128    value = +value
  9129    offset = offset | 0
  9130    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  9131    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9132      this[offset] = value
  9133      this[offset + 1] = (value >>> 8)
  9134      this[offset + 2] = (value >>> 16)
  9135      this[offset + 3] = (value >>> 24)
  9136    } else {
  9137      objectWriteUInt32(this, value, offset, true)
  9138    }
  9139    return offset + 4
  9140  }
  9141  
  9142  Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
  9143    value = +value
  9144    offset = offset | 0
  9145    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  9146    if (value < 0) value = 0xffffffff + value + 1
  9147    if (Buffer.TYPED_ARRAY_SUPPORT) {
  9148      this[offset] = (value >>> 24)
  9149      this[offset + 1] = (value >>> 16)
  9150      this[offset + 2] = (value >>> 8)
  9151      this[offset + 3] = value
  9152    } else {
  9153      objectWriteUInt32(this, value, offset, false)
  9154    }
  9155    return offset + 4
  9156  }
  9157  
  9158  function checkIEEE754 (buf, value, offset, ext, max, min) {
  9159    if (value > max || value < min) throw new RangeError('value is out of bounds')
  9160    if (offset + ext > buf.length) throw new RangeError('index out of range')
  9161    if (offset < 0) throw new RangeError('index out of range')
  9162  }
  9163  
  9164  function writeFloat (buf, value, offset, littleEndian, noAssert) {
  9165    if (!noAssert) {
  9166      checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  9167    }
  9168    ieee754.write(buf, value, offset, littleEndian, 23, 4)
  9169    return offset + 4
  9170  }
  9171  
  9172  Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
  9173    return writeFloat(this, value, offset, true, noAssert)
  9174  }
  9175  
  9176  Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
  9177    return writeFloat(this, value, offset, false, noAssert)
  9178  }
  9179  
  9180  function writeDouble (buf, value, offset, littleEndian, noAssert) {
  9181    if (!noAssert) {
  9182      checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  9183    }
  9184    ieee754.write(buf, value, offset, littleEndian, 52, 8)
  9185    return offset + 8
  9186  }
  9187  
  9188  Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
  9189    return writeDouble(this, value, offset, true, noAssert)
  9190  }
  9191  
  9192  Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
  9193    return writeDouble(this, value, offset, false, noAssert)
  9194  }
  9195  
  9196  // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
  9197  Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  9198    if (!start) start = 0
  9199    if (!end && end !== 0) end = this.length
  9200    if (targetStart >= target.length) targetStart = target.length
  9201    if (!targetStart) targetStart = 0
  9202    if (end > 0 && end < start) end = start
  9203  
  9204    // Copy 0 bytes; we're done
  9205    if (end === start) return 0
  9206    if (target.length === 0 || this.length === 0) return 0
  9207  
  9208    // Fatal error conditions
  9209    if (targetStart < 0) {
  9210      throw new RangeError('targetStart out of bounds')
  9211    }
  9212    if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
  9213    if (end < 0) throw new RangeError('sourceEnd out of bounds')
  9214  
  9215    // Are we oob?
  9216    if (end > this.length) end = this.length
  9217    if (target.length - targetStart < end - start) {
  9218      end = target.length - targetStart + start
  9219    }
  9220  
  9221    var len = end - start
  9222    var i
  9223  
  9224    if (this === target && start < targetStart && targetStart < end) {
  9225      // descending copy from end
  9226      for (i = len - 1; i >= 0; i--) {
  9227        target[i + targetStart] = this[i + start]
  9228      }
  9229    } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
  9230      // ascending copy from start
  9231      for (i = 0; i < len; i++) {
  9232        target[i + targetStart] = this[i + start]
  9233      }
  9234    } else {
  9235      target._set(this.subarray(start, start + len), targetStart)
  9236    }
  9237  
  9238    return len
  9239  }
  9240  
  9241  // fill(value, start=0, end=buffer.length)
  9242  Buffer.prototype.fill = function fill (value, start, end) {
  9243    if (!value) value = 0
  9244    if (!start) start = 0
  9245    if (!end) end = this.length
  9246  
  9247    if (end < start) throw new RangeError('end < start')
  9248  
  9249    // Fill 0 bytes; we're done
  9250    if (end === start) return
  9251    if (this.length === 0) return
  9252  
  9253    if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
  9254    if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
  9255  
  9256    var i
  9257    if (typeof value === 'number') {
  9258      for (i = start; i < end; i++) {
  9259        this[i] = value
  9260      }
  9261    } else {
  9262      var bytes = utf8ToBytes(value.toString())
  9263      var len = bytes.length
  9264      for (i = start; i < end; i++) {
  9265        this[i] = bytes[i % len]
  9266      }
  9267    }
  9268  
  9269    return this
  9270  }
  9271  
  9272  /**
  9273   * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
  9274   * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
  9275   */
  9276  Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
  9277    if (typeof Uint8Array !== 'undefined') {
  9278      if (Buffer.TYPED_ARRAY_SUPPORT) {
  9279        return (new Buffer(this)).buffer
  9280      } else {
  9281        var buf = new Uint8Array(this.length)
  9282        for (var i = 0, len = buf.length; i < len; i += 1) {
  9283          buf[i] = this[i]
  9284        }
  9285        return buf.buffer
  9286      }
  9287    } else {
  9288      throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
  9289    }
  9290  }
  9291  
  9292  // HELPER FUNCTIONS
  9293  // ================
  9294  
  9295  var BP = Buffer.prototype
  9296  
  9297  /**
  9298   * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
  9299   */
  9300  Buffer._augment = function _augment (arr) {
  9301    arr.constructor = Buffer
  9302    arr._isBuffer = true
  9303  
  9304    // save reference to original Uint8Array set method before overwriting
  9305    arr._set = arr.set
  9306  
  9307    // deprecated
  9308    arr.get = BP.get
  9309    arr.set = BP.set
  9310  
  9311    arr.write = BP.write
  9312    arr.toString = BP.toString
  9313    arr.toLocaleString = BP.toString
  9314    arr.toJSON = BP.toJSON
  9315    arr.equals = BP.equals
  9316    arr.compare = BP.compare
  9317    arr.indexOf = BP.indexOf
  9318    arr.copy = BP.copy
  9319    arr.slice = BP.slice
  9320    arr.readUIntLE = BP.readUIntLE
  9321    arr.readUIntBE = BP.readUIntBE
  9322    arr.readUInt8 = BP.readUInt8
  9323    arr.readUInt16LE = BP.readUInt16LE
  9324    arr.readUInt16BE = BP.readUInt16BE
  9325    arr.readUInt32LE = BP.readUInt32LE
  9326    arr.readUInt32BE = BP.readUInt32BE
  9327    arr.readIntLE = BP.readIntLE
  9328    arr.readIntBE = BP.readIntBE
  9329    arr.readInt8 = BP.readInt8
  9330    arr.readInt16LE = BP.readInt16LE
  9331    arr.readInt16BE = BP.readInt16BE
  9332    arr.readInt32LE = BP.readInt32LE
  9333    arr.readInt32BE = BP.readInt32BE
  9334    arr.readFloatLE = BP.readFloatLE
  9335    arr.readFloatBE = BP.readFloatBE
  9336    arr.readDoubleLE = BP.readDoubleLE
  9337    arr.readDoubleBE = BP.readDoubleBE
  9338    arr.writeUInt8 = BP.writeUInt8
  9339    arr.writeUIntLE = BP.writeUIntLE
  9340    arr.writeUIntBE = BP.writeUIntBE
  9341    arr.writeUInt16LE = BP.writeUInt16LE
  9342    arr.writeUInt16BE = BP.writeUInt16BE
  9343    arr.writeUInt32LE = BP.writeUInt32LE
  9344    arr.writeUInt32BE = BP.writeUInt32BE
  9345    arr.writeIntLE = BP.writeIntLE
  9346    arr.writeIntBE = BP.writeIntBE
  9347    arr.writeInt8 = BP.writeInt8
  9348    arr.writeInt16LE = BP.writeInt16LE
  9349    arr.writeInt16BE = BP.writeInt16BE
  9350    arr.writeInt32LE = BP.writeInt32LE
  9351    arr.writeInt32BE = BP.writeInt32BE
  9352    arr.writeFloatLE = BP.writeFloatLE
  9353    arr.writeFloatBE = BP.writeFloatBE
  9354    arr.writeDoubleLE = BP.writeDoubleLE
  9355    arr.writeDoubleBE = BP.writeDoubleBE
  9356    arr.fill = BP.fill
  9357    arr.inspect = BP.inspect
  9358    arr.toArrayBuffer = BP.toArrayBuffer
  9359  
  9360    return arr
  9361  }
  9362  
  9363  var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
  9364  
  9365  function base64clean (str) {
  9366    // Node strips out invalid characters like \n and \t from the string, base64-js does not
  9367    str = stringtrim(str).replace(INVALID_BASE64_RE, '')
  9368    // Node converts strings with length < 2 to ''
  9369    if (str.length < 2) return ''
  9370    // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  9371    while (str.length % 4 !== 0) {
  9372      str = str + '='
  9373    }
  9374    return str
  9375  }
  9376  
  9377  function stringtrim (str) {
  9378    if (str.trim) return str.trim()
  9379    return str.replace(/^\s+|\s+$/g, '')
  9380  }
  9381  
  9382  function toHex (n) {
  9383    if (n < 16) return '0' + n.toString(16)
  9384    return n.toString(16)
  9385  }
  9386  
  9387  function utf8ToBytes (string, units) {
  9388    units = units || Infinity
  9389    var codePoint
  9390    var length = string.length
  9391    var leadSurrogate = null
  9392    var bytes = []
  9393  
  9394    for (var i = 0; i < length; i++) {
  9395      codePoint = string.charCodeAt(i)
  9396  
  9397      // is surrogate component
  9398      if (codePoint > 0xD7FF && codePoint < 0xE000) {
  9399        // last char was a lead
  9400        if (!leadSurrogate) {
  9401          // no lead yet
  9402          if (codePoint > 0xDBFF) {
  9403            // unexpected trail
  9404            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  9405            continue
  9406          } else if (i + 1 === length) {
  9407            // unpaired lead
  9408            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  9409            continue
  9410          }
  9411  
  9412          // valid lead
  9413          leadSurrogate = codePoint
  9414  
  9415          continue
  9416        }
  9417  
  9418        // 2 leads in a row
  9419        if (codePoint < 0xDC00) {
  9420          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  9421          leadSurrogate = codePoint
  9422          continue
  9423        }
  9424  
  9425        // valid surrogate pair
  9426        codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
  9427      } else if (leadSurrogate) {
  9428        // valid bmp char, but last char was a lead
  9429        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  9430      }
  9431  
  9432      leadSurrogate = null
  9433  
  9434      // encode utf8
  9435      if (codePoint < 0x80) {
  9436        if ((units -= 1) < 0) break
  9437        bytes.push(codePoint)
  9438      } else if (codePoint < 0x800) {
  9439        if ((units -= 2) < 0) break
  9440        bytes.push(
  9441          codePoint >> 0x6 | 0xC0,
  9442          codePoint & 0x3F | 0x80
  9443        )
  9444      } else if (codePoint < 0x10000) {
  9445        if ((units -= 3) < 0) break
  9446        bytes.push(
  9447          codePoint >> 0xC | 0xE0,
  9448          codePoint >> 0x6 & 0x3F | 0x80,
  9449          codePoint & 0x3F | 0x80
  9450        )
  9451      } else if (codePoint < 0x110000) {
  9452        if ((units -= 4) < 0) break
  9453        bytes.push(
  9454          codePoint >> 0x12 | 0xF0,
  9455          codePoint >> 0xC & 0x3F | 0x80,
  9456          codePoint >> 0x6 & 0x3F | 0x80,
  9457          codePoint & 0x3F | 0x80
  9458        )
  9459      } else {
  9460        throw new Error('Invalid code point')
  9461      }
  9462    }
  9463  
  9464    return bytes
  9465  }
  9466  
  9467  function asciiToBytes (str) {
  9468    var byteArray = []
  9469    for (var i = 0; i < str.length; i++) {
  9470      // Node's code seems to be doing this and not & 0x7F..
  9471      byteArray.push(str.charCodeAt(i) & 0xFF)
  9472    }
  9473    return byteArray
  9474  }
  9475  
  9476  function utf16leToBytes (str, units) {
  9477    var c, hi, lo
  9478    var byteArray = []
  9479    for (var i = 0; i < str.length; i++) {
  9480      if ((units -= 2) < 0) break
  9481  
  9482      c = str.charCodeAt(i)
  9483      hi = c >> 8
  9484      lo = c % 256
  9485      byteArray.push(lo)
  9486      byteArray.push(hi)
  9487    }
  9488  
  9489    return byteArray
  9490  }
  9491  
  9492  function base64ToBytes (str) {
  9493    return base64.toByteArray(base64clean(str))
  9494  }
  9495  
  9496  function blitBuffer (src, dst, offset, length) {
  9497    for (var i = 0; i < length; i++) {
  9498      if ((i + offset >= dst.length) || (i >= src.length)) break
  9499      dst[i + offset] = src[i]
  9500    }
  9501    return i
  9502  }
  9503  
  9504  },{"base64-js":15,"ieee754":16,"is-array":17}],15:[function(require,module,exports){
  9505  var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  9506  
  9507  ;(function (exports) {
  9508  	'use strict';
  9509  
  9510    var Arr = (typeof Uint8Array !== 'undefined')
  9511      ? Uint8Array
  9512      : Array
  9513  
  9514  	var PLUS   = '+'.charCodeAt(0)
  9515  	var SLASH  = '/'.charCodeAt(0)
  9516  	var NUMBER = '0'.charCodeAt(0)
  9517  	var LOWER  = 'a'.charCodeAt(0)
  9518  	var UPPER  = 'A'.charCodeAt(0)
  9519  	var PLUS_URL_SAFE = '-'.charCodeAt(0)
  9520  	var SLASH_URL_SAFE = '_'.charCodeAt(0)
  9521  
  9522  	function decode (elt) {
  9523  		var code = elt.charCodeAt(0)
  9524  		if (code === PLUS ||
  9525  		    code === PLUS_URL_SAFE)
  9526  			return 62 // '+'
  9527  		if (code === SLASH ||
  9528  		    code === SLASH_URL_SAFE)
  9529  			return 63 // '/'
  9530  		if (code < NUMBER)
  9531  			return -1 //no match
  9532  		if (code < NUMBER + 10)
  9533  			return code - NUMBER + 26 + 26
  9534  		if (code < UPPER + 26)
  9535  			return code - UPPER
  9536  		if (code < LOWER + 26)
  9537  			return code - LOWER + 26
  9538  	}
  9539  
  9540  	function b64ToByteArray (b64) {
  9541  		var i, j, l, tmp, placeHolders, arr
  9542  
  9543  		if (b64.length % 4 > 0) {
  9544  			throw new Error('Invalid string. Length must be a multiple of 4')
  9545  		}
  9546  
  9547  		// the number of equal signs (place holders)
  9548  		// if there are two placeholders, than the two characters before it
  9549  		// represent one byte
  9550  		// if there is only one, then the three characters before it represent 2 bytes
  9551  		// this is just a cheap hack to not do indexOf twice
  9552  		var len = b64.length
  9553  		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
  9554  
  9555  		// base64 is 4/3 + up to two characters of the original data
  9556  		arr = new Arr(b64.length * 3 / 4 - placeHolders)
  9557  
  9558  		// if there are placeholders, only get up to the last complete 4 chars
  9559  		l = placeHolders > 0 ? b64.length - 4 : b64.length
  9560  
  9561  		var L = 0
  9562  
  9563  		function push (v) {
  9564  			arr[L++] = v
  9565  		}
  9566  
  9567  		for (i = 0, j = 0; i < l; i += 4, j += 3) {
  9568  			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
  9569  			push((tmp & 0xFF0000) >> 16)
  9570  			push((tmp & 0xFF00) >> 8)
  9571  			push(tmp & 0xFF)
  9572  		}
  9573  
  9574  		if (placeHolders === 2) {
  9575  			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
  9576  			push(tmp & 0xFF)
  9577  		} else if (placeHolders === 1) {
  9578  			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
  9579  			push((tmp >> 8) & 0xFF)
  9580  			push(tmp & 0xFF)
  9581  		}
  9582  
  9583  		return arr
  9584  	}
  9585  
  9586  	function uint8ToBase64 (uint8) {
  9587  		var i,
  9588  			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
  9589  			output = "",
  9590  			temp, length
  9591  
  9592  		function encode (num) {
  9593  			return lookup.charAt(num)
  9594  		}
  9595  
  9596  		function tripletToBase64 (num) {
  9597  			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
  9598  		}
  9599  
  9600  		// go through the array every three bytes, we'll deal with trailing stuff later
  9601  		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
  9602  			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
  9603  			output += tripletToBase64(temp)
  9604  		}
  9605  
  9606  		// pad the end with zeros, but make sure to not forget the extra bytes
  9607  		switch (extraBytes) {
  9608  			case 1:
  9609  				temp = uint8[uint8.length - 1]
  9610  				output += encode(temp >> 2)
  9611  				output += encode((temp << 4) & 0x3F)
  9612  				output += '=='
  9613  				break
  9614  			case 2:
  9615  				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
  9616  				output += encode(temp >> 10)
  9617  				output += encode((temp >> 4) & 0x3F)
  9618  				output += encode((temp << 2) & 0x3F)
  9619  				output += '='
  9620  				break
  9621  		}
  9622  
  9623  		return output
  9624  	}
  9625  
  9626  	exports.toByteArray = b64ToByteArray
  9627  	exports.fromByteArray = uint8ToBase64
  9628  }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
  9629  
  9630  },{}],16:[function(require,module,exports){
  9631  exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  9632    var e, m
  9633    var eLen = nBytes * 8 - mLen - 1
  9634    var eMax = (1 << eLen) - 1
  9635    var eBias = eMax >> 1
  9636    var nBits = -7
  9637    var i = isLE ? (nBytes - 1) : 0
  9638    var d = isLE ? -1 : 1
  9639    var s = buffer[offset + i]
  9640  
  9641    i += d
  9642  
  9643    e = s & ((1 << (-nBits)) - 1)
  9644    s >>= (-nBits)
  9645    nBits += eLen
  9646    for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  9647  
  9648    m = e & ((1 << (-nBits)) - 1)
  9649    e >>= (-nBits)
  9650    nBits += mLen
  9651    for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  9652  
  9653    if (e === 0) {
  9654      e = 1 - eBias
  9655    } else if (e === eMax) {
  9656      return m ? NaN : ((s ? -1 : 1) * Infinity)
  9657    } else {
  9658      m = m + Math.pow(2, mLen)
  9659      e = e - eBias
  9660    }
  9661    return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
  9662  }
  9663  
  9664  exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  9665    var e, m, c
  9666    var eLen = nBytes * 8 - mLen - 1
  9667    var eMax = (1 << eLen) - 1
  9668    var eBias = eMax >> 1
  9669    var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  9670    var i = isLE ? 0 : (nBytes - 1)
  9671    var d = isLE ? 1 : -1
  9672    var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
  9673  
  9674    value = Math.abs(value)
  9675  
  9676    if (isNaN(value) || value === Infinity) {
  9677      m = isNaN(value) ? 1 : 0
  9678      e = eMax
  9679    } else {
  9680      e = Math.floor(Math.log(value) / Math.LN2)
  9681      if (value * (c = Math.pow(2, -e)) < 1) {
  9682        e--
  9683        c *= 2
  9684      }
  9685      if (e + eBias >= 1) {
  9686        value += rt / c
  9687      } else {
  9688        value += rt * Math.pow(2, 1 - eBias)
  9689      }
  9690      if (value * c >= 2) {
  9691        e++
  9692        c /= 2
  9693      }
  9694  
  9695      if (e + eBias >= eMax) {
  9696        m = 0
  9697        e = eMax
  9698      } else if (e + eBias >= 1) {
  9699        m = (value * c - 1) * Math.pow(2, mLen)
  9700        e = e + eBias
  9701      } else {
  9702        m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
  9703        e = 0
  9704      }
  9705    }
  9706  
  9707    for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  9708  
  9709    e = (e << mLen) | m
  9710    eLen += mLen
  9711    for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  9712  
  9713    buffer[offset + i - d] |= s * 128
  9714  }
  9715  
  9716  },{}],17:[function(require,module,exports){
  9717  
  9718  /**
  9719   * isArray
  9720   */
  9721  
  9722  var isArray = Array.isArray;
  9723  
  9724  /**
  9725   * toString
  9726   */
  9727  
  9728  var str = Object.prototype.toString;
  9729  
  9730  /**
  9731   * Whether or not the given `val`
  9732   * is an array.
  9733   *
  9734   * example:
  9735   *
  9736   *        isArray([]);
  9737   *        // > true
  9738   *        isArray(arguments);
  9739   *        // > false
  9740   *        isArray('');
  9741   *        // > false
  9742   *
  9743   * @param {mixed} val
  9744   * @return {bool}
  9745   */
  9746  
  9747  module.exports = isArray || function (val) {
  9748    return !! val && '[object Array]' == str.call(val);
  9749  };
  9750  
  9751  },{}],18:[function(require,module,exports){
  9752  /* jshint node: true */
  9753  (function () {
  9754      "use strict";
  9755  
  9756      function CookieAccessInfo(domain, path, secure, script) {
  9757          if (this instanceof CookieAccessInfo) {
  9758              this.domain = domain || undefined;
  9759              this.path = path || "/";
  9760              this.secure = !!secure;
  9761              this.script = !!script;
  9762              return this;
  9763          }
  9764          return new CookieAccessInfo(domain, path, secure, script);
  9765      }
  9766      exports.CookieAccessInfo = CookieAccessInfo;
  9767  
  9768      function Cookie(cookiestr, request_domain, request_path) {
  9769          if (cookiestr instanceof Cookie) {
  9770              return cookiestr;
  9771          }
  9772          if (this instanceof Cookie) {
  9773              this.name = null;
  9774              this.value = null;
  9775              this.expiration_date = Infinity;
  9776              this.path = String(request_path || "/");
  9777              this.explicit_path = false;
  9778              this.domain = request_domain || null;
  9779              this.explicit_domain = false;
  9780              this.secure = false; //how to define default?
  9781              this.noscript = false; //httponly
  9782              if (cookiestr) {
  9783                  this.parse(cookiestr, request_domain, request_path);
  9784              }
  9785              return this;
  9786          }
  9787          return new Cookie(cookiestr, request_domain, request_path);
  9788      }
  9789      exports.Cookie = Cookie;
  9790  
  9791      Cookie.prototype.toString = function toString() {
  9792          var str = [this.name + "=" + this.value];
  9793          if (this.expiration_date !== Infinity) {
  9794              str.push("expires=" + (new Date(this.expiration_date)).toGMTString());
  9795          }
  9796          if (this.domain) {
  9797              str.push("domain=" + this.domain);
  9798          }
  9799          if (this.path) {
  9800              str.push("path=" + this.path);
  9801          }
  9802          if (this.secure) {
  9803              str.push("secure");
  9804          }
  9805          if (this.noscript) {
  9806              str.push("httponly");
  9807          }
  9808          return str.join("; ");
  9809      };
  9810  
  9811      Cookie.prototype.toValueString = function toValueString() {
  9812          return this.name + "=" + this.value;
  9813      };
  9814  
  9815      var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;
  9816      Cookie.prototype.parse = function parse(str, request_domain, request_path) {
  9817          if (this instanceof Cookie) {
  9818              var parts = str.split(";").filter(function (value) {
  9819                      return !!value;
  9820                  }),
  9821                  pair = parts[0].match(/([^=]+)=([\s\S]*)/),
  9822                  key = pair[1],
  9823                  value = pair[2],
  9824                  i;
  9825              this.name = key;
  9826              this.value = value;
  9827  
  9828              for (i = 1; i < parts.length; i += 1) {
  9829                  pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/);
  9830                  key = pair[1].trim().toLowerCase();
  9831                  value = pair[2];
  9832                  switch (key) {
  9833                  case "httponly":
  9834                      this.noscript = true;
  9835                      break;
  9836                  case "expires":
  9837                      this.expiration_date = value ?
  9838                              Number(Date.parse(value)) :
  9839                              Infinity;
  9840                      break;
  9841                  case "path":
  9842                      this.path = value ?
  9843                              value.trim() :
  9844                              "";
  9845                      this.explicit_path = true;
  9846                      break;
  9847                  case "domain":
  9848                      this.domain = value ?
  9849                              value.trim() :
  9850                              "";
  9851                      this.explicit_domain = !!this.domain;
  9852                      break;
  9853                  case "secure":
  9854                      this.secure = true;
  9855                      break;
  9856                  }
  9857              }
  9858  
  9859              if (!this.explicit_path) {
  9860                 this.path = request_path || "/";
  9861              }
  9862              if (!this.explicit_domain) {
  9863                 this.domain = request_domain;
  9864              }
  9865  
  9866              return this;
  9867          }
  9868          return new Cookie().parse(str, request_domain, request_path);
  9869      };
  9870  
  9871      Cookie.prototype.matches = function matches(access_info) {
  9872          if (this.noscript && access_info.script ||
  9873                  this.secure && !access_info.secure ||
  9874                  !this.collidesWith(access_info)) {
  9875              return false;
  9876          }
  9877          return true;
  9878      };
  9879  
  9880      Cookie.prototype.collidesWith = function collidesWith(access_info) {
  9881          if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
  9882              return false;
  9883          }
  9884          if (this.path && access_info.path.indexOf(this.path) !== 0) {
  9885              return false;
  9886          }
  9887          if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) {
  9888             return false;
  9889          }
  9890          var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,'');
  9891          var cookie_domain = this.domain && this.domain.replace(/^[\.]/,'');
  9892          if (cookie_domain === access_domain) {
  9893              return true;
  9894          }
  9895          if (cookie_domain) {
  9896              if (!this.explicit_domain) {
  9897                  return false; // we already checked if the domains were exactly the same
  9898              }
  9899              var wildcard = access_domain.indexOf(cookie_domain);
  9900              if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) {
  9901                  return false;
  9902              }
  9903              return true;
  9904          }
  9905          return true;
  9906      };
  9907  
  9908      function CookieJar() {
  9909          var cookies, cookies_list, collidable_cookie;
  9910          if (this instanceof CookieJar) {
  9911              cookies = Object.create(null); //name: [Cookie]
  9912  
  9913              this.setCookie = function setCookie(cookie, request_domain, request_path) {
  9914                  var remove, i;
  9915                  cookie = new Cookie(cookie, request_domain, request_path);
  9916                  //Delete the cookie if the set is past the current time
  9917                  remove = cookie.expiration_date <= Date.now();
  9918                  if (cookies[cookie.name] !== undefined) {
  9919                      cookies_list = cookies[cookie.name];
  9920                      for (i = 0; i < cookies_list.length; i += 1) {
  9921                          collidable_cookie = cookies_list[i];
  9922                          if (collidable_cookie.collidesWith(cookie)) {
  9923                              if (remove) {
  9924                                  cookies_list.splice(i, 1);
  9925                                  if (cookies_list.length === 0) {
  9926                                      delete cookies[cookie.name];
  9927                                  }
  9928                                  return false;
  9929                              }
  9930                              cookies_list[i] = cookie;
  9931                              return cookie;
  9932                          }
  9933                      }
  9934                      if (remove) {
  9935                          return false;
  9936                      }
  9937                      cookies_list.push(cookie);
  9938                      return cookie;
  9939                  }
  9940                  if (remove) {
  9941                      return false;
  9942                  }
  9943                  cookies[cookie.name] = [cookie];
  9944                  return cookies[cookie.name];
  9945              };
  9946              //returns a cookie
  9947              this.getCookie = function getCookie(cookie_name, access_info) {
  9948                  var cookie, i;
  9949                  cookies_list = cookies[cookie_name];
  9950                  if (!cookies_list) {
  9951                      return;
  9952                  }
  9953                  for (i = 0; i < cookies_list.length; i += 1) {
  9954                      cookie = cookies_list[i];
  9955                      if (cookie.expiration_date <= Date.now()) {
  9956                          if (cookies_list.length === 0) {
  9957                              delete cookies[cookie.name];
  9958                          }
  9959                          continue;
  9960                      }
  9961  
  9962                      if (cookie.matches(access_info)) {
  9963                          return cookie;
  9964                      }
  9965                  }
  9966              };
  9967              //returns a list of cookies
  9968              this.getCookies = function getCookies(access_info) {
  9969                  var matches = [], cookie_name, cookie;
  9970                  for (cookie_name in cookies) {
  9971                      cookie = this.getCookie(cookie_name, access_info);
  9972                      if (cookie) {
  9973                          matches.push(cookie);
  9974                      }
  9975                  }
  9976                  matches.toString = function toString() {
  9977                      return matches.join(":");
  9978                  };
  9979                  matches.toValueString = function toValueString() {
  9980                      return matches.map(function (c) {
  9981                          return c.toValueString();
  9982                      }).join(';');
  9983                  };
  9984                  return matches;
  9985              };
  9986  
  9987              return this;
  9988          }
  9989          return new CookieJar();
  9990      }
  9991      exports.CookieJar = CookieJar;
  9992  
  9993      //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned.
  9994      CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) {
  9995          cookies = Array.isArray(cookies) ?
  9996                  cookies :
  9997                  cookies.split(cookie_str_splitter);
  9998          var successful = [],
  9999              i,
 10000              cookie;
 10001          cookies = cookies.map(function(item){
 10002              return new Cookie(item, request_domain, request_path);
 10003          });
 10004          for (i = 0; i < cookies.length; i += 1) {
 10005              cookie = cookies[i];
 10006              if (this.setCookie(cookie, request_domain, request_path)) {
 10007                  successful.push(cookie);
 10008              }
 10009          }
 10010          return successful;
 10011      };
 10012  }());
 10013  
 10014  },{}],19:[function(require,module,exports){
 10015  'use strict';
 10016  
 10017  
 10018  var yaml = require('./lib/js-yaml.js');
 10019  
 10020  
 10021  module.exports = yaml;
 10022  
 10023  },{"./lib/js-yaml.js":20}],20:[function(require,module,exports){
 10024  'use strict';
 10025  
 10026  
 10027  var loader = require('./js-yaml/loader');
 10028  var dumper = require('./js-yaml/dumper');
 10029  
 10030  
 10031  function deprecated(name) {
 10032    return function () {
 10033      throw new Error('Function ' + name + ' is deprecated and cannot be used.');
 10034    };
 10035  }
 10036  
 10037  
 10038  module.exports.Type                = require('./js-yaml/type');
 10039  module.exports.Schema              = require('./js-yaml/schema');
 10040  module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');
 10041  module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');
 10042  module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');
 10043  module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
 10044  module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
 10045  module.exports.load                = loader.load;
 10046  module.exports.loadAll             = loader.loadAll;
 10047  module.exports.safeLoad            = loader.safeLoad;
 10048  module.exports.safeLoadAll         = loader.safeLoadAll;
 10049  module.exports.dump                = dumper.dump;
 10050  module.exports.safeDump            = dumper.safeDump;
 10051  module.exports.YAMLException       = require('./js-yaml/exception');
 10052  
 10053  // Deprecated schema names from JS-YAML 2.0.x
 10054  module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
 10055  module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');
 10056  module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
 10057  
 10058  // Deprecated functions from JS-YAML 1.x.x
 10059  module.exports.scan           = deprecated('scan');
 10060  module.exports.parse          = deprecated('parse');
 10061  module.exports.compose        = deprecated('compose');
 10062  module.exports.addConstructor = deprecated('addConstructor');
 10063  
 10064  },{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(require,module,exports){
 10065  'use strict';
 10066  
 10067  
 10068  function isNothing(subject) {
 10069    return (typeof subject === 'undefined') || (subject === null);
 10070  }
 10071  
 10072  
 10073  function isObject(subject) {
 10074    return (typeof subject === 'object') && (subject !== null);
 10075  }
 10076  
 10077  
 10078  function toArray(sequence) {
 10079    if (Array.isArray(sequence)) return sequence;
 10080    else if (isNothing(sequence)) return [];
 10081  
 10082    return [ sequence ];
 10083  }
 10084  
 10085  
 10086  function extend(target, source) {
 10087    var index, length, key, sourceKeys;
 10088  
 10089    if (source) {
 10090      sourceKeys = Object.keys(source);
 10091  
 10092      for (index = 0, length = sourceKeys.length; index < length; index += 1) {
 10093        key = sourceKeys[index];
 10094        target[key] = source[key];
 10095      }
 10096    }
 10097  
 10098    return target;
 10099  }
 10100  
 10101  
 10102  function repeat(string, count) {
 10103    var result = '', cycle;
 10104  
 10105    for (cycle = 0; cycle < count; cycle += 1) {
 10106      result += string;
 10107    }
 10108  
 10109    return result;
 10110  }
 10111  
 10112  
 10113  function isNegativeZero(number) {
 10114    return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
 10115  }
 10116  
 10117  
 10118  module.exports.isNothing      = isNothing;
 10119  module.exports.isObject       = isObject;
 10120  module.exports.toArray        = toArray;
 10121  module.exports.repeat         = repeat;
 10122  module.exports.isNegativeZero = isNegativeZero;
 10123  module.exports.extend         = extend;
 10124  
 10125  },{}],22:[function(require,module,exports){
 10126  'use strict';
 10127  
 10128  /*eslint-disable no-use-before-define*/
 10129  
 10130  var common              = require('./common');
 10131  var YAMLException       = require('./exception');
 10132  var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
 10133  var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
 10134  
 10135  var _toString       = Object.prototype.toString;
 10136  var _hasOwnProperty = Object.prototype.hasOwnProperty;
 10137  
 10138  var CHAR_TAB                  = 0x09; /* Tab */
 10139  var CHAR_LINE_FEED            = 0x0A; /* LF */
 10140  var CHAR_SPACE                = 0x20; /* Space */
 10141  var CHAR_EXCLAMATION          = 0x21; /* ! */
 10142  var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
 10143  var CHAR_SHARP                = 0x23; /* # */
 10144  var CHAR_PERCENT              = 0x25; /* % */
 10145  var CHAR_AMPERSAND            = 0x26; /* & */
 10146  var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
 10147  var CHAR_ASTERISK             = 0x2A; /* * */
 10148  var CHAR_COMMA                = 0x2C; /* , */
 10149  var CHAR_MINUS                = 0x2D; /* - */
 10150  var CHAR_COLON                = 0x3A; /* : */
 10151  var CHAR_GREATER_THAN         = 0x3E; /* > */
 10152  var CHAR_QUESTION             = 0x3F; /* ? */
 10153  var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
 10154  var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
 10155  var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
 10156  var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
 10157  var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
 10158  var CHAR_VERTICAL_LINE        = 0x7C; /* | */
 10159  var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
 10160  
 10161  var ESCAPE_SEQUENCES = {};
 10162  
 10163  ESCAPE_SEQUENCES[0x00]   = '\\0';
 10164  ESCAPE_SEQUENCES[0x07]   = '\\a';
 10165  ESCAPE_SEQUENCES[0x08]   = '\\b';
 10166  ESCAPE_SEQUENCES[0x09]   = '\\t';
 10167  ESCAPE_SEQUENCES[0x0A]   = '\\n';
 10168  ESCAPE_SEQUENCES[0x0B]   = '\\v';
 10169  ESCAPE_SEQUENCES[0x0C]   = '\\f';
 10170  ESCAPE_SEQUENCES[0x0D]   = '\\r';
 10171  ESCAPE_SEQUENCES[0x1B]   = '\\e';
 10172  ESCAPE_SEQUENCES[0x22]   = '\\"';
 10173  ESCAPE_SEQUENCES[0x5C]   = '\\\\';
 10174  ESCAPE_SEQUENCES[0x85]   = '\\N';
 10175  ESCAPE_SEQUENCES[0xA0]   = '\\_';
 10176  ESCAPE_SEQUENCES[0x2028] = '\\L';
 10177  ESCAPE_SEQUENCES[0x2029] = '\\P';
 10178  
 10179  var DEPRECATED_BOOLEANS_SYNTAX = [
 10180    'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
 10181    'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
 10182  ];
 10183  
 10184  function compileStyleMap(schema, map) {
 10185    var result, keys, index, length, tag, style, type;
 10186  
 10187    if (map === null) return {};
 10188  
 10189    result = {};
 10190    keys = Object.keys(map);
 10191  
 10192    for (index = 0, length = keys.length; index < length; index += 1) {
 10193      tag = keys[index];
 10194      style = String(map[tag]);
 10195  
 10196      if (tag.slice(0, 2) === '!!') {
 10197        tag = 'tag:yaml.org,2002:' + tag.slice(2);
 10198      }
 10199  
 10200      type = schema.compiledTypeMap[tag];
 10201  
 10202      if (type && _hasOwnProperty.call(type.styleAliases, style)) {
 10203        style = type.styleAliases[style];
 10204      }
 10205  
 10206      result[tag] = style;
 10207    }
 10208  
 10209    return result;
 10210  }
 10211  
 10212  function encodeHex(character) {
 10213    var string, handle, length;
 10214  
 10215    string = character.toString(16).toUpperCase();
 10216  
 10217    if (character <= 0xFF) {
 10218      handle = 'x';
 10219      length = 2;
 10220    } else if (character <= 0xFFFF) {
 10221      handle = 'u';
 10222      length = 4;
 10223    } else if (character <= 0xFFFFFFFF) {
 10224      handle = 'U';
 10225      length = 8;
 10226    } else {
 10227      throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
 10228    }
 10229  
 10230    return '\\' + handle + common.repeat('0', length - string.length) + string;
 10231  }
 10232  
 10233  function State(options) {
 10234    this.schema       = options['schema'] || DEFAULT_FULL_SCHEMA;
 10235    this.indent       = Math.max(1, (options['indent'] || 2));
 10236    this.skipInvalid  = options['skipInvalid'] || false;
 10237    this.flowLevel    = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
 10238    this.styleMap     = compileStyleMap(this.schema, options['styles'] || null);
 10239    this.sortKeys     = options['sortKeys'] || false;
 10240    this.lineWidth    = options['lineWidth'] || 80;
 10241    this.noRefs       = options['noRefs'] || false;
 10242    this.noCompatMode = options['noCompatMode'] || false;
 10243  
 10244    this.implicitTypes = this.schema.compiledImplicit;
 10245    this.explicitTypes = this.schema.compiledExplicit;
 10246  
 10247    this.tag = null;
 10248    this.result = '';
 10249  
 10250    this.duplicates = [];
 10251    this.usedDuplicates = null;
 10252  }
 10253  
 10254  // Indents every line in a string. Empty lines (\n only) are not indented.
 10255  function indentString(string, spaces) {
 10256    var ind = common.repeat(' ', spaces),
 10257        position = 0,
 10258        next = -1,
 10259        result = '',
 10260        line,
 10261        length = string.length;
 10262  
 10263    while (position < length) {
 10264      next = string.indexOf('\n', position);
 10265      if (next === -1) {
 10266        line = string.slice(position);
 10267        position = length;
 10268      } else {
 10269        line = string.slice(position, next + 1);
 10270        position = next + 1;
 10271      }
 10272  
 10273      if (line.length && line !== '\n') result += ind;
 10274  
 10275      result += line;
 10276    }
 10277  
 10278    return result;
 10279  }
 10280  
 10281  function generateNextLine(state, level) {
 10282    return '\n' + common.repeat(' ', state.indent * level);
 10283  }
 10284  
 10285  function testImplicitResolving(state, str) {
 10286    var index, length, type;
 10287  
 10288    for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
 10289      type = state.implicitTypes[index];
 10290  
 10291      if (type.resolve(str)) {
 10292        return true;
 10293      }
 10294    }
 10295  
 10296    return false;
 10297  }
 10298  
 10299  // [33] s-white ::= s-space | s-tab
 10300  function isWhitespace(c) {
 10301    return c === CHAR_SPACE || c === CHAR_TAB;
 10302  }
 10303  
 10304  // Returns true if the character can be printed without escaping.
 10305  // From YAML 1.2: "any allowed characters known to be non-printable
 10306  // should also be escaped. [However,] This isn’t mandatory"
 10307  // Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
 10308  function isPrintable(c) {
 10309    return  (0x00020 <= c && c <= 0x00007E)
 10310        || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)
 10311        || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */)
 10312        ||  (0x10000 <= c && c <= 0x10FFFF);
 10313  }
 10314  
 10315  // Simplified test for values allowed after the first character in plain style.
 10316  function isPlainSafe(c) {
 10317    // Uses a subset of nb-char - c-flow-indicator - ":" - "#"
 10318    // where nb-char ::= c-printable - b-char - c-byte-order-mark.
 10319    return isPrintable(c) && c !== 0xFEFF
 10320      // - c-flow-indicator
 10321      && c !== CHAR_COMMA
 10322      && c !== CHAR_LEFT_SQUARE_BRACKET
 10323      && c !== CHAR_RIGHT_SQUARE_BRACKET
 10324      && c !== CHAR_LEFT_CURLY_BRACKET
 10325      && c !== CHAR_RIGHT_CURLY_BRACKET
 10326      // - ":" - "#"
 10327      && c !== CHAR_COLON
 10328      && c !== CHAR_SHARP;
 10329  }
 10330  
 10331  // Simplified test for values allowed as the first character in plain style.
 10332  function isPlainSafeFirst(c) {
 10333    // Uses a subset of ns-char - c-indicator
 10334    // where ns-char = nb-char - s-white.
 10335    return isPrintable(c) && c !== 0xFEFF
 10336      && !isWhitespace(c) // - s-white
 10337      // - (c-indicator ::=
 10338      // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
 10339      && c !== CHAR_MINUS
 10340      && c !== CHAR_QUESTION
 10341      && c !== CHAR_COLON
 10342      && c !== CHAR_COMMA
 10343      && c !== CHAR_LEFT_SQUARE_BRACKET
 10344      && c !== CHAR_RIGHT_SQUARE_BRACKET
 10345      && c !== CHAR_LEFT_CURLY_BRACKET
 10346      && c !== CHAR_RIGHT_CURLY_BRACKET
 10347      // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"”
 10348      && c !== CHAR_SHARP
 10349      && c !== CHAR_AMPERSAND
 10350      && c !== CHAR_ASTERISK
 10351      && c !== CHAR_EXCLAMATION
 10352      && c !== CHAR_VERTICAL_LINE
 10353      && c !== CHAR_GREATER_THAN
 10354      && c !== CHAR_SINGLE_QUOTE
 10355      && c !== CHAR_DOUBLE_QUOTE
 10356      // | “%” | “@” | “`”)
 10357      && c !== CHAR_PERCENT
 10358      && c !== CHAR_COMMERCIAL_AT
 10359      && c !== CHAR_GRAVE_ACCENT;
 10360  }
 10361  
 10362  var STYLE_PLAIN   = 1,
 10363      STYLE_SINGLE  = 2,
 10364      STYLE_LITERAL = 3,
 10365      STYLE_FOLDED  = 4,
 10366      STYLE_DOUBLE  = 5;
 10367  
 10368  // Determines which scalar styles are possible and returns the preferred style.
 10369  // lineWidth = -1 => no limit.
 10370  // Pre-conditions: str.length > 0.
 10371  // Post-conditions:
 10372  //    STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
 10373  //    STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
 10374  //    STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
 10375  function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
 10376    var i;
 10377    var char;
 10378    var hasLineBreak = false;
 10379    var hasFoldableLine = false; // only checked if shouldTrackWidth
 10380    var shouldTrackWidth = lineWidth !== -1;
 10381    var previousLineBreak = -1; // count the first line correctly
 10382    var plain = isPlainSafeFirst(string.charCodeAt(0))
 10383            && !isWhitespace(string.charCodeAt(string.length - 1));
 10384  
 10385    if (singleLineOnly) {
 10386      // Case: no block styles.
 10387      // Check for disallowed characters to rule out plain and single.
 10388      for (i = 0; i < string.length; i++) {
 10389        char = string.charCodeAt(i);
 10390        if (!isPrintable(char)) {
 10391          return STYLE_DOUBLE;
 10392        }
 10393        plain = plain && isPlainSafe(char);
 10394      }
 10395    } else {
 10396      // Case: block styles permitted.
 10397      for (i = 0; i < string.length; i++) {
 10398        char = string.charCodeAt(i);
 10399        if (char === CHAR_LINE_FEED) {
 10400          hasLineBreak = true;
 10401          // Check if any line can be folded.
 10402          if (shouldTrackWidth) {
 10403            hasFoldableLine = hasFoldableLine ||
 10404              // Foldable line = too long, and not more-indented.
 10405              (i - previousLineBreak - 1 > lineWidth &&
 10406               string[previousLineBreak + 1] !== ' ');
 10407            previousLineBreak = i;
 10408          }
 10409        } else if (!isPrintable(char)) {
 10410          return STYLE_DOUBLE;
 10411        }
 10412        plain = plain && isPlainSafe(char);
 10413      }
 10414      // in case the end is missing a \n
 10415      hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
 10416        (i - previousLineBreak - 1 > lineWidth &&
 10417         string[previousLineBreak + 1] !== ' '));
 10418    }
 10419    // Although every style can represent \n without escaping, prefer block styles
 10420    // for multiline, since they're more readable and they don't add empty lines.
 10421    // Also prefer folding a super-long line.
 10422    if (!hasLineBreak && !hasFoldableLine) {
 10423      // Strings interpretable as another type have to be quoted;
 10424      // e.g. the string 'true' vs. the boolean true.
 10425      return plain && !testAmbiguousType(string)
 10426        ? STYLE_PLAIN : STYLE_SINGLE;
 10427    }
 10428    // Edge case: block indentation indicator can only have one digit.
 10429    if (string[0] === ' ' && indentPerLevel > 9) {
 10430      return STYLE_DOUBLE;
 10431    }
 10432    // At this point we know block styles are valid.
 10433    // Prefer literal style unless we want to fold.
 10434    return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
 10435  }
 10436  
 10437  // Note: line breaking/folding is implemented for only the folded style.
 10438  // NB. We drop the last trailing newline (if any) of a returned block scalar
 10439  //  since the dumper adds its own newline. This always works:
 10440  //    • No ending newline => unaffected; already using strip "-" chomping.
 10441  //    • Ending newline    => removed then restored.
 10442  //  Importantly, this keeps the "+" chomp indicator from gaining an extra line.
 10443  function writeScalar(state, string, level, iskey) {
 10444    state.dump = (function () {
 10445      if (string.length === 0) {
 10446        return "''";
 10447      }
 10448      if (!state.noCompatMode &&
 10449          DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) {
 10450        return "'" + string + "'";
 10451      }
 10452  
 10453      var indent = state.indent * Math.max(1, level); // no 0-indent scalars
 10454      // As indentation gets deeper, let the width decrease monotonically
 10455      // to the lower bound min(state.lineWidth, 40).
 10456      // Note that this implies
 10457      //  state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
 10458      //  state.lineWidth > 40 + state.indent: width decreases until the lower bound.
 10459      // This behaves better than a constant minimum width which disallows narrower options,
 10460      // or an indent threshold which causes the width to suddenly increase.
 10461      var lineWidth = state.lineWidth === -1
 10462        ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
 10463  
 10464      // Without knowing if keys are implicit/explicit, assume implicit for safety.
 10465      var singleLineOnly = iskey
 10466        // No block styles in flow mode.
 10467        || (state.flowLevel > -1 && level >= state.flowLevel);
 10468      function testAmbiguity(string) {
 10469        return testImplicitResolving(state, string);
 10470      }
 10471  
 10472      switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
 10473        case STYLE_PLAIN:
 10474          return string;
 10475        case STYLE_SINGLE:
 10476          return "'" + string.replace(/'/g, "''") + "'";
 10477        case STYLE_LITERAL:
 10478          return '|' + blockHeader(string, state.indent)
 10479            + dropEndingNewline(indentString(string, indent));
 10480        case STYLE_FOLDED:
 10481          return '>' + blockHeader(string, state.indent)
 10482            + dropEndingNewline(indentString(foldString(string, lineWidth), indent));
 10483        case STYLE_DOUBLE:
 10484          return '"' + escapeString(string, lineWidth) + '"';
 10485        default:
 10486          throw new YAMLException('impossible error: invalid scalar style');
 10487      }
 10488    }());
 10489  }
 10490  
 10491  // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
 10492  function blockHeader(string, indentPerLevel) {
 10493    var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : '';
 10494  
 10495    // note the special case: the string '\n' counts as a "trailing" empty line.
 10496    var clip =          string[string.length - 1] === '\n';
 10497    var keep = clip && (string[string.length - 2] === '\n' || string === '\n');
 10498    var chomp = keep ? '+' : (clip ? '' : '-');
 10499  
 10500    return indentIndicator + chomp + '\n';
 10501  }
 10502  
 10503  // (See the note for writeScalar.)
 10504  function dropEndingNewline(string) {
 10505    return string[string.length - 1] === '\n' ? string.slice(0, -1) : string;
 10506  }
 10507  
 10508  // Note: a long line without a suitable break point will exceed the width limit.
 10509  // Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
 10510  function foldString(string, width) {
 10511    // In folded style, $k$ consecutive newlines output as $k+1$ newlines—
 10512    // unless they're before or after a more-indented line, or at the very
 10513    // beginning or end, in which case $k$ maps to $k$.
 10514    // Therefore, parse each chunk as newline(s) followed by a content line.
 10515    var lineRe = /(\n+)([^\n]*)/g;
 10516  
 10517    // first line (possibly an empty line)
 10518    var result = (function () {
 10519      var nextLF = string.indexOf('\n');
 10520      nextLF = nextLF !== -1 ? nextLF : string.length;
 10521      lineRe.lastIndex = nextLF;
 10522      return foldLine(string.slice(0, nextLF), width);
 10523    }());
 10524    // If we haven't reached the first content line yet, don't add an extra \n.
 10525    var prevMoreIndented = string[0] === '\n' || string[0] === ' ';
 10526    var moreIndented;
 10527  
 10528    // rest of the lines
 10529    var match;
 10530    while ((match = lineRe.exec(string))) {
 10531      var prefix = match[1], line = match[2];
 10532      moreIndented = (line[0] === ' ');
 10533      result += prefix
 10534        + (!prevMoreIndented && !moreIndented && line !== ''
 10535          ? '\n' : '')
 10536        + foldLine(line, width);
 10537      prevMoreIndented = moreIndented;
 10538    }
 10539  
 10540    return result;
 10541  }
 10542  
 10543  // Greedy line breaking.
 10544  // Picks the longest line under the limit each time,
 10545  // otherwise settles for the shortest line over the limit.
 10546  // NB. More-indented lines *cannot* be folded, as that would add an extra \n.
 10547  function foldLine(line, width) {
 10548    if (line === '' || line[0] === ' ') return line;
 10549  
 10550    // Since a more-indented line adds a \n, breaks can't be followed by a space.
 10551    var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.
 10552    var match;
 10553    // start is an inclusive index. end, curr, and next are exclusive.
 10554    var start = 0, end, curr = 0, next = 0;
 10555    var result = '';
 10556  
 10557    // Invariants: 0 <= start <= length-1.
 10558    //   0 <= curr <= next <= max(0, length-2). curr - start <= width.
 10559    // Inside the loop:
 10560    //   A match implies length >= 2, so curr and next are <= length-2.
 10561    while ((match = breakRe.exec(line))) {
 10562      next = match.index;
 10563      // maintain invariant: curr - start <= width
 10564      if (next - start > width) {
 10565        end = (curr > start) ? curr : next; // derive end <= length-2
 10566        result += '\n' + line.slice(start, end);
 10567        // skip the space that was output as \n
 10568        start = end + 1;                    // derive start <= length-1
 10569      }
 10570      curr = next;
 10571    }
 10572  
 10573    // By the invariants, start <= length-1, so there is something left over.
 10574    // It is either the whole string or a part starting from non-whitespace.
 10575    result += '\n';
 10576    // Insert a break if the remainder is too long and there is a break available.
 10577    if (line.length - start > width && curr > start) {
 10578      result += line.slice(start, curr) + '\n' + line.slice(curr + 1);
 10579    } else {
 10580      result += line.slice(start);
 10581    }
 10582  
 10583    return result.slice(1); // drop extra \n joiner
 10584  }
 10585  
 10586  // Escapes a double-quoted string.
 10587  function escapeString(string) {
 10588    var result = '';
 10589    var char;
 10590    var escapeSeq;
 10591  
 10592    for (var i = 0; i < string.length; i++) {
 10593      char = string.charCodeAt(i);
 10594      escapeSeq = ESCAPE_SEQUENCES[char];
 10595      result += !escapeSeq && isPrintable(char)
 10596        ? string[i]
 10597        : escapeSeq || encodeHex(char);
 10598    }
 10599  
 10600    return result;
 10601  }
 10602  
 10603  function writeFlowSequence(state, level, object) {
 10604    var _result = '',
 10605        _tag    = state.tag,
 10606        index,
 10607        length;
 10608  
 10609    for (index = 0, length = object.length; index < length; index += 1) {
 10610      // Write only valid elements.
 10611      if (writeNode(state, level, object[index], false, false)) {
 10612        if (index !== 0) _result += ', ';
 10613        _result += state.dump;
 10614      }
 10615    }
 10616  
 10617    state.tag = _tag;
 10618    state.dump = '[' + _result + ']';
 10619  }
 10620  
 10621  function writeBlockSequence(state, level, object, compact) {
 10622    var _result = '',
 10623        _tag    = state.tag,
 10624        index,
 10625        length;
 10626  
 10627    for (index = 0, length = object.length; index < length; index += 1) {
 10628      // Write only valid elements.
 10629      if (writeNode(state, level + 1, object[index], true, true)) {
 10630        if (!compact || index !== 0) {
 10631          _result += generateNextLine(state, level);
 10632        }
 10633        _result += '- ' + state.dump;
 10634      }
 10635    }
 10636  
 10637    state.tag = _tag;
 10638    state.dump = _result || '[]'; // Empty sequence if no valid values.
 10639  }
 10640  
 10641  function writeFlowMapping(state, level, object) {
 10642    var _result       = '',
 10643        _tag          = state.tag,
 10644        objectKeyList = Object.keys(object),
 10645        index,
 10646        length,
 10647        objectKey,
 10648        objectValue,
 10649        pairBuffer;
 10650  
 10651    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
 10652      pairBuffer = '';
 10653  
 10654      if (index !== 0) pairBuffer += ', ';
 10655  
 10656      objectKey = objectKeyList[index];
 10657      objectValue = object[objectKey];
 10658  
 10659      if (!writeNode(state, level, objectKey, false, false)) {
 10660        continue; // Skip this pair because of invalid key;
 10661      }
 10662  
 10663      if (state.dump.length > 1024) pairBuffer += '? ';
 10664  
 10665      pairBuffer += state.dump + ': ';
 10666  
 10667      if (!writeNode(state, level, objectValue, false, false)) {
 10668        continue; // Skip this pair because of invalid value.
 10669      }
 10670  
 10671      pairBuffer += state.dump;
 10672  
 10673      // Both key and value are valid.
 10674      _result += pairBuffer;
 10675    }
 10676  
 10677    state.tag = _tag;
 10678    state.dump = '{' + _result + '}';
 10679  }
 10680  
 10681  function writeBlockMapping(state, level, object, compact) {
 10682    var _result       = '',
 10683        _tag          = state.tag,
 10684        objectKeyList = Object.keys(object),
 10685        index,
 10686        length,
 10687        objectKey,
 10688        objectValue,
 10689        explicitPair,
 10690        pairBuffer;
 10691  
 10692    // Allow sorting keys so that the output file is deterministic
 10693    if (state.sortKeys === true) {
 10694      // Default sorting
 10695      objectKeyList.sort();
 10696    } else if (typeof state.sortKeys === 'function') {
 10697      // Custom sort function
 10698      objectKeyList.sort(state.sortKeys);
 10699    } else if (state.sortKeys) {
 10700      // Something is wrong
 10701      throw new YAMLException('sortKeys must be a boolean or a function');
 10702    }
 10703  
 10704    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
 10705      pairBuffer = '';
 10706  
 10707      if (!compact || index !== 0) {
 10708        pairBuffer += generateNextLine(state, level);
 10709      }
 10710  
 10711      objectKey = objectKeyList[index];
 10712      objectValue = object[objectKey];
 10713  
 10714      if (!writeNode(state, level + 1, objectKey, true, true, true)) {
 10715        continue; // Skip this pair because of invalid key.
 10716      }
 10717  
 10718      explicitPair = (state.tag !== null && state.tag !== '?') ||
 10719                     (state.dump && state.dump.length > 1024);
 10720  
 10721      if (explicitPair) {
 10722        if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
 10723          pairBuffer += '?';
 10724        } else {
 10725          pairBuffer += '? ';
 10726        }
 10727      }
 10728  
 10729      pairBuffer += state.dump;
 10730  
 10731      if (explicitPair) {
 10732        pairBuffer += generateNextLine(state, level);
 10733      }
 10734  
 10735      if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
 10736        continue; // Skip this pair because of invalid value.
 10737      }
 10738  
 10739      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
 10740        pairBuffer += ':';
 10741      } else {
 10742        pairBuffer += ': ';
 10743      }
 10744  
 10745      pairBuffer += state.dump;
 10746  
 10747      // Both key and value are valid.
 10748      _result += pairBuffer;
 10749    }
 10750  
 10751    state.tag = _tag;
 10752    state.dump = _result || '{}'; // Empty mapping if no valid pairs.
 10753  }
 10754  
 10755  function detectType(state, object, explicit) {
 10756    var _result, typeList, index, length, type, style;
 10757  
 10758    typeList = explicit ? state.explicitTypes : state.implicitTypes;
 10759  
 10760    for (index = 0, length = typeList.length; index < length; index += 1) {
 10761      type = typeList[index];
 10762  
 10763      if ((type.instanceOf  || type.predicate) &&
 10764          (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
 10765          (!type.predicate  || type.predicate(object))) {
 10766  
 10767        state.tag = explicit ? type.tag : '?';
 10768  
 10769        if (type.represent) {
 10770          style = state.styleMap[type.tag] || type.defaultStyle;
 10771  
 10772          if (_toString.call(type.represent) === '[object Function]') {
 10773            _result = type.represent(object, style);
 10774          } else if (_hasOwnProperty.call(type.represent, style)) {
 10775            _result = type.represent[style](object, style);
 10776          } else {
 10777            throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
 10778          }
 10779  
 10780          state.dump = _result;
 10781        }
 10782  
 10783        return true;
 10784      }
 10785    }
 10786  
 10787    return false;
 10788  }
 10789  
 10790  // Serializes `object` and writes it to global `result`.
 10791  // Returns true on success, or false on invalid object.
 10792  //
 10793  function writeNode(state, level, object, block, compact, iskey) {
 10794    state.tag = null;
 10795    state.dump = object;
 10796  
 10797    if (!detectType(state, object, false)) {
 10798      detectType(state, object, true);
 10799    }
 10800  
 10801    var type = _toString.call(state.dump);
 10802  
 10803    if (block) {
 10804      block = (state.flowLevel < 0 || state.flowLevel > level);
 10805    }
 10806  
 10807    var objectOrArray = type === '[object Object]' || type === '[object Array]',
 10808        duplicateIndex,
 10809        duplicate;
 10810  
 10811    if (objectOrArray) {
 10812      duplicateIndex = state.duplicates.indexOf(object);
 10813      duplicate = duplicateIndex !== -1;
 10814    }
 10815  
 10816    if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
 10817      compact = false;
 10818    }
 10819  
 10820    if (duplicate && state.usedDuplicates[duplicateIndex]) {
 10821      state.dump = '*ref_' + duplicateIndex;
 10822    } else {
 10823      if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
 10824        state.usedDuplicates[duplicateIndex] = true;
 10825      }
 10826      if (type === '[object Object]') {
 10827        if (block && (Object.keys(state.dump).length !== 0)) {
 10828          writeBlockMapping(state, level, state.dump, compact);
 10829          if (duplicate) {
 10830            state.dump = '&ref_' + duplicateIndex + state.dump;
 10831          }
 10832        } else {
 10833          writeFlowMapping(state, level, state.dump);
 10834          if (duplicate) {
 10835            state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
 10836          }
 10837        }
 10838      } else if (type === '[object Array]') {
 10839        if (block && (state.dump.length !== 0)) {
 10840          writeBlockSequence(state, level, state.dump, compact);
 10841          if (duplicate) {
 10842            state.dump = '&ref_' + duplicateIndex + state.dump;
 10843          }
 10844        } else {
 10845          writeFlowSequence(state, level, state.dump);
 10846          if (duplicate) {
 10847            state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
 10848          }
 10849        }
 10850      } else if (type === '[object String]') {
 10851        if (state.tag !== '?') {
 10852          writeScalar(state, state.dump, level, iskey);
 10853        }
 10854      } else {
 10855        if (state.skipInvalid) return false;
 10856        throw new YAMLException('unacceptable kind of an object to dump ' + type);
 10857      }
 10858  
 10859      if (state.tag !== null && state.tag !== '?') {
 10860        state.dump = '!<' + state.tag + '> ' + state.dump;
 10861      }
 10862    }
 10863  
 10864    return true;
 10865  }
 10866  
 10867  function getDuplicateReferences(object, state) {
 10868    var objects = [],
 10869        duplicatesIndexes = [],
 10870        index,
 10871        length;
 10872  
 10873    inspectNode(object, objects, duplicatesIndexes);
 10874  
 10875    for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
 10876      state.duplicates.push(objects[duplicatesIndexes[index]]);
 10877    }
 10878    state.usedDuplicates = new Array(length);
 10879  }
 10880  
 10881  function inspectNode(object, objects, duplicatesIndexes) {
 10882    var objectKeyList,
 10883        index,
 10884        length;
 10885  
 10886    if (object !== null && typeof object === 'object') {
 10887      index = objects.indexOf(object);
 10888      if (index !== -1) {
 10889        if (duplicatesIndexes.indexOf(index) === -1) {
 10890          duplicatesIndexes.push(index);
 10891        }
 10892      } else {
 10893        objects.push(object);
 10894  
 10895        if (Array.isArray(object)) {
 10896          for (index = 0, length = object.length; index < length; index += 1) {
 10897            inspectNode(object[index], objects, duplicatesIndexes);
 10898          }
 10899        } else {
 10900          objectKeyList = Object.keys(object);
 10901  
 10902          for (index = 0, length = objectKeyList.length; index < length; index += 1) {
 10903            inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
 10904          }
 10905        }
 10906      }
 10907    }
 10908  }
 10909  
 10910  function dump(input, options) {
 10911    options = options || {};
 10912  
 10913    var state = new State(options);
 10914  
 10915    if (!state.noRefs) getDuplicateReferences(input, state);
 10916  
 10917    if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
 10918  
 10919    return '';
 10920  }
 10921  
 10922  function safeDump(input, options) {
 10923    return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
 10924  }
 10925  
 10926  module.exports.dump     = dump;
 10927  module.exports.safeDump = safeDump;
 10928  
 10929  },{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(require,module,exports){
 10930  // YAML error class. http://stackoverflow.com/questions/8458984
 10931  //
 10932  'use strict';
 10933  
 10934  function YAMLException(reason, mark) {
 10935    // Super constructor
 10936    Error.call(this);
 10937  
 10938    // Include stack trace in error object
 10939    if (Error.captureStackTrace) {
 10940      // Chrome and NodeJS
 10941      Error.captureStackTrace(this, this.constructor);
 10942    } else {
 10943      // FF, IE 10+ and Safari 6+. Fallback for others
 10944      this.stack = (new Error()).stack || '';
 10945    }
 10946  
 10947    this.name = 'YAMLException';
 10948    this.reason = reason;
 10949    this.mark = mark;
 10950    this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
 10951  }
 10952  
 10953  
 10954  // Inherit from Error
 10955  YAMLException.prototype = Object.create(Error.prototype);
 10956  YAMLException.prototype.constructor = YAMLException;
 10957  
 10958  
 10959  YAMLException.prototype.toString = function toString(compact) {
 10960    var result = this.name + ': ';
 10961  
 10962    result += this.reason || '(unknown reason)';
 10963  
 10964    if (!compact && this.mark) {
 10965      result += ' ' + this.mark.toString();
 10966    }
 10967  
 10968    return result;
 10969  };
 10970  
 10971  
 10972  module.exports = YAMLException;
 10973  
 10974  },{}],24:[function(require,module,exports){
 10975  'use strict';
 10976  
 10977  /*eslint-disable max-len,no-use-before-define*/
 10978  
 10979  var common              = require('./common');
 10980  var YAMLException       = require('./exception');
 10981  var Mark                = require('./mark');
 10982  var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
 10983  var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
 10984  
 10985  
 10986  var _hasOwnProperty = Object.prototype.hasOwnProperty;
 10987  
 10988  
 10989  var CONTEXT_FLOW_IN   = 1;
 10990  var CONTEXT_FLOW_OUT  = 2;
 10991  var CONTEXT_BLOCK_IN  = 3;
 10992  var CONTEXT_BLOCK_OUT = 4;
 10993  
 10994  
 10995  var CHOMPING_CLIP  = 1;
 10996  var CHOMPING_STRIP = 2;
 10997  var CHOMPING_KEEP  = 3;
 10998  
 10999  
 11000  var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
 11001  var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
 11002  var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
 11003  var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
 11004  var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
 11005  
 11006  
 11007  function is_EOL(c) {
 11008    return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
 11009  }
 11010  
 11011  function is_WHITE_SPACE(c) {
 11012    return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
 11013  }
 11014  
 11015  function is_WS_OR_EOL(c) {
 11016    return (c === 0x09/* Tab */) ||
 11017           (c === 0x20/* Space */) ||
 11018           (c === 0x0A/* LF */) ||
 11019           (c === 0x0D/* CR */);
 11020  }
 11021  
 11022  function is_FLOW_INDICATOR(c) {
 11023    return c === 0x2C/* , */ ||
 11024           c === 0x5B/* [ */ ||
 11025           c === 0x5D/* ] */ ||
 11026           c === 0x7B/* { */ ||
 11027           c === 0x7D/* } */;
 11028  }
 11029  
 11030  function fromHexCode(c) {
 11031    var lc;
 11032  
 11033    if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
 11034      return c - 0x30;
 11035    }
 11036  
 11037    /*eslint-disable no-bitwise*/
 11038    lc = c | 0x20;
 11039  
 11040    if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
 11041      return lc - 0x61 + 10;
 11042    }
 11043  
 11044    return -1;
 11045  }
 11046  
 11047  function escapedHexLen(c) {
 11048    if (c === 0x78/* x */) { return 2; }
 11049    if (c === 0x75/* u */) { return 4; }
 11050    if (c === 0x55/* U */) { return 8; }
 11051    return 0;
 11052  }
 11053  
 11054  function fromDecimalCode(c) {
 11055    if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
 11056      return c - 0x30;
 11057    }
 11058  
 11059    return -1;
 11060  }
 11061  
 11062  function simpleEscapeSequence(c) {
 11063    return (c === 0x30/* 0 */) ? '\x00' :
 11064          (c === 0x61/* a */) ? '\x07' :
 11065          (c === 0x62/* b */) ? '\x08' :
 11066          (c === 0x74/* t */) ? '\x09' :
 11067          (c === 0x09/* Tab */) ? '\x09' :
 11068          (c === 0x6E/* n */) ? '\x0A' :
 11069          (c === 0x76/* v */) ? '\x0B' :
 11070          (c === 0x66/* f */) ? '\x0C' :
 11071          (c === 0x72/* r */) ? '\x0D' :
 11072          (c === 0x65/* e */) ? '\x1B' :
 11073          (c === 0x20/* Space */) ? ' ' :
 11074          (c === 0x22/* " */) ? '\x22' :
 11075          (c === 0x2F/* / */) ? '/' :
 11076          (c === 0x5C/* \ */) ? '\x5C' :
 11077          (c === 0x4E/* N */) ? '\x85' :
 11078          (c === 0x5F/* _ */) ? '\xA0' :
 11079          (c === 0x4C/* L */) ? '\u2028' :
 11080          (c === 0x50/* P */) ? '\u2029' : '';
 11081  }
 11082  
 11083  function charFromCodepoint(c) {
 11084    if (c <= 0xFFFF) {
 11085      return String.fromCharCode(c);
 11086    }
 11087    // Encode UTF-16 surrogate pair
 11088    // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
 11089    return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
 11090                               ((c - 0x010000) & 0x03FF) + 0xDC00);
 11091  }
 11092  
 11093  var simpleEscapeCheck = new Array(256); // integer, for fast access
 11094  var simpleEscapeMap = new Array(256);
 11095  for (var i = 0; i < 256; i++) {
 11096    simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
 11097    simpleEscapeMap[i] = simpleEscapeSequence(i);
 11098  }
 11099  
 11100  
 11101  function State(input, options) {
 11102    this.input = input;
 11103  
 11104    this.filename  = options['filename']  || null;
 11105    this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;
 11106    this.onWarning = options['onWarning'] || null;
 11107    this.legacy    = options['legacy']    || false;
 11108    this.json      = options['json']      || false;
 11109    this.listener  = options['listener']  || null;
 11110  
 11111    this.implicitTypes = this.schema.compiledImplicit;
 11112    this.typeMap       = this.schema.compiledTypeMap;
 11113  
 11114    this.length     = input.length;
 11115    this.position   = 0;
 11116    this.line       = 0;
 11117    this.lineStart  = 0;
 11118    this.lineIndent = 0;
 11119  
 11120    this.documents = [];
 11121  
 11122    /*
 11123    this.version;
 11124    this.checkLineBreaks;
 11125    this.tagMap;
 11126    this.anchorMap;
 11127    this.tag;
 11128    this.anchor;
 11129    this.kind;
 11130    this.result;*/
 11131  
 11132  }
 11133  
 11134  
 11135  function generateError(state, message) {
 11136    return new YAMLException(
 11137      message,
 11138      new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
 11139  }
 11140  
 11141  function throwError(state, message) {
 11142    throw generateError(state, message);
 11143  }
 11144  
 11145  function throwWarning(state, message) {
 11146    if (state.onWarning) {
 11147      state.onWarning.call(null, generateError(state, message));
 11148    }
 11149  }
 11150  
 11151  
 11152  var directiveHandlers = {
 11153  
 11154    YAML: function handleYamlDirective(state, name, args) {
 11155  
 11156      var match, major, minor;
 11157  
 11158      if (state.version !== null) {
 11159        throwError(state, 'duplication of %YAML directive');
 11160      }
 11161  
 11162      if (args.length !== 1) {
 11163        throwError(state, 'YAML directive accepts exactly one argument');
 11164      }
 11165  
 11166      match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
 11167  
 11168      if (match === null) {
 11169        throwError(state, 'ill-formed argument of the YAML directive');
 11170      }
 11171  
 11172      major = parseInt(match[1], 10);
 11173      minor = parseInt(match[2], 10);
 11174  
 11175      if (major !== 1) {
 11176        throwError(state, 'unacceptable YAML version of the document');
 11177      }
 11178  
 11179      state.version = args[0];
 11180      state.checkLineBreaks = (minor < 2);
 11181  
 11182      if (minor !== 1 && minor !== 2) {
 11183        throwWarning(state, 'unsupported YAML version of the document');
 11184      }
 11185    },
 11186  
 11187    TAG: function handleTagDirective(state, name, args) {
 11188  
 11189      var handle, prefix;
 11190  
 11191      if (args.length !== 2) {
 11192        throwError(state, 'TAG directive accepts exactly two arguments');
 11193      }
 11194  
 11195      handle = args[0];
 11196      prefix = args[1];
 11197  
 11198      if (!PATTERN_TAG_HANDLE.test(handle)) {
 11199        throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
 11200      }
 11201  
 11202      if (_hasOwnProperty.call(state.tagMap, handle)) {
 11203        throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
 11204      }
 11205  
 11206      if (!PATTERN_TAG_URI.test(prefix)) {
 11207        throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
 11208      }
 11209  
 11210      state.tagMap[handle] = prefix;
 11211    }
 11212  };
 11213  
 11214  
 11215  function captureSegment(state, start, end, checkJson) {
 11216    var _position, _length, _character, _result;
 11217  
 11218    if (start < end) {
 11219      _result = state.input.slice(start, end);
 11220  
 11221      if (checkJson) {
 11222        for (_position = 0, _length = _result.length;
 11223             _position < _length;
 11224             _position += 1) {
 11225          _character = _result.charCodeAt(_position);
 11226          if (!(_character === 0x09 ||
 11227                (0x20 <= _character && _character <= 0x10FFFF))) {
 11228            throwError(state, 'expected valid JSON character');
 11229          }
 11230        }
 11231      } else if (PATTERN_NON_PRINTABLE.test(_result)) {
 11232        throwError(state, 'the stream contains non-printable characters');
 11233      }
 11234  
 11235      state.result += _result;
 11236    }
 11237  }
 11238  
 11239  function mergeMappings(state, destination, source, overridableKeys) {
 11240    var sourceKeys, key, index, quantity;
 11241  
 11242    if (!common.isObject(source)) {
 11243      throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
 11244    }
 11245  
 11246    sourceKeys = Object.keys(source);
 11247  
 11248    for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
 11249      key = sourceKeys[index];
 11250  
 11251      if (!_hasOwnProperty.call(destination, key)) {
 11252        destination[key] = source[key];
 11253        overridableKeys[key] = true;
 11254      }
 11255    }
 11256  }
 11257  
 11258  function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
 11259    var index, quantity;
 11260  
 11261    keyNode = String(keyNode);
 11262  
 11263    if (_result === null) {
 11264      _result = {};
 11265    }
 11266  
 11267    if (keyTag === 'tag:yaml.org,2002:merge') {
 11268      if (Array.isArray(valueNode)) {
 11269        for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
 11270          mergeMappings(state, _result, valueNode[index], overridableKeys);
 11271        }
 11272      } else {
 11273        mergeMappings(state, _result, valueNode, overridableKeys);
 11274      }
 11275    } else {
 11276      if (!state.json &&
 11277          !_hasOwnProperty.call(overridableKeys, keyNode) &&
 11278          _hasOwnProperty.call(_result, keyNode)) {
 11279        throwError(state, 'duplicated mapping key');
 11280      }
 11281      _result[keyNode] = valueNode;
 11282      delete overridableKeys[keyNode];
 11283    }
 11284  
 11285    return _result;
 11286  }
 11287  
 11288  function readLineBreak(state) {
 11289    var ch;
 11290  
 11291    ch = state.input.charCodeAt(state.position);
 11292  
 11293    if (ch === 0x0A/* LF */) {
 11294      state.position++;
 11295    } else if (ch === 0x0D/* CR */) {
 11296      state.position++;
 11297      if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {
 11298        state.position++;
 11299      }
 11300    } else {
 11301      throwError(state, 'a line break is expected');
 11302    }
 11303  
 11304    state.line += 1;
 11305    state.lineStart = state.position;
 11306  }
 11307  
 11308  function skipSeparationSpace(state, allowComments, checkIndent) {
 11309    var lineBreaks = 0,
 11310        ch = state.input.charCodeAt(state.position);
 11311  
 11312    while (ch !== 0) {
 11313      while (is_WHITE_SPACE(ch)) {
 11314        ch = state.input.charCodeAt(++state.position);
 11315      }
 11316  
 11317      if (allowComments && ch === 0x23/* # */) {
 11318        do {
 11319          ch = state.input.charCodeAt(++state.position);
 11320        } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);
 11321      }
 11322  
 11323      if (is_EOL(ch)) {
 11324        readLineBreak(state);
 11325  
 11326        ch = state.input.charCodeAt(state.position);
 11327        lineBreaks++;
 11328        state.lineIndent = 0;
 11329  
 11330        while (ch === 0x20/* Space */) {
 11331          state.lineIndent++;
 11332          ch = state.input.charCodeAt(++state.position);
 11333        }
 11334      } else {
 11335        break;
 11336      }
 11337    }
 11338  
 11339    if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
 11340      throwWarning(state, 'deficient indentation');
 11341    }
 11342  
 11343    return lineBreaks;
 11344  }
 11345  
 11346  function testDocumentSeparator(state) {
 11347    var _position = state.position,
 11348        ch;
 11349  
 11350    ch = state.input.charCodeAt(_position);
 11351  
 11352    // Condition state.position === state.lineStart is tested
 11353    // in parent on each call, for efficiency. No needs to test here again.
 11354    if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&
 11355        ch === state.input.charCodeAt(_position + 1) &&
 11356        ch === state.input.charCodeAt(_position + 2)) {
 11357  
 11358      _position += 3;
 11359  
 11360      ch = state.input.charCodeAt(_position);
 11361  
 11362      if (ch === 0 || is_WS_OR_EOL(ch)) {
 11363        return true;
 11364      }
 11365    }
 11366  
 11367    return false;
 11368  }
 11369  
 11370  function writeFoldedLines(state, count) {
 11371    if (count === 1) {
 11372      state.result += ' ';
 11373    } else if (count > 1) {
 11374      state.result += common.repeat('\n', count - 1);
 11375    }
 11376  }
 11377  
 11378  
 11379  function readPlainScalar(state, nodeIndent, withinFlowCollection) {
 11380    var preceding,
 11381        following,
 11382        captureStart,
 11383        captureEnd,
 11384        hasPendingContent,
 11385        _line,
 11386        _lineStart,
 11387        _lineIndent,
 11388        _kind = state.kind,
 11389        _result = state.result,
 11390        ch;
 11391  
 11392    ch = state.input.charCodeAt(state.position);
 11393  
 11394    if (is_WS_OR_EOL(ch)      ||
 11395        is_FLOW_INDICATOR(ch) ||
 11396        ch === 0x23/* # */    ||
 11397        ch === 0x26/* & */    ||
 11398        ch === 0x2A/* * */    ||
 11399        ch === 0x21/* ! */    ||
 11400        ch === 0x7C/* | */    ||
 11401        ch === 0x3E/* > */    ||
 11402        ch === 0x27/* ' */    ||
 11403        ch === 0x22/* " */    ||
 11404        ch === 0x25/* % */    ||
 11405        ch === 0x40/* @ */    ||
 11406        ch === 0x60/* ` */) {
 11407      return false;
 11408    }
 11409  
 11410    if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {
 11411      following = state.input.charCodeAt(state.position + 1);
 11412  
 11413      if (is_WS_OR_EOL(following) ||
 11414          withinFlowCollection && is_FLOW_INDICATOR(following)) {
 11415        return false;
 11416      }
 11417    }
 11418  
 11419    state.kind = 'scalar';
 11420    state.result = '';
 11421    captureStart = captureEnd = state.position;
 11422    hasPendingContent = false;
 11423  
 11424    while (ch !== 0) {
 11425      if (ch === 0x3A/* : */) {
 11426        following = state.input.charCodeAt(state.position + 1);
 11427  
 11428        if (is_WS_OR_EOL(following) ||
 11429            withinFlowCollection && is_FLOW_INDICATOR(following)) {
 11430          break;
 11431        }
 11432  
 11433      } else if (ch === 0x23/* # */) {
 11434        preceding = state.input.charCodeAt(state.position - 1);
 11435  
 11436        if (is_WS_OR_EOL(preceding)) {
 11437          break;
 11438        }
 11439  
 11440      } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
 11441                 withinFlowCollection && is_FLOW_INDICATOR(ch)) {
 11442        break;
 11443  
 11444      } else if (is_EOL(ch)) {
 11445        _line = state.line;
 11446        _lineStart = state.lineStart;
 11447        _lineIndent = state.lineIndent;
 11448        skipSeparationSpace(state, false, -1);
 11449  
 11450        if (state.lineIndent >= nodeIndent) {
 11451          hasPendingContent = true;
 11452          ch = state.input.charCodeAt(state.position);
 11453          continue;
 11454        } else {
 11455          state.position = captureEnd;
 11456          state.line = _line;
 11457          state.lineStart = _lineStart;
 11458          state.lineIndent = _lineIndent;
 11459          break;
 11460        }
 11461      }
 11462  
 11463      if (hasPendingContent) {
 11464        captureSegment(state, captureStart, captureEnd, false);
 11465        writeFoldedLines(state, state.line - _line);
 11466        captureStart = captureEnd = state.position;
 11467        hasPendingContent = false;
 11468      }
 11469  
 11470      if (!is_WHITE_SPACE(ch)) {
 11471        captureEnd = state.position + 1;
 11472      }
 11473  
 11474      ch = state.input.charCodeAt(++state.position);
 11475    }
 11476  
 11477    captureSegment(state, captureStart, captureEnd, false);
 11478  
 11479    if (state.result) {
 11480      return true;
 11481    }
 11482  
 11483    state.kind = _kind;
 11484    state.result = _result;
 11485    return false;
 11486  }
 11487  
 11488  function readSingleQuotedScalar(state, nodeIndent) {
 11489    var ch,
 11490        captureStart, captureEnd;
 11491  
 11492    ch = state.input.charCodeAt(state.position);
 11493  
 11494    if (ch !== 0x27/* ' */) {
 11495      return false;
 11496    }
 11497  
 11498    state.kind = 'scalar';
 11499    state.result = '';
 11500    state.position++;
 11501    captureStart = captureEnd = state.position;
 11502  
 11503    while ((ch = state.input.charCodeAt(state.position)) !== 0) {
 11504      if (ch === 0x27/* ' */) {
 11505        captureSegment(state, captureStart, state.position, true);
 11506        ch = state.input.charCodeAt(++state.position);
 11507  
 11508        if (ch === 0x27/* ' */) {
 11509          captureStart = captureEnd = state.position;
 11510          state.position++;
 11511        } else {
 11512          return true;
 11513        }
 11514  
 11515      } else if (is_EOL(ch)) {
 11516        captureSegment(state, captureStart, captureEnd, true);
 11517        writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
 11518        captureStart = captureEnd = state.position;
 11519  
 11520      } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
 11521        throwError(state, 'unexpected end of the document within a single quoted scalar');
 11522  
 11523      } else {
 11524        state.position++;
 11525        captureEnd = state.position;
 11526      }
 11527    }
 11528  
 11529    throwError(state, 'unexpected end of the stream within a single quoted scalar');
 11530  }
 11531  
 11532  function readDoubleQuotedScalar(state, nodeIndent) {
 11533    var captureStart,
 11534        captureEnd,
 11535        hexLength,
 11536        hexResult,
 11537        tmp,
 11538        ch;
 11539  
 11540    ch = state.input.charCodeAt(state.position);
 11541  
 11542    if (ch !== 0x22/* " */) {
 11543      return false;
 11544    }
 11545  
 11546    state.kind = 'scalar';
 11547    state.result = '';
 11548    state.position++;
 11549    captureStart = captureEnd = state.position;
 11550  
 11551    while ((ch = state.input.charCodeAt(state.position)) !== 0) {
 11552      if (ch === 0x22/* " */) {
 11553        captureSegment(state, captureStart, state.position, true);
 11554        state.position++;
 11555        return true;
 11556  
 11557      } else if (ch === 0x5C/* \ */) {
 11558        captureSegment(state, captureStart, state.position, true);
 11559        ch = state.input.charCodeAt(++state.position);
 11560  
 11561        if (is_EOL(ch)) {
 11562          skipSeparationSpace(state, false, nodeIndent);
 11563  
 11564          // TODO: rework to inline fn with no type cast?
 11565        } else if (ch < 256 && simpleEscapeCheck[ch]) {
 11566          state.result += simpleEscapeMap[ch];
 11567          state.position++;
 11568  
 11569        } else if ((tmp = escapedHexLen(ch)) > 0) {
 11570          hexLength = tmp;
 11571          hexResult = 0;
 11572  
 11573          for (; hexLength > 0; hexLength--) {
 11574            ch = state.input.charCodeAt(++state.position);
 11575  
 11576            if ((tmp = fromHexCode(ch)) >= 0) {
 11577              hexResult = (hexResult << 4) + tmp;
 11578  
 11579            } else {
 11580              throwError(state, 'expected hexadecimal character');
 11581            }
 11582          }
 11583  
 11584          state.result += charFromCodepoint(hexResult);
 11585  
 11586          state.position++;
 11587  
 11588        } else {
 11589          throwError(state, 'unknown escape sequence');
 11590        }
 11591  
 11592        captureStart = captureEnd = state.position;
 11593  
 11594      } else if (is_EOL(ch)) {
 11595        captureSegment(state, captureStart, captureEnd, true);
 11596        writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
 11597        captureStart = captureEnd = state.position;
 11598  
 11599      } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
 11600        throwError(state, 'unexpected end of the document within a double quoted scalar');
 11601  
 11602      } else {
 11603        state.position++;
 11604        captureEnd = state.position;
 11605      }
 11606    }
 11607  
 11608    throwError(state, 'unexpected end of the stream within a double quoted scalar');
 11609  }
 11610  
 11611  function readFlowCollection(state, nodeIndent) {
 11612    var readNext = true,
 11613        _line,
 11614        _tag     = state.tag,
 11615        _result,
 11616        _anchor  = state.anchor,
 11617        following,
 11618        terminator,
 11619        isPair,
 11620        isExplicitPair,
 11621        isMapping,
 11622        overridableKeys = {},
 11623        keyNode,
 11624        keyTag,
 11625        valueNode,
 11626        ch;
 11627  
 11628    ch = state.input.charCodeAt(state.position);
 11629  
 11630    if (ch === 0x5B/* [ */) {
 11631      terminator = 0x5D;/* ] */
 11632      isMapping = false;
 11633      _result = [];
 11634    } else if (ch === 0x7B/* { */) {
 11635      terminator = 0x7D;/* } */
 11636      isMapping = true;
 11637      _result = {};
 11638    } else {
 11639      return false;
 11640    }
 11641  
 11642    if (state.anchor !== null) {
 11643      state.anchorMap[state.anchor] = _result;
 11644    }
 11645  
 11646    ch = state.input.charCodeAt(++state.position);
 11647  
 11648    while (ch !== 0) {
 11649      skipSeparationSpace(state, true, nodeIndent);
 11650  
 11651      ch = state.input.charCodeAt(state.position);
 11652  
 11653      if (ch === terminator) {
 11654        state.position++;
 11655        state.tag = _tag;
 11656        state.anchor = _anchor;
 11657        state.kind = isMapping ? 'mapping' : 'sequence';
 11658        state.result = _result;
 11659        return true;
 11660      } else if (!readNext) {
 11661        throwError(state, 'missed comma between flow collection entries');
 11662      }
 11663  
 11664      keyTag = keyNode = valueNode = null;
 11665      isPair = isExplicitPair = false;
 11666  
 11667      if (ch === 0x3F/* ? */) {
 11668        following = state.input.charCodeAt(state.position + 1);
 11669  
 11670        if (is_WS_OR_EOL(following)) {
 11671          isPair = isExplicitPair = true;
 11672          state.position++;
 11673          skipSeparationSpace(state, true, nodeIndent);
 11674        }
 11675      }
 11676  
 11677      _line = state.line;
 11678      composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
 11679      keyTag = state.tag;
 11680      keyNode = state.result;
 11681      skipSeparationSpace(state, true, nodeIndent);
 11682  
 11683      ch = state.input.charCodeAt(state.position);
 11684  
 11685      if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {
 11686        isPair = true;
 11687        ch = state.input.charCodeAt(++state.position);
 11688        skipSeparationSpace(state, true, nodeIndent);
 11689        composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
 11690        valueNode = state.result;
 11691      }
 11692  
 11693      if (isMapping) {
 11694        storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
 11695      } else if (isPair) {
 11696        _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode));
 11697      } else {
 11698        _result.push(keyNode);
 11699      }
 11700  
 11701      skipSeparationSpace(state, true, nodeIndent);
 11702  
 11703      ch = state.input.charCodeAt(state.position);
 11704  
 11705      if (ch === 0x2C/* , */) {
 11706        readNext = true;
 11707        ch = state.input.charCodeAt(++state.position);
 11708      } else {
 11709        readNext = false;
 11710      }
 11711    }
 11712  
 11713    throwError(state, 'unexpected end of the stream within a flow collection');
 11714  }
 11715  
 11716  function readBlockScalar(state, nodeIndent) {
 11717    var captureStart,
 11718        folding,
 11719        chomping       = CHOMPING_CLIP,
 11720        didReadContent = false,
 11721        detectedIndent = false,
 11722        textIndent     = nodeIndent,
 11723        emptyLines     = 0,
 11724        atMoreIndented = false,
 11725        tmp,
 11726        ch;
 11727  
 11728    ch = state.input.charCodeAt(state.position);
 11729  
 11730    if (ch === 0x7C/* | */) {
 11731      folding = false;
 11732    } else if (ch === 0x3E/* > */) {
 11733      folding = true;
 11734    } else {
 11735      return false;
 11736    }
 11737  
 11738    state.kind = 'scalar';
 11739    state.result = '';
 11740  
 11741    while (ch !== 0) {
 11742      ch = state.input.charCodeAt(++state.position);
 11743  
 11744      if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
 11745        if (CHOMPING_CLIP === chomping) {
 11746          chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;
 11747        } else {
 11748          throwError(state, 'repeat of a chomping mode identifier');
 11749        }
 11750  
 11751      } else if ((tmp = fromDecimalCode(ch)) >= 0) {
 11752        if (tmp === 0) {
 11753          throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
 11754        } else if (!detectedIndent) {
 11755          textIndent = nodeIndent + tmp - 1;
 11756          detectedIndent = true;
 11757        } else {
 11758          throwError(state, 'repeat of an indentation width identifier');
 11759        }
 11760  
 11761      } else {
 11762        break;
 11763      }
 11764    }
 11765  
 11766    if (is_WHITE_SPACE(ch)) {
 11767      do { ch = state.input.charCodeAt(++state.position); }
 11768      while (is_WHITE_SPACE(ch));
 11769  
 11770      if (ch === 0x23/* # */) {
 11771        do { ch = state.input.charCodeAt(++state.position); }
 11772        while (!is_EOL(ch) && (ch !== 0));
 11773      }
 11774    }
 11775  
 11776    while (ch !== 0) {
 11777      readLineBreak(state);
 11778      state.lineIndent = 0;
 11779  
 11780      ch = state.input.charCodeAt(state.position);
 11781  
 11782      while ((!detectedIndent || state.lineIndent < textIndent) &&
 11783             (ch === 0x20/* Space */)) {
 11784        state.lineIndent++;
 11785        ch = state.input.charCodeAt(++state.position);
 11786      }
 11787  
 11788      if (!detectedIndent && state.lineIndent > textIndent) {
 11789        textIndent = state.lineIndent;
 11790      }
 11791  
 11792      if (is_EOL(ch)) {
 11793        emptyLines++;
 11794        continue;
 11795      }
 11796  
 11797      // End of the scalar.
 11798      if (state.lineIndent < textIndent) {
 11799  
 11800        // Perform the chomping.
 11801        if (chomping === CHOMPING_KEEP) {
 11802          state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
 11803        } else if (chomping === CHOMPING_CLIP) {
 11804          if (didReadContent) { // i.e. only if the scalar is not empty.
 11805            state.result += '\n';
 11806          }
 11807        }
 11808  
 11809        // Break this `while` cycle and go to the funciton's epilogue.
 11810        break;
 11811      }
 11812  
 11813      // Folded style: use fancy rules to handle line breaks.
 11814      if (folding) {
 11815  
 11816        // Lines starting with white space characters (more-indented lines) are not folded.
 11817        if (is_WHITE_SPACE(ch)) {
 11818          atMoreIndented = true;
 11819          // except for the first content line (cf. Example 8.1)
 11820          state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
 11821  
 11822        // End of more-indented block.
 11823        } else if (atMoreIndented) {
 11824          atMoreIndented = false;
 11825          state.result += common.repeat('\n', emptyLines + 1);
 11826  
 11827        // Just one line break - perceive as the same line.
 11828        } else if (emptyLines === 0) {
 11829          if (didReadContent) { // i.e. only if we have already read some scalar content.
 11830            state.result += ' ';
 11831          }
 11832  
 11833        // Several line breaks - perceive as different lines.
 11834        } else {
 11835          state.result += common.repeat('\n', emptyLines);
 11836        }
 11837  
 11838      // Literal style: just add exact number of line breaks between content lines.
 11839      } else {
 11840        // Keep all line breaks except the header line break.
 11841        state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
 11842      }
 11843  
 11844      didReadContent = true;
 11845      detectedIndent = true;
 11846      emptyLines = 0;
 11847      captureStart = state.position;
 11848  
 11849      while (!is_EOL(ch) && (ch !== 0)) {
 11850        ch = state.input.charCodeAt(++state.position);
 11851      }
 11852  
 11853      captureSegment(state, captureStart, state.position, false);
 11854    }
 11855  
 11856    return true;
 11857  }
 11858  
 11859  function readBlockSequence(state, nodeIndent) {
 11860    var _line,
 11861        _tag      = state.tag,
 11862        _anchor   = state.anchor,
 11863        _result   = [],
 11864        following,
 11865        detected  = false,
 11866        ch;
 11867  
 11868    if (state.anchor !== null) {
 11869      state.anchorMap[state.anchor] = _result;
 11870    }
 11871  
 11872    ch = state.input.charCodeAt(state.position);
 11873  
 11874    while (ch !== 0) {
 11875  
 11876      if (ch !== 0x2D/* - */) {
 11877        break;
 11878      }
 11879  
 11880      following = state.input.charCodeAt(state.position + 1);
 11881  
 11882      if (!is_WS_OR_EOL(following)) {
 11883        break;
 11884      }
 11885  
 11886      detected = true;
 11887      state.position++;
 11888  
 11889      if (skipSeparationSpace(state, true, -1)) {
 11890        if (state.lineIndent <= nodeIndent) {
 11891          _result.push(null);
 11892          ch = state.input.charCodeAt(state.position);
 11893          continue;
 11894        }
 11895      }
 11896  
 11897      _line = state.line;
 11898      composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
 11899      _result.push(state.result);
 11900      skipSeparationSpace(state, true, -1);
 11901  
 11902      ch = state.input.charCodeAt(state.position);
 11903  
 11904      if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
 11905        throwError(state, 'bad indentation of a sequence entry');
 11906      } else if (state.lineIndent < nodeIndent) {
 11907        break;
 11908      }
 11909    }
 11910  
 11911    if (detected) {
 11912      state.tag = _tag;
 11913      state.anchor = _anchor;
 11914      state.kind = 'sequence';
 11915      state.result = _result;
 11916      return true;
 11917    }
 11918    return false;
 11919  }
 11920  
 11921  function readBlockMapping(state, nodeIndent, flowIndent) {
 11922    var following,
 11923        allowCompact,
 11924        _line,
 11925        _tag          = state.tag,
 11926        _anchor       = state.anchor,
 11927        _result       = {},
 11928        overridableKeys = {},
 11929        keyTag        = null,
 11930        keyNode       = null,
 11931        valueNode     = null,
 11932        atExplicitKey = false,
 11933        detected      = false,
 11934        ch;
 11935  
 11936    if (state.anchor !== null) {
 11937      state.anchorMap[state.anchor] = _result;
 11938    }
 11939  
 11940    ch = state.input.charCodeAt(state.position);
 11941  
 11942    while (ch !== 0) {
 11943      following = state.input.charCodeAt(state.position + 1);
 11944      _line = state.line; // Save the current line.
 11945  
 11946      //
 11947      // Explicit notation case. There are two separate blocks:
 11948      // first for the key (denoted by "?") and second for the value (denoted by ":")
 11949      //
 11950      if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {
 11951  
 11952        if (ch === 0x3F/* ? */) {
 11953          if (atExplicitKey) {
 11954            storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
 11955            keyTag = keyNode = valueNode = null;
 11956          }
 11957  
 11958          detected = true;
 11959          atExplicitKey = true;
 11960          allowCompact = true;
 11961  
 11962        } else if (atExplicitKey) {
 11963          // i.e. 0x3A/* : */ === character after the explicit key.
 11964          atExplicitKey = false;
 11965          allowCompact = true;
 11966  
 11967        } else {
 11968          throwError(state, 'incomplete explicit mapping pair; a key node is missed');
 11969        }
 11970  
 11971        state.position += 1;
 11972        ch = following;
 11973  
 11974      //
 11975      // Implicit notation case. Flow-style node as the key first, then ":", and the value.
 11976      //
 11977      } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
 11978  
 11979        if (state.line === _line) {
 11980          ch = state.input.charCodeAt(state.position);
 11981  
 11982          while (is_WHITE_SPACE(ch)) {
 11983            ch = state.input.charCodeAt(++state.position);
 11984          }
 11985  
 11986          if (ch === 0x3A/* : */) {
 11987            ch = state.input.charCodeAt(++state.position);
 11988  
 11989            if (!is_WS_OR_EOL(ch)) {
 11990              throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
 11991            }
 11992  
 11993            if (atExplicitKey) {
 11994              storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
 11995              keyTag = keyNode = valueNode = null;
 11996            }
 11997  
 11998            detected = true;
 11999            atExplicitKey = false;
 12000            allowCompact = false;
 12001            keyTag = state.tag;
 12002            keyNode = state.result;
 12003  
 12004          } else if (detected) {
 12005            throwError(state, 'can not read an implicit mapping pair; a colon is missed');
 12006  
 12007          } else {
 12008            state.tag = _tag;
 12009            state.anchor = _anchor;
 12010            return true; // Keep the result of `composeNode`.
 12011          }
 12012  
 12013        } else if (detected) {
 12014          throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
 12015  
 12016        } else {
 12017          state.tag = _tag;
 12018          state.anchor = _anchor;
 12019          return true; // Keep the result of `composeNode`.
 12020        }
 12021  
 12022      } else {
 12023        break; // Reading is done. Go to the epilogue.
 12024      }
 12025  
 12026      //
 12027      // Common reading code for both explicit and implicit notations.
 12028      //
 12029      if (state.line === _line || state.lineIndent > nodeIndent) {
 12030        if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
 12031          if (atExplicitKey) {
 12032            keyNode = state.result;
 12033          } else {
 12034            valueNode = state.result;
 12035          }
 12036        }
 12037  
 12038        if (!atExplicitKey) {
 12039          storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
 12040          keyTag = keyNode = valueNode = null;
 12041        }
 12042  
 12043        skipSeparationSpace(state, true, -1);
 12044        ch = state.input.charCodeAt(state.position);
 12045      }
 12046  
 12047      if (state.lineIndent > nodeIndent && (ch !== 0)) {
 12048        throwError(state, 'bad indentation of a mapping entry');
 12049      } else if (state.lineIndent < nodeIndent) {
 12050        break;
 12051      }
 12052    }
 12053  
 12054    //
 12055    // Epilogue.
 12056    //
 12057  
 12058    // Special case: last mapping's node contains only the key in explicit notation.
 12059    if (atExplicitKey) {
 12060      storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
 12061    }
 12062  
 12063    // Expose the resulting mapping.
 12064    if (detected) {
 12065      state.tag = _tag;
 12066      state.anchor = _anchor;
 12067      state.kind = 'mapping';
 12068      state.result = _result;
 12069    }
 12070  
 12071    return detected;
 12072  }
 12073  
 12074  function readTagProperty(state) {
 12075    var _position,
 12076        isVerbatim = false,
 12077        isNamed    = false,
 12078        tagHandle,
 12079        tagName,
 12080        ch;
 12081  
 12082    ch = state.input.charCodeAt(state.position);
 12083  
 12084    if (ch !== 0x21/* ! */) return false;
 12085  
 12086    if (state.tag !== null) {
 12087      throwError(state, 'duplication of a tag property');
 12088    }
 12089  
 12090    ch = state.input.charCodeAt(++state.position);
 12091  
 12092    if (ch === 0x3C/* < */) {
 12093      isVerbatim = true;
 12094      ch = state.input.charCodeAt(++state.position);
 12095  
 12096    } else if (ch === 0x21/* ! */) {
 12097      isNamed = true;
 12098      tagHandle = '!!';
 12099      ch = state.input.charCodeAt(++state.position);
 12100  
 12101    } else {
 12102      tagHandle = '!';
 12103    }
 12104  
 12105    _position = state.position;
 12106  
 12107    if (isVerbatim) {
 12108      do { ch = state.input.charCodeAt(++state.position); }
 12109      while (ch !== 0 && ch !== 0x3E/* > */);
 12110  
 12111      if (state.position < state.length) {
 12112        tagName = state.input.slice(_position, state.position);
 12113        ch = state.input.charCodeAt(++state.position);
 12114      } else {
 12115        throwError(state, 'unexpected end of the stream within a verbatim tag');
 12116      }
 12117    } else {
 12118      while (ch !== 0 && !is_WS_OR_EOL(ch)) {
 12119  
 12120        if (ch === 0x21/* ! */) {
 12121          if (!isNamed) {
 12122            tagHandle = state.input.slice(_position - 1, state.position + 1);
 12123  
 12124            if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
 12125              throwError(state, 'named tag handle cannot contain such characters');
 12126            }
 12127  
 12128            isNamed = true;
 12129            _position = state.position + 1;
 12130          } else {
 12131            throwError(state, 'tag suffix cannot contain exclamation marks');
 12132          }
 12133        }
 12134  
 12135        ch = state.input.charCodeAt(++state.position);
 12136      }
 12137  
 12138      tagName = state.input.slice(_position, state.position);
 12139  
 12140      if (PATTERN_FLOW_INDICATORS.test(tagName)) {
 12141        throwError(state, 'tag suffix cannot contain flow indicator characters');
 12142      }
 12143    }
 12144  
 12145    if (tagName && !PATTERN_TAG_URI.test(tagName)) {
 12146      throwError(state, 'tag name cannot contain such characters: ' + tagName);
 12147    }
 12148  
 12149    if (isVerbatim) {
 12150      state.tag = tagName;
 12151  
 12152    } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
 12153      state.tag = state.tagMap[tagHandle] + tagName;
 12154  
 12155    } else if (tagHandle === '!') {
 12156      state.tag = '!' + tagName;
 12157  
 12158    } else if (tagHandle === '!!') {
 12159      state.tag = 'tag:yaml.org,2002:' + tagName;
 12160  
 12161    } else {
 12162      throwError(state, 'undeclared tag handle "' + tagHandle + '"');
 12163    }
 12164  
 12165    return true;
 12166  }
 12167  
 12168  function readAnchorProperty(state) {
 12169    var _position,
 12170        ch;
 12171  
 12172    ch = state.input.charCodeAt(state.position);
 12173  
 12174    if (ch !== 0x26/* & */) return false;
 12175  
 12176    if (state.anchor !== null) {
 12177      throwError(state, 'duplication of an anchor property');
 12178    }
 12179  
 12180    ch = state.input.charCodeAt(++state.position);
 12181    _position = state.position;
 12182  
 12183    while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
 12184      ch = state.input.charCodeAt(++state.position);
 12185    }
 12186  
 12187    if (state.position === _position) {
 12188      throwError(state, 'name of an anchor node must contain at least one character');
 12189    }
 12190  
 12191    state.anchor = state.input.slice(_position, state.position);
 12192    return true;
 12193  }
 12194  
 12195  function readAlias(state) {
 12196    var _position, alias,
 12197        ch;
 12198  
 12199    ch = state.input.charCodeAt(state.position);
 12200  
 12201    if (ch !== 0x2A/* * */) return false;
 12202  
 12203    ch = state.input.charCodeAt(++state.position);
 12204    _position = state.position;
 12205  
 12206    while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
 12207      ch = state.input.charCodeAt(++state.position);
 12208    }
 12209  
 12210    if (state.position === _position) {
 12211      throwError(state, 'name of an alias node must contain at least one character');
 12212    }
 12213  
 12214    alias = state.input.slice(_position, state.position);
 12215  
 12216    if (!state.anchorMap.hasOwnProperty(alias)) {
 12217      throwError(state, 'unidentified alias "' + alias + '"');
 12218    }
 12219  
 12220    state.result = state.anchorMap[alias];
 12221    skipSeparationSpace(state, true, -1);
 12222    return true;
 12223  }
 12224  
 12225  function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
 12226    var allowBlockStyles,
 12227        allowBlockScalars,
 12228        allowBlockCollections,
 12229        indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent
 12230        atNewLine  = false,
 12231        hasContent = false,
 12232        typeIndex,
 12233        typeQuantity,
 12234        type,
 12235        flowIndent,
 12236        blockIndent;
 12237  
 12238    if (state.listener !== null) {
 12239      state.listener('open', state);
 12240    }
 12241  
 12242    state.tag    = null;
 12243    state.anchor = null;
 12244    state.kind   = null;
 12245    state.result = null;
 12246  
 12247    allowBlockStyles = allowBlockScalars = allowBlockCollections =
 12248      CONTEXT_BLOCK_OUT === nodeContext ||
 12249      CONTEXT_BLOCK_IN  === nodeContext;
 12250  
 12251    if (allowToSeek) {
 12252      if (skipSeparationSpace(state, true, -1)) {
 12253        atNewLine = true;
 12254  
 12255        if (state.lineIndent > parentIndent) {
 12256          indentStatus = 1;
 12257        } else if (state.lineIndent === parentIndent) {
 12258          indentStatus = 0;
 12259        } else if (state.lineIndent < parentIndent) {
 12260          indentStatus = -1;
 12261        }
 12262      }
 12263    }
 12264  
 12265    if (indentStatus === 1) {
 12266      while (readTagProperty(state) || readAnchorProperty(state)) {
 12267        if (skipSeparationSpace(state, true, -1)) {
 12268          atNewLine = true;
 12269          allowBlockCollections = allowBlockStyles;
 12270  
 12271          if (state.lineIndent > parentIndent) {
 12272            indentStatus = 1;
 12273          } else if (state.lineIndent === parentIndent) {
 12274            indentStatus = 0;
 12275          } else if (state.lineIndent < parentIndent) {
 12276            indentStatus = -1;
 12277          }
 12278        } else {
 12279          allowBlockCollections = false;
 12280        }
 12281      }
 12282    }
 12283  
 12284    if (allowBlockCollections) {
 12285      allowBlockCollections = atNewLine || allowCompact;
 12286    }
 12287  
 12288    if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
 12289      if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
 12290        flowIndent = parentIndent;
 12291      } else {
 12292        flowIndent = parentIndent + 1;
 12293      }
 12294  
 12295      blockIndent = state.position - state.lineStart;
 12296  
 12297      if (indentStatus === 1) {
 12298        if (allowBlockCollections &&
 12299            (readBlockSequence(state, blockIndent) ||
 12300             readBlockMapping(state, blockIndent, flowIndent)) ||
 12301            readFlowCollection(state, flowIndent)) {
 12302          hasContent = true;
 12303        } else {
 12304          if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||
 12305              readSingleQuotedScalar(state, flowIndent) ||
 12306              readDoubleQuotedScalar(state, flowIndent)) {
 12307            hasContent = true;
 12308  
 12309          } else if (readAlias(state)) {
 12310            hasContent = true;
 12311  
 12312            if (state.tag !== null || state.anchor !== null) {
 12313              throwError(state, 'alias node should not have any properties');
 12314            }
 12315  
 12316          } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
 12317            hasContent = true;
 12318  
 12319            if (state.tag === null) {
 12320              state.tag = '?';
 12321            }
 12322          }
 12323  
 12324          if (state.anchor !== null) {
 12325            state.anchorMap[state.anchor] = state.result;
 12326          }
 12327        }
 12328      } else if (indentStatus === 0) {
 12329        // Special case: block sequences are allowed to have same indentation level as the parent.
 12330        // http://www.yaml.org/spec/1.2/spec.html#id2799784
 12331        hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
 12332      }
 12333    }
 12334  
 12335    if (state.tag !== null && state.tag !== '!') {
 12336      if (state.tag === '?') {
 12337        for (typeIndex = 0, typeQuantity = state.implicitTypes.length;
 12338             typeIndex < typeQuantity;
 12339             typeIndex += 1) {
 12340          type = state.implicitTypes[typeIndex];
 12341  
 12342          // Implicit resolving is not allowed for non-scalar types, and '?'
 12343          // non-specific tag is only assigned to plain scalars. So, it isn't
 12344          // needed to check for 'kind' conformity.
 12345  
 12346          if (type.resolve(state.result)) { // `state.result` updated in resolver if matched
 12347            state.result = type.construct(state.result);
 12348            state.tag = type.tag;
 12349            if (state.anchor !== null) {
 12350              state.anchorMap[state.anchor] = state.result;
 12351            }
 12352            break;
 12353          }
 12354        }
 12355      } else if (_hasOwnProperty.call(state.typeMap, state.tag)) {
 12356        type = state.typeMap[state.tag];
 12357  
 12358        if (state.result !== null && type.kind !== state.kind) {
 12359          throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
 12360        }
 12361  
 12362        if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched
 12363          throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
 12364        } else {
 12365          state.result = type.construct(state.result);
 12366          if (state.anchor !== null) {
 12367            state.anchorMap[state.anchor] = state.result;
 12368          }
 12369        }
 12370      } else {
 12371        throwError(state, 'unknown tag !<' + state.tag + '>');
 12372      }
 12373    }
 12374  
 12375    if (state.listener !== null) {
 12376      state.listener('close', state);
 12377    }
 12378    return state.tag !== null ||  state.anchor !== null || hasContent;
 12379  }
 12380  
 12381  function readDocument(state) {
 12382    var documentStart = state.position,
 12383        _position,
 12384        directiveName,
 12385        directiveArgs,
 12386        hasDirectives = false,
 12387        ch;
 12388  
 12389    state.version = null;
 12390    state.checkLineBreaks = state.legacy;
 12391    state.tagMap = {};
 12392    state.anchorMap = {};
 12393  
 12394    while ((ch = state.input.charCodeAt(state.position)) !== 0) {
 12395      skipSeparationSpace(state, true, -1);
 12396  
 12397      ch = state.input.charCodeAt(state.position);
 12398  
 12399      if (state.lineIndent > 0 || ch !== 0x25/* % */) {
 12400        break;
 12401      }
 12402  
 12403      hasDirectives = true;
 12404      ch = state.input.charCodeAt(++state.position);
 12405      _position = state.position;
 12406  
 12407      while (ch !== 0 && !is_WS_OR_EOL(ch)) {
 12408        ch = state.input.charCodeAt(++state.position);
 12409      }
 12410  
 12411      directiveName = state.input.slice(_position, state.position);
 12412      directiveArgs = [];
 12413  
 12414      if (directiveName.length < 1) {
 12415        throwError(state, 'directive name must not be less than one character in length');
 12416      }
 12417  
 12418      while (ch !== 0) {
 12419        while (is_WHITE_SPACE(ch)) {
 12420          ch = state.input.charCodeAt(++state.position);
 12421        }
 12422  
 12423        if (ch === 0x23/* # */) {
 12424          do { ch = state.input.charCodeAt(++state.position); }
 12425          while (ch !== 0 && !is_EOL(ch));
 12426          break;
 12427        }
 12428  
 12429        if (is_EOL(ch)) break;
 12430  
 12431        _position = state.position;
 12432  
 12433        while (ch !== 0 && !is_WS_OR_EOL(ch)) {
 12434          ch = state.input.charCodeAt(++state.position);
 12435        }
 12436  
 12437        directiveArgs.push(state.input.slice(_position, state.position));
 12438      }
 12439  
 12440      if (ch !== 0) readLineBreak(state);
 12441  
 12442      if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
 12443        directiveHandlers[directiveName](state, directiveName, directiveArgs);
 12444      } else {
 12445        throwWarning(state, 'unknown document directive "' + directiveName + '"');
 12446      }
 12447    }
 12448  
 12449    skipSeparationSpace(state, true, -1);
 12450  
 12451    if (state.lineIndent === 0 &&
 12452        state.input.charCodeAt(state.position)     === 0x2D/* - */ &&
 12453        state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&
 12454        state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {
 12455      state.position += 3;
 12456      skipSeparationSpace(state, true, -1);
 12457  
 12458    } else if (hasDirectives) {
 12459      throwError(state, 'directives end mark is expected');
 12460    }
 12461  
 12462    composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
 12463    skipSeparationSpace(state, true, -1);
 12464  
 12465    if (state.checkLineBreaks &&
 12466        PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
 12467      throwWarning(state, 'non-ASCII line breaks are interpreted as content');
 12468    }
 12469  
 12470    state.documents.push(state.result);
 12471  
 12472    if (state.position === state.lineStart && testDocumentSeparator(state)) {
 12473  
 12474      if (state.input.charCodeAt(state.position) === 0x2E/* . */) {
 12475        state.position += 3;
 12476        skipSeparationSpace(state, true, -1);
 12477      }
 12478      return;
 12479    }
 12480  
 12481    if (state.position < (state.length - 1)) {
 12482      throwError(state, 'end of the stream or a document separator is expected');
 12483    } else {
 12484      return;
 12485    }
 12486  }
 12487  
 12488  
 12489  function loadDocuments(input, options) {
 12490    input = String(input);
 12491    options = options || {};
 12492  
 12493    if (input.length !== 0) {
 12494  
 12495      // Add tailing `\n` if not exists
 12496      if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&
 12497          input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {
 12498        input += '\n';
 12499      }
 12500  
 12501      // Strip BOM
 12502      if (input.charCodeAt(0) === 0xFEFF) {
 12503        input = input.slice(1);
 12504      }
 12505    }
 12506  
 12507    var state = new State(input, options);
 12508  
 12509    // Use 0 as string terminator. That significantly simplifies bounds check.
 12510    state.input += '\0';
 12511  
 12512    while (state.input.charCodeAt(state.position) === 0x20/* Space */) {
 12513      state.lineIndent += 1;
 12514      state.position += 1;
 12515    }
 12516  
 12517    while (state.position < (state.length - 1)) {
 12518      readDocument(state);
 12519    }
 12520  
 12521    return state.documents;
 12522  }
 12523  
 12524  
 12525  function loadAll(input, iterator, options) {
 12526    var documents = loadDocuments(input, options), index, length;
 12527  
 12528    for (index = 0, length = documents.length; index < length; index += 1) {
 12529      iterator(documents[index]);
 12530    }
 12531  }
 12532  
 12533  
 12534  function load(input, options) {
 12535    var documents = loadDocuments(input, options);
 12536  
 12537    if (documents.length === 0) {
 12538      /*eslint-disable no-undefined*/
 12539      return undefined;
 12540    } else if (documents.length === 1) {
 12541      return documents[0];
 12542    }
 12543    throw new YAMLException('expected a single document in the stream, but found more');
 12544  }
 12545  
 12546  
 12547  function safeLoadAll(input, output, options) {
 12548    loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
 12549  }
 12550  
 12551  
 12552  function safeLoad(input, options) {
 12553    return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
 12554  }
 12555  
 12556  
 12557  module.exports.loadAll     = loadAll;
 12558  module.exports.load        = load;
 12559  module.exports.safeLoadAll = safeLoadAll;
 12560  module.exports.safeLoad    = safeLoad;
 12561  
 12562  },{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(require,module,exports){
 12563  'use strict';
 12564  
 12565  
 12566  var common = require('./common');
 12567  
 12568  
 12569  function Mark(name, buffer, position, line, column) {
 12570    this.name     = name;
 12571    this.buffer   = buffer;
 12572    this.position = position;
 12573    this.line     = line;
 12574    this.column   = column;
 12575  }
 12576  
 12577  
 12578  Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {
 12579    var head, start, tail, end, snippet;
 12580  
 12581    if (!this.buffer) return null;
 12582  
 12583    indent = indent || 4;
 12584    maxLength = maxLength || 75;
 12585  
 12586    head = '';
 12587    start = this.position;
 12588  
 12589    while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {
 12590      start -= 1;
 12591      if (this.position - start > (maxLength / 2 - 1)) {
 12592        head = ' ... ';
 12593        start += 5;
 12594        break;
 12595      }
 12596    }
 12597  
 12598    tail = '';
 12599    end = this.position;
 12600  
 12601    while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {
 12602      end += 1;
 12603      if (end - this.position > (maxLength / 2 - 1)) {
 12604        tail = ' ... ';
 12605        end -= 5;
 12606        break;
 12607      }
 12608    }
 12609  
 12610    snippet = this.buffer.slice(start, end);
 12611  
 12612    return common.repeat(' ', indent) + head + snippet + tail + '\n' +
 12613           common.repeat(' ', indent + this.position - start + head.length) + '^';
 12614  };
 12615  
 12616  
 12617  Mark.prototype.toString = function toString(compact) {
 12618    var snippet, where = '';
 12619  
 12620    if (this.name) {
 12621      where += 'in "' + this.name + '" ';
 12622    }
 12623  
 12624    where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
 12625  
 12626    if (!compact) {
 12627      snippet = this.getSnippet();
 12628  
 12629      if (snippet) {
 12630        where += ':\n' + snippet;
 12631      }
 12632    }
 12633  
 12634    return where;
 12635  };
 12636  
 12637  
 12638  module.exports = Mark;
 12639  
 12640  },{"./common":21}],26:[function(require,module,exports){
 12641  'use strict';
 12642  
 12643  /*eslint-disable max-len*/
 12644  
 12645  var common        = require('./common');
 12646  var YAMLException = require('./exception');
 12647  var Type          = require('./type');
 12648  
 12649  
 12650  function compileList(schema, name, result) {
 12651    var exclude = [];
 12652  
 12653    schema.include.forEach(function (includedSchema) {
 12654      result = compileList(includedSchema, name, result);
 12655    });
 12656  
 12657    schema[name].forEach(function (currentType) {
 12658      result.forEach(function (previousType, previousIndex) {
 12659        if (previousType.tag === currentType.tag) {
 12660          exclude.push(previousIndex);
 12661        }
 12662      });
 12663  
 12664      result.push(currentType);
 12665    });
 12666  
 12667    return result.filter(function (type, index) {
 12668      return exclude.indexOf(index) === -1;
 12669    });
 12670  }
 12671  
 12672  
 12673  function compileMap(/* lists... */) {
 12674    var result = {}, index, length;
 12675  
 12676    function collectType(type) {
 12677      result[type.tag] = type;
 12678    }
 12679  
 12680    for (index = 0, length = arguments.length; index < length; index += 1) {
 12681      arguments[index].forEach(collectType);
 12682    }
 12683  
 12684    return result;
 12685  }
 12686  
 12687  
 12688  function Schema(definition) {
 12689    this.include  = definition.include  || [];
 12690    this.implicit = definition.implicit || [];
 12691    this.explicit = definition.explicit || [];
 12692  
 12693    this.implicit.forEach(function (type) {
 12694      if (type.loadKind && type.loadKind !== 'scalar') {
 12695        throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
 12696      }
 12697    });
 12698  
 12699    this.compiledImplicit = compileList(this, 'implicit', []);
 12700    this.compiledExplicit = compileList(this, 'explicit', []);
 12701    this.compiledTypeMap  = compileMap(this.compiledImplicit, this.compiledExplicit);
 12702  }
 12703  
 12704  
 12705  Schema.DEFAULT = null;
 12706  
 12707  
 12708  Schema.create = function createSchema() {
 12709    var schemas, types;
 12710  
 12711    switch (arguments.length) {
 12712      case 1:
 12713        schemas = Schema.DEFAULT;
 12714        types = arguments[0];
 12715        break;
 12716  
 12717      case 2:
 12718        schemas = arguments[0];
 12719        types = arguments[1];
 12720        break;
 12721  
 12722      default:
 12723        throw new YAMLException('Wrong number of arguments for Schema.create function');
 12724    }
 12725  
 12726    schemas = common.toArray(schemas);
 12727    types = common.toArray(types);
 12728  
 12729    if (!schemas.every(function (schema) { return schema instanceof Schema; })) {
 12730      throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
 12731    }
 12732  
 12733    if (!types.every(function (type) { return type instanceof Type; })) {
 12734      throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
 12735    }
 12736  
 12737    return new Schema({
 12738      include: schemas,
 12739      explicit: types
 12740    });
 12741  };
 12742  
 12743  
 12744  module.exports = Schema;
 12745  
 12746  },{"./common":21,"./exception":23,"./type":32}],27:[function(require,module,exports){
 12747  // Standard YAML's Core schema.
 12748  // http://www.yaml.org/spec/1.2/spec.html#id2804923
 12749  //
 12750  // NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
 12751  // So, Core schema has no distinctions from JSON schema is JS-YAML.
 12752  
 12753  
 12754  'use strict';
 12755  
 12756  
 12757  var Schema = require('../schema');
 12758  
 12759  
 12760  module.exports = new Schema({
 12761    include: [
 12762      require('./json')
 12763    ]
 12764  });
 12765  
 12766  },{"../schema":26,"./json":31}],28:[function(require,module,exports){
 12767  // JS-YAML's default schema for `load` function.
 12768  // It is not described in the YAML specification.
 12769  //
 12770  // This schema is based on JS-YAML's default safe schema and includes
 12771  // JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
 12772  //
 12773  // Also this schema is used as default base schema at `Schema.create` function.
 12774  
 12775  
 12776  'use strict';
 12777  
 12778  
 12779  var Schema = require('../schema');
 12780  
 12781  
 12782  module.exports = Schema.DEFAULT = new Schema({
 12783    include: [
 12784      require('./default_safe')
 12785    ],
 12786    explicit: [
 12787      require('../type/js/undefined'),
 12788      require('../type/js/regexp'),
 12789      require('../type/js/function')
 12790    ]
 12791  });
 12792  
 12793  },{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(require,module,exports){
 12794  // JS-YAML's default schema for `safeLoad` function.
 12795  // It is not described in the YAML specification.
 12796  //
 12797  // This schema is based on standard YAML's Core schema and includes most of
 12798  // extra types described at YAML tag repository. (http://yaml.org/type/)
 12799  
 12800  
 12801  'use strict';
 12802  
 12803  
 12804  var Schema = require('../schema');
 12805  
 12806  
 12807  module.exports = new Schema({
 12808    include: [
 12809      require('./core')
 12810    ],
 12811    implicit: [
 12812      require('../type/timestamp'),
 12813      require('../type/merge')
 12814    ],
 12815    explicit: [
 12816      require('../type/binary'),
 12817      require('../type/omap'),
 12818      require('../type/pairs'),
 12819      require('../type/set')
 12820    ]
 12821  });
 12822  
 12823  },{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(require,module,exports){
 12824  // Standard YAML's Failsafe schema.
 12825  // http://www.yaml.org/spec/1.2/spec.html#id2802346
 12826  
 12827  
 12828  'use strict';
 12829  
 12830  
 12831  var Schema = require('../schema');
 12832  
 12833  
 12834  module.exports = new Schema({
 12835    explicit: [
 12836      require('../type/str'),
 12837      require('../type/seq'),
 12838      require('../type/map')
 12839    ]
 12840  });
 12841  
 12842  },{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(require,module,exports){
 12843  // Standard YAML's JSON schema.
 12844  // http://www.yaml.org/spec/1.2/spec.html#id2803231
 12845  //
 12846  // NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
 12847  // So, this schema is not such strict as defined in the YAML specification.
 12848  // It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
 12849  
 12850  
 12851  'use strict';
 12852  
 12853  
 12854  var Schema = require('../schema');
 12855  
 12856  
 12857  module.exports = new Schema({
 12858    include: [
 12859      require('./failsafe')
 12860    ],
 12861    implicit: [
 12862      require('../type/null'),
 12863      require('../type/bool'),
 12864      require('../type/int'),
 12865      require('../type/float')
 12866    ]
 12867  });
 12868  
 12869  },{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(require,module,exports){
 12870  'use strict';
 12871  
 12872  var YAMLException = require('./exception');
 12873  
 12874  var TYPE_CONSTRUCTOR_OPTIONS = [
 12875    'kind',
 12876    'resolve',
 12877    'construct',
 12878    'instanceOf',
 12879    'predicate',
 12880    'represent',
 12881    'defaultStyle',
 12882    'styleAliases'
 12883  ];
 12884  
 12885  var YAML_NODE_KINDS = [
 12886    'scalar',
 12887    'sequence',
 12888    'mapping'
 12889  ];
 12890  
 12891  function compileStyleAliases(map) {
 12892    var result = {};
 12893  
 12894    if (map !== null) {
 12895      Object.keys(map).forEach(function (style) {
 12896        map[style].forEach(function (alias) {
 12897          result[String(alias)] = style;
 12898        });
 12899      });
 12900    }
 12901  
 12902    return result;
 12903  }
 12904  
 12905  function Type(tag, options) {
 12906    options = options || {};
 12907  
 12908    Object.keys(options).forEach(function (name) {
 12909      if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
 12910        throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
 12911      }
 12912    });
 12913  
 12914    // TODO: Add tag format check.
 12915    this.tag          = tag;
 12916    this.kind         = options['kind']         || null;
 12917    this.resolve      = options['resolve']      || function () { return true; };
 12918    this.construct    = options['construct']    || function (data) { return data; };
 12919    this.instanceOf   = options['instanceOf']   || null;
 12920    this.predicate    = options['predicate']    || null;
 12921    this.represent    = options['represent']    || null;
 12922    this.defaultStyle = options['defaultStyle'] || null;
 12923    this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
 12924  
 12925    if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
 12926      throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
 12927    }
 12928  }
 12929  
 12930  module.exports = Type;
 12931  
 12932  },{"./exception":23}],33:[function(require,module,exports){
 12933  'use strict';
 12934  
 12935  /*eslint-disable no-bitwise*/
 12936  
 12937  var NodeBuffer;
 12938  
 12939  try {
 12940    // A trick for browserified version, to not include `Buffer` shim
 12941    var _require = require;
 12942    NodeBuffer = _require('buffer').Buffer;
 12943  } catch (__) {}
 12944  
 12945  var Type       = require('../type');
 12946  
 12947  
 12948  // [ 64, 65, 66 ] -> [ padding, CR, LF ]
 12949  var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
 12950  
 12951  
 12952  function resolveYamlBinary(data) {
 12953    if (data === null) return false;
 12954  
 12955    var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
 12956  
 12957    // Convert one by one.
 12958    for (idx = 0; idx < max; idx++) {
 12959      code = map.indexOf(data.charAt(idx));
 12960  
 12961      // Skip CR/LF
 12962      if (code > 64) continue;
 12963  
 12964      // Fail on illegal characters
 12965      if (code < 0) return false;
 12966  
 12967      bitlen += 6;
 12968    }
 12969  
 12970    // If there are any bits left, source was corrupted
 12971    return (bitlen % 8) === 0;
 12972  }
 12973  
 12974  function constructYamlBinary(data) {
 12975    var idx, tailbits,
 12976        input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
 12977        max = input.length,
 12978        map = BASE64_MAP,
 12979        bits = 0,
 12980        result = [];
 12981  
 12982    // Collect by 6*4 bits (3 bytes)
 12983  
 12984    for (idx = 0; idx < max; idx++) {
 12985      if ((idx % 4 === 0) && idx) {
 12986        result.push((bits >> 16) & 0xFF);
 12987        result.push((bits >> 8) & 0xFF);
 12988        result.push(bits & 0xFF);
 12989      }
 12990  
 12991      bits = (bits << 6) | map.indexOf(input.charAt(idx));
 12992    }
 12993  
 12994    // Dump tail
 12995  
 12996    tailbits = (max % 4) * 6;
 12997  
 12998    if (tailbits === 0) {
 12999      result.push((bits >> 16) & 0xFF);
 13000      result.push((bits >> 8) & 0xFF);
 13001      result.push(bits & 0xFF);
 13002    } else if (tailbits === 18) {
 13003      result.push((bits >> 10) & 0xFF);
 13004      result.push((bits >> 2) & 0xFF);
 13005    } else if (tailbits === 12) {
 13006      result.push((bits >> 4) & 0xFF);
 13007    }
 13008  
 13009    // Wrap into Buffer for NodeJS and leave Array for browser
 13010    if (NodeBuffer) return new NodeBuffer(result);
 13011  
 13012    return result;
 13013  }
 13014  
 13015  function representYamlBinary(object /*, style*/) {
 13016    var result = '', bits = 0, idx, tail,
 13017        max = object.length,
 13018        map = BASE64_MAP;
 13019  
 13020    // Convert every three bytes to 4 ASCII characters.
 13021  
 13022    for (idx = 0; idx < max; idx++) {
 13023      if ((idx % 3 === 0) && idx) {
 13024        result += map[(bits >> 18) & 0x3F];
 13025        result += map[(bits >> 12) & 0x3F];
 13026        result += map[(bits >> 6) & 0x3F];
 13027        result += map[bits & 0x3F];
 13028      }
 13029  
 13030      bits = (bits << 8) + object[idx];
 13031    }
 13032  
 13033    // Dump tail
 13034  
 13035    tail = max % 3;
 13036  
 13037    if (tail === 0) {
 13038      result += map[(bits >> 18) & 0x3F];
 13039      result += map[(bits >> 12) & 0x3F];
 13040      result += map[(bits >> 6) & 0x3F];
 13041      result += map[bits & 0x3F];
 13042    } else if (tail === 2) {
 13043      result += map[(bits >> 10) & 0x3F];
 13044      result += map[(bits >> 4) & 0x3F];
 13045      result += map[(bits << 2) & 0x3F];
 13046      result += map[64];
 13047    } else if (tail === 1) {
 13048      result += map[(bits >> 2) & 0x3F];
 13049      result += map[(bits << 4) & 0x3F];
 13050      result += map[64];
 13051      result += map[64];
 13052    }
 13053  
 13054    return result;
 13055  }
 13056  
 13057  function isBinary(object) {
 13058    return NodeBuffer && NodeBuffer.isBuffer(object);
 13059  }
 13060  
 13061  module.exports = new Type('tag:yaml.org,2002:binary', {
 13062    kind: 'scalar',
 13063    resolve: resolveYamlBinary,
 13064    construct: constructYamlBinary,
 13065    predicate: isBinary,
 13066    represent: representYamlBinary
 13067  });
 13068  
 13069  },{"../type":32}],34:[function(require,module,exports){
 13070  'use strict';
 13071  
 13072  var Type = require('../type');
 13073  
 13074  function resolveYamlBoolean(data) {
 13075    if (data === null) return false;
 13076  
 13077    var max = data.length;
 13078  
 13079    return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
 13080           (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
 13081  }
 13082  
 13083  function constructYamlBoolean(data) {
 13084    return data === 'true' ||
 13085           data === 'True' ||
 13086           data === 'TRUE';
 13087  }
 13088  
 13089  function isBoolean(object) {
 13090    return Object.prototype.toString.call(object) === '[object Boolean]';
 13091  }
 13092  
 13093  module.exports = new Type('tag:yaml.org,2002:bool', {
 13094    kind: 'scalar',
 13095    resolve: resolveYamlBoolean,
 13096    construct: constructYamlBoolean,
 13097    predicate: isBoolean,
 13098    represent: {
 13099      lowercase: function (object) { return object ? 'true' : 'false'; },
 13100      uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
 13101      camelcase: function (object) { return object ? 'True' : 'False'; }
 13102    },
 13103    defaultStyle: 'lowercase'
 13104  });
 13105  
 13106  },{"../type":32}],35:[function(require,module,exports){
 13107  'use strict';
 13108  
 13109  var common = require('../common');
 13110  var Type   = require('../type');
 13111  
 13112  var YAML_FLOAT_PATTERN = new RegExp(
 13113    '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +
 13114    '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +
 13115    '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
 13116    '|[-+]?\\.(?:inf|Inf|INF)' +
 13117    '|\\.(?:nan|NaN|NAN))$');
 13118  
 13119  function resolveYamlFloat(data) {
 13120    if (data === null) return false;
 13121  
 13122    if (!YAML_FLOAT_PATTERN.test(data)) return false;
 13123  
 13124    return true;
 13125  }
 13126  
 13127  function constructYamlFloat(data) {
 13128    var value, sign, base, digits;
 13129  
 13130    value  = data.replace(/_/g, '').toLowerCase();
 13131    sign   = value[0] === '-' ? -1 : 1;
 13132    digits = [];
 13133  
 13134    if ('+-'.indexOf(value[0]) >= 0) {
 13135      value = value.slice(1);
 13136    }
 13137  
 13138    if (value === '.inf') {
 13139      return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
 13140  
 13141    } else if (value === '.nan') {
 13142      return NaN;
 13143  
 13144    } else if (value.indexOf(':') >= 0) {
 13145      value.split(':').forEach(function (v) {
 13146        digits.unshift(parseFloat(v, 10));
 13147      });
 13148  
 13149      value = 0.0;
 13150      base = 1;
 13151  
 13152      digits.forEach(function (d) {
 13153        value += d * base;
 13154        base *= 60;
 13155      });
 13156  
 13157      return sign * value;
 13158  
 13159    }
 13160    return sign * parseFloat(value, 10);
 13161  }
 13162  
 13163  
 13164  var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
 13165  
 13166  function representYamlFloat(object, style) {
 13167    var res;
 13168  
 13169    if (isNaN(object)) {
 13170      switch (style) {
 13171        case 'lowercase': return '.nan';
 13172        case 'uppercase': return '.NAN';
 13173        case 'camelcase': return '.NaN';
 13174      }
 13175    } else if (Number.POSITIVE_INFINITY === object) {
 13176      switch (style) {
 13177        case 'lowercase': return '.inf';
 13178        case 'uppercase': return '.INF';
 13179        case 'camelcase': return '.Inf';
 13180      }
 13181    } else if (Number.NEGATIVE_INFINITY === object) {
 13182      switch (style) {
 13183        case 'lowercase': return '-.inf';
 13184        case 'uppercase': return '-.INF';
 13185        case 'camelcase': return '-.Inf';
 13186      }
 13187    } else if (common.isNegativeZero(object)) {
 13188      return '-0.0';
 13189    }
 13190  
 13191    res = object.toString(10);
 13192  
 13193    // JS stringifier can build scientific format without dots: 5e-100,
 13194    // while YAML requres dot: 5.e-100. Fix it with simple hack
 13195  
 13196    return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
 13197  }
 13198  
 13199  function isFloat(object) {
 13200    return (Object.prototype.toString.call(object) === '[object Number]') &&
 13201           (object % 1 !== 0 || common.isNegativeZero(object));
 13202  }
 13203  
 13204  module.exports = new Type('tag:yaml.org,2002:float', {
 13205    kind: 'scalar',
 13206    resolve: resolveYamlFloat,
 13207    construct: constructYamlFloat,
 13208    predicate: isFloat,
 13209    represent: representYamlFloat,
 13210    defaultStyle: 'lowercase'
 13211  });
 13212  
 13213  },{"../common":21,"../type":32}],36:[function(require,module,exports){
 13214  'use strict';
 13215  
 13216  var common = require('../common');
 13217  var Type   = require('../type');
 13218  
 13219  function isHexCode(c) {
 13220    return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
 13221           ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
 13222           ((0x61/* a */ <= c) && (c <= 0x66/* f */));
 13223  }
 13224  
 13225  function isOctCode(c) {
 13226    return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
 13227  }
 13228  
 13229  function isDecCode(c) {
 13230    return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
 13231  }
 13232  
 13233  function resolveYamlInteger(data) {
 13234    if (data === null) return false;
 13235  
 13236    var max = data.length,
 13237        index = 0,
 13238        hasDigits = false,
 13239        ch;
 13240  
 13241    if (!max) return false;
 13242  
 13243    ch = data[index];
 13244  
 13245    // sign
 13246    if (ch === '-' || ch === '+') {
 13247      ch = data[++index];
 13248    }
 13249  
 13250    if (ch === '0') {
 13251      // 0
 13252      if (index + 1 === max) return true;
 13253      ch = data[++index];
 13254  
 13255      // base 2, base 8, base 16
 13256  
 13257      if (ch === 'b') {
 13258        // base 2
 13259        index++;
 13260  
 13261        for (; index < max; index++) {
 13262          ch = data[index];
 13263          if (ch === '_') continue;
 13264          if (ch !== '0' && ch !== '1') return false;
 13265          hasDigits = true;
 13266        }
 13267        return hasDigits;
 13268      }
 13269  
 13270  
 13271      if (ch === 'x') {
 13272        // base 16
 13273        index++;
 13274  
 13275        for (; index < max; index++) {
 13276          ch = data[index];
 13277          if (ch === '_') continue;
 13278          if (!isHexCode(data.charCodeAt(index))) return false;
 13279          hasDigits = true;
 13280        }
 13281        return hasDigits;
 13282      }
 13283  
 13284      // base 8
 13285      for (; index < max; index++) {
 13286        ch = data[index];
 13287        if (ch === '_') continue;
 13288        if (!isOctCode(data.charCodeAt(index))) return false;
 13289        hasDigits = true;
 13290      }
 13291      return hasDigits;
 13292    }
 13293  
 13294    // base 10 (except 0) or base 60
 13295  
 13296    for (; index < max; index++) {
 13297      ch = data[index];
 13298      if (ch === '_') continue;
 13299      if (ch === ':') break;
 13300      if (!isDecCode(data.charCodeAt(index))) {
 13301        return false;
 13302      }
 13303      hasDigits = true;
 13304    }
 13305  
 13306    if (!hasDigits) return false;
 13307  
 13308    // if !base60 - done;
 13309    if (ch !== ':') return true;
 13310  
 13311    // base60 almost not used, no needs to optimize
 13312    return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
 13313  }
 13314  
 13315  function constructYamlInteger(data) {
 13316    var value = data, sign = 1, ch, base, digits = [];
 13317  
 13318    if (value.indexOf('_') !== -1) {
 13319      value = value.replace(/_/g, '');
 13320    }
 13321  
 13322    ch = value[0];
 13323  
 13324    if (ch === '-' || ch === '+') {
 13325      if (ch === '-') sign = -1;
 13326      value = value.slice(1);
 13327      ch = value[0];
 13328    }
 13329  
 13330    if (value === '0') return 0;
 13331  
 13332    if (ch === '0') {
 13333      if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
 13334      if (value[1] === 'x') return sign * parseInt(value, 16);
 13335      return sign * parseInt(value, 8);
 13336    }
 13337  
 13338    if (value.indexOf(':') !== -1) {
 13339      value.split(':').forEach(function (v) {
 13340        digits.unshift(parseInt(v, 10));
 13341      });
 13342  
 13343      value = 0;
 13344      base = 1;
 13345  
 13346      digits.forEach(function (d) {
 13347        value += (d * base);
 13348        base *= 60;
 13349      });
 13350  
 13351      return sign * value;
 13352  
 13353    }
 13354  
 13355    return sign * parseInt(value, 10);
 13356  }
 13357  
 13358  function isInteger(object) {
 13359    return (Object.prototype.toString.call(object)) === '[object Number]' &&
 13360           (object % 1 === 0 && !common.isNegativeZero(object));
 13361  }
 13362  
 13363  module.exports = new Type('tag:yaml.org,2002:int', {
 13364    kind: 'scalar',
 13365    resolve: resolveYamlInteger,
 13366    construct: constructYamlInteger,
 13367    predicate: isInteger,
 13368    represent: {
 13369      binary:      function (object) { return '0b' + object.toString(2); },
 13370      octal:       function (object) { return '0'  + object.toString(8); },
 13371      decimal:     function (object) { return        object.toString(10); },
 13372      hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
 13373    },
 13374    defaultStyle: 'decimal',
 13375    styleAliases: {
 13376      binary:      [ 2,  'bin' ],
 13377      octal:       [ 8,  'oct' ],
 13378      decimal:     [ 10, 'dec' ],
 13379      hexadecimal: [ 16, 'hex' ]
 13380    }
 13381  });
 13382  
 13383  },{"../common":21,"../type":32}],37:[function(require,module,exports){
 13384  'use strict';
 13385  
 13386  var esprima;
 13387  
 13388  // Browserified version does not have esprima
 13389  //
 13390  // 1. For node.js just require module as deps
 13391  // 2. For browser try to require mudule via external AMD system.
 13392  //    If not found - try to fallback to window.esprima. If not
 13393  //    found too - then fail to parse.
 13394  //
 13395  try {
 13396    // workaround to exclude package from browserify list.
 13397    var _require = require;
 13398    esprima = _require('esprima');
 13399  } catch (_) {
 13400    /*global window */
 13401    if (typeof window !== 'undefined') esprima = window.esprima;
 13402  }
 13403  
 13404  var Type = require('../../type');
 13405  
 13406  function resolveJavascriptFunction(data) {
 13407    if (data === null) return false;
 13408  
 13409    try {
 13410      var source = '(' + data + ')',
 13411          ast    = esprima.parse(source, { range: true });
 13412  
 13413      if (ast.type                    !== 'Program'             ||
 13414          ast.body.length             !== 1                     ||
 13415          ast.body[0].type            !== 'ExpressionStatement' ||
 13416          ast.body[0].expression.type !== 'FunctionExpression') {
 13417        return false;
 13418      }
 13419  
 13420      return true;
 13421    } catch (err) {
 13422      return false;
 13423    }
 13424  }
 13425  
 13426  function constructJavascriptFunction(data) {
 13427    /*jslint evil:true*/
 13428  
 13429    var source = '(' + data + ')',
 13430        ast    = esprima.parse(source, { range: true }),
 13431        params = [],
 13432        body;
 13433  
 13434    if (ast.type                    !== 'Program'             ||
 13435        ast.body.length             !== 1                     ||
 13436        ast.body[0].type            !== 'ExpressionStatement' ||
 13437        ast.body[0].expression.type !== 'FunctionExpression') {
 13438      throw new Error('Failed to resolve function');
 13439    }
 13440  
 13441    ast.body[0].expression.params.forEach(function (param) {
 13442      params.push(param.name);
 13443    });
 13444  
 13445    body = ast.body[0].expression.body.range;
 13446  
 13447    // Esprima's ranges include the first '{' and the last '}' characters on
 13448    // function expressions. So cut them out.
 13449    /*eslint-disable no-new-func*/
 13450    return new Function(params, source.slice(body[0] + 1, body[1] - 1));
 13451  }
 13452  
 13453  function representJavascriptFunction(object /*, style*/) {
 13454    return object.toString();
 13455  }
 13456  
 13457  function isFunction(object) {
 13458    return Object.prototype.toString.call(object) === '[object Function]';
 13459  }
 13460  
 13461  module.exports = new Type('tag:yaml.org,2002:js/function', {
 13462    kind: 'scalar',
 13463    resolve: resolveJavascriptFunction,
 13464    construct: constructJavascriptFunction,
 13465    predicate: isFunction,
 13466    represent: representJavascriptFunction
 13467  });
 13468  
 13469  },{"../../type":32}],38:[function(require,module,exports){
 13470  'use strict';
 13471  
 13472  var Type = require('../../type');
 13473  
 13474  function resolveJavascriptRegExp(data) {
 13475    if (data === null) return false;
 13476    if (data.length === 0) return false;
 13477  
 13478    var regexp = data,
 13479        tail   = /\/([gim]*)$/.exec(data),
 13480        modifiers = '';
 13481  
 13482    // if regexp starts with '/' it can have modifiers and must be properly closed
 13483    // `/foo/gim` - modifiers tail can be maximum 3 chars
 13484    if (regexp[0] === '/') {
 13485      if (tail) modifiers = tail[1];
 13486  
 13487      if (modifiers.length > 3) return false;
 13488      // if expression starts with /, is should be properly terminated
 13489      if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
 13490    }
 13491  
 13492    return true;
 13493  }
 13494  
 13495  function constructJavascriptRegExp(data) {
 13496    var regexp = data,
 13497        tail   = /\/([gim]*)$/.exec(data),
 13498        modifiers = '';
 13499  
 13500    // `/foo/gim` - tail can be maximum 4 chars
 13501    if (regexp[0] === '/') {
 13502      if (tail) modifiers = tail[1];
 13503      regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
 13504    }
 13505  
 13506    return new RegExp(regexp, modifiers);
 13507  }
 13508  
 13509  function representJavascriptRegExp(object /*, style*/) {
 13510    var result = '/' + object.source + '/';
 13511  
 13512    if (object.global) result += 'g';
 13513    if (object.multiline) result += 'm';
 13514    if (object.ignoreCase) result += 'i';
 13515  
 13516    return result;
 13517  }
 13518  
 13519  function isRegExp(object) {
 13520    return Object.prototype.toString.call(object) === '[object RegExp]';
 13521  }
 13522  
 13523  module.exports = new Type('tag:yaml.org,2002:js/regexp', {
 13524    kind: 'scalar',
 13525    resolve: resolveJavascriptRegExp,
 13526    construct: constructJavascriptRegExp,
 13527    predicate: isRegExp,
 13528    represent: representJavascriptRegExp
 13529  });
 13530  
 13531  },{"../../type":32}],39:[function(require,module,exports){
 13532  'use strict';
 13533  
 13534  var Type = require('../../type');
 13535  
 13536  function resolveJavascriptUndefined() {
 13537    return true;
 13538  }
 13539  
 13540  function constructJavascriptUndefined() {
 13541    /*eslint-disable no-undefined*/
 13542    return undefined;
 13543  }
 13544  
 13545  function representJavascriptUndefined() {
 13546    return '';
 13547  }
 13548  
 13549  function isUndefined(object) {
 13550    return typeof object === 'undefined';
 13551  }
 13552  
 13553  module.exports = new Type('tag:yaml.org,2002:js/undefined', {
 13554    kind: 'scalar',
 13555    resolve: resolveJavascriptUndefined,
 13556    construct: constructJavascriptUndefined,
 13557    predicate: isUndefined,
 13558    represent: representJavascriptUndefined
 13559  });
 13560  
 13561  },{"../../type":32}],40:[function(require,module,exports){
 13562  'use strict';
 13563  
 13564  var Type = require('../type');
 13565  
 13566  module.exports = new Type('tag:yaml.org,2002:map', {
 13567    kind: 'mapping',
 13568    construct: function (data) { return data !== null ? data : {}; }
 13569  });
 13570  
 13571  },{"../type":32}],41:[function(require,module,exports){
 13572  'use strict';
 13573  
 13574  var Type = require('../type');
 13575  
 13576  function resolveYamlMerge(data) {
 13577    return data === '<<' || data === null;
 13578  }
 13579  
 13580  module.exports = new Type('tag:yaml.org,2002:merge', {
 13581    kind: 'scalar',
 13582    resolve: resolveYamlMerge
 13583  });
 13584  
 13585  },{"../type":32}],42:[function(require,module,exports){
 13586  'use strict';
 13587  
 13588  var Type = require('../type');
 13589  
 13590  function resolveYamlNull(data) {
 13591    if (data === null) return true;
 13592  
 13593    var max = data.length;
 13594  
 13595    return (max === 1 && data === '~') ||
 13596           (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
 13597  }
 13598  
 13599  function constructYamlNull() {
 13600    return null;
 13601  }
 13602  
 13603  function isNull(object) {
 13604    return object === null;
 13605  }
 13606  
 13607  module.exports = new Type('tag:yaml.org,2002:null', {
 13608    kind: 'scalar',
 13609    resolve: resolveYamlNull,
 13610    construct: constructYamlNull,
 13611    predicate: isNull,
 13612    represent: {
 13613      canonical: function () { return '~';    },
 13614      lowercase: function () { return 'null'; },
 13615      uppercase: function () { return 'NULL'; },
 13616      camelcase: function () { return 'Null'; }
 13617    },
 13618    defaultStyle: 'lowercase'
 13619  });
 13620  
 13621  },{"../type":32}],43:[function(require,module,exports){
 13622  'use strict';
 13623  
 13624  var Type = require('../type');
 13625  
 13626  var _hasOwnProperty = Object.prototype.hasOwnProperty;
 13627  var _toString       = Object.prototype.toString;
 13628  
 13629  function resolveYamlOmap(data) {
 13630    if (data === null) return true;
 13631  
 13632    var objectKeys = [], index, length, pair, pairKey, pairHasKey,
 13633        object = data;
 13634  
 13635    for (index = 0, length = object.length; index < length; index += 1) {
 13636      pair = object[index];
 13637      pairHasKey = false;
 13638  
 13639      if (_toString.call(pair) !== '[object Object]') return false;
 13640  
 13641      for (pairKey in pair) {
 13642        if (_hasOwnProperty.call(pair, pairKey)) {
 13643          if (!pairHasKey) pairHasKey = true;
 13644          else return false;
 13645        }
 13646      }
 13647  
 13648      if (!pairHasKey) return false;
 13649  
 13650      if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
 13651      else return false;
 13652    }
 13653  
 13654    return true;
 13655  }
 13656  
 13657  function constructYamlOmap(data) {
 13658    return data !== null ? data : [];
 13659  }
 13660  
 13661  module.exports = new Type('tag:yaml.org,2002:omap', {
 13662    kind: 'sequence',
 13663    resolve: resolveYamlOmap,
 13664    construct: constructYamlOmap
 13665  });
 13666  
 13667  },{"../type":32}],44:[function(require,module,exports){
 13668  'use strict';
 13669  
 13670  var Type = require('../type');
 13671  
 13672  var _toString = Object.prototype.toString;
 13673  
 13674  function resolveYamlPairs(data) {
 13675    if (data === null) return true;
 13676  
 13677    var index, length, pair, keys, result,
 13678        object = data;
 13679  
 13680    result = new Array(object.length);
 13681  
 13682    for (index = 0, length = object.length; index < length; index += 1) {
 13683      pair = object[index];
 13684  
 13685      if (_toString.call(pair) !== '[object Object]') return false;
 13686  
 13687      keys = Object.keys(pair);
 13688  
 13689      if (keys.length !== 1) return false;
 13690  
 13691      result[index] = [ keys[0], pair[keys[0]] ];
 13692    }
 13693  
 13694    return true;
 13695  }
 13696  
 13697  function constructYamlPairs(data) {
 13698    if (data === null) return [];
 13699  
 13700    var index, length, pair, keys, result,
 13701        object = data;
 13702  
 13703    result = new Array(object.length);
 13704  
 13705    for (index = 0, length = object.length; index < length; index += 1) {
 13706      pair = object[index];
 13707  
 13708      keys = Object.keys(pair);
 13709  
 13710      result[index] = [ keys[0], pair[keys[0]] ];
 13711    }
 13712  
 13713    return result;
 13714  }
 13715  
 13716  module.exports = new Type('tag:yaml.org,2002:pairs', {
 13717    kind: 'sequence',
 13718    resolve: resolveYamlPairs,
 13719    construct: constructYamlPairs
 13720  });
 13721  
 13722  },{"../type":32}],45:[function(require,module,exports){
 13723  'use strict';
 13724  
 13725  var Type = require('../type');
 13726  
 13727  module.exports = new Type('tag:yaml.org,2002:seq', {
 13728    kind: 'sequence',
 13729    construct: function (data) { return data !== null ? data : []; }
 13730  });
 13731  
 13732  },{"../type":32}],46:[function(require,module,exports){
 13733  'use strict';
 13734  
 13735  var Type = require('../type');
 13736  
 13737  var _hasOwnProperty = Object.prototype.hasOwnProperty;
 13738  
 13739  function resolveYamlSet(data) {
 13740    if (data === null) return true;
 13741  
 13742    var key, object = data;
 13743  
 13744    for (key in object) {
 13745      if (_hasOwnProperty.call(object, key)) {
 13746        if (object[key] !== null) return false;
 13747      }
 13748    }
 13749  
 13750    return true;
 13751  }
 13752  
 13753  function constructYamlSet(data) {
 13754    return data !== null ? data : {};
 13755  }
 13756  
 13757  module.exports = new Type('tag:yaml.org,2002:set', {
 13758    kind: 'mapping',
 13759    resolve: resolveYamlSet,
 13760    construct: constructYamlSet
 13761  });
 13762  
 13763  },{"../type":32}],47:[function(require,module,exports){
 13764  'use strict';
 13765  
 13766  var Type = require('../type');
 13767  
 13768  module.exports = new Type('tag:yaml.org,2002:str', {
 13769    kind: 'scalar',
 13770    construct: function (data) { return data !== null ? data : ''; }
 13771  });
 13772  
 13773  },{"../type":32}],48:[function(require,module,exports){
 13774  'use strict';
 13775  
 13776  var Type = require('../type');
 13777  
 13778  var YAML_DATE_REGEXP = new RegExp(
 13779    '^([0-9][0-9][0-9][0-9])'          + // [1] year
 13780    '-([0-9][0-9])'                    + // [2] month
 13781    '-([0-9][0-9])$');                   // [3] day
 13782  
 13783  var YAML_TIMESTAMP_REGEXP = new RegExp(
 13784    '^([0-9][0-9][0-9][0-9])'          + // [1] year
 13785    '-([0-9][0-9]?)'                   + // [2] month
 13786    '-([0-9][0-9]?)'                   + // [3] day
 13787    '(?:[Tt]|[ \\t]+)'                 + // ...
 13788    '([0-9][0-9]?)'                    + // [4] hour
 13789    ':([0-9][0-9])'                    + // [5] minute
 13790    ':([0-9][0-9])'                    + // [6] second
 13791    '(?:\\.([0-9]*))?'                 + // [7] fraction
 13792    '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
 13793    '(?::([0-9][0-9]))?))?$');           // [11] tz_minute
 13794  
 13795  function resolveYamlTimestamp(data) {
 13796    if (data === null) return false;
 13797    if (YAML_DATE_REGEXP.exec(data) !== null) return true;
 13798    if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
 13799    return false;
 13800  }
 13801  
 13802  function constructYamlTimestamp(data) {
 13803    var match, year, month, day, hour, minute, second, fraction = 0,
 13804        delta = null, tz_hour, tz_minute, date;
 13805  
 13806    match = YAML_DATE_REGEXP.exec(data);
 13807    if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
 13808  
 13809    if (match === null) throw new Error('Date resolve error');
 13810  
 13811    // match: [1] year [2] month [3] day
 13812  
 13813    year = +(match[1]);
 13814    month = +(match[2]) - 1; // JS month starts with 0
 13815    day = +(match[3]);
 13816  
 13817    if (!match[4]) { // no hour
 13818      return new Date(Date.UTC(year, month, day));
 13819    }
 13820  
 13821    // match: [4] hour [5] minute [6] second [7] fraction
 13822  
 13823    hour = +(match[4]);
 13824    minute = +(match[5]);
 13825    second = +(match[6]);
 13826  
 13827    if (match[7]) {
 13828      fraction = match[7].slice(0, 3);
 13829      while (fraction.length < 3) { // milli-seconds
 13830        fraction += '0';
 13831      }
 13832      fraction = +fraction;
 13833    }
 13834  
 13835    // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
 13836  
 13837    if (match[9]) {
 13838      tz_hour = +(match[10]);
 13839      tz_minute = +(match[11] || 0);
 13840      delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
 13841      if (match[9] === '-') delta = -delta;
 13842    }
 13843  
 13844    date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
 13845  
 13846    if (delta) date.setTime(date.getTime() - delta);
 13847  
 13848    return date;
 13849  }
 13850  
 13851  function representYamlTimestamp(object /*, style*/) {
 13852    return object.toISOString();
 13853  }
 13854  
 13855  module.exports = new Type('tag:yaml.org,2002:timestamp', {
 13856    kind: 'scalar',
 13857    resolve: resolveYamlTimestamp,
 13858    construct: constructYamlTimestamp,
 13859    instanceOf: Date,
 13860    represent: representYamlTimestamp
 13861  });
 13862  
 13863  },{"../type":32}],49:[function(require,module,exports){
 13864  var baseIndexOf = require('../internal/baseIndexOf'),
 13865      binaryIndex = require('../internal/binaryIndex');
 13866  
 13867  /* Native method references for those with the same name as other `lodash` methods. */
 13868  var nativeMax = Math.max;
 13869  
 13870  /**
 13871   * Gets the index at which the first occurrence of `value` is found in `array`
 13872   * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
 13873   * for equality comparisons. If `fromIndex` is negative, it's used as the offset
 13874   * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
 13875   * performs a faster binary search.
 13876   *
 13877   * @static
 13878   * @memberOf _
 13879   * @category Array
 13880   * @param {Array} array The array to search.
 13881   * @param {*} value The value to search for.
 13882   * @param {boolean|number} [fromIndex=0] The index to search from or `true`
 13883   *  to perform a binary search on a sorted array.
 13884   * @returns {number} Returns the index of the matched value, else `-1`.
 13885   * @example
 13886   *
 13887   * _.indexOf([1, 2, 1, 2], 2);
 13888   * // => 1
 13889   *
 13890   * // using `fromIndex`
 13891   * _.indexOf([1, 2, 1, 2], 2, 2);
 13892   * // => 3
 13893   *
 13894   * // performing a binary search
 13895   * _.indexOf([1, 1, 2, 2], 2, true);
 13896   * // => 2
 13897   */
 13898  function indexOf(array, value, fromIndex) {
 13899    var length = array ? array.length : 0;
 13900    if (!length) {
 13901      return -1;
 13902    }
 13903    if (typeof fromIndex == 'number') {
 13904      fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
 13905    } else if (fromIndex) {
 13906      var index = binaryIndex(array, value);
 13907      if (index < length &&
 13908          (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
 13909        return index;
 13910      }
 13911      return -1;
 13912    }
 13913    return baseIndexOf(array, value, fromIndex || 0);
 13914  }
 13915  
 13916  module.exports = indexOf;
 13917  
 13918  },{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(require,module,exports){
 13919  /**
 13920   * Gets the last element of `array`.
 13921   *
 13922   * @static
 13923   * @memberOf _
 13924   * @category Array
 13925   * @param {Array} array The array to query.
 13926   * @returns {*} Returns the last element of `array`.
 13927   * @example
 13928   *
 13929   * _.last([1, 2, 3]);
 13930   * // => 3
 13931   */
 13932  function last(array) {
 13933    var length = array ? array.length : 0;
 13934    return length ? array[length - 1] : undefined;
 13935  }
 13936  
 13937  module.exports = last;
 13938  
 13939  },{}],51:[function(require,module,exports){
 13940  var LazyWrapper = require('../internal/LazyWrapper'),
 13941      LodashWrapper = require('../internal/LodashWrapper'),
 13942      baseLodash = require('../internal/baseLodash'),
 13943      isArray = require('../lang/isArray'),
 13944      isObjectLike = require('../internal/isObjectLike'),
 13945      wrapperClone = require('../internal/wrapperClone');
 13946  
 13947  /** Used for native method references. */
 13948  var objectProto = Object.prototype;
 13949  
 13950  /** Used to check objects for own properties. */
 13951  var hasOwnProperty = objectProto.hasOwnProperty;
 13952  
 13953  /**
 13954   * Creates a `lodash` object which wraps `value` to enable implicit chaining.
 13955   * Methods that operate on and return arrays, collections, and functions can
 13956   * be chained together. Methods that retrieve a single value or may return a
 13957   * primitive value will automatically end the chain returning the unwrapped
 13958   * value. Explicit chaining may be enabled using `_.chain`. The execution of
 13959   * chained methods is lazy, that is, execution is deferred until `_#value`
 13960   * is implicitly or explicitly called.
 13961   *
 13962   * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
 13963   * fusion is an optimization strategy which merge iteratee calls; this can help
 13964   * to avoid the creation of intermediate data structures and greatly reduce the
 13965   * number of iteratee executions.
 13966   *
 13967   * Chaining is supported in custom builds as long as the `_#value` method is
 13968   * directly or indirectly included in the build.
 13969   *
 13970   * In addition to lodash methods, wrappers have `Array` and `String` methods.
 13971   *
 13972   * The wrapper `Array` methods are:
 13973   * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
 13974   * `splice`, and `unshift`
 13975   *
 13976   * The wrapper `String` methods are:
 13977   * `replace` and `split`
 13978   *
 13979   * The wrapper methods that support shortcut fusion are:
 13980   * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
 13981   * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
 13982   * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
 13983   * and `where`
 13984   *
 13985   * The chainable wrapper methods are:
 13986   * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
 13987   * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
 13988   * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
 13989   * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
 13990   * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
 13991   * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
 13992   * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
 13993   * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
 13994   * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
 13995   * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
 13996   * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
 13997   * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
 13998   * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
 13999   * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
 14000   * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
 14001   * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
 14002   * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
 14003   *
 14004   * The wrapper methods that are **not** chainable by default are:
 14005   * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
 14006   * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
 14007   * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
 14008   * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
 14009   * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
 14010   * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
 14011   * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
 14012   * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
 14013   * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
 14014   * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
 14015   * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
 14016   * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
 14017   * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
 14018   * `unescape`, `uniqueId`, `value`, and `words`
 14019   *
 14020   * The wrapper method `sample` will return a wrapped value when `n` is provided,
 14021   * otherwise an unwrapped value is returned.
 14022   *
 14023   * @name _
 14024   * @constructor
 14025   * @category Chain
 14026   * @param {*} value The value to wrap in a `lodash` instance.
 14027   * @returns {Object} Returns the new `lodash` wrapper instance.
 14028   * @example
 14029   *
 14030   * var wrapped = _([1, 2, 3]);
 14031   *
 14032   * // returns an unwrapped value
 14033   * wrapped.reduce(function(total, n) {
 14034   *   return total + n;
 14035   * });
 14036   * // => 6
 14037   *
 14038   * // returns a wrapped value
 14039   * var squares = wrapped.map(function(n) {
 14040   *   return n * n;
 14041   * });
 14042   *
 14043   * _.isArray(squares);
 14044   * // => false
 14045   *
 14046   * _.isArray(squares.value());
 14047   * // => true
 14048   */
 14049  function lodash(value) {
 14050    if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
 14051      if (value instanceof LodashWrapper) {
 14052        return value;
 14053      }
 14054      if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
 14055        return wrapperClone(value);
 14056      }
 14057    }
 14058    return new LodashWrapper(value);
 14059  }
 14060  
 14061  // Ensure wrappers are instances of `baseLodash`.
 14062  lodash.prototype = baseLodash.prototype;
 14063  
 14064  module.exports = lodash;
 14065  
 14066  },{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(require,module,exports){
 14067  module.exports = require('./forEach');
 14068  
 14069  },{"./forEach":54}],53:[function(require,module,exports){
 14070  var baseEach = require('../internal/baseEach'),
 14071      createFind = require('../internal/createFind');
 14072  
 14073  /**
 14074   * Iterates over elements of `collection`, returning the first element
 14075   * `predicate` returns truthy for. The predicate is bound to `thisArg` and
 14076   * invoked with three arguments: (value, index|key, collection).
 14077   *
 14078   * If a property name is provided for `predicate` the created `_.property`
 14079   * style callback returns the property value of the given element.
 14080   *
 14081   * If a value is also provided for `thisArg` the created `_.matchesProperty`
 14082   * style callback returns `true` for elements that have a matching property
 14083   * value, else `false`.
 14084   *
 14085   * If an object is provided for `predicate` the created `_.matches` style
 14086   * callback returns `true` for elements that have the properties of the given
 14087   * object, else `false`.
 14088   *
 14089   * @static
 14090   * @memberOf _
 14091   * @alias detect
 14092   * @category Collection
 14093   * @param {Array|Object|string} collection The collection to search.
 14094   * @param {Function|Object|string} [predicate=_.identity] The function invoked
 14095   *  per iteration.
 14096   * @param {*} [thisArg] The `this` binding of `predicate`.
 14097   * @returns {*} Returns the matched element, else `undefined`.
 14098   * @example
 14099   *
 14100   * var users = [
 14101   *   { 'user': 'barney',  'age': 36, 'active': true },
 14102   *   { 'user': 'fred',    'age': 40, 'active': false },
 14103   *   { 'user': 'pebbles', 'age': 1,  'active': true }
 14104   * ];
 14105   *
 14106   * _.result(_.find(users, function(chr) {
 14107   *   return chr.age < 40;
 14108   * }), 'user');
 14109   * // => 'barney'
 14110   *
 14111   * // using the `_.matches` callback shorthand
 14112   * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
 14113   * // => 'pebbles'
 14114   *
 14115   * // using the `_.matchesProperty` callback shorthand
 14116   * _.result(_.find(users, 'active', false), 'user');
 14117   * // => 'fred'
 14118   *
 14119   * // using the `_.property` callback shorthand
 14120   * _.result(_.find(users, 'active'), 'user');
 14121   * // => 'barney'
 14122   */
 14123  var find = createFind(baseEach);
 14124  
 14125  module.exports = find;
 14126  
 14127  },{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(require,module,exports){
 14128  var arrayEach = require('../internal/arrayEach'),
 14129      baseEach = require('../internal/baseEach'),
 14130      createForEach = require('../internal/createForEach');
 14131  
 14132  /**
 14133   * Iterates over elements of `collection` invoking `iteratee` for each element.
 14134   * The `iteratee` is bound to `thisArg` and invoked with three arguments:
 14135   * (value, index|key, collection). Iteratee functions may exit iteration early
 14136   * by explicitly returning `false`.
 14137   *
 14138   * **Note:** As with other "Collections" methods, objects with a "length" property
 14139   * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
 14140   * may be used for object iteration.
 14141   *
 14142   * @static
 14143   * @memberOf _
 14144   * @alias each
 14145   * @category Collection
 14146   * @param {Array|Object|string} collection The collection to iterate over.
 14147   * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 14148   * @param {*} [thisArg] The `this` binding of `iteratee`.
 14149   * @returns {Array|Object|string} Returns `collection`.
 14150   * @example
 14151   *
 14152   * _([1, 2]).forEach(function(n) {
 14153   *   console.log(n);
 14154   * }).value();
 14155   * // => logs each value from left to right and returns the array
 14156   *
 14157   * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
 14158   *   console.log(n, key);
 14159   * });
 14160   * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
 14161   */
 14162  var forEach = createForEach(arrayEach, baseEach);
 14163  
 14164  module.exports = forEach;
 14165  
 14166  },{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(require,module,exports){
 14167  var baseIndexOf = require('../internal/baseIndexOf'),
 14168      getLength = require('../internal/getLength'),
 14169      isArray = require('../lang/isArray'),
 14170      isIterateeCall = require('../internal/isIterateeCall'),
 14171      isLength = require('../internal/isLength'),
 14172      isString = require('../lang/isString'),
 14173      values = require('../object/values');
 14174  
 14175  /* Native method references for those with the same name as other `lodash` methods. */
 14176  var nativeMax = Math.max;
 14177  
 14178  /**
 14179   * Checks if `target` is in `collection` using
 14180   * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
 14181   * for equality comparisons. If `fromIndex` is negative, it's used as the offset
 14182   * from the end of `collection`.
 14183   *
 14184   * @static
 14185   * @memberOf _
 14186   * @alias contains, include
 14187   * @category Collection
 14188   * @param {Array|Object|string} collection The collection to search.
 14189   * @param {*} target The value to search for.
 14190   * @param {number} [fromIndex=0] The index to search from.
 14191   * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
 14192   * @returns {boolean} Returns `true` if a matching element is found, else `false`.
 14193   * @example
 14194   *
 14195   * _.includes([1, 2, 3], 1);
 14196   * // => true
 14197   *
 14198   * _.includes([1, 2, 3], 1, 2);
 14199   * // => false
 14200   *
 14201   * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
 14202   * // => true
 14203   *
 14204   * _.includes('pebbles', 'eb');
 14205   * // => true
 14206   */
 14207  function includes(collection, target, fromIndex, guard) {
 14208    var length = collection ? getLength(collection) : 0;
 14209    if (!isLength(length)) {
 14210      collection = values(collection);
 14211      length = collection.length;
 14212    }
 14213    if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
 14214      fromIndex = 0;
 14215    } else {
 14216      fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
 14217    }
 14218    return (typeof collection == 'string' || !isArray(collection) && isString(collection))
 14219      ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
 14220      : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
 14221  }
 14222  
 14223  module.exports = includes;
 14224  
 14225  },{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(require,module,exports){
 14226  var arrayMap = require('../internal/arrayMap'),
 14227      baseCallback = require('../internal/baseCallback'),
 14228      baseMap = require('../internal/baseMap'),
 14229      isArray = require('../lang/isArray');
 14230  
 14231  /**
 14232   * Creates an array of values by running each element in `collection` through
 14233   * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
 14234   * arguments: (value, index|key, collection).
 14235   *
 14236   * If a property name is provided for `iteratee` the created `_.property`
 14237   * style callback returns the property value of the given element.
 14238   *
 14239   * If a value is also provided for `thisArg` the created `_.matchesProperty`
 14240   * style callback returns `true` for elements that have a matching property
 14241   * value, else `false`.
 14242   *
 14243   * If an object is provided for `iteratee` the created `_.matches` style
 14244   * callback returns `true` for elements that have the properties of the given
 14245   * object, else `false`.
 14246   *
 14247   * Many lodash methods are guarded to work as iteratees for methods like
 14248   * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
 14249   *
 14250   * The guarded methods are:
 14251   * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
 14252   * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
 14253   * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
 14254   * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
 14255   * `sum`, `uniq`, and `words`
 14256   *
 14257   * @static
 14258   * @memberOf _
 14259   * @alias collect
 14260   * @category Collection
 14261   * @param {Array|Object|string} collection The collection to iterate over.
 14262   * @param {Function|Object|string} [iteratee=_.identity] The function invoked
 14263   *  per iteration.
 14264   * @param {*} [thisArg] The `this` binding of `iteratee`.
 14265   * @returns {Array} Returns the new mapped array.
 14266   * @example
 14267   *
 14268   * function timesThree(n) {
 14269   *   return n * 3;
 14270   * }
 14271   *
 14272   * _.map([1, 2], timesThree);
 14273   * // => [3, 6]
 14274   *
 14275   * _.map({ 'a': 1, 'b': 2 }, timesThree);
 14276   * // => [3, 6] (iteration order is not guaranteed)
 14277   *
 14278   * var users = [
 14279   *   { 'user': 'barney' },
 14280   *   { 'user': 'fred' }
 14281   * ];
 14282   *
 14283   * // using the `_.property` callback shorthand
 14284   * _.map(users, 'user');
 14285   * // => ['barney', 'fred']
 14286   */
 14287  function map(collection, iteratee, thisArg) {
 14288    var func = isArray(collection) ? arrayMap : baseMap;
 14289    iteratee = baseCallback(iteratee, thisArg, 3);
 14290    return func(collection, iteratee);
 14291  }
 14292  
 14293  module.exports = map;
 14294  
 14295  },{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(require,module,exports){
 14296  var getNative = require('../internal/getNative');
 14297  
 14298  /* Native method references for those with the same name as other `lodash` methods. */
 14299  var nativeNow = getNative(Date, 'now');
 14300  
 14301  /**
 14302   * Gets the number of milliseconds that have elapsed since the Unix epoch
 14303   * (1 January 1970 00:00:00 UTC).
 14304   *
 14305   * @static
 14306   * @memberOf _
 14307   * @category Date
 14308   * @example
 14309   *
 14310   * _.defer(function(stamp) {
 14311   *   console.log(_.now() - stamp);
 14312   * }, _.now());
 14313   * // => logs the number of milliseconds it took for the deferred function to be invoked
 14314   */
 14315  var now = nativeNow || function() {
 14316    return new Date().getTime();
 14317  };
 14318  
 14319  module.exports = now;
 14320  
 14321  },{"../internal/getNative":114}],58:[function(require,module,exports){
 14322  var createWrapper = require('../internal/createWrapper'),
 14323      replaceHolders = require('../internal/replaceHolders'),
 14324      restParam = require('./restParam');
 14325  
 14326  /** Used to compose bitmasks for wrapper metadata. */
 14327  var BIND_FLAG = 1,
 14328      PARTIAL_FLAG = 32;
 14329  
 14330  /**
 14331   * Creates a function that invokes `func` with the `this` binding of `thisArg`
 14332   * and prepends any additional `_.bind` arguments to those provided to the
 14333   * bound function.
 14334   *
 14335   * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
 14336   * may be used as a placeholder for partially applied arguments.
 14337   *
 14338   * **Note:** Unlike native `Function#bind` this method does not set the "length"
 14339   * property of bound functions.
 14340   *
 14341   * @static
 14342   * @memberOf _
 14343   * @category Function
 14344   * @param {Function} func The function to bind.
 14345   * @param {*} thisArg The `this` binding of `func`.
 14346   * @param {...*} [partials] The arguments to be partially applied.
 14347   * @returns {Function} Returns the new bound function.
 14348   * @example
 14349   *
 14350   * var greet = function(greeting, punctuation) {
 14351   *   return greeting + ' ' + this.user + punctuation;
 14352   * };
 14353   *
 14354   * var object = { 'user': 'fred' };
 14355   *
 14356   * var bound = _.bind(greet, object, 'hi');
 14357   * bound('!');
 14358   * // => 'hi fred!'
 14359   *
 14360   * // using placeholders
 14361   * var bound = _.bind(greet, object, _, '!');
 14362   * bound('hi');
 14363   * // => 'hi fred!'
 14364   */
 14365  var bind = restParam(function(func, thisArg, partials) {
 14366    var bitmask = BIND_FLAG;
 14367    if (partials.length) {
 14368      var holders = replaceHolders(partials, bind.placeholder);
 14369      bitmask |= PARTIAL_FLAG;
 14370    }
 14371    return createWrapper(func, bitmask, thisArg, partials, holders);
 14372  });
 14373  
 14374  // Assign default placeholders.
 14375  bind.placeholder = {};
 14376  
 14377  module.exports = bind;
 14378  
 14379  },{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(require,module,exports){
 14380  /** Used as the `TypeError` message for "Functions" methods. */
 14381  var FUNC_ERROR_TEXT = 'Expected a function';
 14382  
 14383  /* Native method references for those with the same name as other `lodash` methods. */
 14384  var nativeMax = Math.max;
 14385  
 14386  /**
 14387   * Creates a function that invokes `func` with the `this` binding of the
 14388   * created function and arguments from `start` and beyond provided as an array.
 14389   *
 14390   * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
 14391   *
 14392   * @static
 14393   * @memberOf _
 14394   * @category Function
 14395   * @param {Function} func The function to apply a rest parameter to.
 14396   * @param {number} [start=func.length-1] The start position of the rest parameter.
 14397   * @returns {Function} Returns the new function.
 14398   * @example
 14399   *
 14400   * var say = _.restParam(function(what, names) {
 14401   *   return what + ' ' + _.initial(names).join(', ') +
 14402   *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
 14403   * });
 14404   *
 14405   * say('hello', 'fred', 'barney', 'pebbles');
 14406   * // => 'hello fred, barney, & pebbles'
 14407   */
 14408  function restParam(func, start) {
 14409    if (typeof func != 'function') {
 14410      throw new TypeError(FUNC_ERROR_TEXT);
 14411    }
 14412    start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
 14413    return function() {
 14414      var args = arguments,
 14415          index = -1,
 14416          length = nativeMax(args.length - start, 0),
 14417          rest = Array(length);
 14418  
 14419      while (++index < length) {
 14420        rest[index] = args[start + index];
 14421      }
 14422      switch (start) {
 14423        case 0: return func.call(this, rest);
 14424        case 1: return func.call(this, args[0], rest);
 14425        case 2: return func.call(this, args[0], args[1], rest);
 14426      }
 14427      var otherArgs = Array(start + 1);
 14428      index = -1;
 14429      while (++index < start) {
 14430        otherArgs[index] = args[index];
 14431      }
 14432      otherArgs[start] = rest;
 14433      return func.apply(this, otherArgs);
 14434    };
 14435  }
 14436  
 14437  module.exports = restParam;
 14438  
 14439  },{}],60:[function(require,module,exports){
 14440  var baseCreate = require('./baseCreate'),
 14441      baseLodash = require('./baseLodash');
 14442  
 14443  /** Used as references for `-Infinity` and `Infinity`. */
 14444  var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
 14445  
 14446  /**
 14447   * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
 14448   *
 14449   * @private
 14450   * @param {*} value The value to wrap.
 14451   */
 14452  function LazyWrapper(value) {
 14453    this.__wrapped__ = value;
 14454    this.__actions__ = [];
 14455    this.__dir__ = 1;
 14456    this.__filtered__ = false;
 14457    this.__iteratees__ = [];
 14458    this.__takeCount__ = POSITIVE_INFINITY;
 14459    this.__views__ = [];
 14460  }
 14461  
 14462  LazyWrapper.prototype = baseCreate(baseLodash.prototype);
 14463  LazyWrapper.prototype.constructor = LazyWrapper;
 14464  
 14465  module.exports = LazyWrapper;
 14466  
 14467  },{"./baseCreate":70,"./baseLodash":82}],61:[function(require,module,exports){
 14468  var baseCreate = require('./baseCreate'),
 14469      baseLodash = require('./baseLodash');
 14470  
 14471  /**
 14472   * The base constructor for creating `lodash` wrapper objects.
 14473   *
 14474   * @private
 14475   * @param {*} value The value to wrap.
 14476   * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
 14477   * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
 14478   */
 14479  function LodashWrapper(value, chainAll, actions) {
 14480    this.__wrapped__ = value;
 14481    this.__actions__ = actions || [];
 14482    this.__chain__ = !!chainAll;
 14483  }
 14484  
 14485  LodashWrapper.prototype = baseCreate(baseLodash.prototype);
 14486  LodashWrapper.prototype.constructor = LodashWrapper;
 14487  
 14488  module.exports = LodashWrapper;
 14489  
 14490  },{"./baseCreate":70,"./baseLodash":82}],62:[function(require,module,exports){
 14491  /**
 14492   * Copies the values of `source` to `array`.
 14493   *
 14494   * @private
 14495   * @param {Array} source The array to copy values from.
 14496   * @param {Array} [array=[]] The array to copy values to.
 14497   * @returns {Array} Returns `array`.
 14498   */
 14499  function arrayCopy(source, array) {
 14500    var index = -1,
 14501        length = source.length;
 14502  
 14503    array || (array = Array(length));
 14504    while (++index < length) {
 14505      array[index] = source[index];
 14506    }
 14507    return array;
 14508  }
 14509  
 14510  module.exports = arrayCopy;
 14511  
 14512  },{}],63:[function(require,module,exports){
 14513  /**
 14514   * A specialized version of `_.forEach` for arrays without support for callback
 14515   * shorthands and `this` binding.
 14516   *
 14517   * @private
 14518   * @param {Array} array The array to iterate over.
 14519   * @param {Function} iteratee The function invoked per iteration.
 14520   * @returns {Array} Returns `array`.
 14521   */
 14522  function arrayEach(array, iteratee) {
 14523    var index = -1,
 14524        length = array.length;
 14525  
 14526    while (++index < length) {
 14527      if (iteratee(array[index], index, array) === false) {
 14528        break;
 14529      }
 14530    }
 14531    return array;
 14532  }
 14533  
 14534  module.exports = arrayEach;
 14535  
 14536  },{}],64:[function(require,module,exports){
 14537  /**
 14538   * A specialized version of `_.map` for arrays without support for callback
 14539   * shorthands and `this` binding.
 14540   *
 14541   * @private
 14542   * @param {Array} array The array to iterate over.
 14543   * @param {Function} iteratee The function invoked per iteration.
 14544   * @returns {Array} Returns the new mapped array.
 14545   */
 14546  function arrayMap(array, iteratee) {
 14547    var index = -1,
 14548        length = array.length,
 14549        result = Array(length);
 14550  
 14551    while (++index < length) {
 14552      result[index] = iteratee(array[index], index, array);
 14553    }
 14554    return result;
 14555  }
 14556  
 14557  module.exports = arrayMap;
 14558  
 14559  },{}],65:[function(require,module,exports){
 14560  /**
 14561   * A specialized version of `_.some` for arrays without support for callback
 14562   * shorthands and `this` binding.
 14563   *
 14564   * @private
 14565   * @param {Array} array The array to iterate over.
 14566   * @param {Function} predicate The function invoked per iteration.
 14567   * @returns {boolean} Returns `true` if any element passes the predicate check,
 14568   *  else `false`.
 14569   */
 14570  function arraySome(array, predicate) {
 14571    var index = -1,
 14572        length = array.length;
 14573  
 14574    while (++index < length) {
 14575      if (predicate(array[index], index, array)) {
 14576        return true;
 14577      }
 14578    }
 14579    return false;
 14580  }
 14581  
 14582  module.exports = arraySome;
 14583  
 14584  },{}],66:[function(require,module,exports){
 14585  var baseCopy = require('./baseCopy'),
 14586      keys = require('../object/keys');
 14587  
 14588  /**
 14589   * The base implementation of `_.assign` without support for argument juggling,
 14590   * multiple sources, and `customizer` functions.
 14591   *
 14592   * @private
 14593   * @param {Object} object The destination object.
 14594   * @param {Object} source The source object.
 14595   * @returns {Object} Returns `object`.
 14596   */
 14597  function baseAssign(object, source) {
 14598    return source == null
 14599      ? object
 14600      : baseCopy(source, keys(source), object);
 14601  }
 14602  
 14603  module.exports = baseAssign;
 14604  
 14605  },{"../object/keys":149,"./baseCopy":69}],67:[function(require,module,exports){
 14606  var baseMatches = require('./baseMatches'),
 14607      baseMatchesProperty = require('./baseMatchesProperty'),
 14608      bindCallback = require('./bindCallback'),
 14609      identity = require('../utility/identity'),
 14610      property = require('../utility/property');
 14611  
 14612  /**
 14613   * The base implementation of `_.callback` which supports specifying the
 14614   * number of arguments to provide to `func`.
 14615   *
 14616   * @private
 14617   * @param {*} [func=_.identity] The value to convert to a callback.
 14618   * @param {*} [thisArg] The `this` binding of `func`.
 14619   * @param {number} [argCount] The number of arguments to provide to `func`.
 14620   * @returns {Function} Returns the callback.
 14621   */
 14622  function baseCallback(func, thisArg, argCount) {
 14623    var type = typeof func;
 14624    if (type == 'function') {
 14625      return thisArg === undefined
 14626        ? func
 14627        : bindCallback(func, thisArg, argCount);
 14628    }
 14629    if (func == null) {
 14630      return identity;
 14631    }
 14632    if (type == 'object') {
 14633      return baseMatches(func);
 14634    }
 14635    return thisArg === undefined
 14636      ? property(func)
 14637      : baseMatchesProperty(func, thisArg);
 14638  }
 14639  
 14640  module.exports = baseCallback;
 14641  
 14642  },{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(require,module,exports){
 14643  var arrayCopy = require('./arrayCopy'),
 14644      arrayEach = require('./arrayEach'),
 14645      baseAssign = require('./baseAssign'),
 14646      baseForOwn = require('./baseForOwn'),
 14647      initCloneArray = require('./initCloneArray'),
 14648      initCloneByTag = require('./initCloneByTag'),
 14649      initCloneObject = require('./initCloneObject'),
 14650      isArray = require('../lang/isArray'),
 14651      isHostObject = require('./isHostObject'),
 14652      isObject = require('../lang/isObject');
 14653  
 14654  /** `Object#toString` result references. */
 14655  var argsTag = '[object Arguments]',
 14656      arrayTag = '[object Array]',
 14657      boolTag = '[object Boolean]',
 14658      dateTag = '[object Date]',
 14659      errorTag = '[object Error]',
 14660      funcTag = '[object Function]',
 14661      mapTag = '[object Map]',
 14662      numberTag = '[object Number]',
 14663      objectTag = '[object Object]',
 14664      regexpTag = '[object RegExp]',
 14665      setTag = '[object Set]',
 14666      stringTag = '[object String]',
 14667      weakMapTag = '[object WeakMap]';
 14668  
 14669  var arrayBufferTag = '[object ArrayBuffer]',
 14670      float32Tag = '[object Float32Array]',
 14671      float64Tag = '[object Float64Array]',
 14672      int8Tag = '[object Int8Array]',
 14673      int16Tag = '[object Int16Array]',
 14674      int32Tag = '[object Int32Array]',
 14675      uint8Tag = '[object Uint8Array]',
 14676      uint8ClampedTag = '[object Uint8ClampedArray]',
 14677      uint16Tag = '[object Uint16Array]',
 14678      uint32Tag = '[object Uint32Array]';
 14679  
 14680  /** Used to identify `toStringTag` values supported by `_.clone`. */
 14681  var cloneableTags = {};
 14682  cloneableTags[argsTag] = cloneableTags[arrayTag] =
 14683  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
 14684  cloneableTags[dateTag] = cloneableTags[float32Tag] =
 14685  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
 14686  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
 14687  cloneableTags[numberTag] = cloneableTags[objectTag] =
 14688  cloneableTags[regexpTag] = cloneableTags[stringTag] =
 14689  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
 14690  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
 14691  cloneableTags[errorTag] = cloneableTags[funcTag] =
 14692  cloneableTags[mapTag] = cloneableTags[setTag] =
 14693  cloneableTags[weakMapTag] = false;
 14694  
 14695  /** Used for native method references. */
 14696  var objectProto = Object.prototype;
 14697  
 14698  /**
 14699   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 14700   * of values.
 14701   */
 14702  var objToString = objectProto.toString;
 14703  
 14704  /**
 14705   * The base implementation of `_.clone` without support for argument juggling
 14706   * and `this` binding `customizer` functions.
 14707   *
 14708   * @private
 14709   * @param {*} value The value to clone.
 14710   * @param {boolean} [isDeep] Specify a deep clone.
 14711   * @param {Function} [customizer] The function to customize cloning values.
 14712   * @param {string} [key] The key of `value`.
 14713   * @param {Object} [object] The object `value` belongs to.
 14714   * @param {Array} [stackA=[]] Tracks traversed source objects.
 14715   * @param {Array} [stackB=[]] Associates clones with source counterparts.
 14716   * @returns {*} Returns the cloned value.
 14717   */
 14718  function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
 14719    var result;
 14720    if (customizer) {
 14721      result = object ? customizer(value, key, object) : customizer(value);
 14722    }
 14723    if (result !== undefined) {
 14724      return result;
 14725    }
 14726    if (!isObject(value)) {
 14727      return value;
 14728    }
 14729    var isArr = isArray(value);
 14730    if (isArr) {
 14731      result = initCloneArray(value);
 14732      if (!isDeep) {
 14733        return arrayCopy(value, result);
 14734      }
 14735    } else {
 14736      var tag = objToString.call(value),
 14737          isFunc = tag == funcTag;
 14738  
 14739      if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
 14740        if (isHostObject(value)) {
 14741          return object ? value : {};
 14742        }
 14743        result = initCloneObject(isFunc ? {} : value);
 14744        if (!isDeep) {
 14745          return baseAssign(result, value);
 14746        }
 14747      } else {
 14748        return cloneableTags[tag]
 14749          ? initCloneByTag(value, tag, isDeep)
 14750          : (object ? value : {});
 14751      }
 14752    }
 14753    // Check for circular references and return its corresponding clone.
 14754    stackA || (stackA = []);
 14755    stackB || (stackB = []);
 14756  
 14757    var length = stackA.length;
 14758    while (length--) {
 14759      if (stackA[length] == value) {
 14760        return stackB[length];
 14761      }
 14762    }
 14763    // Add the source value to the stack of traversed objects and associate it with its clone.
 14764    stackA.push(value);
 14765    stackB.push(result);
 14766  
 14767    // Recursively populate clone (susceptible to call stack limits).
 14768    (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
 14769      result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
 14770    });
 14771    return result;
 14772  }
 14773  
 14774  module.exports = baseClone;
 14775  
 14776  },{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(require,module,exports){
 14777  /**
 14778   * Copies properties of `source` to `object`.
 14779   *
 14780   * @private
 14781   * @param {Object} source The object to copy properties from.
 14782   * @param {Array} props The property names to copy.
 14783   * @param {Object} [object={}] The object to copy properties to.
 14784   * @returns {Object} Returns `object`.
 14785   */
 14786  function baseCopy(source, props, object) {
 14787    object || (object = {});
 14788  
 14789    var index = -1,
 14790        length = props.length;
 14791  
 14792    while (++index < length) {
 14793      var key = props[index];
 14794      object[key] = source[key];
 14795    }
 14796    return object;
 14797  }
 14798  
 14799  module.exports = baseCopy;
 14800  
 14801  },{}],70:[function(require,module,exports){
 14802  var isObject = require('../lang/isObject');
 14803  
 14804  /**
 14805   * The base implementation of `_.create` without support for assigning
 14806   * properties to the created object.
 14807   *
 14808   * @private
 14809   * @param {Object} prototype The object to inherit from.
 14810   * @returns {Object} Returns the new object.
 14811   */
 14812  var baseCreate = (function() {
 14813    function object() {}
 14814    return function(prototype) {
 14815      if (isObject(prototype)) {
 14816        object.prototype = prototype;
 14817        var result = new object;
 14818        object.prototype = undefined;
 14819      }
 14820      return result || {};
 14821    };
 14822  }());
 14823  
 14824  module.exports = baseCreate;
 14825  
 14826  },{"../lang/isObject":144}],71:[function(require,module,exports){
 14827  var baseForOwn = require('./baseForOwn'),
 14828      createBaseEach = require('./createBaseEach');
 14829  
 14830  /**
 14831   * The base implementation of `_.forEach` without support for callback
 14832   * shorthands and `this` binding.
 14833   *
 14834   * @private
 14835   * @param {Array|Object|string} collection The collection to iterate over.
 14836   * @param {Function} iteratee The function invoked per iteration.
 14837   * @returns {Array|Object|string} Returns `collection`.
 14838   */
 14839  var baseEach = createBaseEach(baseForOwn);
 14840  
 14841  module.exports = baseEach;
 14842  
 14843  },{"./baseForOwn":76,"./createBaseEach":98}],72:[function(require,module,exports){
 14844  /**
 14845   * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
 14846   * without support for callback shorthands and `this` binding, which iterates
 14847   * over `collection` using the provided `eachFunc`.
 14848   *
 14849   * @private
 14850   * @param {Array|Object|string} collection The collection to search.
 14851   * @param {Function} predicate The function invoked per iteration.
 14852   * @param {Function} eachFunc The function to iterate over `collection`.
 14853   * @param {boolean} [retKey] Specify returning the key of the found element
 14854   *  instead of the element itself.
 14855   * @returns {*} Returns the found element or its key, else `undefined`.
 14856   */
 14857  function baseFind(collection, predicate, eachFunc, retKey) {
 14858    var result;
 14859    eachFunc(collection, function(value, key, collection) {
 14860      if (predicate(value, key, collection)) {
 14861        result = retKey ? key : value;
 14862        return false;
 14863      }
 14864    });
 14865    return result;
 14866  }
 14867  
 14868  module.exports = baseFind;
 14869  
 14870  },{}],73:[function(require,module,exports){
 14871  /**
 14872   * The base implementation of `_.findIndex` and `_.findLastIndex` without
 14873   * support for callback shorthands and `this` binding.
 14874   *
 14875   * @private
 14876   * @param {Array} array The array to search.
 14877   * @param {Function} predicate The function invoked per iteration.
 14878   * @param {boolean} [fromRight] Specify iterating from right to left.
 14879   * @returns {number} Returns the index of the matched value, else `-1`.
 14880   */
 14881  function baseFindIndex(array, predicate, fromRight) {
 14882    var length = array.length,
 14883        index = fromRight ? length : -1;
 14884  
 14885    while ((fromRight ? index-- : ++index < length)) {
 14886      if (predicate(array[index], index, array)) {
 14887        return index;
 14888      }
 14889    }
 14890    return -1;
 14891  }
 14892  
 14893  module.exports = baseFindIndex;
 14894  
 14895  },{}],74:[function(require,module,exports){
 14896  var createBaseFor = require('./createBaseFor');
 14897  
 14898  /**
 14899   * The base implementation of `baseForIn` and `baseForOwn` which iterates
 14900   * over `object` properties returned by `keysFunc` invoking `iteratee` for
 14901   * each property. Iteratee functions may exit iteration early by explicitly
 14902   * returning `false`.
 14903   *
 14904   * @private
 14905   * @param {Object} object The object to iterate over.
 14906   * @param {Function} iteratee The function invoked per iteration.
 14907   * @param {Function} keysFunc The function to get the keys of `object`.
 14908   * @returns {Object} Returns `object`.
 14909   */
 14910  var baseFor = createBaseFor();
 14911  
 14912  module.exports = baseFor;
 14913  
 14914  },{"./createBaseFor":99}],75:[function(require,module,exports){
 14915  var baseFor = require('./baseFor'),
 14916      keysIn = require('../object/keysIn');
 14917  
 14918  /**
 14919   * The base implementation of `_.forIn` without support for callback
 14920   * shorthands and `this` binding.
 14921   *
 14922   * @private
 14923   * @param {Object} object The object to iterate over.
 14924   * @param {Function} iteratee The function invoked per iteration.
 14925   * @returns {Object} Returns `object`.
 14926   */
 14927  function baseForIn(object, iteratee) {
 14928    return baseFor(object, iteratee, keysIn);
 14929  }
 14930  
 14931  module.exports = baseForIn;
 14932  
 14933  },{"../object/keysIn":150,"./baseFor":74}],76:[function(require,module,exports){
 14934  var baseFor = require('./baseFor'),
 14935      keys = require('../object/keys');
 14936  
 14937  /**
 14938   * The base implementation of `_.forOwn` without support for callback
 14939   * shorthands and `this` binding.
 14940   *
 14941   * @private
 14942   * @param {Object} object The object to iterate over.
 14943   * @param {Function} iteratee The function invoked per iteration.
 14944   * @returns {Object} Returns `object`.
 14945   */
 14946  function baseForOwn(object, iteratee) {
 14947    return baseFor(object, iteratee, keys);
 14948  }
 14949  
 14950  module.exports = baseForOwn;
 14951  
 14952  },{"../object/keys":149,"./baseFor":74}],77:[function(require,module,exports){
 14953  var toObject = require('./toObject');
 14954  
 14955  /**
 14956   * The base implementation of `get` without support for string paths
 14957   * and default values.
 14958   *
 14959   * @private
 14960   * @param {Object} object The object to query.
 14961   * @param {Array} path The path of the property to get.
 14962   * @param {string} [pathKey] The key representation of path.
 14963   * @returns {*} Returns the resolved value.
 14964   */
 14965  function baseGet(object, path, pathKey) {
 14966    if (object == null) {
 14967      return;
 14968    }
 14969    object = toObject(object);
 14970    if (pathKey !== undefined && pathKey in object) {
 14971      path = [pathKey];
 14972    }
 14973    var index = 0,
 14974        length = path.length;
 14975  
 14976    while (object != null && index < length) {
 14977      object = toObject(object)[path[index++]];
 14978    }
 14979    return (index && index == length) ? object : undefined;
 14980  }
 14981  
 14982  module.exports = baseGet;
 14983  
 14984  },{"./toObject":135}],78:[function(require,module,exports){
 14985  var indexOfNaN = require('./indexOfNaN');
 14986  
 14987  /**
 14988   * The base implementation of `_.indexOf` without support for binary searches.
 14989   *
 14990   * @private
 14991   * @param {Array} array The array to search.
 14992   * @param {*} value The value to search for.
 14993   * @param {number} fromIndex The index to search from.
 14994   * @returns {number} Returns the index of the matched value, else `-1`.
 14995   */
 14996  function baseIndexOf(array, value, fromIndex) {
 14997    if (value !== value) {
 14998      return indexOfNaN(array, fromIndex);
 14999    }
 15000    var index = fromIndex - 1,
 15001        length = array.length;
 15002  
 15003    while (++index < length) {
 15004      if (array[index] === value) {
 15005        return index;
 15006      }
 15007    }
 15008    return -1;
 15009  }
 15010  
 15011  module.exports = baseIndexOf;
 15012  
 15013  },{"./indexOfNaN":115}],79:[function(require,module,exports){
 15014  var baseIsEqualDeep = require('./baseIsEqualDeep'),
 15015      isObject = require('../lang/isObject'),
 15016      isObjectLike = require('./isObjectLike');
 15017  
 15018  /**
 15019   * The base implementation of `_.isEqual` without support for `this` binding
 15020   * `customizer` functions.
 15021   *
 15022   * @private
 15023   * @param {*} value The value to compare.
 15024   * @param {*} other The other value to compare.
 15025   * @param {Function} [customizer] The function to customize comparing values.
 15026   * @param {boolean} [isLoose] Specify performing partial comparisons.
 15027   * @param {Array} [stackA] Tracks traversed `value` objects.
 15028   * @param {Array} [stackB] Tracks traversed `other` objects.
 15029   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 15030   */
 15031  function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
 15032    if (value === other) {
 15033      return true;
 15034    }
 15035    if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
 15036      return value !== value && other !== other;
 15037    }
 15038    return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
 15039  }
 15040  
 15041  module.exports = baseIsEqual;
 15042  
 15043  },{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(require,module,exports){
 15044  var equalArrays = require('./equalArrays'),
 15045      equalByTag = require('./equalByTag'),
 15046      equalObjects = require('./equalObjects'),
 15047      isArray = require('../lang/isArray'),
 15048      isHostObject = require('./isHostObject'),
 15049      isTypedArray = require('../lang/isTypedArray');
 15050  
 15051  /** `Object#toString` result references. */
 15052  var argsTag = '[object Arguments]',
 15053      arrayTag = '[object Array]',
 15054      objectTag = '[object Object]';
 15055  
 15056  /** Used for native method references. */
 15057  var objectProto = Object.prototype;
 15058  
 15059  /** Used to check objects for own properties. */
 15060  var hasOwnProperty = objectProto.hasOwnProperty;
 15061  
 15062  /**
 15063   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 15064   * of values.
 15065   */
 15066  var objToString = objectProto.toString;
 15067  
 15068  /**
 15069   * A specialized version of `baseIsEqual` for arrays and objects which performs
 15070   * deep comparisons and tracks traversed objects enabling objects with circular
 15071   * references to be compared.
 15072   *
 15073   * @private
 15074   * @param {Object} object The object to compare.
 15075   * @param {Object} other The other object to compare.
 15076   * @param {Function} equalFunc The function to determine equivalents of values.
 15077   * @param {Function} [customizer] The function to customize comparing objects.
 15078   * @param {boolean} [isLoose] Specify performing partial comparisons.
 15079   * @param {Array} [stackA=[]] Tracks traversed `value` objects.
 15080   * @param {Array} [stackB=[]] Tracks traversed `other` objects.
 15081   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 15082   */
 15083  function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
 15084    var objIsArr = isArray(object),
 15085        othIsArr = isArray(other),
 15086        objTag = arrayTag,
 15087        othTag = arrayTag;
 15088  
 15089    if (!objIsArr) {
 15090      objTag = objToString.call(object);
 15091      if (objTag == argsTag) {
 15092        objTag = objectTag;
 15093      } else if (objTag != objectTag) {
 15094        objIsArr = isTypedArray(object);
 15095      }
 15096    }
 15097    if (!othIsArr) {
 15098      othTag = objToString.call(other);
 15099      if (othTag == argsTag) {
 15100        othTag = objectTag;
 15101      } else if (othTag != objectTag) {
 15102        othIsArr = isTypedArray(other);
 15103      }
 15104    }
 15105    var objIsObj = objTag == objectTag && !isHostObject(object),
 15106        othIsObj = othTag == objectTag && !isHostObject(other),
 15107        isSameTag = objTag == othTag;
 15108  
 15109    if (isSameTag && !(objIsArr || objIsObj)) {
 15110      return equalByTag(object, other, objTag);
 15111    }
 15112    if (!isLoose) {
 15113      var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
 15114          othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
 15115  
 15116      if (objIsWrapped || othIsWrapped) {
 15117        return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
 15118      }
 15119    }
 15120    if (!isSameTag) {
 15121      return false;
 15122    }
 15123    // Assume cyclic values are equal.
 15124    // For more information on detecting circular references see https://es5.github.io/#JO.
 15125    stackA || (stackA = []);
 15126    stackB || (stackB = []);
 15127  
 15128    var length = stackA.length;
 15129    while (length--) {
 15130      if (stackA[length] == object) {
 15131        return stackB[length] == other;
 15132      }
 15133    }
 15134    // Add `object` and `other` to the stack of traversed objects.
 15135    stackA.push(object);
 15136    stackB.push(other);
 15137  
 15138    var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
 15139  
 15140    stackA.pop();
 15141    stackB.pop();
 15142  
 15143    return result;
 15144  }
 15145  
 15146  module.exports = baseIsEqualDeep;
 15147  
 15148  },{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(require,module,exports){
 15149  var baseIsEqual = require('./baseIsEqual'),
 15150      toObject = require('./toObject');
 15151  
 15152  /**
 15153   * The base implementation of `_.isMatch` without support for callback
 15154   * shorthands and `this` binding.
 15155   *
 15156   * @private
 15157   * @param {Object} object The object to inspect.
 15158   * @param {Array} matchData The propery names, values, and compare flags to match.
 15159   * @param {Function} [customizer] The function to customize comparing objects.
 15160   * @returns {boolean} Returns `true` if `object` is a match, else `false`.
 15161   */
 15162  function baseIsMatch(object, matchData, customizer) {
 15163    var index = matchData.length,
 15164        length = index,
 15165        noCustomizer = !customizer;
 15166  
 15167    if (object == null) {
 15168      return !length;
 15169    }
 15170    object = toObject(object);
 15171    while (index--) {
 15172      var data = matchData[index];
 15173      if ((noCustomizer && data[2])
 15174            ? data[1] !== object[data[0]]
 15175            : !(data[0] in object)
 15176          ) {
 15177        return false;
 15178      }
 15179    }
 15180    while (++index < length) {
 15181      data = matchData[index];
 15182      var key = data[0],
 15183          objValue = object[key],
 15184          srcValue = data[1];
 15185  
 15186      if (noCustomizer && data[2]) {
 15187        if (objValue === undefined && !(key in object)) {
 15188          return false;
 15189        }
 15190      } else {
 15191        var result = customizer ? customizer(objValue, srcValue, key) : undefined;
 15192        if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
 15193          return false;
 15194        }
 15195      }
 15196    }
 15197    return true;
 15198  }
 15199  
 15200  module.exports = baseIsMatch;
 15201  
 15202  },{"./baseIsEqual":79,"./toObject":135}],82:[function(require,module,exports){
 15203  /**
 15204   * The function whose prototype all chaining wrappers inherit from.
 15205   *
 15206   * @private
 15207   */
 15208  function baseLodash() {
 15209    // No operation performed.
 15210  }
 15211  
 15212  module.exports = baseLodash;
 15213  
 15214  },{}],83:[function(require,module,exports){
 15215  var baseEach = require('./baseEach'),
 15216      isArrayLike = require('./isArrayLike');
 15217  
 15218  /**
 15219   * The base implementation of `_.map` without support for callback shorthands
 15220   * and `this` binding.
 15221   *
 15222   * @private
 15223   * @param {Array|Object|string} collection The collection to iterate over.
 15224   * @param {Function} iteratee The function invoked per iteration.
 15225   * @returns {Array} Returns the new mapped array.
 15226   */
 15227  function baseMap(collection, iteratee) {
 15228    var index = -1,
 15229        result = isArrayLike(collection) ? Array(collection.length) : [];
 15230  
 15231    baseEach(collection, function(value, key, collection) {
 15232      result[++index] = iteratee(value, key, collection);
 15233    });
 15234    return result;
 15235  }
 15236  
 15237  module.exports = baseMap;
 15238  
 15239  },{"./baseEach":71,"./isArrayLike":119}],84:[function(require,module,exports){
 15240  var baseIsMatch = require('./baseIsMatch'),
 15241      getMatchData = require('./getMatchData'),
 15242      toObject = require('./toObject');
 15243  
 15244  /**
 15245   * The base implementation of `_.matches` which does not clone `source`.
 15246   *
 15247   * @private
 15248   * @param {Object} source The object of property values to match.
 15249   * @returns {Function} Returns the new function.
 15250   */
 15251  function baseMatches(source) {
 15252    var matchData = getMatchData(source);
 15253    if (matchData.length == 1 && matchData[0][2]) {
 15254      var key = matchData[0][0],
 15255          value = matchData[0][1];
 15256  
 15257      return function(object) {
 15258        if (object == null) {
 15259          return false;
 15260        }
 15261        object = toObject(object);
 15262        return object[key] === value && (value !== undefined || (key in object));
 15263      };
 15264    }
 15265    return function(object) {
 15266      return baseIsMatch(object, matchData);
 15267    };
 15268  }
 15269  
 15270  module.exports = baseMatches;
 15271  
 15272  },{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(require,module,exports){
 15273  var baseGet = require('./baseGet'),
 15274      baseIsEqual = require('./baseIsEqual'),
 15275      baseSlice = require('./baseSlice'),
 15276      isArray = require('../lang/isArray'),
 15277      isKey = require('./isKey'),
 15278      isStrictComparable = require('./isStrictComparable'),
 15279      last = require('../array/last'),
 15280      toObject = require('./toObject'),
 15281      toPath = require('./toPath');
 15282  
 15283  /**
 15284   * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
 15285   *
 15286   * @private
 15287   * @param {string} path The path of the property to get.
 15288   * @param {*} srcValue The value to compare.
 15289   * @returns {Function} Returns the new function.
 15290   */
 15291  function baseMatchesProperty(path, srcValue) {
 15292    var isArr = isArray(path),
 15293        isCommon = isKey(path) && isStrictComparable(srcValue),
 15294        pathKey = (path + '');
 15295  
 15296    path = toPath(path);
 15297    return function(object) {
 15298      if (object == null) {
 15299        return false;
 15300      }
 15301      var key = pathKey;
 15302      object = toObject(object);
 15303      if ((isArr || !isCommon) && !(key in object)) {
 15304        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
 15305        if (object == null) {
 15306          return false;
 15307        }
 15308        key = last(path);
 15309        object = toObject(object);
 15310      }
 15311      return object[key] === srcValue
 15312        ? (srcValue !== undefined || (key in object))
 15313        : baseIsEqual(srcValue, object[key], undefined, true);
 15314    };
 15315  }
 15316  
 15317  module.exports = baseMatchesProperty;
 15318  
 15319  },{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(require,module,exports){
 15320  var toObject = require('./toObject');
 15321  
 15322  /**
 15323   * The base implementation of `_.property` without support for deep paths.
 15324   *
 15325   * @private
 15326   * @param {string} key The key of the property to get.
 15327   * @returns {Function} Returns the new function.
 15328   */
 15329  function baseProperty(key) {
 15330    return function(object) {
 15331      return object == null ? undefined : toObject(object)[key];
 15332    };
 15333  }
 15334  
 15335  module.exports = baseProperty;
 15336  
 15337  },{"./toObject":135}],87:[function(require,module,exports){
 15338  var baseGet = require('./baseGet'),
 15339      toPath = require('./toPath');
 15340  
 15341  /**
 15342   * A specialized version of `baseProperty` which supports deep paths.
 15343   *
 15344   * @private
 15345   * @param {Array|string} path The path of the property to get.
 15346   * @returns {Function} Returns the new function.
 15347   */
 15348  function basePropertyDeep(path) {
 15349    var pathKey = (path + '');
 15350    path = toPath(path);
 15351    return function(object) {
 15352      return baseGet(object, path, pathKey);
 15353    };
 15354  }
 15355  
 15356  module.exports = basePropertyDeep;
 15357  
 15358  },{"./baseGet":77,"./toPath":136}],88:[function(require,module,exports){
 15359  var identity = require('../utility/identity'),
 15360      metaMap = require('./metaMap');
 15361  
 15362  /**
 15363   * The base implementation of `setData` without support for hot loop detection.
 15364   *
 15365   * @private
 15366   * @param {Function} func The function to associate metadata with.
 15367   * @param {*} data The metadata.
 15368   * @returns {Function} Returns `func`.
 15369   */
 15370  var baseSetData = !metaMap ? identity : function(func, data) {
 15371    metaMap.set(func, data);
 15372    return func;
 15373  };
 15374  
 15375  module.exports = baseSetData;
 15376  
 15377  },{"../utility/identity":154,"./metaMap":129}],89:[function(require,module,exports){
 15378  /**
 15379   * The base implementation of `_.slice` without an iteratee call guard.
 15380   *
 15381   * @private
 15382   * @param {Array} array The array to slice.
 15383   * @param {number} [start=0] The start position.
 15384   * @param {number} [end=array.length] The end position.
 15385   * @returns {Array} Returns the slice of `array`.
 15386   */
 15387  function baseSlice(array, start, end) {
 15388    var index = -1,
 15389        length = array.length;
 15390  
 15391    start = start == null ? 0 : (+start || 0);
 15392    if (start < 0) {
 15393      start = -start > length ? 0 : (length + start);
 15394    }
 15395    end = (end === undefined || end > length) ? length : (+end || 0);
 15396    if (end < 0) {
 15397      end += length;
 15398    }
 15399    length = start > end ? 0 : ((end - start) >>> 0);
 15400    start >>>= 0;
 15401  
 15402    var result = Array(length);
 15403    while (++index < length) {
 15404      result[index] = array[index + start];
 15405    }
 15406    return result;
 15407  }
 15408  
 15409  module.exports = baseSlice;
 15410  
 15411  },{}],90:[function(require,module,exports){
 15412  /**
 15413   * Converts `value` to a string if it's not one. An empty string is returned
 15414   * for `null` or `undefined` values.
 15415   *
 15416   * @private
 15417   * @param {*} value The value to process.
 15418   * @returns {string} Returns the string.
 15419   */
 15420  function baseToString(value) {
 15421    return value == null ? '' : (value + '');
 15422  }
 15423  
 15424  module.exports = baseToString;
 15425  
 15426  },{}],91:[function(require,module,exports){
 15427  /**
 15428   * The base implementation of `_.values` and `_.valuesIn` which creates an
 15429   * array of `object` property values corresponding to the property names
 15430   * of `props`.
 15431   *
 15432   * @private
 15433   * @param {Object} object The object to query.
 15434   * @param {Array} props The property names to get values for.
 15435   * @returns {Object} Returns the array of property values.
 15436   */
 15437  function baseValues(object, props) {
 15438    var index = -1,
 15439        length = props.length,
 15440        result = Array(length);
 15441  
 15442    while (++index < length) {
 15443      result[index] = object[props[index]];
 15444    }
 15445    return result;
 15446  }
 15447  
 15448  module.exports = baseValues;
 15449  
 15450  },{}],92:[function(require,module,exports){
 15451  var binaryIndexBy = require('./binaryIndexBy'),
 15452      identity = require('../utility/identity');
 15453  
 15454  /** Used as references for the maximum length and index of an array. */
 15455  var MAX_ARRAY_LENGTH = 4294967295,
 15456      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
 15457  
 15458  /**
 15459   * Performs a binary search of `array` to determine the index at which `value`
 15460   * should be inserted into `array` in order to maintain its sort order.
 15461   *
 15462   * @private
 15463   * @param {Array} array The sorted array to inspect.
 15464   * @param {*} value The value to evaluate.
 15465   * @param {boolean} [retHighest] Specify returning the highest qualified index.
 15466   * @returns {number} Returns the index at which `value` should be inserted
 15467   *  into `array`.
 15468   */
 15469  function binaryIndex(array, value, retHighest) {
 15470    var low = 0,
 15471        high = array ? array.length : low;
 15472  
 15473    if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
 15474      while (low < high) {
 15475        var mid = (low + high) >>> 1,
 15476            computed = array[mid];
 15477  
 15478        if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
 15479          low = mid + 1;
 15480        } else {
 15481          high = mid;
 15482        }
 15483      }
 15484      return high;
 15485    }
 15486    return binaryIndexBy(array, value, identity, retHighest);
 15487  }
 15488  
 15489  module.exports = binaryIndex;
 15490  
 15491  },{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(require,module,exports){
 15492  /* Native method references for those with the same name as other `lodash` methods. */
 15493  var nativeFloor = Math.floor,
 15494      nativeMin = Math.min;
 15495  
 15496  /** Used as references for the maximum length and index of an array. */
 15497  var MAX_ARRAY_LENGTH = 4294967295,
 15498      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
 15499  
 15500  /**
 15501   * This function is like `binaryIndex` except that it invokes `iteratee` for
 15502   * `value` and each element of `array` to compute their sort ranking. The
 15503   * iteratee is invoked with one argument; (value).
 15504   *
 15505   * @private
 15506   * @param {Array} array The sorted array to inspect.
 15507   * @param {*} value The value to evaluate.
 15508   * @param {Function} iteratee The function invoked per iteration.
 15509   * @param {boolean} [retHighest] Specify returning the highest qualified index.
 15510   * @returns {number} Returns the index at which `value` should be inserted
 15511   *  into `array`.
 15512   */
 15513  function binaryIndexBy(array, value, iteratee, retHighest) {
 15514    value = iteratee(value);
 15515  
 15516    var low = 0,
 15517        high = array ? array.length : 0,
 15518        valIsNaN = value !== value,
 15519        valIsNull = value === null,
 15520        valIsUndef = value === undefined;
 15521  
 15522    while (low < high) {
 15523      var mid = nativeFloor((low + high) / 2),
 15524          computed = iteratee(array[mid]),
 15525          isDef = computed !== undefined,
 15526          isReflexive = computed === computed;
 15527  
 15528      if (valIsNaN) {
 15529        var setLow = isReflexive || retHighest;
 15530      } else if (valIsNull) {
 15531        setLow = isReflexive && isDef && (retHighest || computed != null);
 15532      } else if (valIsUndef) {
 15533        setLow = isReflexive && (retHighest || isDef);
 15534      } else if (computed == null) {
 15535        setLow = false;
 15536      } else {
 15537        setLow = retHighest ? (computed <= value) : (computed < value);
 15538      }
 15539      if (setLow) {
 15540        low = mid + 1;
 15541      } else {
 15542        high = mid;
 15543      }
 15544    }
 15545    return nativeMin(high, MAX_ARRAY_INDEX);
 15546  }
 15547  
 15548  module.exports = binaryIndexBy;
 15549  
 15550  },{}],94:[function(require,module,exports){
 15551  var identity = require('../utility/identity');
 15552  
 15553  /**
 15554   * A specialized version of `baseCallback` which only supports `this` binding
 15555   * and specifying the number of arguments to provide to `func`.
 15556   *
 15557   * @private
 15558   * @param {Function} func The function to bind.
 15559   * @param {*} thisArg The `this` binding of `func`.
 15560   * @param {number} [argCount] The number of arguments to provide to `func`.
 15561   * @returns {Function} Returns the callback.
 15562   */
 15563  function bindCallback(func, thisArg, argCount) {
 15564    if (typeof func != 'function') {
 15565      return identity;
 15566    }
 15567    if (thisArg === undefined) {
 15568      return func;
 15569    }
 15570    switch (argCount) {
 15571      case 1: return function(value) {
 15572        return func.call(thisArg, value);
 15573      };
 15574      case 3: return function(value, index, collection) {
 15575        return func.call(thisArg, value, index, collection);
 15576      };
 15577      case 4: return function(accumulator, value, index, collection) {
 15578        return func.call(thisArg, accumulator, value, index, collection);
 15579      };
 15580      case 5: return function(value, other, key, object, source) {
 15581        return func.call(thisArg, value, other, key, object, source);
 15582      };
 15583    }
 15584    return function() {
 15585      return func.apply(thisArg, arguments);
 15586    };
 15587  }
 15588  
 15589  module.exports = bindCallback;
 15590  
 15591  },{"../utility/identity":154}],95:[function(require,module,exports){
 15592  (function (global){
 15593  /** Native method references. */
 15594  var ArrayBuffer = global.ArrayBuffer,
 15595      Uint8Array = global.Uint8Array;
 15596  
 15597  /**
 15598   * Creates a clone of the given array buffer.
 15599   *
 15600   * @private
 15601   * @param {ArrayBuffer} buffer The array buffer to clone.
 15602   * @returns {ArrayBuffer} Returns the cloned array buffer.
 15603   */
 15604  function bufferClone(buffer) {
 15605    var result = new ArrayBuffer(buffer.byteLength),
 15606        view = new Uint8Array(result);
 15607  
 15608    view.set(new Uint8Array(buffer));
 15609    return result;
 15610  }
 15611  
 15612  module.exports = bufferClone;
 15613  
 15614  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 15615  
 15616  },{}],96:[function(require,module,exports){
 15617  /* Native method references for those with the same name as other `lodash` methods. */
 15618  var nativeMax = Math.max;
 15619  
 15620  /**
 15621   * Creates an array that is the composition of partially applied arguments,
 15622   * placeholders, and provided arguments into a single array of arguments.
 15623   *
 15624   * @private
 15625   * @param {Array|Object} args The provided arguments.
 15626   * @param {Array} partials The arguments to prepend to those provided.
 15627   * @param {Array} holders The `partials` placeholder indexes.
 15628   * @returns {Array} Returns the new array of composed arguments.
 15629   */
 15630  function composeArgs(args, partials, holders) {
 15631    var holdersLength = holders.length,
 15632        argsIndex = -1,
 15633        argsLength = nativeMax(args.length - holdersLength, 0),
 15634        leftIndex = -1,
 15635        leftLength = partials.length,
 15636        result = Array(leftLength + argsLength);
 15637  
 15638    while (++leftIndex < leftLength) {
 15639      result[leftIndex] = partials[leftIndex];
 15640    }
 15641    while (++argsIndex < holdersLength) {
 15642      result[holders[argsIndex]] = args[argsIndex];
 15643    }
 15644    while (argsLength--) {
 15645      result[leftIndex++] = args[argsIndex++];
 15646    }
 15647    return result;
 15648  }
 15649  
 15650  module.exports = composeArgs;
 15651  
 15652  },{}],97:[function(require,module,exports){
 15653  /* Native method references for those with the same name as other `lodash` methods. */
 15654  var nativeMax = Math.max;
 15655  
 15656  /**
 15657   * This function is like `composeArgs` except that the arguments composition
 15658   * is tailored for `_.partialRight`.
 15659   *
 15660   * @private
 15661   * @param {Array|Object} args The provided arguments.
 15662   * @param {Array} partials The arguments to append to those provided.
 15663   * @param {Array} holders The `partials` placeholder indexes.
 15664   * @returns {Array} Returns the new array of composed arguments.
 15665   */
 15666  function composeArgsRight(args, partials, holders) {
 15667    var holdersIndex = -1,
 15668        holdersLength = holders.length,
 15669        argsIndex = -1,
 15670        argsLength = nativeMax(args.length - holdersLength, 0),
 15671        rightIndex = -1,
 15672        rightLength = partials.length,
 15673        result = Array(argsLength + rightLength);
 15674  
 15675    while (++argsIndex < argsLength) {
 15676      result[argsIndex] = args[argsIndex];
 15677    }
 15678    var offset = argsIndex;
 15679    while (++rightIndex < rightLength) {
 15680      result[offset + rightIndex] = partials[rightIndex];
 15681    }
 15682    while (++holdersIndex < holdersLength) {
 15683      result[offset + holders[holdersIndex]] = args[argsIndex++];
 15684    }
 15685    return result;
 15686  }
 15687  
 15688  module.exports = composeArgsRight;
 15689  
 15690  },{}],98:[function(require,module,exports){
 15691  var getLength = require('./getLength'),
 15692      isLength = require('./isLength'),
 15693      toObject = require('./toObject');
 15694  
 15695  /**
 15696   * Creates a `baseEach` or `baseEachRight` function.
 15697   *
 15698   * @private
 15699   * @param {Function} eachFunc The function to iterate over a collection.
 15700   * @param {boolean} [fromRight] Specify iterating from right to left.
 15701   * @returns {Function} Returns the new base function.
 15702   */
 15703  function createBaseEach(eachFunc, fromRight) {
 15704    return function(collection, iteratee) {
 15705      var length = collection ? getLength(collection) : 0;
 15706      if (!isLength(length)) {
 15707        return eachFunc(collection, iteratee);
 15708      }
 15709      var index = fromRight ? length : -1,
 15710          iterable = toObject(collection);
 15711  
 15712      while ((fromRight ? index-- : ++index < length)) {
 15713        if (iteratee(iterable[index], index, iterable) === false) {
 15714          break;
 15715        }
 15716      }
 15717      return collection;
 15718    };
 15719  }
 15720  
 15721  module.exports = createBaseEach;
 15722  
 15723  },{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(require,module,exports){
 15724  var toObject = require('./toObject');
 15725  
 15726  /**
 15727   * Creates a base function for `_.forIn` or `_.forInRight`.
 15728   *
 15729   * @private
 15730   * @param {boolean} [fromRight] Specify iterating from right to left.
 15731   * @returns {Function} Returns the new base function.
 15732   */
 15733  function createBaseFor(fromRight) {
 15734    return function(object, iteratee, keysFunc) {
 15735      var iterable = toObject(object),
 15736          props = keysFunc(object),
 15737          length = props.length,
 15738          index = fromRight ? length : -1;
 15739  
 15740      while ((fromRight ? index-- : ++index < length)) {
 15741        var key = props[index];
 15742        if (iteratee(iterable[key], key, iterable) === false) {
 15743          break;
 15744        }
 15745      }
 15746      return object;
 15747    };
 15748  }
 15749  
 15750  module.exports = createBaseFor;
 15751  
 15752  },{"./toObject":135}],100:[function(require,module,exports){
 15753  (function (global){
 15754  var createCtorWrapper = require('./createCtorWrapper');
 15755  
 15756  /**
 15757   * Creates a function that wraps `func` and invokes it with the `this`
 15758   * binding of `thisArg`.
 15759   *
 15760   * @private
 15761   * @param {Function} func The function to bind.
 15762   * @param {*} [thisArg] The `this` binding of `func`.
 15763   * @returns {Function} Returns the new bound function.
 15764   */
 15765  function createBindWrapper(func, thisArg) {
 15766    var Ctor = createCtorWrapper(func);
 15767  
 15768    function wrapper() {
 15769      var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
 15770      return fn.apply(thisArg, arguments);
 15771    }
 15772    return wrapper;
 15773  }
 15774  
 15775  module.exports = createBindWrapper;
 15776  
 15777  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 15778  
 15779  },{"./createCtorWrapper":101}],101:[function(require,module,exports){
 15780  var baseCreate = require('./baseCreate'),
 15781      isObject = require('../lang/isObject');
 15782  
 15783  /**
 15784   * Creates a function that produces an instance of `Ctor` regardless of
 15785   * whether it was invoked as part of a `new` expression or by `call` or `apply`.
 15786   *
 15787   * @private
 15788   * @param {Function} Ctor The constructor to wrap.
 15789   * @returns {Function} Returns the new wrapped function.
 15790   */
 15791  function createCtorWrapper(Ctor) {
 15792    return function() {
 15793      // Use a `switch` statement to work with class constructors.
 15794      // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
 15795      // for more details.
 15796      var args = arguments;
 15797      switch (args.length) {
 15798        case 0: return new Ctor;
 15799        case 1: return new Ctor(args[0]);
 15800        case 2: return new Ctor(args[0], args[1]);
 15801        case 3: return new Ctor(args[0], args[1], args[2]);
 15802        case 4: return new Ctor(args[0], args[1], args[2], args[3]);
 15803        case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
 15804        case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
 15805        case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
 15806      }
 15807      var thisBinding = baseCreate(Ctor.prototype),
 15808          result = Ctor.apply(thisBinding, args);
 15809  
 15810      // Mimic the constructor's `return` behavior.
 15811      // See https://es5.github.io/#x13.2.2 for more details.
 15812      return isObject(result) ? result : thisBinding;
 15813    };
 15814  }
 15815  
 15816  module.exports = createCtorWrapper;
 15817  
 15818  },{"../lang/isObject":144,"./baseCreate":70}],102:[function(require,module,exports){
 15819  var baseCallback = require('./baseCallback'),
 15820      baseFind = require('./baseFind'),
 15821      baseFindIndex = require('./baseFindIndex'),
 15822      isArray = require('../lang/isArray');
 15823  
 15824  /**
 15825   * Creates a `_.find` or `_.findLast` function.
 15826   *
 15827   * @private
 15828   * @param {Function} eachFunc The function to iterate over a collection.
 15829   * @param {boolean} [fromRight] Specify iterating from right to left.
 15830   * @returns {Function} Returns the new find function.
 15831   */
 15832  function createFind(eachFunc, fromRight) {
 15833    return function(collection, predicate, thisArg) {
 15834      predicate = baseCallback(predicate, thisArg, 3);
 15835      if (isArray(collection)) {
 15836        var index = baseFindIndex(collection, predicate, fromRight);
 15837        return index > -1 ? collection[index] : undefined;
 15838      }
 15839      return baseFind(collection, predicate, eachFunc);
 15840    };
 15841  }
 15842  
 15843  module.exports = createFind;
 15844  
 15845  },{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(require,module,exports){
 15846  var bindCallback = require('./bindCallback'),
 15847      isArray = require('../lang/isArray');
 15848  
 15849  /**
 15850   * Creates a function for `_.forEach` or `_.forEachRight`.
 15851   *
 15852   * @private
 15853   * @param {Function} arrayFunc The function to iterate over an array.
 15854   * @param {Function} eachFunc The function to iterate over a collection.
 15855   * @returns {Function} Returns the new each function.
 15856   */
 15857  function createForEach(arrayFunc, eachFunc) {
 15858    return function(collection, iteratee, thisArg) {
 15859      return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
 15860        ? arrayFunc(collection, iteratee)
 15861        : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
 15862    };
 15863  }
 15864  
 15865  module.exports = createForEach;
 15866  
 15867  },{"../lang/isArray":140,"./bindCallback":94}],104:[function(require,module,exports){
 15868  (function (global){
 15869  var arrayCopy = require('./arrayCopy'),
 15870      composeArgs = require('./composeArgs'),
 15871      composeArgsRight = require('./composeArgsRight'),
 15872      createCtorWrapper = require('./createCtorWrapper'),
 15873      isLaziable = require('./isLaziable'),
 15874      reorder = require('./reorder'),
 15875      replaceHolders = require('./replaceHolders'),
 15876      setData = require('./setData');
 15877  
 15878  /** Used to compose bitmasks for wrapper metadata. */
 15879  var BIND_FLAG = 1,
 15880      BIND_KEY_FLAG = 2,
 15881      CURRY_BOUND_FLAG = 4,
 15882      CURRY_FLAG = 8,
 15883      CURRY_RIGHT_FLAG = 16,
 15884      PARTIAL_FLAG = 32,
 15885      PARTIAL_RIGHT_FLAG = 64,
 15886      ARY_FLAG = 128;
 15887  
 15888  /* Native method references for those with the same name as other `lodash` methods. */
 15889  var nativeMax = Math.max;
 15890  
 15891  /**
 15892   * Creates a function that wraps `func` and invokes it with optional `this`
 15893   * binding of, partial application, and currying.
 15894   *
 15895   * @private
 15896   * @param {Function|string} func The function or method name to reference.
 15897   * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
 15898   * @param {*} [thisArg] The `this` binding of `func`.
 15899   * @param {Array} [partials] The arguments to prepend to those provided to the new function.
 15900   * @param {Array} [holders] The `partials` placeholder indexes.
 15901   * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
 15902   * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
 15903   * @param {Array} [argPos] The argument positions of the new function.
 15904   * @param {number} [ary] The arity cap of `func`.
 15905   * @param {number} [arity] The arity of `func`.
 15906   * @returns {Function} Returns the new wrapped function.
 15907   */
 15908  function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
 15909    var isAry = bitmask & ARY_FLAG,
 15910        isBind = bitmask & BIND_FLAG,
 15911        isBindKey = bitmask & BIND_KEY_FLAG,
 15912        isCurry = bitmask & CURRY_FLAG,
 15913        isCurryBound = bitmask & CURRY_BOUND_FLAG,
 15914        isCurryRight = bitmask & CURRY_RIGHT_FLAG,
 15915        Ctor = isBindKey ? undefined : createCtorWrapper(func);
 15916  
 15917    function wrapper() {
 15918      // Avoid `arguments` object use disqualifying optimizations by
 15919      // converting it to an array before providing it to other functions.
 15920      var length = arguments.length,
 15921          index = length,
 15922          args = Array(length);
 15923  
 15924      while (index--) {
 15925        args[index] = arguments[index];
 15926      }
 15927      if (partials) {
 15928        args = composeArgs(args, partials, holders);
 15929      }
 15930      if (partialsRight) {
 15931        args = composeArgsRight(args, partialsRight, holdersRight);
 15932      }
 15933      if (isCurry || isCurryRight) {
 15934        var placeholder = wrapper.placeholder,
 15935            argsHolders = replaceHolders(args, placeholder);
 15936  
 15937        length -= argsHolders.length;
 15938        if (length < arity) {
 15939          var newArgPos = argPos ? arrayCopy(argPos) : undefined,
 15940              newArity = nativeMax(arity - length, 0),
 15941              newsHolders = isCurry ? argsHolders : undefined,
 15942              newHoldersRight = isCurry ? undefined : argsHolders,
 15943              newPartials = isCurry ? args : undefined,
 15944              newPartialsRight = isCurry ? undefined : args;
 15945  
 15946          bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
 15947          bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
 15948  
 15949          if (!isCurryBound) {
 15950            bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
 15951          }
 15952          var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
 15953              result = createHybridWrapper.apply(undefined, newData);
 15954  
 15955          if (isLaziable(func)) {
 15956            setData(result, newData);
 15957          }
 15958          result.placeholder = placeholder;
 15959          return result;
 15960        }
 15961      }
 15962      var thisBinding = isBind ? thisArg : this,
 15963          fn = isBindKey ? thisBinding[func] : func;
 15964  
 15965      if (argPos) {
 15966        args = reorder(args, argPos);
 15967      }
 15968      if (isAry && ary < args.length) {
 15969        args.length = ary;
 15970      }
 15971      if (this && this !== global && this instanceof wrapper) {
 15972        fn = Ctor || createCtorWrapper(func);
 15973      }
 15974      return fn.apply(thisBinding, args);
 15975    }
 15976    return wrapper;
 15977  }
 15978  
 15979  module.exports = createHybridWrapper;
 15980  
 15981  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 15982  
 15983  },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(require,module,exports){
 15984  (function (global){
 15985  var createCtorWrapper = require('./createCtorWrapper');
 15986  
 15987  /** Used to compose bitmasks for wrapper metadata. */
 15988  var BIND_FLAG = 1;
 15989  
 15990  /**
 15991   * Creates a function that wraps `func` and invokes it with the optional `this`
 15992   * binding of `thisArg` and the `partials` prepended to those provided to
 15993   * the wrapper.
 15994   *
 15995   * @private
 15996   * @param {Function} func The function to partially apply arguments to.
 15997   * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
 15998   * @param {*} thisArg The `this` binding of `func`.
 15999   * @param {Array} partials The arguments to prepend to those provided to the new function.
 16000   * @returns {Function} Returns the new bound function.
 16001   */
 16002  function createPartialWrapper(func, bitmask, thisArg, partials) {
 16003    var isBind = bitmask & BIND_FLAG,
 16004        Ctor = createCtorWrapper(func);
 16005  
 16006    function wrapper() {
 16007      // Avoid `arguments` object use disqualifying optimizations by
 16008      // converting it to an array before providing it `func`.
 16009      var argsIndex = -1,
 16010          argsLength = arguments.length,
 16011          leftIndex = -1,
 16012          leftLength = partials.length,
 16013          args = Array(leftLength + argsLength);
 16014  
 16015      while (++leftIndex < leftLength) {
 16016        args[leftIndex] = partials[leftIndex];
 16017      }
 16018      while (argsLength--) {
 16019        args[leftIndex++] = arguments[++argsIndex];
 16020      }
 16021      var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
 16022      return fn.apply(isBind ? thisArg : this, args);
 16023    }
 16024    return wrapper;
 16025  }
 16026  
 16027  module.exports = createPartialWrapper;
 16028  
 16029  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 16030  
 16031  },{"./createCtorWrapper":101}],106:[function(require,module,exports){
 16032  var baseSetData = require('./baseSetData'),
 16033      createBindWrapper = require('./createBindWrapper'),
 16034      createHybridWrapper = require('./createHybridWrapper'),
 16035      createPartialWrapper = require('./createPartialWrapper'),
 16036      getData = require('./getData'),
 16037      mergeData = require('./mergeData'),
 16038      setData = require('./setData');
 16039  
 16040  /** Used to compose bitmasks for wrapper metadata. */
 16041  var BIND_FLAG = 1,
 16042      BIND_KEY_FLAG = 2,
 16043      PARTIAL_FLAG = 32,
 16044      PARTIAL_RIGHT_FLAG = 64;
 16045  
 16046  /** Used as the `TypeError` message for "Functions" methods. */
 16047  var FUNC_ERROR_TEXT = 'Expected a function';
 16048  
 16049  /* Native method references for those with the same name as other `lodash` methods. */
 16050  var nativeMax = Math.max;
 16051  
 16052  /**
 16053   * Creates a function that either curries or invokes `func` with optional
 16054   * `this` binding and partially applied arguments.
 16055   *
 16056   * @private
 16057   * @param {Function|string} func The function or method name to reference.
 16058   * @param {number} bitmask The bitmask of flags.
 16059   *  The bitmask may be composed of the following flags:
 16060   *     1 - `_.bind`
 16061   *     2 - `_.bindKey`
 16062   *     4 - `_.curry` or `_.curryRight` of a bound function
 16063   *     8 - `_.curry`
 16064   *    16 - `_.curryRight`
 16065   *    32 - `_.partial`
 16066   *    64 - `_.partialRight`
 16067   *   128 - `_.rearg`
 16068   *   256 - `_.ary`
 16069   * @param {*} [thisArg] The `this` binding of `func`.
 16070   * @param {Array} [partials] The arguments to be partially applied.
 16071   * @param {Array} [holders] The `partials` placeholder indexes.
 16072   * @param {Array} [argPos] The argument positions of the new function.
 16073   * @param {number} [ary] The arity cap of `func`.
 16074   * @param {number} [arity] The arity of `func`.
 16075   * @returns {Function} Returns the new wrapped function.
 16076   */
 16077  function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
 16078    var isBindKey = bitmask & BIND_KEY_FLAG;
 16079    if (!isBindKey && typeof func != 'function') {
 16080      throw new TypeError(FUNC_ERROR_TEXT);
 16081    }
 16082    var length = partials ? partials.length : 0;
 16083    if (!length) {
 16084      bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
 16085      partials = holders = undefined;
 16086    }
 16087    length -= (holders ? holders.length : 0);
 16088    if (bitmask & PARTIAL_RIGHT_FLAG) {
 16089      var partialsRight = partials,
 16090          holdersRight = holders;
 16091  
 16092      partials = holders = undefined;
 16093    }
 16094    var data = isBindKey ? undefined : getData(func),
 16095        newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
 16096  
 16097    if (data) {
 16098      mergeData(newData, data);
 16099      bitmask = newData[1];
 16100      arity = newData[9];
 16101    }
 16102    newData[9] = arity == null
 16103      ? (isBindKey ? 0 : func.length)
 16104      : (nativeMax(arity - length, 0) || 0);
 16105  
 16106    if (bitmask == BIND_FLAG) {
 16107      var result = createBindWrapper(newData[0], newData[2]);
 16108    } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
 16109      result = createPartialWrapper.apply(undefined, newData);
 16110    } else {
 16111      result = createHybridWrapper.apply(undefined, newData);
 16112    }
 16113    var setter = data ? baseSetData : setData;
 16114    return setter(result, newData);
 16115  }
 16116  
 16117  module.exports = createWrapper;
 16118  
 16119  },{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(require,module,exports){
 16120  var arraySome = require('./arraySome');
 16121  
 16122  /**
 16123   * A specialized version of `baseIsEqualDeep` for arrays with support for
 16124   * partial deep comparisons.
 16125   *
 16126   * @private
 16127   * @param {Array} array The array to compare.
 16128   * @param {Array} other The other array to compare.
 16129   * @param {Function} equalFunc The function to determine equivalents of values.
 16130   * @param {Function} [customizer] The function to customize comparing arrays.
 16131   * @param {boolean} [isLoose] Specify performing partial comparisons.
 16132   * @param {Array} [stackA] Tracks traversed `value` objects.
 16133   * @param {Array} [stackB] Tracks traversed `other` objects.
 16134   * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
 16135   */
 16136  function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
 16137    var index = -1,
 16138        arrLength = array.length,
 16139        othLength = other.length;
 16140  
 16141    if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
 16142      return false;
 16143    }
 16144    // Ignore non-index properties.
 16145    while (++index < arrLength) {
 16146      var arrValue = array[index],
 16147          othValue = other[index],
 16148          result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
 16149  
 16150      if (result !== undefined) {
 16151        if (result) {
 16152          continue;
 16153        }
 16154        return false;
 16155      }
 16156      // Recursively compare arrays (susceptible to call stack limits).
 16157      if (isLoose) {
 16158        if (!arraySome(other, function(othValue) {
 16159              return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
 16160            })) {
 16161          return false;
 16162        }
 16163      } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
 16164        return false;
 16165      }
 16166    }
 16167    return true;
 16168  }
 16169  
 16170  module.exports = equalArrays;
 16171  
 16172  },{"./arraySome":65}],108:[function(require,module,exports){
 16173  /** `Object#toString` result references. */
 16174  var boolTag = '[object Boolean]',
 16175      dateTag = '[object Date]',
 16176      errorTag = '[object Error]',
 16177      numberTag = '[object Number]',
 16178      regexpTag = '[object RegExp]',
 16179      stringTag = '[object String]';
 16180  
 16181  /**
 16182   * A specialized version of `baseIsEqualDeep` for comparing objects of
 16183   * the same `toStringTag`.
 16184   *
 16185   * **Note:** This function only supports comparing values with tags of
 16186   * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
 16187   *
 16188   * @private
 16189   * @param {Object} object The object to compare.
 16190   * @param {Object} other The other object to compare.
 16191   * @param {string} tag The `toStringTag` of the objects to compare.
 16192   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 16193   */
 16194  function equalByTag(object, other, tag) {
 16195    switch (tag) {
 16196      case boolTag:
 16197      case dateTag:
 16198        // Coerce dates and booleans to numbers, dates to milliseconds and booleans
 16199        // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
 16200        return +object == +other;
 16201  
 16202      case errorTag:
 16203        return object.name == other.name && object.message == other.message;
 16204  
 16205      case numberTag:
 16206        // Treat `NaN` vs. `NaN` as equal.
 16207        return (object != +object)
 16208          ? other != +other
 16209          : object == +other;
 16210  
 16211      case regexpTag:
 16212      case stringTag:
 16213        // Coerce regexes to strings and treat strings primitives and string
 16214        // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
 16215        return object == (other + '');
 16216    }
 16217    return false;
 16218  }
 16219  
 16220  module.exports = equalByTag;
 16221  
 16222  },{}],109:[function(require,module,exports){
 16223  var keys = require('../object/keys');
 16224  
 16225  /** Used for native method references. */
 16226  var objectProto = Object.prototype;
 16227  
 16228  /** Used to check objects for own properties. */
 16229  var hasOwnProperty = objectProto.hasOwnProperty;
 16230  
 16231  /**
 16232   * A specialized version of `baseIsEqualDeep` for objects with support for
 16233   * partial deep comparisons.
 16234   *
 16235   * @private
 16236   * @param {Object} object The object to compare.
 16237   * @param {Object} other The other object to compare.
 16238   * @param {Function} equalFunc The function to determine equivalents of values.
 16239   * @param {Function} [customizer] The function to customize comparing values.
 16240   * @param {boolean} [isLoose] Specify performing partial comparisons.
 16241   * @param {Array} [stackA] Tracks traversed `value` objects.
 16242   * @param {Array} [stackB] Tracks traversed `other` objects.
 16243   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 16244   */
 16245  function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
 16246    var objProps = keys(object),
 16247        objLength = objProps.length,
 16248        othProps = keys(other),
 16249        othLength = othProps.length;
 16250  
 16251    if (objLength != othLength && !isLoose) {
 16252      return false;
 16253    }
 16254    var index = objLength;
 16255    while (index--) {
 16256      var key = objProps[index];
 16257      if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
 16258        return false;
 16259      }
 16260    }
 16261    var skipCtor = isLoose;
 16262    while (++index < objLength) {
 16263      key = objProps[index];
 16264      var objValue = object[key],
 16265          othValue = other[key],
 16266          result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
 16267  
 16268      // Recursively compare objects (susceptible to call stack limits).
 16269      if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
 16270        return false;
 16271      }
 16272      skipCtor || (skipCtor = key == 'constructor');
 16273    }
 16274    if (!skipCtor) {
 16275      var objCtor = object.constructor,
 16276          othCtor = other.constructor;
 16277  
 16278      // Non `Object` object instances with different constructors are not equal.
 16279      if (objCtor != othCtor &&
 16280          ('constructor' in object && 'constructor' in other) &&
 16281          !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
 16282            typeof othCtor == 'function' && othCtor instanceof othCtor)) {
 16283        return false;
 16284      }
 16285    }
 16286    return true;
 16287  }
 16288  
 16289  module.exports = equalObjects;
 16290  
 16291  },{"../object/keys":149}],110:[function(require,module,exports){
 16292  var metaMap = require('./metaMap'),
 16293      noop = require('../utility/noop');
 16294  
 16295  /**
 16296   * Gets metadata for `func`.
 16297   *
 16298   * @private
 16299   * @param {Function} func The function to query.
 16300   * @returns {*} Returns the metadata for `func`.
 16301   */
 16302  var getData = !metaMap ? noop : function(func) {
 16303    return metaMap.get(func);
 16304  };
 16305  
 16306  module.exports = getData;
 16307  
 16308  },{"../utility/noop":155,"./metaMap":129}],111:[function(require,module,exports){
 16309  var realNames = require('./realNames');
 16310  
 16311  /**
 16312   * Gets the name of `func`.
 16313   *
 16314   * @private
 16315   * @param {Function} func The function to query.
 16316   * @returns {string} Returns the function name.
 16317   */
 16318  function getFuncName(func) {
 16319    var result = (func.name + ''),
 16320        array = realNames[result],
 16321        length = array ? array.length : 0;
 16322  
 16323    while (length--) {
 16324      var data = array[length],
 16325          otherFunc = data.func;
 16326      if (otherFunc == null || otherFunc == func) {
 16327        return data.name;
 16328      }
 16329    }
 16330    return result;
 16331  }
 16332  
 16333  module.exports = getFuncName;
 16334  
 16335  },{"./realNames":130}],112:[function(require,module,exports){
 16336  var baseProperty = require('./baseProperty');
 16337  
 16338  /**
 16339   * Gets the "length" property value of `object`.
 16340   *
 16341   * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
 16342   * that affects Safari on at least iOS 8.1-8.3 ARM64.
 16343   *
 16344   * @private
 16345   * @param {Object} object The object to query.
 16346   * @returns {*} Returns the "length" value.
 16347   */
 16348  var getLength = baseProperty('length');
 16349  
 16350  module.exports = getLength;
 16351  
 16352  },{"./baseProperty":86}],113:[function(require,module,exports){
 16353  var isStrictComparable = require('./isStrictComparable'),
 16354      pairs = require('../object/pairs');
 16355  
 16356  /**
 16357   * Gets the propery names, values, and compare flags of `object`.
 16358   *
 16359   * @private
 16360   * @param {Object} object The object to query.
 16361   * @returns {Array} Returns the match data of `object`.
 16362   */
 16363  function getMatchData(object) {
 16364    var result = pairs(object),
 16365        length = result.length;
 16366  
 16367    while (length--) {
 16368      result[length][2] = isStrictComparable(result[length][1]);
 16369    }
 16370    return result;
 16371  }
 16372  
 16373  module.exports = getMatchData;
 16374  
 16375  },{"../object/pairs":151,"./isStrictComparable":127}],114:[function(require,module,exports){
 16376  var isNative = require('../lang/isNative');
 16377  
 16378  /**
 16379   * Gets the native function at `key` of `object`.
 16380   *
 16381   * @private
 16382   * @param {Object} object The object to query.
 16383   * @param {string} key The key of the method to get.
 16384   * @returns {*} Returns the function if it's native, else `undefined`.
 16385   */
 16386  function getNative(object, key) {
 16387    var value = object == null ? undefined : object[key];
 16388    return isNative(value) ? value : undefined;
 16389  }
 16390  
 16391  module.exports = getNative;
 16392  
 16393  },{"../lang/isNative":143}],115:[function(require,module,exports){
 16394  /**
 16395   * Gets the index at which the first occurrence of `NaN` is found in `array`.
 16396   *
 16397   * @private
 16398   * @param {Array} array The array to search.
 16399   * @param {number} fromIndex The index to search from.
 16400   * @param {boolean} [fromRight] Specify iterating from right to left.
 16401   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
 16402   */
 16403  function indexOfNaN(array, fromIndex, fromRight) {
 16404    var length = array.length,
 16405        index = fromIndex + (fromRight ? 0 : -1);
 16406  
 16407    while ((fromRight ? index-- : ++index < length)) {
 16408      var other = array[index];
 16409      if (other !== other) {
 16410        return index;
 16411      }
 16412    }
 16413    return -1;
 16414  }
 16415  
 16416  module.exports = indexOfNaN;
 16417  
 16418  },{}],116:[function(require,module,exports){
 16419  /** Used for native method references. */
 16420  var objectProto = Object.prototype;
 16421  
 16422  /** Used to check objects for own properties. */
 16423  var hasOwnProperty = objectProto.hasOwnProperty;
 16424  
 16425  /**
 16426   * Initializes an array clone.
 16427   *
 16428   * @private
 16429   * @param {Array} array The array to clone.
 16430   * @returns {Array} Returns the initialized clone.
 16431   */
 16432  function initCloneArray(array) {
 16433    var length = array.length,
 16434        result = new array.constructor(length);
 16435  
 16436    // Add array properties assigned by `RegExp#exec`.
 16437    if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
 16438      result.index = array.index;
 16439      result.input = array.input;
 16440    }
 16441    return result;
 16442  }
 16443  
 16444  module.exports = initCloneArray;
 16445  
 16446  },{}],117:[function(require,module,exports){
 16447  (function (global){
 16448  var bufferClone = require('./bufferClone');
 16449  
 16450  /** `Object#toString` result references. */
 16451  var boolTag = '[object Boolean]',
 16452      dateTag = '[object Date]',
 16453      numberTag = '[object Number]',
 16454      regexpTag = '[object RegExp]',
 16455      stringTag = '[object String]';
 16456  
 16457  var arrayBufferTag = '[object ArrayBuffer]',
 16458      float32Tag = '[object Float32Array]',
 16459      float64Tag = '[object Float64Array]',
 16460      int8Tag = '[object Int8Array]',
 16461      int16Tag = '[object Int16Array]',
 16462      int32Tag = '[object Int32Array]',
 16463      uint8Tag = '[object Uint8Array]',
 16464      uint8ClampedTag = '[object Uint8ClampedArray]',
 16465      uint16Tag = '[object Uint16Array]',
 16466      uint32Tag = '[object Uint32Array]';
 16467  
 16468  /** Used to match `RegExp` flags from their coerced string values. */
 16469  var reFlags = /\w*$/;
 16470  
 16471  /** Native method references. */
 16472  var Uint8Array = global.Uint8Array;
 16473  
 16474  /** Used to lookup a type array constructors by `toStringTag`. */
 16475  var ctorByTag = {};
 16476  ctorByTag[float32Tag] = global.Float32Array;
 16477  ctorByTag[float64Tag] = global.Float64Array;
 16478  ctorByTag[int8Tag] = global.Int8Array;
 16479  ctorByTag[int16Tag] = global.Int16Array;
 16480  ctorByTag[int32Tag] = global.Int32Array;
 16481  ctorByTag[uint8Tag] = Uint8Array;
 16482  ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray;
 16483  ctorByTag[uint16Tag] = global.Uint16Array;
 16484  ctorByTag[uint32Tag] = global.Uint32Array;
 16485  
 16486  /**
 16487   * Initializes an object clone based on its `toStringTag`.
 16488   *
 16489   * **Note:** This function only supports cloning values with tags of
 16490   * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
 16491   *
 16492   * @private
 16493   * @param {Object} object The object to clone.
 16494   * @param {string} tag The `toStringTag` of the object to clone.
 16495   * @param {boolean} [isDeep] Specify a deep clone.
 16496   * @returns {Object} Returns the initialized clone.
 16497   */
 16498  function initCloneByTag(object, tag, isDeep) {
 16499    var Ctor = object.constructor;
 16500    switch (tag) {
 16501      case arrayBufferTag:
 16502        return bufferClone(object);
 16503  
 16504      case boolTag:
 16505      case dateTag:
 16506        return new Ctor(+object);
 16507  
 16508      case float32Tag: case float64Tag:
 16509      case int8Tag: case int16Tag: case int32Tag:
 16510      case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
 16511        // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.
 16512        if (Ctor instanceof Ctor) {
 16513          Ctor = ctorByTag[tag];
 16514        }
 16515        var buffer = object.buffer;
 16516        return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
 16517  
 16518      case numberTag:
 16519      case stringTag:
 16520        return new Ctor(object);
 16521  
 16522      case regexpTag:
 16523        var result = new Ctor(object.source, reFlags.exec(object));
 16524        result.lastIndex = object.lastIndex;
 16525    }
 16526    return result;
 16527  }
 16528  
 16529  module.exports = initCloneByTag;
 16530  
 16531  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 16532  
 16533  },{"./bufferClone":95}],118:[function(require,module,exports){
 16534  /**
 16535   * Initializes an object clone.
 16536   *
 16537   * @private
 16538   * @param {Object} object The object to clone.
 16539   * @returns {Object} Returns the initialized clone.
 16540   */
 16541  function initCloneObject(object) {
 16542    var Ctor = object.constructor;
 16543    if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
 16544      Ctor = Object;
 16545    }
 16546    return new Ctor;
 16547  }
 16548  
 16549  module.exports = initCloneObject;
 16550  
 16551  },{}],119:[function(require,module,exports){
 16552  var getLength = require('./getLength'),
 16553      isLength = require('./isLength');
 16554  
 16555  /**
 16556   * Checks if `value` is array-like.
 16557   *
 16558   * @private
 16559   * @param {*} value The value to check.
 16560   * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
 16561   */
 16562  function isArrayLike(value) {
 16563    return value != null && isLength(getLength(value));
 16564  }
 16565  
 16566  module.exports = isArrayLike;
 16567  
 16568  },{"./getLength":112,"./isLength":125}],120:[function(require,module,exports){
 16569  /**
 16570   * Checks if `value` is a host object in IE < 9.
 16571   *
 16572   * @private
 16573   * @param {*} value The value to check.
 16574   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
 16575   */
 16576  var isHostObject = (function() {
 16577    try {
 16578      Object({ 'toString': 0 } + '');
 16579    } catch(e) {
 16580      return function() { return false; };
 16581    }
 16582    return function(value) {
 16583      // IE < 9 presents many host objects as `Object` objects that can coerce
 16584      // to strings despite having improperly defined `toString` methods.
 16585      return typeof value.toString != 'function' && typeof (value + '') == 'string';
 16586    };
 16587  }());
 16588  
 16589  module.exports = isHostObject;
 16590  
 16591  },{}],121:[function(require,module,exports){
 16592  /** Used to detect unsigned integer values. */
 16593  var reIsUint = /^\d+$/;
 16594  
 16595  /**
 16596   * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
 16597   * of an array-like value.
 16598   */
 16599  var MAX_SAFE_INTEGER = 9007199254740991;
 16600  
 16601  /**
 16602   * Checks if `value` is a valid array-like index.
 16603   *
 16604   * @private
 16605   * @param {*} value The value to check.
 16606   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
 16607   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
 16608   */
 16609  function isIndex(value, length) {
 16610    value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
 16611    length = length == null ? MAX_SAFE_INTEGER : length;
 16612    return value > -1 && value % 1 == 0 && value < length;
 16613  }
 16614  
 16615  module.exports = isIndex;
 16616  
 16617  },{}],122:[function(require,module,exports){
 16618  var isArrayLike = require('./isArrayLike'),
 16619      isIndex = require('./isIndex'),
 16620      isObject = require('../lang/isObject');
 16621  
 16622  /**
 16623   * Checks if the provided arguments are from an iteratee call.
 16624   *
 16625   * @private
 16626   * @param {*} value The potential iteratee value argument.
 16627   * @param {*} index The potential iteratee index or key argument.
 16628   * @param {*} object The potential iteratee object argument.
 16629   * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
 16630   */
 16631  function isIterateeCall(value, index, object) {
 16632    if (!isObject(object)) {
 16633      return false;
 16634    }
 16635    var type = typeof index;
 16636    if (type == 'number'
 16637        ? (isArrayLike(object) && isIndex(index, object.length))
 16638        : (type == 'string' && index in object)) {
 16639      var other = object[index];
 16640      return value === value ? (value === other) : (other !== other);
 16641    }
 16642    return false;
 16643  }
 16644  
 16645  module.exports = isIterateeCall;
 16646  
 16647  },{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(require,module,exports){
 16648  var isArray = require('../lang/isArray'),
 16649      toObject = require('./toObject');
 16650  
 16651  /** Used to match property names within property paths. */
 16652  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
 16653      reIsPlainProp = /^\w*$/;
 16654  
 16655  /**
 16656   * Checks if `value` is a property name and not a property path.
 16657   *
 16658   * @private
 16659   * @param {*} value The value to check.
 16660   * @param {Object} [object] The object to query keys on.
 16661   * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
 16662   */
 16663  function isKey(value, object) {
 16664    var type = typeof value;
 16665    if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
 16666      return true;
 16667    }
 16668    if (isArray(value)) {
 16669      return false;
 16670    }
 16671    var result = !reIsDeepProp.test(value);
 16672    return result || (object != null && value in toObject(object));
 16673  }
 16674  
 16675  module.exports = isKey;
 16676  
 16677  },{"../lang/isArray":140,"./toObject":135}],124:[function(require,module,exports){
 16678  var LazyWrapper = require('./LazyWrapper'),
 16679      getData = require('./getData'),
 16680      getFuncName = require('./getFuncName'),
 16681      lodash = require('../chain/lodash');
 16682  
 16683  /**
 16684   * Checks if `func` has a lazy counterpart.
 16685   *
 16686   * @private
 16687   * @param {Function} func The function to check.
 16688   * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
 16689   */
 16690  function isLaziable(func) {
 16691    var funcName = getFuncName(func),
 16692        other = lodash[funcName];
 16693  
 16694    if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
 16695      return false;
 16696    }
 16697    if (func === other) {
 16698      return true;
 16699    }
 16700    var data = getData(other);
 16701    return !!data && func === data[0];
 16702  }
 16703  
 16704  module.exports = isLaziable;
 16705  
 16706  },{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(require,module,exports){
 16707  /**
 16708   * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
 16709   * of an array-like value.
 16710   */
 16711  var MAX_SAFE_INTEGER = 9007199254740991;
 16712  
 16713  /**
 16714   * Checks if `value` is a valid array-like length.
 16715   *
 16716   * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
 16717   *
 16718   * @private
 16719   * @param {*} value The value to check.
 16720   * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
 16721   */
 16722  function isLength(value) {
 16723    return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
 16724  }
 16725  
 16726  module.exports = isLength;
 16727  
 16728  },{}],126:[function(require,module,exports){
 16729  /**
 16730   * Checks if `value` is object-like.
 16731   *
 16732   * @private
 16733   * @param {*} value The value to check.
 16734   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 16735   */
 16736  function isObjectLike(value) {
 16737    return !!value && typeof value == 'object';
 16738  }
 16739  
 16740  module.exports = isObjectLike;
 16741  
 16742  },{}],127:[function(require,module,exports){
 16743  var isObject = require('../lang/isObject');
 16744  
 16745  /**
 16746   * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
 16747   *
 16748   * @private
 16749   * @param {*} value The value to check.
 16750   * @returns {boolean} Returns `true` if `value` if suitable for strict
 16751   *  equality comparisons, else `false`.
 16752   */
 16753  function isStrictComparable(value) {
 16754    return value === value && !isObject(value);
 16755  }
 16756  
 16757  module.exports = isStrictComparable;
 16758  
 16759  },{"../lang/isObject":144}],128:[function(require,module,exports){
 16760  var arrayCopy = require('./arrayCopy'),
 16761      composeArgs = require('./composeArgs'),
 16762      composeArgsRight = require('./composeArgsRight'),
 16763      replaceHolders = require('./replaceHolders');
 16764  
 16765  /** Used to compose bitmasks for wrapper metadata. */
 16766  var BIND_FLAG = 1,
 16767      CURRY_BOUND_FLAG = 4,
 16768      CURRY_FLAG = 8,
 16769      ARY_FLAG = 128,
 16770      REARG_FLAG = 256;
 16771  
 16772  /** Used as the internal argument placeholder. */
 16773  var PLACEHOLDER = '__lodash_placeholder__';
 16774  
 16775  /* Native method references for those with the same name as other `lodash` methods. */
 16776  var nativeMin = Math.min;
 16777  
 16778  /**
 16779   * Merges the function metadata of `source` into `data`.
 16780   *
 16781   * Merging metadata reduces the number of wrappers required to invoke a function.
 16782   * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
 16783   * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
 16784   * augment function arguments, making the order in which they are executed important,
 16785   * preventing the merging of metadata. However, we make an exception for a safe
 16786   * common case where curried functions have `_.ary` and or `_.rearg` applied.
 16787   *
 16788   * @private
 16789   * @param {Array} data The destination metadata.
 16790   * @param {Array} source The source metadata.
 16791   * @returns {Array} Returns `data`.
 16792   */
 16793  function mergeData(data, source) {
 16794    var bitmask = data[1],
 16795        srcBitmask = source[1],
 16796        newBitmask = bitmask | srcBitmask,
 16797        isCommon = newBitmask < ARY_FLAG;
 16798  
 16799    var isCombo =
 16800      (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
 16801      (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
 16802      (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
 16803  
 16804    // Exit early if metadata can't be merged.
 16805    if (!(isCommon || isCombo)) {
 16806      return data;
 16807    }
 16808    // Use source `thisArg` if available.
 16809    if (srcBitmask & BIND_FLAG) {
 16810      data[2] = source[2];
 16811      // Set when currying a bound function.
 16812      newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
 16813    }
 16814    // Compose partial arguments.
 16815    var value = source[3];
 16816    if (value) {
 16817      var partials = data[3];
 16818      data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
 16819      data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
 16820    }
 16821    // Compose partial right arguments.
 16822    value = source[5];
 16823    if (value) {
 16824      partials = data[5];
 16825      data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
 16826      data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
 16827    }
 16828    // Use source `argPos` if available.
 16829    value = source[7];
 16830    if (value) {
 16831      data[7] = arrayCopy(value);
 16832    }
 16833    // Use source `ary` if it's smaller.
 16834    if (srcBitmask & ARY_FLAG) {
 16835      data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
 16836    }
 16837    // Use source `arity` if one is not provided.
 16838    if (data[9] == null) {
 16839      data[9] = source[9];
 16840    }
 16841    // Use source `func` and merge bitmasks.
 16842    data[0] = source[0];
 16843    data[1] = newBitmask;
 16844  
 16845    return data;
 16846  }
 16847  
 16848  module.exports = mergeData;
 16849  
 16850  },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(require,module,exports){
 16851  (function (global){
 16852  var getNative = require('./getNative');
 16853  
 16854  /** Native method references. */
 16855  var WeakMap = getNative(global, 'WeakMap');
 16856  
 16857  /** Used to store function metadata. */
 16858  var metaMap = WeakMap && new WeakMap;
 16859  
 16860  module.exports = metaMap;
 16861  
 16862  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 16863  
 16864  },{"./getNative":114}],130:[function(require,module,exports){
 16865  /** Used to lookup unminified function names. */
 16866  var realNames = {};
 16867  
 16868  module.exports = realNames;
 16869  
 16870  },{}],131:[function(require,module,exports){
 16871  var arrayCopy = require('./arrayCopy'),
 16872      isIndex = require('./isIndex');
 16873  
 16874  /* Native method references for those with the same name as other `lodash` methods. */
 16875  var nativeMin = Math.min;
 16876  
 16877  /**
 16878   * Reorder `array` according to the specified indexes where the element at
 16879   * the first index is assigned as the first element, the element at
 16880   * the second index is assigned as the second element, and so on.
 16881   *
 16882   * @private
 16883   * @param {Array} array The array to reorder.
 16884   * @param {Array} indexes The arranged array indexes.
 16885   * @returns {Array} Returns `array`.
 16886   */
 16887  function reorder(array, indexes) {
 16888    var arrLength = array.length,
 16889        length = nativeMin(indexes.length, arrLength),
 16890        oldArray = arrayCopy(array);
 16891  
 16892    while (length--) {
 16893      var index = indexes[length];
 16894      array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
 16895    }
 16896    return array;
 16897  }
 16898  
 16899  module.exports = reorder;
 16900  
 16901  },{"./arrayCopy":62,"./isIndex":121}],132:[function(require,module,exports){
 16902  /** Used as the internal argument placeholder. */
 16903  var PLACEHOLDER = '__lodash_placeholder__';
 16904  
 16905  /**
 16906   * Replaces all `placeholder` elements in `array` with an internal placeholder
 16907   * and returns an array of their indexes.
 16908   *
 16909   * @private
 16910   * @param {Array} array The array to modify.
 16911   * @param {*} placeholder The placeholder to replace.
 16912   * @returns {Array} Returns the new array of placeholder indexes.
 16913   */
 16914  function replaceHolders(array, placeholder) {
 16915    var index = -1,
 16916        length = array.length,
 16917        resIndex = -1,
 16918        result = [];
 16919  
 16920    while (++index < length) {
 16921      if (array[index] === placeholder) {
 16922        array[index] = PLACEHOLDER;
 16923        result[++resIndex] = index;
 16924      }
 16925    }
 16926    return result;
 16927  }
 16928  
 16929  module.exports = replaceHolders;
 16930  
 16931  },{}],133:[function(require,module,exports){
 16932  var baseSetData = require('./baseSetData'),
 16933      now = require('../date/now');
 16934  
 16935  /** Used to detect when a function becomes hot. */
 16936  var HOT_COUNT = 150,
 16937      HOT_SPAN = 16;
 16938  
 16939  /**
 16940   * Sets metadata for `func`.
 16941   *
 16942   * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
 16943   * period of time, it will trip its breaker and transition to an identity function
 16944   * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
 16945   * for more details.
 16946   *
 16947   * @private
 16948   * @param {Function} func The function to associate metadata with.
 16949   * @param {*} data The metadata.
 16950   * @returns {Function} Returns `func`.
 16951   */
 16952  var setData = (function() {
 16953    var count = 0,
 16954        lastCalled = 0;
 16955  
 16956    return function(key, value) {
 16957      var stamp = now(),
 16958          remaining = HOT_SPAN - (stamp - lastCalled);
 16959  
 16960      lastCalled = stamp;
 16961      if (remaining > 0) {
 16962        if (++count >= HOT_COUNT) {
 16963          return key;
 16964        }
 16965      } else {
 16966        count = 0;
 16967      }
 16968      return baseSetData(key, value);
 16969    };
 16970  }());
 16971  
 16972  module.exports = setData;
 16973  
 16974  },{"../date/now":57,"./baseSetData":88}],134:[function(require,module,exports){
 16975  var isArguments = require('../lang/isArguments'),
 16976      isArray = require('../lang/isArray'),
 16977      isIndex = require('./isIndex'),
 16978      isLength = require('./isLength'),
 16979      isString = require('../lang/isString'),
 16980      keysIn = require('../object/keysIn');
 16981  
 16982  /** Used for native method references. */
 16983  var objectProto = Object.prototype;
 16984  
 16985  /** Used to check objects for own properties. */
 16986  var hasOwnProperty = objectProto.hasOwnProperty;
 16987  
 16988  /**
 16989   * A fallback implementation of `Object.keys` which creates an array of the
 16990   * own enumerable property names of `object`.
 16991   *
 16992   * @private
 16993   * @param {Object} object The object to query.
 16994   * @returns {Array} Returns the array of property names.
 16995   */
 16996  function shimKeys(object) {
 16997    var props = keysIn(object),
 16998        propsLength = props.length,
 16999        length = propsLength && object.length;
 17000  
 17001    var allowIndexes = !!length && isLength(length) &&
 17002      (isArray(object) || isArguments(object) || isString(object));
 17003  
 17004    var index = -1,
 17005        result = [];
 17006  
 17007    while (++index < propsLength) {
 17008      var key = props[index];
 17009      if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
 17010        result.push(key);
 17011      }
 17012    }
 17013    return result;
 17014  }
 17015  
 17016  module.exports = shimKeys;
 17017  
 17018  },{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(require,module,exports){
 17019  var isObject = require('../lang/isObject'),
 17020      isString = require('../lang/isString'),
 17021      support = require('../support');
 17022  
 17023  /**
 17024   * Converts `value` to an object if it's not one.
 17025   *
 17026   * @private
 17027   * @param {*} value The value to process.
 17028   * @returns {Object} Returns the object.
 17029   */
 17030  function toObject(value) {
 17031    if (support.unindexedChars && isString(value)) {
 17032      var index = -1,
 17033          length = value.length,
 17034          result = Object(value);
 17035  
 17036      while (++index < length) {
 17037        result[index] = value.charAt(index);
 17038      }
 17039      return result;
 17040    }
 17041    return isObject(value) ? value : Object(value);
 17042  }
 17043  
 17044  module.exports = toObject;
 17045  
 17046  },{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(require,module,exports){
 17047  var baseToString = require('./baseToString'),
 17048      isArray = require('../lang/isArray');
 17049  
 17050  /** Used to match property names within property paths. */
 17051  var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
 17052  
 17053  /** Used to match backslashes in property paths. */
 17054  var reEscapeChar = /\\(\\)?/g;
 17055  
 17056  /**
 17057   * Converts `value` to property path array if it's not one.
 17058   *
 17059   * @private
 17060   * @param {*} value The value to process.
 17061   * @returns {Array} Returns the property path array.
 17062   */
 17063  function toPath(value) {
 17064    if (isArray(value)) {
 17065      return value;
 17066    }
 17067    var result = [];
 17068    baseToString(value).replace(rePropName, function(match, number, quote, string) {
 17069      result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
 17070    });
 17071    return result;
 17072  }
 17073  
 17074  module.exports = toPath;
 17075  
 17076  },{"../lang/isArray":140,"./baseToString":90}],137:[function(require,module,exports){
 17077  var LazyWrapper = require('./LazyWrapper'),
 17078      LodashWrapper = require('./LodashWrapper'),
 17079      arrayCopy = require('./arrayCopy');
 17080  
 17081  /**
 17082   * Creates a clone of `wrapper`.
 17083   *
 17084   * @private
 17085   * @param {Object} wrapper The wrapper to clone.
 17086   * @returns {Object} Returns the cloned wrapper.
 17087   */
 17088  function wrapperClone(wrapper) {
 17089    return wrapper instanceof LazyWrapper
 17090      ? wrapper.clone()
 17091      : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
 17092  }
 17093  
 17094  module.exports = wrapperClone;
 17095  
 17096  },{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(require,module,exports){
 17097  var baseClone = require('../internal/baseClone'),
 17098      bindCallback = require('../internal/bindCallback');
 17099  
 17100  /**
 17101   * Creates a deep clone of `value`. If `customizer` is provided it's invoked
 17102   * to produce the cloned values. If `customizer` returns `undefined` cloning
 17103   * is handled by the method instead. The `customizer` is bound to `thisArg`
 17104   * and invoked with up to three argument; (value [, index|key, object]).
 17105   *
 17106   * **Note:** This method is loosely based on the
 17107   * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
 17108   * The enumerable properties of `arguments` objects and objects created by
 17109   * constructors other than `Object` are cloned to plain `Object` objects. An
 17110   * empty object is returned for uncloneable values such as functions, DOM nodes,
 17111   * Maps, Sets, and WeakMaps.
 17112   *
 17113   * @static
 17114   * @memberOf _
 17115   * @category Lang
 17116   * @param {*} value The value to deep clone.
 17117   * @param {Function} [customizer] The function to customize cloning values.
 17118   * @param {*} [thisArg] The `this` binding of `customizer`.
 17119   * @returns {*} Returns the deep cloned value.
 17120   * @example
 17121   *
 17122   * var users = [
 17123   *   { 'user': 'barney' },
 17124   *   { 'user': 'fred' }
 17125   * ];
 17126   *
 17127   * var deep = _.cloneDeep(users);
 17128   * deep[0] === users[0];
 17129   * // => false
 17130   *
 17131   * // using a customizer callback
 17132   * var el = _.cloneDeep(document.body, function(value) {
 17133   *   if (_.isElement(value)) {
 17134   *     return value.cloneNode(true);
 17135   *   }
 17136   * });
 17137   *
 17138   * el === document.body
 17139   * // => false
 17140   * el.nodeName
 17141   * // => BODY
 17142   * el.childNodes.length;
 17143   * // => 20
 17144   */
 17145  function cloneDeep(value, customizer, thisArg) {
 17146    return typeof customizer == 'function'
 17147      ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
 17148      : baseClone(value, true);
 17149  }
 17150  
 17151  module.exports = cloneDeep;
 17152  
 17153  },{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(require,module,exports){
 17154  var isArrayLike = require('../internal/isArrayLike'),
 17155      isObjectLike = require('../internal/isObjectLike');
 17156  
 17157  /** Used for native method references. */
 17158  var objectProto = Object.prototype;
 17159  
 17160  /** Used to check objects for own properties. */
 17161  var hasOwnProperty = objectProto.hasOwnProperty;
 17162  
 17163  /** Native method references. */
 17164  var propertyIsEnumerable = objectProto.propertyIsEnumerable;
 17165  
 17166  /**
 17167   * Checks if `value` is classified as an `arguments` object.
 17168   *
 17169   * @static
 17170   * @memberOf _
 17171   * @category Lang
 17172   * @param {*} value The value to check.
 17173   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 17174   * @example
 17175   *
 17176   * _.isArguments(function() { return arguments; }());
 17177   * // => true
 17178   *
 17179   * _.isArguments([1, 2, 3]);
 17180   * // => false
 17181   */
 17182  function isArguments(value) {
 17183    return isObjectLike(value) && isArrayLike(value) &&
 17184      hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
 17185  }
 17186  
 17187  module.exports = isArguments;
 17188  
 17189  },{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(require,module,exports){
 17190  var getNative = require('../internal/getNative'),
 17191      isLength = require('../internal/isLength'),
 17192      isObjectLike = require('../internal/isObjectLike');
 17193  
 17194  /** `Object#toString` result references. */
 17195  var arrayTag = '[object Array]';
 17196  
 17197  /** Used for native method references. */
 17198  var objectProto = Object.prototype;
 17199  
 17200  /**
 17201   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17202   * of values.
 17203   */
 17204  var objToString = objectProto.toString;
 17205  
 17206  /* Native method references for those with the same name as other `lodash` methods. */
 17207  var nativeIsArray = getNative(Array, 'isArray');
 17208  
 17209  /**
 17210   * Checks if `value` is classified as an `Array` object.
 17211   *
 17212   * @static
 17213   * @memberOf _
 17214   * @category Lang
 17215   * @param {*} value The value to check.
 17216   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 17217   * @example
 17218   *
 17219   * _.isArray([1, 2, 3]);
 17220   * // => true
 17221   *
 17222   * _.isArray(function() { return arguments; }());
 17223   * // => false
 17224   */
 17225  var isArray = nativeIsArray || function(value) {
 17226    return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
 17227  };
 17228  
 17229  module.exports = isArray;
 17230  
 17231  },{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(require,module,exports){
 17232  var isArguments = require('./isArguments'),
 17233      isArray = require('./isArray'),
 17234      isArrayLike = require('../internal/isArrayLike'),
 17235      isFunction = require('./isFunction'),
 17236      isObjectLike = require('../internal/isObjectLike'),
 17237      isString = require('./isString'),
 17238      keys = require('../object/keys');
 17239  
 17240  /**
 17241   * Checks if `value` is empty. A value is considered empty unless it's an
 17242   * `arguments` object, array, string, or jQuery-like collection with a length
 17243   * greater than `0` or an object with own enumerable properties.
 17244   *
 17245   * @static
 17246   * @memberOf _
 17247   * @category Lang
 17248   * @param {Array|Object|string} value The value to inspect.
 17249   * @returns {boolean} Returns `true` if `value` is empty, else `false`.
 17250   * @example
 17251   *
 17252   * _.isEmpty(null);
 17253   * // => true
 17254   *
 17255   * _.isEmpty(true);
 17256   * // => true
 17257   *
 17258   * _.isEmpty(1);
 17259   * // => true
 17260   *
 17261   * _.isEmpty([1, 2, 3]);
 17262   * // => false
 17263   *
 17264   * _.isEmpty({ 'a': 1 });
 17265   * // => false
 17266   */
 17267  function isEmpty(value) {
 17268    if (value == null) {
 17269      return true;
 17270    }
 17271    if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
 17272        (isObjectLike(value) && isFunction(value.splice)))) {
 17273      return !value.length;
 17274    }
 17275    return !keys(value).length;
 17276  }
 17277  
 17278  module.exports = isEmpty;
 17279  
 17280  },{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(require,module,exports){
 17281  var isObject = require('./isObject');
 17282  
 17283  /** `Object#toString` result references. */
 17284  var funcTag = '[object Function]';
 17285  
 17286  /** Used for native method references. */
 17287  var objectProto = Object.prototype;
 17288  
 17289  /**
 17290   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17291   * of values.
 17292   */
 17293  var objToString = objectProto.toString;
 17294  
 17295  /**
 17296   * Checks if `value` is classified as a `Function` object.
 17297   *
 17298   * @static
 17299   * @memberOf _
 17300   * @category Lang
 17301   * @param {*} value The value to check.
 17302   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 17303   * @example
 17304   *
 17305   * _.isFunction(_);
 17306   * // => true
 17307   *
 17308   * _.isFunction(/abc/);
 17309   * // => false
 17310   */
 17311  function isFunction(value) {
 17312    // The use of `Object#toString` avoids issues with the `typeof` operator
 17313    // in older versions of Chrome and Safari which return 'function' for regexes
 17314    // and Safari 8 which returns 'object' for typed array constructors.
 17315    return isObject(value) && objToString.call(value) == funcTag;
 17316  }
 17317  
 17318  module.exports = isFunction;
 17319  
 17320  },{"./isObject":144}],143:[function(require,module,exports){
 17321  var isFunction = require('./isFunction'),
 17322      isHostObject = require('../internal/isHostObject'),
 17323      isObjectLike = require('../internal/isObjectLike');
 17324  
 17325  /** Used to detect host constructors (Safari > 5). */
 17326  var reIsHostCtor = /^\[object .+?Constructor\]$/;
 17327  
 17328  /** Used for native method references. */
 17329  var objectProto = Object.prototype;
 17330  
 17331  /** Used to resolve the decompiled source of functions. */
 17332  var fnToString = Function.prototype.toString;
 17333  
 17334  /** Used to check objects for own properties. */
 17335  var hasOwnProperty = objectProto.hasOwnProperty;
 17336  
 17337  /** Used to detect if a method is native. */
 17338  var reIsNative = RegExp('^' +
 17339    fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
 17340    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
 17341  );
 17342  
 17343  /**
 17344   * Checks if `value` is a native function.
 17345   *
 17346   * @static
 17347   * @memberOf _
 17348   * @category Lang
 17349   * @param {*} value The value to check.
 17350   * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
 17351   * @example
 17352   *
 17353   * _.isNative(Array.prototype.push);
 17354   * // => true
 17355   *
 17356   * _.isNative(_);
 17357   * // => false
 17358   */
 17359  function isNative(value) {
 17360    if (value == null) {
 17361      return false;
 17362    }
 17363    if (isFunction(value)) {
 17364      return reIsNative.test(fnToString.call(value));
 17365    }
 17366    return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
 17367  }
 17368  
 17369  module.exports = isNative;
 17370  
 17371  },{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(require,module,exports){
 17372  /**
 17373   * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
 17374   * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 17375   *
 17376   * @static
 17377   * @memberOf _
 17378   * @category Lang
 17379   * @param {*} value The value to check.
 17380   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 17381   * @example
 17382   *
 17383   * _.isObject({});
 17384   * // => true
 17385   *
 17386   * _.isObject([1, 2, 3]);
 17387   * // => true
 17388   *
 17389   * _.isObject(1);
 17390   * // => false
 17391   */
 17392  function isObject(value) {
 17393    // Avoid a V8 JIT bug in Chrome 19-20.
 17394    // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
 17395    var type = typeof value;
 17396    return !!value && (type == 'object' || type == 'function');
 17397  }
 17398  
 17399  module.exports = isObject;
 17400  
 17401  },{}],145:[function(require,module,exports){
 17402  var baseForIn = require('../internal/baseForIn'),
 17403      isArguments = require('./isArguments'),
 17404      isHostObject = require('../internal/isHostObject'),
 17405      isObjectLike = require('../internal/isObjectLike'),
 17406      support = require('../support');
 17407  
 17408  /** `Object#toString` result references. */
 17409  var objectTag = '[object Object]';
 17410  
 17411  /** Used for native method references. */
 17412  var objectProto = Object.prototype;
 17413  
 17414  /** Used to check objects for own properties. */
 17415  var hasOwnProperty = objectProto.hasOwnProperty;
 17416  
 17417  /**
 17418   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17419   * of values.
 17420   */
 17421  var objToString = objectProto.toString;
 17422  
 17423  /**
 17424   * Checks if `value` is a plain object, that is, an object created by the
 17425   * `Object` constructor or one with a `[[Prototype]]` of `null`.
 17426   *
 17427   * **Note:** This method assumes objects created by the `Object` constructor
 17428   * have no inherited enumerable properties.
 17429   *
 17430   * @static
 17431   * @memberOf _
 17432   * @category Lang
 17433   * @param {*} value The value to check.
 17434   * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
 17435   * @example
 17436   *
 17437   * function Foo() {
 17438   *   this.a = 1;
 17439   * }
 17440   *
 17441   * _.isPlainObject(new Foo);
 17442   * // => false
 17443   *
 17444   * _.isPlainObject([1, 2, 3]);
 17445   * // => false
 17446   *
 17447   * _.isPlainObject({ 'x': 0, 'y': 0 });
 17448   * // => true
 17449   *
 17450   * _.isPlainObject(Object.create(null));
 17451   * // => true
 17452   */
 17453  function isPlainObject(value) {
 17454    var Ctor;
 17455  
 17456    // Exit early for non `Object` objects.
 17457    if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
 17458        (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
 17459      return false;
 17460    }
 17461    // IE < 9 iterates inherited properties before own properties. If the first
 17462    // iterated property is an object's own property then there are no inherited
 17463    // enumerable properties.
 17464    var result;
 17465    if (support.ownLast) {
 17466      baseForIn(value, function(subValue, key, object) {
 17467        result = hasOwnProperty.call(object, key);
 17468        return false;
 17469      });
 17470      return result !== false;
 17471    }
 17472    // In most environments an object's own properties are iterated before
 17473    // its inherited properties. If the last iterated property is an object's
 17474    // own property then there are no inherited enumerable properties.
 17475    baseForIn(value, function(subValue, key) {
 17476      result = key;
 17477    });
 17478    return result === undefined || hasOwnProperty.call(value, result);
 17479  }
 17480  
 17481  module.exports = isPlainObject;
 17482  
 17483  },{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(require,module,exports){
 17484  var isObjectLike = require('../internal/isObjectLike');
 17485  
 17486  /** `Object#toString` result references. */
 17487  var stringTag = '[object String]';
 17488  
 17489  /** Used for native method references. */
 17490  var objectProto = Object.prototype;
 17491  
 17492  /**
 17493   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17494   * of values.
 17495   */
 17496  var objToString = objectProto.toString;
 17497  
 17498  /**
 17499   * Checks if `value` is classified as a `String` primitive or object.
 17500   *
 17501   * @static
 17502   * @memberOf _
 17503   * @category Lang
 17504   * @param {*} value The value to check.
 17505   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 17506   * @example
 17507   *
 17508   * _.isString('abc');
 17509   * // => true
 17510   *
 17511   * _.isString(1);
 17512   * // => false
 17513   */
 17514  function isString(value) {
 17515    return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
 17516  }
 17517  
 17518  module.exports = isString;
 17519  
 17520  },{"../internal/isObjectLike":126}],147:[function(require,module,exports){
 17521  var isLength = require('../internal/isLength'),
 17522      isObjectLike = require('../internal/isObjectLike');
 17523  
 17524  /** `Object#toString` result references. */
 17525  var argsTag = '[object Arguments]',
 17526      arrayTag = '[object Array]',
 17527      boolTag = '[object Boolean]',
 17528      dateTag = '[object Date]',
 17529      errorTag = '[object Error]',
 17530      funcTag = '[object Function]',
 17531      mapTag = '[object Map]',
 17532      numberTag = '[object Number]',
 17533      objectTag = '[object Object]',
 17534      regexpTag = '[object RegExp]',
 17535      setTag = '[object Set]',
 17536      stringTag = '[object String]',
 17537      weakMapTag = '[object WeakMap]';
 17538  
 17539  var arrayBufferTag = '[object ArrayBuffer]',
 17540      float32Tag = '[object Float32Array]',
 17541      float64Tag = '[object Float64Array]',
 17542      int8Tag = '[object Int8Array]',
 17543      int16Tag = '[object Int16Array]',
 17544      int32Tag = '[object Int32Array]',
 17545      uint8Tag = '[object Uint8Array]',
 17546      uint8ClampedTag = '[object Uint8ClampedArray]',
 17547      uint16Tag = '[object Uint16Array]',
 17548      uint32Tag = '[object Uint32Array]';
 17549  
 17550  /** Used to identify `toStringTag` values of typed arrays. */
 17551  var typedArrayTags = {};
 17552  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
 17553  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
 17554  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
 17555  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
 17556  typedArrayTags[uint32Tag] = true;
 17557  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
 17558  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
 17559  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
 17560  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
 17561  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
 17562  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
 17563  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
 17564  
 17565  /** Used for native method references. */
 17566  var objectProto = Object.prototype;
 17567  
 17568  /**
 17569   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17570   * of values.
 17571   */
 17572  var objToString = objectProto.toString;
 17573  
 17574  /**
 17575   * Checks if `value` is classified as a typed array.
 17576   *
 17577   * @static
 17578   * @memberOf _
 17579   * @category Lang
 17580   * @param {*} value The value to check.
 17581   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 17582   * @example
 17583   *
 17584   * _.isTypedArray(new Uint8Array);
 17585   * // => true
 17586   *
 17587   * _.isTypedArray([]);
 17588   * // => false
 17589   */
 17590  function isTypedArray(value) {
 17591    return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
 17592  }
 17593  
 17594  module.exports = isTypedArray;
 17595  
 17596  },{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(require,module,exports){
 17597  /**
 17598   * Checks if `value` is `undefined`.
 17599   *
 17600   * @static
 17601   * @memberOf _
 17602   * @category Lang
 17603   * @param {*} value The value to check.
 17604   * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
 17605   * @example
 17606   *
 17607   * _.isUndefined(void 0);
 17608   * // => true
 17609   *
 17610   * _.isUndefined(null);
 17611   * // => false
 17612   */
 17613  function isUndefined(value) {
 17614    return value === undefined;
 17615  }
 17616  
 17617  module.exports = isUndefined;
 17618  
 17619  },{}],149:[function(require,module,exports){
 17620  var getNative = require('../internal/getNative'),
 17621      isArrayLike = require('../internal/isArrayLike'),
 17622      isObject = require('../lang/isObject'),
 17623      shimKeys = require('../internal/shimKeys'),
 17624      support = require('../support');
 17625  
 17626  /* Native method references for those with the same name as other `lodash` methods. */
 17627  var nativeKeys = getNative(Object, 'keys');
 17628  
 17629  /**
 17630   * Creates an array of the own enumerable property names of `object`.
 17631   *
 17632   * **Note:** Non-object values are coerced to objects. See the
 17633   * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
 17634   * for more details.
 17635   *
 17636   * @static
 17637   * @memberOf _
 17638   * @category Object
 17639   * @param {Object} object The object to query.
 17640   * @returns {Array} Returns the array of property names.
 17641   * @example
 17642   *
 17643   * function Foo() {
 17644   *   this.a = 1;
 17645   *   this.b = 2;
 17646   * }
 17647   *
 17648   * Foo.prototype.c = 3;
 17649   *
 17650   * _.keys(new Foo);
 17651   * // => ['a', 'b'] (iteration order is not guaranteed)
 17652   *
 17653   * _.keys('hi');
 17654   * // => ['0', '1']
 17655   */
 17656  var keys = !nativeKeys ? shimKeys : function(object) {
 17657    var Ctor = object == null ? undefined : object.constructor;
 17658    if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
 17659        (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
 17660      return shimKeys(object);
 17661    }
 17662    return isObject(object) ? nativeKeys(object) : [];
 17663  };
 17664  
 17665  module.exports = keys;
 17666  
 17667  },{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(require,module,exports){
 17668  var arrayEach = require('../internal/arrayEach'),
 17669      isArguments = require('../lang/isArguments'),
 17670      isArray = require('../lang/isArray'),
 17671      isFunction = require('../lang/isFunction'),
 17672      isIndex = require('../internal/isIndex'),
 17673      isLength = require('../internal/isLength'),
 17674      isObject = require('../lang/isObject'),
 17675      isString = require('../lang/isString'),
 17676      support = require('../support');
 17677  
 17678  /** `Object#toString` result references. */
 17679  var arrayTag = '[object Array]',
 17680      boolTag = '[object Boolean]',
 17681      dateTag = '[object Date]',
 17682      errorTag = '[object Error]',
 17683      funcTag = '[object Function]',
 17684      numberTag = '[object Number]',
 17685      objectTag = '[object Object]',
 17686      regexpTag = '[object RegExp]',
 17687      stringTag = '[object String]';
 17688  
 17689  /** Used to fix the JScript `[[DontEnum]]` bug. */
 17690  var shadowProps = [
 17691    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
 17692    'toLocaleString', 'toString', 'valueOf'
 17693  ];
 17694  
 17695  /** Used for native method references. */
 17696  var errorProto = Error.prototype,
 17697      objectProto = Object.prototype,
 17698      stringProto = String.prototype;
 17699  
 17700  /** Used to check objects for own properties. */
 17701  var hasOwnProperty = objectProto.hasOwnProperty;
 17702  
 17703  /**
 17704   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 17705   * of values.
 17706   */
 17707  var objToString = objectProto.toString;
 17708  
 17709  /** Used to avoid iterating over non-enumerable properties in IE < 9. */
 17710  var nonEnumProps = {};
 17711  nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
 17712  nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
 17713  nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
 17714  nonEnumProps[objectTag] = { 'constructor': true };
 17715  
 17716  arrayEach(shadowProps, function(key) {
 17717    for (var tag in nonEnumProps) {
 17718      if (hasOwnProperty.call(nonEnumProps, tag)) {
 17719        var props = nonEnumProps[tag];
 17720        props[key] = hasOwnProperty.call(props, key);
 17721      }
 17722    }
 17723  });
 17724  
 17725  /**
 17726   * Creates an array of the own and inherited enumerable property names of `object`.
 17727   *
 17728   * **Note:** Non-object values are coerced to objects.
 17729   *
 17730   * @static
 17731   * @memberOf _
 17732   * @category Object
 17733   * @param {Object} object The object to query.
 17734   * @returns {Array} Returns the array of property names.
 17735   * @example
 17736   *
 17737   * function Foo() {
 17738   *   this.a = 1;
 17739   *   this.b = 2;
 17740   * }
 17741   *
 17742   * Foo.prototype.c = 3;
 17743   *
 17744   * _.keysIn(new Foo);
 17745   * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
 17746   */
 17747  function keysIn(object) {
 17748    if (object == null) {
 17749      return [];
 17750    }
 17751    if (!isObject(object)) {
 17752      object = Object(object);
 17753    }
 17754    var length = object.length;
 17755  
 17756    length = (length && isLength(length) &&
 17757      (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
 17758  
 17759    var Ctor = object.constructor,
 17760        index = -1,
 17761        proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
 17762        isProto = proto === object,
 17763        result = Array(length),
 17764        skipIndexes = length > 0,
 17765        skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
 17766        skipProto = support.enumPrototypes && isFunction(object);
 17767  
 17768    while (++index < length) {
 17769      result[index] = (index + '');
 17770    }
 17771    // lodash skips the `constructor` property when it infers it's iterating
 17772    // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
 17773    // attribute of an existing property and the `constructor` property of a
 17774    // prototype defaults to non-enumerable.
 17775    for (var key in object) {
 17776      if (!(skipProto && key == 'prototype') &&
 17777          !(skipErrorProps && (key == 'message' || key == 'name')) &&
 17778          !(skipIndexes && isIndex(key, length)) &&
 17779          !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
 17780        result.push(key);
 17781      }
 17782    }
 17783    if (support.nonEnumShadows && object !== objectProto) {
 17784      var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
 17785          nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
 17786  
 17787      if (tag == objectTag) {
 17788        proto = objectProto;
 17789      }
 17790      length = shadowProps.length;
 17791      while (length--) {
 17792        key = shadowProps[length];
 17793        var nonEnum = nonEnums[key];
 17794        if (!(isProto && nonEnum) &&
 17795            (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
 17796          result.push(key);
 17797        }
 17798      }
 17799    }
 17800    return result;
 17801  }
 17802  
 17803  module.exports = keysIn;
 17804  
 17805  },{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(require,module,exports){
 17806  var keys = require('./keys'),
 17807      toObject = require('../internal/toObject');
 17808  
 17809  /**
 17810   * Creates a two dimensional array of the key-value pairs for `object`,
 17811   * e.g. `[[key1, value1], [key2, value2]]`.
 17812   *
 17813   * @static
 17814   * @memberOf _
 17815   * @category Object
 17816   * @param {Object} object The object to query.
 17817   * @returns {Array} Returns the new array of key-value pairs.
 17818   * @example
 17819   *
 17820   * _.pairs({ 'barney': 36, 'fred': 40 });
 17821   * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
 17822   */
 17823  function pairs(object) {
 17824    object = toObject(object);
 17825  
 17826    var index = -1,
 17827        props = keys(object),
 17828        length = props.length,
 17829        result = Array(length);
 17830  
 17831    while (++index < length) {
 17832      var key = props[index];
 17833      result[index] = [key, object[key]];
 17834    }
 17835    return result;
 17836  }
 17837  
 17838  module.exports = pairs;
 17839  
 17840  },{"../internal/toObject":135,"./keys":149}],152:[function(require,module,exports){
 17841  var baseValues = require('../internal/baseValues'),
 17842      keys = require('./keys');
 17843  
 17844  /**
 17845   * Creates an array of the own enumerable property values of `object`.
 17846   *
 17847   * **Note:** Non-object values are coerced to objects.
 17848   *
 17849   * @static
 17850   * @memberOf _
 17851   * @category Object
 17852   * @param {Object} object The object to query.
 17853   * @returns {Array} Returns the array of property values.
 17854   * @example
 17855   *
 17856   * function Foo() {
 17857   *   this.a = 1;
 17858   *   this.b = 2;
 17859   * }
 17860   *
 17861   * Foo.prototype.c = 3;
 17862   *
 17863   * _.values(new Foo);
 17864   * // => [1, 2] (iteration order is not guaranteed)
 17865   *
 17866   * _.values('hi');
 17867   * // => ['h', 'i']
 17868   */
 17869  function values(object) {
 17870    return baseValues(object, keys(object));
 17871  }
 17872  
 17873  module.exports = values;
 17874  
 17875  },{"../internal/baseValues":91,"./keys":149}],153:[function(require,module,exports){
 17876  /** Used for native method references. */
 17877  var arrayProto = Array.prototype,
 17878      errorProto = Error.prototype,
 17879      objectProto = Object.prototype;
 17880  
 17881  /** Native method references. */
 17882  var propertyIsEnumerable = objectProto.propertyIsEnumerable,
 17883      splice = arrayProto.splice;
 17884  
 17885  /**
 17886   * An object environment feature flags.
 17887   *
 17888   * @static
 17889   * @memberOf _
 17890   * @type Object
 17891   */
 17892  var support = {};
 17893  
 17894  (function(x) {
 17895    var Ctor = function() { this.x = x; },
 17896        object = { '0': x, 'length': x },
 17897        props = [];
 17898  
 17899    Ctor.prototype = { 'valueOf': x, 'y': x };
 17900    for (var key in new Ctor) { props.push(key); }
 17901  
 17902    /**
 17903     * Detect if `name` or `message` properties of `Error.prototype` are
 17904     * enumerable by default (IE < 9, Safari < 5.1).
 17905     *
 17906     * @memberOf _.support
 17907     * @type boolean
 17908     */
 17909    support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
 17910      propertyIsEnumerable.call(errorProto, 'name');
 17911  
 17912    /**
 17913     * Detect if `prototype` properties are enumerable by default.
 17914     *
 17915     * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
 17916     * (if the prototype or a property on the prototype has been set)
 17917     * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
 17918     * property to `true`.
 17919     *
 17920     * @memberOf _.support
 17921     * @type boolean
 17922     */
 17923    support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
 17924  
 17925    /**
 17926     * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
 17927     *
 17928     * In IE < 9 an object's own properties, shadowing non-enumerable ones,
 17929     * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
 17930     *
 17931     * @memberOf _.support
 17932     * @type boolean
 17933     */
 17934    support.nonEnumShadows = !/valueOf/.test(props);
 17935  
 17936    /**
 17937     * Detect if own properties are iterated after inherited properties (IE < 9).
 17938     *
 17939     * @memberOf _.support
 17940     * @type boolean
 17941     */
 17942    support.ownLast = props[0] != 'x';
 17943  
 17944    /**
 17945     * Detect if `Array#shift` and `Array#splice` augment array-like objects
 17946     * correctly.
 17947     *
 17948     * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
 17949     * `shift()` and `splice()` functions that fail to remove the last element,
 17950     * `value[0]`, of array-like objects even though the "length" property is
 17951     * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
 17952     * while `splice()` is buggy regardless of mode in IE < 9.
 17953     *
 17954     * @memberOf _.support
 17955     * @type boolean
 17956     */
 17957    support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
 17958  
 17959    /**
 17960     * Detect lack of support for accessing string characters by index.
 17961     *
 17962     * IE < 8 can't access characters by index. IE 8 can only access characters
 17963     * by index on string literals, not string objects.
 17964     *
 17965     * @memberOf _.support
 17966     * @type boolean
 17967     */
 17968    support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
 17969  }(1, 0));
 17970  
 17971  module.exports = support;
 17972  
 17973  },{}],154:[function(require,module,exports){
 17974  /**
 17975   * This method returns the first argument provided to it.
 17976   *
 17977   * @static
 17978   * @memberOf _
 17979   * @category Utility
 17980   * @param {*} value Any value.
 17981   * @returns {*} Returns `value`.
 17982   * @example
 17983   *
 17984   * var object = { 'user': 'fred' };
 17985   *
 17986   * _.identity(object) === object;
 17987   * // => true
 17988   */
 17989  function identity(value) {
 17990    return value;
 17991  }
 17992  
 17993  module.exports = identity;
 17994  
 17995  },{}],155:[function(require,module,exports){
 17996  /**
 17997   * A no-operation function that returns `undefined` regardless of the
 17998   * arguments it receives.
 17999   *
 18000   * @static
 18001   * @memberOf _
 18002   * @category Utility
 18003   * @example
 18004   *
 18005   * var object = { 'user': 'fred' };
 18006   *
 18007   * _.noop(object) === undefined;
 18008   * // => true
 18009   */
 18010  function noop() {
 18011    // No operation performed.
 18012  }
 18013  
 18014  module.exports = noop;
 18015  
 18016  },{}],156:[function(require,module,exports){
 18017  var baseProperty = require('../internal/baseProperty'),
 18018      basePropertyDeep = require('../internal/basePropertyDeep'),
 18019      isKey = require('../internal/isKey');
 18020  
 18021  /**
 18022   * Creates a function that returns the property value at `path` on a
 18023   * given object.
 18024   *
 18025   * @static
 18026   * @memberOf _
 18027   * @category Utility
 18028   * @param {Array|string} path The path of the property to get.
 18029   * @returns {Function} Returns the new function.
 18030   * @example
 18031   *
 18032   * var objects = [
 18033   *   { 'a': { 'b': { 'c': 2 } } },
 18034   *   { 'a': { 'b': { 'c': 1 } } }
 18035   * ];
 18036   *
 18037   * _.map(objects, _.property('a.b.c'));
 18038   * // => [2, 1]
 18039   *
 18040   * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
 18041   * // => [1, 2]
 18042   */
 18043  function property(path) {
 18044    return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
 18045  }
 18046  
 18047  module.exports = property;
 18048  
 18049  },{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(require,module,exports){
 18050  (function (process){
 18051  // vim:ts=4:sts=4:sw=4:
 18052  /*!
 18053   *
 18054   * Copyright 2009-2012 Kris Kowal under the terms of the MIT
 18055   * license found at http://github.com/kriskowal/q/raw/master/LICENSE
 18056   *
 18057   * With parts by Tyler Close
 18058   * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
 18059   * at http://www.opensource.org/licenses/mit-license.html
 18060   * Forked at ref_send.js version: 2009-05-11
 18061   *
 18062   * With parts by Mark Miller
 18063   * Copyright (C) 2011 Google Inc.
 18064   *
 18065   * Licensed under the Apache License, Version 2.0 (the "License");
 18066   * you may not use this file except in compliance with the License.
 18067   * You may obtain a copy of the License at
 18068   *
 18069   * http://www.apache.org/licenses/LICENSE-2.0
 18070   *
 18071   * Unless required by applicable law or agreed to in writing, software
 18072   * distributed under the License is distributed on an "AS IS" BASIS,
 18073   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 18074   * See the License for the specific language governing permissions and
 18075   * limitations under the License.
 18076   *
 18077   */
 18078  
 18079  (function (definition) {
 18080      "use strict";
 18081  
 18082      // This file will function properly as a <script> tag, or a module
 18083      // using CommonJS and NodeJS or RequireJS module formats.  In
 18084      // Common/Node/RequireJS, the module exports the Q API and when
 18085      // executed as a simple <script>, it creates a Q global instead.
 18086  
 18087      // Montage Require
 18088      if (typeof bootstrap === "function") {
 18089          bootstrap("promise", definition);
 18090  
 18091      // CommonJS
 18092      } else if (typeof exports === "object" && typeof module === "object") {
 18093          module.exports = definition();
 18094  
 18095      // RequireJS
 18096      } else if (typeof define === "function" && define.amd) {
 18097          define(definition);
 18098  
 18099      // SES (Secure EcmaScript)
 18100      } else if (typeof ses !== "undefined") {
 18101          if (!ses.ok()) {
 18102              return;
 18103          } else {
 18104              ses.makeQ = definition;
 18105          }
 18106  
 18107      // <script>
 18108      } else if (typeof window !== "undefined" || typeof self !== "undefined") {
 18109          // Prefer window over self for add-on scripts. Use self for
 18110          // non-windowed contexts.
 18111          var global = typeof window !== "undefined" ? window : self;
 18112  
 18113          // Get the `window` object, save the previous Q global
 18114          // and initialize Q as a global.
 18115          var previousQ = global.Q;
 18116          global.Q = definition();
 18117  
 18118          // Add a noConflict function so Q can be removed from the
 18119          // global namespace.
 18120          global.Q.noConflict = function () {
 18121              global.Q = previousQ;
 18122              return this;
 18123          };
 18124  
 18125      } else {
 18126          throw new Error("This environment was not anticipated by Q. Please file a bug.");
 18127      }
 18128  
 18129  })(function () {
 18130  "use strict";
 18131  
 18132  var hasStacks = false;
 18133  try {
 18134      throw new Error();
 18135  } catch (e) {
 18136      hasStacks = !!e.stack;
 18137  }
 18138  
 18139  // All code after this point will be filtered from stack traces reported
 18140  // by Q.
 18141  var qStartingLine = captureLine();
 18142  var qFileName;
 18143  
 18144  // shims
 18145  
 18146  // used for fallback in "allResolved"
 18147  var noop = function () {};
 18148  
 18149  // Use the fastest possible means to execute a task in a future turn
 18150  // of the event loop.
 18151  var nextTick =(function () {
 18152      // linked list of tasks (single, with head node)
 18153      var head = {task: void 0, next: null};
 18154      var tail = head;
 18155      var flushing = false;
 18156      var requestTick = void 0;
 18157      var isNodeJS = false;
 18158      // queue for late tasks, used by unhandled rejection tracking
 18159      var laterQueue = [];
 18160  
 18161      function flush() {
 18162          /* jshint loopfunc: true */
 18163          var task, domain;
 18164  
 18165          while (head.next) {
 18166              head = head.next;
 18167              task = head.task;
 18168              head.task = void 0;
 18169              domain = head.domain;
 18170  
 18171              if (domain) {
 18172                  head.domain = void 0;
 18173                  domain.enter();
 18174              }
 18175              runSingle(task, domain);
 18176  
 18177          }
 18178          while (laterQueue.length) {
 18179              task = laterQueue.pop();
 18180              runSingle(task);
 18181          }
 18182          flushing = false;
 18183      }
 18184      // runs a single function in the async queue
 18185      function runSingle(task, domain) {
 18186          try {
 18187              task();
 18188  
 18189          } catch (e) {
 18190              if (isNodeJS) {
 18191                  // In node, uncaught exceptions are considered fatal errors.
 18192                  // Re-throw them synchronously to interrupt flushing!
 18193  
 18194                  // Ensure continuation if the uncaught exception is suppressed
 18195                  // listening "uncaughtException" events (as domains does).
 18196                  // Continue in next event to avoid tick recursion.
 18197                  if (domain) {
 18198                      domain.exit();
 18199                  }
 18200                  setTimeout(flush, 0);
 18201                  if (domain) {
 18202                      domain.enter();
 18203                  }
 18204  
 18205                  throw e;
 18206  
 18207              } else {
 18208                  // In browsers, uncaught exceptions are not fatal.
 18209                  // Re-throw them asynchronously to avoid slow-downs.
 18210                  setTimeout(function () {
 18211                      throw e;
 18212                  }, 0);
 18213              }
 18214          }
 18215  
 18216          if (domain) {
 18217              domain.exit();
 18218          }
 18219      }
 18220  
 18221      nextTick = function (task) {
 18222          tail = tail.next = {
 18223              task: task,
 18224              domain: isNodeJS && process.domain,
 18225              next: null
 18226          };
 18227  
 18228          if (!flushing) {
 18229              flushing = true;
 18230              requestTick();
 18231          }
 18232      };
 18233  
 18234      if (typeof process === "object" &&
 18235          process.toString() === "[object process]" && process.nextTick) {
 18236          // Ensure Q is in a real Node environment, with a `process.nextTick`.
 18237          // To see through fake Node environments:
 18238          // * Mocha test runner - exposes a `process` global without a `nextTick`
 18239          // * Browserify - exposes a `process.nexTick` function that uses
 18240          //   `setTimeout`. In this case `setImmediate` is preferred because
 18241          //    it is faster. Browserify's `process.toString()` yields
 18242          //   "[object Object]", while in a real Node environment
 18243          //   `process.nextTick()` yields "[object process]".
 18244          isNodeJS = true;
 18245  
 18246          requestTick = function () {
 18247              process.nextTick(flush);
 18248          };
 18249  
 18250      } else if (typeof setImmediate === "function") {
 18251          // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
 18252          if (typeof window !== "undefined") {
 18253              requestTick = setImmediate.bind(window, flush);
 18254          } else {
 18255              requestTick = function () {
 18256                  setImmediate(flush);
 18257              };
 18258          }
 18259  
 18260      } else if (typeof MessageChannel !== "undefined") {
 18261          // modern browsers
 18262          // http://www.nonblocking.io/2011/06/windownexttick.html
 18263          var channel = new MessageChannel();
 18264          // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
 18265          // working message ports the first time a page loads.
 18266          channel.port1.onmessage = function () {
 18267              requestTick = requestPortTick;
 18268              channel.port1.onmessage = flush;
 18269              flush();
 18270          };
 18271          var requestPortTick = function () {
 18272              // Opera requires us to provide a message payload, regardless of
 18273              // whether we use it.
 18274              channel.port2.postMessage(0);
 18275          };
 18276          requestTick = function () {
 18277              setTimeout(flush, 0);
 18278              requestPortTick();
 18279          };
 18280  
 18281      } else {
 18282          // old browsers
 18283          requestTick = function () {
 18284              setTimeout(flush, 0);
 18285          };
 18286      }
 18287      // runs a task after all other tasks have been run
 18288      // this is useful for unhandled rejection tracking that needs to happen
 18289      // after all `then`d tasks have been run.
 18290      nextTick.runAfter = function (task) {
 18291          laterQueue.push(task);
 18292          if (!flushing) {
 18293              flushing = true;
 18294              requestTick();
 18295          }
 18296      };
 18297      return nextTick;
 18298  })();
 18299  
 18300  // Attempt to make generics safe in the face of downstream
 18301  // modifications.
 18302  // There is no situation where this is necessary.
 18303  // If you need a security guarantee, these primordials need to be
 18304  // deeply frozen anyway, and if you don’t need a security guarantee,
 18305  // this is just plain paranoid.
 18306  // However, this **might** have the nice side-effect of reducing the size of
 18307  // the minified code by reducing x.call() to merely x()
 18308  // See Mark Miller’s explanation of what this does.
 18309  // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
 18310  var call = Function.call;
 18311  function uncurryThis(f) {
 18312      return function () {
 18313          return call.apply(f, arguments);
 18314      };
 18315  }
 18316  // This is equivalent, but slower:
 18317  // uncurryThis = Function_bind.bind(Function_bind.call);
 18318  // http://jsperf.com/uncurrythis
 18319  
 18320  var array_slice = uncurryThis(Array.prototype.slice);
 18321  
 18322  var array_reduce = uncurryThis(
 18323      Array.prototype.reduce || function (callback, basis) {
 18324          var index = 0,
 18325              length = this.length;
 18326          // concerning the initial value, if one is not provided
 18327          if (arguments.length === 1) {
 18328              // seek to the first value in the array, accounting
 18329              // for the possibility that is is a sparse array
 18330              do {
 18331                  if (index in this) {
 18332                      basis = this[index++];
 18333                      break;
 18334                  }
 18335                  if (++index >= length) {
 18336                      throw new TypeError();
 18337                  }
 18338              } while (1);
 18339          }
 18340          // reduce
 18341          for (; index < length; index++) {
 18342              // account for the possibility that the array is sparse
 18343              if (index in this) {
 18344                  basis = callback(basis, this[index], index);
 18345              }
 18346          }
 18347          return basis;
 18348      }
 18349  );
 18350  
 18351  var array_indexOf = uncurryThis(
 18352      Array.prototype.indexOf || function (value) {
 18353          // not a very good shim, but good enough for our one use of it
 18354          for (var i = 0; i < this.length; i++) {
 18355              if (this[i] === value) {
 18356                  return i;
 18357              }
 18358          }
 18359          return -1;
 18360      }
 18361  );
 18362  
 18363  var array_map = uncurryThis(
 18364      Array.prototype.map || function (callback, thisp) {
 18365          var self = this;
 18366          var collect = [];
 18367          array_reduce(self, function (undefined, value, index) {
 18368              collect.push(callback.call(thisp, value, index, self));
 18369          }, void 0);
 18370          return collect;
 18371      }
 18372  );
 18373  
 18374  var object_create = Object.create || function (prototype) {
 18375      function Type() { }
 18376      Type.prototype = prototype;
 18377      return new Type();
 18378  };
 18379  
 18380  var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
 18381  
 18382  var object_keys = Object.keys || function (object) {
 18383      var keys = [];
 18384      for (var key in object) {
 18385          if (object_hasOwnProperty(object, key)) {
 18386              keys.push(key);
 18387          }
 18388      }
 18389      return keys;
 18390  };
 18391  
 18392  var object_toString = uncurryThis(Object.prototype.toString);
 18393  
 18394  function isObject(value) {
 18395      return value === Object(value);
 18396  }
 18397  
 18398  // generator related shims
 18399  
 18400  // FIXME: Remove this function once ES6 generators are in SpiderMonkey.
 18401  function isStopIteration(exception) {
 18402      return (
 18403          object_toString(exception) === "[object StopIteration]" ||
 18404          exception instanceof QReturnValue
 18405      );
 18406  }
 18407  
 18408  // FIXME: Remove this helper and Q.return once ES6 generators are in
 18409  // SpiderMonkey.
 18410  var QReturnValue;
 18411  if (typeof ReturnValue !== "undefined") {
 18412      QReturnValue = ReturnValue;
 18413  } else {
 18414      QReturnValue = function (value) {
 18415          this.value = value;
 18416      };
 18417  }
 18418  
 18419  // long stack traces
 18420  
 18421  var STACK_JUMP_SEPARATOR = "From previous event:";
 18422  
 18423  function makeStackTraceLong(error, promise) {
 18424      // If possible, transform the error stack trace by removing Node and Q
 18425      // cruft, then concatenating with the stack trace of `promise`. See #57.
 18426      if (hasStacks &&
 18427          promise.stack &&
 18428          typeof error === "object" &&
 18429          error !== null &&
 18430          error.stack &&
 18431          error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
 18432      ) {
 18433          var stacks = [];
 18434          for (var p = promise; !!p; p = p.source) {
 18435              if (p.stack) {
 18436                  stacks.unshift(p.stack);
 18437              }
 18438          }
 18439          stacks.unshift(error.stack);
 18440  
 18441          var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
 18442          error.stack = filterStackString(concatedStacks);
 18443      }
 18444  }
 18445  
 18446  function filterStackString(stackString) {
 18447      var lines = stackString.split("\n");
 18448      var desiredLines = [];
 18449      for (var i = 0; i < lines.length; ++i) {
 18450          var line = lines[i];
 18451  
 18452          if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
 18453              desiredLines.push(line);
 18454          }
 18455      }
 18456      return desiredLines.join("\n");
 18457  }
 18458  
 18459  function isNodeFrame(stackLine) {
 18460      return stackLine.indexOf("(module.js:") !== -1 ||
 18461             stackLine.indexOf("(node.js:") !== -1;
 18462  }
 18463  
 18464  function getFileNameAndLineNumber(stackLine) {
 18465      // Named functions: "at functionName (filename:lineNumber:columnNumber)"
 18466      // In IE10 function name can have spaces ("Anonymous function") O_o
 18467      var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
 18468      if (attempt1) {
 18469          return [attempt1[1], Number(attempt1[2])];
 18470      }
 18471  
 18472      // Anonymous functions: "at filename:lineNumber:columnNumber"
 18473      var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
 18474      if (attempt2) {
 18475          return [attempt2[1], Number(attempt2[2])];
 18476      }
 18477  
 18478      // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
 18479      var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
 18480      if (attempt3) {
 18481          return [attempt3[1], Number(attempt3[2])];
 18482      }
 18483  }
 18484  
 18485  function isInternalFrame(stackLine) {
 18486      var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
 18487  
 18488      if (!fileNameAndLineNumber) {
 18489          return false;
 18490      }
 18491  
 18492      var fileName = fileNameAndLineNumber[0];
 18493      var lineNumber = fileNameAndLineNumber[1];
 18494  
 18495      return fileName === qFileName &&
 18496          lineNumber >= qStartingLine &&
 18497          lineNumber <= qEndingLine;
 18498  }
 18499  
 18500  // discover own file name and line number range for filtering stack
 18501  // traces
 18502  function captureLine() {
 18503      if (!hasStacks) {
 18504          return;
 18505      }
 18506  
 18507      try {
 18508          throw new Error();
 18509      } catch (e) {
 18510          var lines = e.stack.split("\n");
 18511          var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
 18512          var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
 18513          if (!fileNameAndLineNumber) {
 18514              return;
 18515          }
 18516  
 18517          qFileName = fileNameAndLineNumber[0];
 18518          return fileNameAndLineNumber[1];
 18519      }
 18520  }
 18521  
 18522  function deprecate(callback, name, alternative) {
 18523      return function () {
 18524          if (typeof console !== "undefined" &&
 18525              typeof console.warn === "function") {
 18526              console.warn(name + " is deprecated, use " + alternative +
 18527                           " instead.", new Error("").stack);
 18528          }
 18529          return callback.apply(callback, arguments);
 18530      };
 18531  }
 18532  
 18533  // end of shims
 18534  // beginning of real work
 18535  
 18536  /**
 18537   * Constructs a promise for an immediate reference, passes promises through, or
 18538   * coerces promises from different systems.
 18539   * @param value immediate reference or promise
 18540   */
 18541  function Q(value) {
 18542      // If the object is already a Promise, return it directly.  This enables
 18543      // the resolve function to both be used to created references from objects,
 18544      // but to tolerably coerce non-promises to promises.
 18545      if (value instanceof Promise) {
 18546          return value;
 18547      }
 18548  
 18549      // assimilate thenables
 18550      if (isPromiseAlike(value)) {
 18551          return coerce(value);
 18552      } else {
 18553          return fulfill(value);
 18554      }
 18555  }
 18556  Q.resolve = Q;
 18557  
 18558  /**
 18559   * Performs a task in a future turn of the event loop.
 18560   * @param {Function} task
 18561   */
 18562  Q.nextTick = nextTick;
 18563  
 18564  /**
 18565   * Controls whether or not long stack traces will be on
 18566   */
 18567  Q.longStackSupport = false;
 18568  
 18569  // enable long stacks if Q_DEBUG is set
 18570  if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
 18571      Q.longStackSupport = true;
 18572  }
 18573  
 18574  /**
 18575   * Constructs a {promise, resolve, reject} object.
 18576   *
 18577   * `resolve` is a callback to invoke with a more resolved value for the
 18578   * promise. To fulfill the promise, invoke `resolve` with any value that is
 18579   * not a thenable. To reject the promise, invoke `resolve` with a rejected
 18580   * thenable, or invoke `reject` with the reason directly. To resolve the
 18581   * promise to another thenable, thus putting it in the same state, invoke
 18582   * `resolve` with that other thenable.
 18583   */
 18584  Q.defer = defer;
 18585  function defer() {
 18586      // if "messages" is an "Array", that indicates that the promise has not yet
 18587      // been resolved.  If it is "undefined", it has been resolved.  Each
 18588      // element of the messages array is itself an array of complete arguments to
 18589      // forward to the resolved promise.  We coerce the resolution value to a
 18590      // promise using the `resolve` function because it handles both fully
 18591      // non-thenable values and other thenables gracefully.
 18592      var messages = [], progressListeners = [], resolvedPromise;
 18593  
 18594      var deferred = object_create(defer.prototype);
 18595      var promise = object_create(Promise.prototype);
 18596  
 18597      promise.promiseDispatch = function (resolve, op, operands) {
 18598          var args = array_slice(arguments);
 18599          if (messages) {
 18600              messages.push(args);
 18601              if (op === "when" && operands[1]) { // progress operand
 18602                  progressListeners.push(operands[1]);
 18603              }
 18604          } else {
 18605              Q.nextTick(function () {
 18606                  resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
 18607              });
 18608          }
 18609      };
 18610  
 18611      // XXX deprecated
 18612      promise.valueOf = function () {
 18613          if (messages) {
 18614              return promise;
 18615          }
 18616          var nearerValue = nearer(resolvedPromise);
 18617          if (isPromise(nearerValue)) {
 18618              resolvedPromise = nearerValue; // shorten chain
 18619          }
 18620          return nearerValue;
 18621      };
 18622  
 18623      promise.inspect = function () {
 18624          if (!resolvedPromise) {
 18625              return { state: "pending" };
 18626          }
 18627          return resolvedPromise.inspect();
 18628      };
 18629  
 18630      if (Q.longStackSupport && hasStacks) {
 18631          try {
 18632              throw new Error();
 18633          } catch (e) {
 18634              // NOTE: don't try to use `Error.captureStackTrace` or transfer the
 18635              // accessor around; that causes memory leaks as per GH-111. Just
 18636              // reify the stack trace as a string ASAP.
 18637              //
 18638              // At the same time, cut off the first line; it's always just
 18639              // "[object Promise]\n", as per the `toString`.
 18640              promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
 18641          }
 18642      }
 18643  
 18644      // NOTE: we do the checks for `resolvedPromise` in each method, instead of
 18645      // consolidating them into `become`, since otherwise we'd create new
 18646      // promises with the lines `become(whatever(value))`. See e.g. GH-252.
 18647  
 18648      function become(newPromise) {
 18649          resolvedPromise = newPromise;
 18650          promise.source = newPromise;
 18651  
 18652          array_reduce(messages, function (undefined, message) {
 18653              Q.nextTick(function () {
 18654                  newPromise.promiseDispatch.apply(newPromise, message);
 18655              });
 18656          }, void 0);
 18657  
 18658          messages = void 0;
 18659          progressListeners = void 0;
 18660      }
 18661  
 18662      deferred.promise = promise;
 18663      deferred.resolve = function (value) {
 18664          if (resolvedPromise) {
 18665              return;
 18666          }
 18667  
 18668          become(Q(value));
 18669      };
 18670  
 18671      deferred.fulfill = function (value) {
 18672          if (resolvedPromise) {
 18673              return;
 18674          }
 18675  
 18676          become(fulfill(value));
 18677      };
 18678      deferred.reject = function (reason) {
 18679          if (resolvedPromise) {
 18680              return;
 18681          }
 18682  
 18683          become(reject(reason));
 18684      };
 18685      deferred.notify = function (progress) {
 18686          if (resolvedPromise) {
 18687              return;
 18688          }
 18689  
 18690          array_reduce(progressListeners, function (undefined, progressListener) {
 18691              Q.nextTick(function () {
 18692                  progressListener(progress);
 18693              });
 18694          }, void 0);
 18695      };
 18696  
 18697      return deferred;
 18698  }
 18699  
 18700  /**
 18701   * Creates a Node-style callback that will resolve or reject the deferred
 18702   * promise.
 18703   * @returns a nodeback
 18704   */
 18705  defer.prototype.makeNodeResolver = function () {
 18706      var self = this;
 18707      return function (error, value) {
 18708          if (error) {
 18709              self.reject(error);
 18710          } else if (arguments.length > 2) {
 18711              self.resolve(array_slice(arguments, 1));
 18712          } else {
 18713              self.resolve(value);
 18714          }
 18715      };
 18716  };
 18717  
 18718  /**
 18719   * @param resolver {Function} a function that returns nothing and accepts
 18720   * the resolve, reject, and notify functions for a deferred.
 18721   * @returns a promise that may be resolved with the given resolve and reject
 18722   * functions, or rejected by a thrown exception in resolver
 18723   */
 18724  Q.Promise = promise; // ES6
 18725  Q.promise = promise;
 18726  function promise(resolver) {
 18727      if (typeof resolver !== "function") {
 18728          throw new TypeError("resolver must be a function.");
 18729      }
 18730      var deferred = defer();
 18731      try {
 18732          resolver(deferred.resolve, deferred.reject, deferred.notify);
 18733      } catch (reason) {
 18734          deferred.reject(reason);
 18735      }
 18736      return deferred.promise;
 18737  }
 18738  
 18739  promise.race = race; // ES6
 18740  promise.all = all; // ES6
 18741  promise.reject = reject; // ES6
 18742  promise.resolve = Q; // ES6
 18743  
 18744  // XXX experimental.  This method is a way to denote that a local value is
 18745  // serializable and should be immediately dispatched to a remote upon request,
 18746  // instead of passing a reference.
 18747  Q.passByCopy = function (object) {
 18748      //freeze(object);
 18749      //passByCopies.set(object, true);
 18750      return object;
 18751  };
 18752  
 18753  Promise.prototype.passByCopy = function () {
 18754      //freeze(object);
 18755      //passByCopies.set(object, true);
 18756      return this;
 18757  };
 18758  
 18759  /**
 18760   * If two promises eventually fulfill to the same value, promises that value,
 18761   * but otherwise rejects.
 18762   * @param x {Any*}
 18763   * @param y {Any*}
 18764   * @returns {Any*} a promise for x and y if they are the same, but a rejection
 18765   * otherwise.
 18766   *
 18767   */
 18768  Q.join = function (x, y) {
 18769      return Q(x).join(y);
 18770  };
 18771  
 18772  Promise.prototype.join = function (that) {
 18773      return Q([this, that]).spread(function (x, y) {
 18774          if (x === y) {
 18775              // TODO: "===" should be Object.is or equiv
 18776              return x;
 18777          } else {
 18778              throw new Error("Can't join: not the same: " + x + " " + y);
 18779          }
 18780      });
 18781  };
 18782  
 18783  /**
 18784   * Returns a promise for the first of an array of promises to become settled.
 18785   * @param answers {Array[Any*]} promises to race
 18786   * @returns {Any*} the first promise to be settled
 18787   */
 18788  Q.race = race;
 18789  function race(answerPs) {
 18790      return promise(function (resolve, reject) {
 18791          // Switch to this once we can assume at least ES5
 18792          // answerPs.forEach(function (answerP) {
 18793          //     Q(answerP).then(resolve, reject);
 18794          // });
 18795          // Use this in the meantime
 18796          for (var i = 0, len = answerPs.length; i < len; i++) {
 18797              Q(answerPs[i]).then(resolve, reject);
 18798          }
 18799      });
 18800  }
 18801  
 18802  Promise.prototype.race = function () {
 18803      return this.then(Q.race);
 18804  };
 18805  
 18806  /**
 18807   * Constructs a Promise with a promise descriptor object and optional fallback
 18808   * function.  The descriptor contains methods like when(rejected), get(name),
 18809   * set(name, value), post(name, args), and delete(name), which all
 18810   * return either a value, a promise for a value, or a rejection.  The fallback
 18811   * accepts the operation name, a resolver, and any further arguments that would
 18812   * have been forwarded to the appropriate method above had a method been
 18813   * provided with the proper name.  The API makes no guarantees about the nature
 18814   * of the returned object, apart from that it is usable whereever promises are
 18815   * bought and sold.
 18816   */
 18817  Q.makePromise = Promise;
 18818  function Promise(descriptor, fallback, inspect) {
 18819      if (fallback === void 0) {
 18820          fallback = function (op) {
 18821              return reject(new Error(
 18822                  "Promise does not support operation: " + op
 18823              ));
 18824          };
 18825      }
 18826      if (inspect === void 0) {
 18827          inspect = function () {
 18828              return {state: "unknown"};
 18829          };
 18830      }
 18831  
 18832      var promise = object_create(Promise.prototype);
 18833  
 18834      promise.promiseDispatch = function (resolve, op, args) {
 18835          var result;
 18836          try {
 18837              if (descriptor[op]) {
 18838                  result = descriptor[op].apply(promise, args);
 18839              } else {
 18840                  result = fallback.call(promise, op, args);
 18841              }
 18842          } catch (exception) {
 18843              result = reject(exception);
 18844          }
 18845          if (resolve) {
 18846              resolve(result);
 18847          }
 18848      };
 18849  
 18850      promise.inspect = inspect;
 18851  
 18852      // XXX deprecated `valueOf` and `exception` support
 18853      if (inspect) {
 18854          var inspected = inspect();
 18855          if (inspected.state === "rejected") {
 18856              promise.exception = inspected.reason;
 18857          }
 18858  
 18859          promise.valueOf = function () {
 18860              var inspected = inspect();
 18861              if (inspected.state === "pending" ||
 18862                  inspected.state === "rejected") {
 18863                  return promise;
 18864              }
 18865              return inspected.value;
 18866          };
 18867      }
 18868  
 18869      return promise;
 18870  }
 18871  
 18872  Promise.prototype.toString = function () {
 18873      return "[object Promise]";
 18874  };
 18875  
 18876  Promise.prototype.then = function (fulfilled, rejected, progressed) {
 18877      var self = this;
 18878      var deferred = defer();
 18879      var done = false;   // ensure the untrusted promise makes at most a
 18880                          // single call to one of the callbacks
 18881  
 18882      function _fulfilled(value) {
 18883          try {
 18884              return typeof fulfilled === "function" ? fulfilled(value) : value;
 18885          } catch (exception) {
 18886              return reject(exception);
 18887          }
 18888      }
 18889  
 18890      function _rejected(exception) {
 18891          if (typeof rejected === "function") {
 18892              makeStackTraceLong(exception, self);
 18893              try {
 18894                  return rejected(exception);
 18895              } catch (newException) {
 18896                  return reject(newException);
 18897              }
 18898          }
 18899          return reject(exception);
 18900      }
 18901  
 18902      function _progressed(value) {
 18903          return typeof progressed === "function" ? progressed(value) : value;
 18904      }
 18905  
 18906      Q.nextTick(function () {
 18907          self.promiseDispatch(function (value) {
 18908              if (done) {
 18909                  return;
 18910              }
 18911              done = true;
 18912  
 18913              deferred.resolve(_fulfilled(value));
 18914          }, "when", [function (exception) {
 18915              if (done) {
 18916                  return;
 18917              }
 18918              done = true;
 18919  
 18920              deferred.resolve(_rejected(exception));
 18921          }]);
 18922      });
 18923  
 18924      // Progress propagator need to be attached in the current tick.
 18925      self.promiseDispatch(void 0, "when", [void 0, function (value) {
 18926          var newValue;
 18927          var threw = false;
 18928          try {
 18929              newValue = _progressed(value);
 18930          } catch (e) {
 18931              threw = true;
 18932              if (Q.onerror) {
 18933                  Q.onerror(e);
 18934              } else {
 18935                  throw e;
 18936              }
 18937          }
 18938  
 18939          if (!threw) {
 18940              deferred.notify(newValue);
 18941          }
 18942      }]);
 18943  
 18944      return deferred.promise;
 18945  };
 18946  
 18947  Q.tap = function (promise, callback) {
 18948      return Q(promise).tap(callback);
 18949  };
 18950  
 18951  /**
 18952   * Works almost like "finally", but not called for rejections.
 18953   * Original resolution value is passed through callback unaffected.
 18954   * Callback may return a promise that will be awaited for.
 18955   * @param {Function} callback
 18956   * @returns {Q.Promise}
 18957   * @example
 18958   * doSomething()
 18959   *   .then(...)
 18960   *   .tap(console.log)
 18961   *   .then(...);
 18962   */
 18963  Promise.prototype.tap = function (callback) {
 18964      callback = Q(callback);
 18965  
 18966      return this.then(function (value) {
 18967          return callback.fcall(value).thenResolve(value);
 18968      });
 18969  };
 18970  
 18971  /**
 18972   * Registers an observer on a promise.
 18973   *
 18974   * Guarantees:
 18975   *
 18976   * 1. that fulfilled and rejected will be called only once.
 18977   * 2. that either the fulfilled callback or the rejected callback will be
 18978   *    called, but not both.
 18979   * 3. that fulfilled and rejected will not be called in this turn.
 18980   *
 18981   * @param value      promise or immediate reference to observe
 18982   * @param fulfilled  function to be called with the fulfilled value
 18983   * @param rejected   function to be called with the rejection exception
 18984   * @param progressed function to be called on any progress notifications
 18985   * @return promise for the return value from the invoked callback
 18986   */
 18987  Q.when = when;
 18988  function when(value, fulfilled, rejected, progressed) {
 18989      return Q(value).then(fulfilled, rejected, progressed);
 18990  }
 18991  
 18992  Promise.prototype.thenResolve = function (value) {
 18993      return this.then(function () { return value; });
 18994  };
 18995  
 18996  Q.thenResolve = function (promise, value) {
 18997      return Q(promise).thenResolve(value);
 18998  };
 18999  
 19000  Promise.prototype.thenReject = function (reason) {
 19001      return this.then(function () { throw reason; });
 19002  };
 19003  
 19004  Q.thenReject = function (promise, reason) {
 19005      return Q(promise).thenReject(reason);
 19006  };
 19007  
 19008  /**
 19009   * If an object is not a promise, it is as "near" as possible.
 19010   * If a promise is rejected, it is as "near" as possible too.
 19011   * If it’s a fulfilled promise, the fulfillment value is nearer.
 19012   * If it’s a deferred promise and the deferred has been resolved, the
 19013   * resolution is "nearer".
 19014   * @param object
 19015   * @returns most resolved (nearest) form of the object
 19016   */
 19017  
 19018  // XXX should we re-do this?
 19019  Q.nearer = nearer;
 19020  function nearer(value) {
 19021      if (isPromise(value)) {
 19022          var inspected = value.inspect();
 19023          if (inspected.state === "fulfilled") {
 19024              return inspected.value;
 19025          }
 19026      }
 19027      return value;
 19028  }
 19029  
 19030  /**
 19031   * @returns whether the given object is a promise.
 19032   * Otherwise it is a fulfilled value.
 19033   */
 19034  Q.isPromise = isPromise;
 19035  function isPromise(object) {
 19036      return object instanceof Promise;
 19037  }
 19038  
 19039  Q.isPromiseAlike = isPromiseAlike;
 19040  function isPromiseAlike(object) {
 19041      return isObject(object) && typeof object.then === "function";
 19042  }
 19043  
 19044  /**
 19045   * @returns whether the given object is a pending promise, meaning not
 19046   * fulfilled or rejected.
 19047   */
 19048  Q.isPending = isPending;
 19049  function isPending(object) {
 19050      return isPromise(object) && object.inspect().state === "pending";
 19051  }
 19052  
 19053  Promise.prototype.isPending = function () {
 19054      return this.inspect().state === "pending";
 19055  };
 19056  
 19057  /**
 19058   * @returns whether the given object is a value or fulfilled
 19059   * promise.
 19060   */
 19061  Q.isFulfilled = isFulfilled;
 19062  function isFulfilled(object) {
 19063      return !isPromise(object) || object.inspect().state === "fulfilled";
 19064  }
 19065  
 19066  Promise.prototype.isFulfilled = function () {
 19067      return this.inspect().state === "fulfilled";
 19068  };
 19069  
 19070  /**
 19071   * @returns whether the given object is a rejected promise.
 19072   */
 19073  Q.isRejected = isRejected;
 19074  function isRejected(object) {
 19075      return isPromise(object) && object.inspect().state === "rejected";
 19076  }
 19077  
 19078  Promise.prototype.isRejected = function () {
 19079      return this.inspect().state === "rejected";
 19080  };
 19081  
 19082  //// BEGIN UNHANDLED REJECTION TRACKING
 19083  
 19084  // This promise library consumes exceptions thrown in handlers so they can be
 19085  // handled by a subsequent promise.  The exceptions get added to this array when
 19086  // they are created, and removed when they are handled.  Note that in ES6 or
 19087  // shimmed environments, this would naturally be a `Set`.
 19088  var unhandledReasons = [];
 19089  var unhandledRejections = [];
 19090  var reportedUnhandledRejections = [];
 19091  var trackUnhandledRejections = true;
 19092  
 19093  function resetUnhandledRejections() {
 19094      unhandledReasons.length = 0;
 19095      unhandledRejections.length = 0;
 19096  
 19097      if (!trackUnhandledRejections) {
 19098          trackUnhandledRejections = true;
 19099      }
 19100  }
 19101  
 19102  function trackRejection(promise, reason) {
 19103      if (!trackUnhandledRejections) {
 19104          return;
 19105      }
 19106      if (typeof process === "object" && typeof process.emit === "function") {
 19107          Q.nextTick.runAfter(function () {
 19108              if (array_indexOf(unhandledRejections, promise) !== -1) {
 19109                  process.emit("unhandledRejection", reason, promise);
 19110                  reportedUnhandledRejections.push(promise);
 19111              }
 19112          });
 19113      }
 19114  
 19115      unhandledRejections.push(promise);
 19116      if (reason && typeof reason.stack !== "undefined") {
 19117          unhandledReasons.push(reason.stack);
 19118      } else {
 19119          unhandledReasons.push("(no stack) " + reason);
 19120      }
 19121  }
 19122  
 19123  function untrackRejection(promise) {
 19124      if (!trackUnhandledRejections) {
 19125          return;
 19126      }
 19127  
 19128      var at = array_indexOf(unhandledRejections, promise);
 19129      if (at !== -1) {
 19130          if (typeof process === "object" && typeof process.emit === "function") {
 19131              Q.nextTick.runAfter(function () {
 19132                  var atReport = array_indexOf(reportedUnhandledRejections, promise);
 19133                  if (atReport !== -1) {
 19134                      process.emit("rejectionHandled", unhandledReasons[at], promise);
 19135                      reportedUnhandledRejections.splice(atReport, 1);
 19136                  }
 19137              });
 19138          }
 19139          unhandledRejections.splice(at, 1);
 19140          unhandledReasons.splice(at, 1);
 19141      }
 19142  }
 19143  
 19144  Q.resetUnhandledRejections = resetUnhandledRejections;
 19145  
 19146  Q.getUnhandledReasons = function () {
 19147      // Make a copy so that consumers can't interfere with our internal state.
 19148      return unhandledReasons.slice();
 19149  };
 19150  
 19151  Q.stopUnhandledRejectionTracking = function () {
 19152      resetUnhandledRejections();
 19153      trackUnhandledRejections = false;
 19154  };
 19155  
 19156  resetUnhandledRejections();
 19157  
 19158  //// END UNHANDLED REJECTION TRACKING
 19159  
 19160  /**
 19161   * Constructs a rejected promise.
 19162   * @param reason value describing the failure
 19163   */
 19164  Q.reject = reject;
 19165  function reject(reason) {
 19166      var rejection = Promise({
 19167          "when": function (rejected) {
 19168              // note that the error has been handled
 19169              if (rejected) {
 19170                  untrackRejection(this);
 19171              }
 19172              return rejected ? rejected(reason) : this;
 19173          }
 19174      }, function fallback() {
 19175          return this;
 19176      }, function inspect() {
 19177          return { state: "rejected", reason: reason };
 19178      });
 19179  
 19180      // Note that the reason has not been handled.
 19181      trackRejection(rejection, reason);
 19182  
 19183      return rejection;
 19184  }
 19185  
 19186  /**
 19187   * Constructs a fulfilled promise for an immediate reference.
 19188   * @param value immediate reference
 19189   */
 19190  Q.fulfill = fulfill;
 19191  function fulfill(value) {
 19192      return Promise({
 19193          "when": function () {
 19194              return value;
 19195          },
 19196          "get": function (name) {
 19197              return value[name];
 19198          },
 19199          "set": function (name, rhs) {
 19200              value[name] = rhs;
 19201          },
 19202          "delete": function (name) {
 19203              delete value[name];
 19204          },
 19205          "post": function (name, args) {
 19206              // Mark Miller proposes that post with no name should apply a
 19207              // promised function.
 19208              if (name === null || name === void 0) {
 19209                  return value.apply(void 0, args);
 19210              } else {
 19211                  return value[name].apply(value, args);
 19212              }
 19213          },
 19214          "apply": function (thisp, args) {
 19215              return value.apply(thisp, args);
 19216          },
 19217          "keys": function () {
 19218              return object_keys(value);
 19219          }
 19220      }, void 0, function inspect() {
 19221          return { state: "fulfilled", value: value };
 19222      });
 19223  }
 19224  
 19225  /**
 19226   * Converts thenables to Q promises.
 19227   * @param promise thenable promise
 19228   * @returns a Q promise
 19229   */
 19230  function coerce(promise) {
 19231      var deferred = defer();
 19232      Q.nextTick(function () {
 19233          try {
 19234              promise.then(deferred.resolve, deferred.reject, deferred.notify);
 19235          } catch (exception) {
 19236              deferred.reject(exception);
 19237          }
 19238      });
 19239      return deferred.promise;
 19240  }
 19241  
 19242  /**
 19243   * Annotates an object such that it will never be
 19244   * transferred away from this process over any promise
 19245   * communication channel.
 19246   * @param object
 19247   * @returns promise a wrapping of that object that
 19248   * additionally responds to the "isDef" message
 19249   * without a rejection.
 19250   */
 19251  Q.master = master;
 19252  function master(object) {
 19253      return Promise({
 19254          "isDef": function () {}
 19255      }, function fallback(op, args) {
 19256          return dispatch(object, op, args);
 19257      }, function () {
 19258          return Q(object).inspect();
 19259      });
 19260  }
 19261  
 19262  /**
 19263   * Spreads the values of a promised array of arguments into the
 19264   * fulfillment callback.
 19265   * @param fulfilled callback that receives variadic arguments from the
 19266   * promised array
 19267   * @param rejected callback that receives the exception if the promise
 19268   * is rejected.
 19269   * @returns a promise for the return value or thrown exception of
 19270   * either callback.
 19271   */
 19272  Q.spread = spread;
 19273  function spread(value, fulfilled, rejected) {
 19274      return Q(value).spread(fulfilled, rejected);
 19275  }
 19276  
 19277  Promise.prototype.spread = function (fulfilled, rejected) {
 19278      return this.all().then(function (array) {
 19279          return fulfilled.apply(void 0, array);
 19280      }, rejected);
 19281  };
 19282  
 19283  /**
 19284   * The async function is a decorator for generator functions, turning
 19285   * them into asynchronous generators.  Although generators are only part
 19286   * of the newest ECMAScript 6 drafts, this code does not cause syntax
 19287   * errors in older engines.  This code should continue to work and will
 19288   * in fact improve over time as the language improves.
 19289   *
 19290   * ES6 generators are currently part of V8 version 3.19 with the
 19291   * --harmony-generators runtime flag enabled.  SpiderMonkey has had them
 19292   * for longer, but under an older Python-inspired form.  This function
 19293   * works on both kinds of generators.
 19294   *
 19295   * Decorates a generator function such that:
 19296   *  - it may yield promises
 19297   *  - execution will continue when that promise is fulfilled
 19298   *  - the value of the yield expression will be the fulfilled value
 19299   *  - it returns a promise for the return value (when the generator
 19300   *    stops iterating)
 19301   *  - the decorated function returns a promise for the return value
 19302   *    of the generator or the first rejected promise among those
 19303   *    yielded.
 19304   *  - if an error is thrown in the generator, it propagates through
 19305   *    every following yield until it is caught, or until it escapes
 19306   *    the generator function altogether, and is translated into a
 19307   *    rejection for the promise returned by the decorated generator.
 19308   */
 19309  Q.async = async;
 19310  function async(makeGenerator) {
 19311      return function () {
 19312          // when verb is "send", arg is a value
 19313          // when verb is "throw", arg is an exception
 19314          function continuer(verb, arg) {
 19315              var result;
 19316  
 19317              // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
 19318              // engine that has a deployed base of browsers that support generators.
 19319              // However, SM's generators use the Python-inspired semantics of
 19320              // outdated ES6 drafts.  We would like to support ES6, but we'd also
 19321              // like to make it possible to use generators in deployed browsers, so
 19322              // we also support Python-style generators.  At some point we can remove
 19323              // this block.
 19324  
 19325              if (typeof StopIteration === "undefined") {
 19326                  // ES6 Generators
 19327                  try {
 19328                      result = generator[verb](arg);
 19329                  } catch (exception) {
 19330                      return reject(exception);
 19331                  }
 19332                  if (result.done) {
 19333                      return Q(result.value);
 19334                  } else {
 19335                      return when(result.value, callback, errback);
 19336                  }
 19337              } else {
 19338                  // SpiderMonkey Generators
 19339                  // FIXME: Remove this case when SM does ES6 generators.
 19340                  try {
 19341                      result = generator[verb](arg);
 19342                  } catch (exception) {
 19343                      if (isStopIteration(exception)) {
 19344                          return Q(exception.value);
 19345                      } else {
 19346                          return reject(exception);
 19347                      }
 19348                  }
 19349                  return when(result, callback, errback);
 19350              }
 19351          }
 19352          var generator = makeGenerator.apply(this, arguments);
 19353          var callback = continuer.bind(continuer, "next");
 19354          var errback = continuer.bind(continuer, "throw");
 19355          return callback();
 19356      };
 19357  }
 19358  
 19359  /**
 19360   * The spawn function is a small wrapper around async that immediately
 19361   * calls the generator and also ends the promise chain, so that any
 19362   * unhandled errors are thrown instead of forwarded to the error
 19363   * handler. This is useful because it's extremely common to run
 19364   * generators at the top-level to work with libraries.
 19365   */
 19366  Q.spawn = spawn;
 19367  function spawn(makeGenerator) {
 19368      Q.done(Q.async(makeGenerator)());
 19369  }
 19370  
 19371  // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
 19372  /**
 19373   * Throws a ReturnValue exception to stop an asynchronous generator.
 19374   *
 19375   * This interface is a stop-gap measure to support generator return
 19376   * values in older Firefox/SpiderMonkey.  In browsers that support ES6
 19377   * generators like Chromium 29, just use "return" in your generator
 19378   * functions.
 19379   *
 19380   * @param value the return value for the surrounding generator
 19381   * @throws ReturnValue exception with the value.
 19382   * @example
 19383   * // ES6 style
 19384   * Q.async(function* () {
 19385   *      var foo = yield getFooPromise();
 19386   *      var bar = yield getBarPromise();
 19387   *      return foo + bar;
 19388   * })
 19389   * // Older SpiderMonkey style
 19390   * Q.async(function () {
 19391   *      var foo = yield getFooPromise();
 19392   *      var bar = yield getBarPromise();
 19393   *      Q.return(foo + bar);
 19394   * })
 19395   */
 19396  Q["return"] = _return;
 19397  function _return(value) {
 19398      throw new QReturnValue(value);
 19399  }
 19400  
 19401  /**
 19402   * The promised function decorator ensures that any promise arguments
 19403   * are settled and passed as values (`this` is also settled and passed
 19404   * as a value).  It will also ensure that the result of a function is
 19405   * always a promise.
 19406   *
 19407   * @example
 19408   * var add = Q.promised(function (a, b) {
 19409   *     return a + b;
 19410   * });
 19411   * add(Q(a), Q(B));
 19412   *
 19413   * @param {function} callback The function to decorate
 19414   * @returns {function} a function that has been decorated.
 19415   */
 19416  Q.promised = promised;
 19417  function promised(callback) {
 19418      return function () {
 19419          return spread([this, all(arguments)], function (self, args) {
 19420              return callback.apply(self, args);
 19421          });
 19422      };
 19423  }
 19424  
 19425  /**
 19426   * sends a message to a value in a future turn
 19427   * @param object* the recipient
 19428   * @param op the name of the message operation, e.g., "when",
 19429   * @param args further arguments to be forwarded to the operation
 19430   * @returns result {Promise} a promise for the result of the operation
 19431   */
 19432  Q.dispatch = dispatch;
 19433  function dispatch(object, op, args) {
 19434      return Q(object).dispatch(op, args);
 19435  }
 19436  
 19437  Promise.prototype.dispatch = function (op, args) {
 19438      var self = this;
 19439      var deferred = defer();
 19440      Q.nextTick(function () {
 19441          self.promiseDispatch(deferred.resolve, op, args);
 19442      });
 19443      return deferred.promise;
 19444  };
 19445  
 19446  /**
 19447   * Gets the value of a property in a future turn.
 19448   * @param object    promise or immediate reference for target object
 19449   * @param name      name of property to get
 19450   * @return promise for the property value
 19451   */
 19452  Q.get = function (object, key) {
 19453      return Q(object).dispatch("get", [key]);
 19454  };
 19455  
 19456  Promise.prototype.get = function (key) {
 19457      return this.dispatch("get", [key]);
 19458  };
 19459  
 19460  /**
 19461   * Sets the value of a property in a future turn.
 19462   * @param object    promise or immediate reference for object object
 19463   * @param name      name of property to set
 19464   * @param value     new value of property
 19465   * @return promise for the return value
 19466   */
 19467  Q.set = function (object, key, value) {
 19468      return Q(object).dispatch("set", [key, value]);
 19469  };
 19470  
 19471  Promise.prototype.set = function (key, value) {
 19472      return this.dispatch("set", [key, value]);
 19473  };
 19474  
 19475  /**
 19476   * Deletes a property in a future turn.
 19477   * @param object    promise or immediate reference for target object
 19478   * @param name      name of property to delete
 19479   * @return promise for the return value
 19480   */
 19481  Q.del = // XXX legacy
 19482  Q["delete"] = function (object, key) {
 19483      return Q(object).dispatch("delete", [key]);
 19484  };
 19485  
 19486  Promise.prototype.del = // XXX legacy
 19487  Promise.prototype["delete"] = function (key) {
 19488      return this.dispatch("delete", [key]);
 19489  };
 19490  
 19491  /**
 19492   * Invokes a method in a future turn.
 19493   * @param object    promise or immediate reference for target object
 19494   * @param name      name of method to invoke
 19495   * @param value     a value to post, typically an array of
 19496   *                  invocation arguments for promises that
 19497   *                  are ultimately backed with `resolve` values,
 19498   *                  as opposed to those backed with URLs
 19499   *                  wherein the posted value can be any
 19500   *                  JSON serializable object.
 19501   * @return promise for the return value
 19502   */
 19503  // bound locally because it is used by other methods
 19504  Q.mapply = // XXX As proposed by "Redsandro"
 19505  Q.post = function (object, name, args) {
 19506      return Q(object).dispatch("post", [name, args]);
 19507  };
 19508  
 19509  Promise.prototype.mapply = // XXX As proposed by "Redsandro"
 19510  Promise.prototype.post = function (name, args) {
 19511      return this.dispatch("post", [name, args]);
 19512  };
 19513  
 19514  /**
 19515   * Invokes a method in a future turn.
 19516   * @param object    promise or immediate reference for target object
 19517   * @param name      name of method to invoke
 19518   * @param ...args   array of invocation arguments
 19519   * @return promise for the return value
 19520   */
 19521  Q.send = // XXX Mark Miller's proposed parlance
 19522  Q.mcall = // XXX As proposed by "Redsandro"
 19523  Q.invoke = function (object, name /*...args*/) {
 19524      return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
 19525  };
 19526  
 19527  Promise.prototype.send = // XXX Mark Miller's proposed parlance
 19528  Promise.prototype.mcall = // XXX As proposed by "Redsandro"
 19529  Promise.prototype.invoke = function (name /*...args*/) {
 19530      return this.dispatch("post", [name, array_slice(arguments, 1)]);
 19531  };
 19532  
 19533  /**
 19534   * Applies the promised function in a future turn.
 19535   * @param object    promise or immediate reference for target function
 19536   * @param args      array of application arguments
 19537   */
 19538  Q.fapply = function (object, args) {
 19539      return Q(object).dispatch("apply", [void 0, args]);
 19540  };
 19541  
 19542  Promise.prototype.fapply = function (args) {
 19543      return this.dispatch("apply", [void 0, args]);
 19544  };
 19545  
 19546  /**
 19547   * Calls the promised function in a future turn.
 19548   * @param object    promise or immediate reference for target function
 19549   * @param ...args   array of application arguments
 19550   */
 19551  Q["try"] =
 19552  Q.fcall = function (object /* ...args*/) {
 19553      return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
 19554  };
 19555  
 19556  Promise.prototype.fcall = function (/*...args*/) {
 19557      return this.dispatch("apply", [void 0, array_slice(arguments)]);
 19558  };
 19559  
 19560  /**
 19561   * Binds the promised function, transforming return values into a fulfilled
 19562   * promise and thrown errors into a rejected one.
 19563   * @param object    promise or immediate reference for target function
 19564   * @param ...args   array of application arguments
 19565   */
 19566  Q.fbind = function (object /*...args*/) {
 19567      var promise = Q(object);
 19568      var args = array_slice(arguments, 1);
 19569      return function fbound() {
 19570          return promise.dispatch("apply", [
 19571              this,
 19572              args.concat(array_slice(arguments))
 19573          ]);
 19574      };
 19575  };
 19576  Promise.prototype.fbind = function (/*...args*/) {
 19577      var promise = this;
 19578      var args = array_slice(arguments);
 19579      return function fbound() {
 19580          return promise.dispatch("apply", [
 19581              this,
 19582              args.concat(array_slice(arguments))
 19583          ]);
 19584      };
 19585  };
 19586  
 19587  /**
 19588   * Requests the names of the owned properties of a promised
 19589   * object in a future turn.
 19590   * @param object    promise or immediate reference for target object
 19591   * @return promise for the keys of the eventually settled object
 19592   */
 19593  Q.keys = function (object) {
 19594      return Q(object).dispatch("keys", []);
 19595  };
 19596  
 19597  Promise.prototype.keys = function () {
 19598      return this.dispatch("keys", []);
 19599  };
 19600  
 19601  /**
 19602   * Turns an array of promises into a promise for an array.  If any of
 19603   * the promises gets rejected, the whole array is rejected immediately.
 19604   * @param {Array*} an array (or promise for an array) of values (or
 19605   * promises for values)
 19606   * @returns a promise for an array of the corresponding values
 19607   */
 19608  // By Mark Miller
 19609  // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
 19610  Q.all = all;
 19611  function all(promises) {
 19612      return when(promises, function (promises) {
 19613          var pendingCount = 0;
 19614          var deferred = defer();
 19615          array_reduce(promises, function (undefined, promise, index) {
 19616              var snapshot;
 19617              if (
 19618                  isPromise(promise) &&
 19619                  (snapshot = promise.inspect()).state === "fulfilled"
 19620              ) {
 19621                  promises[index] = snapshot.value;
 19622              } else {
 19623                  ++pendingCount;
 19624                  when(
 19625                      promise,
 19626                      function (value) {
 19627                          promises[index] = value;
 19628                          if (--pendingCount === 0) {
 19629                              deferred.resolve(promises);
 19630                          }
 19631                      },
 19632                      deferred.reject,
 19633                      function (progress) {
 19634                          deferred.notify({ index: index, value: progress });
 19635                      }
 19636                  );
 19637              }
 19638          }, void 0);
 19639          if (pendingCount === 0) {
 19640              deferred.resolve(promises);
 19641          }
 19642          return deferred.promise;
 19643      });
 19644  }
 19645  
 19646  Promise.prototype.all = function () {
 19647      return all(this);
 19648  };
 19649  
 19650  /**
 19651   * Returns the first resolved promise of an array. Prior rejected promises are
 19652   * ignored.  Rejects only if all promises are rejected.
 19653   * @param {Array*} an array containing values or promises for values
 19654   * @returns a promise fulfilled with the value of the first resolved promise,
 19655   * or a rejected promise if all promises are rejected.
 19656   */
 19657  Q.any = any;
 19658  
 19659  function any(promises) {
 19660      if (promises.length === 0) {
 19661          return Q.resolve();
 19662      }
 19663  
 19664      var deferred = Q.defer();
 19665      var pendingCount = 0;
 19666      array_reduce(promises, function (prev, current, index) {
 19667          var promise = promises[index];
 19668  
 19669          pendingCount++;
 19670  
 19671          when(promise, onFulfilled, onRejected, onProgress);
 19672          function onFulfilled(result) {
 19673              deferred.resolve(result);
 19674          }
 19675          function onRejected() {
 19676              pendingCount--;
 19677              if (pendingCount === 0) {
 19678                  deferred.reject(new Error(
 19679                      "Can't get fulfillment value from any promise, all " +
 19680                      "promises were rejected."
 19681                  ));
 19682              }
 19683          }
 19684          function onProgress(progress) {
 19685              deferred.notify({
 19686                  index: index,
 19687                  value: progress
 19688              });
 19689          }
 19690      }, undefined);
 19691  
 19692      return deferred.promise;
 19693  }
 19694  
 19695  Promise.prototype.any = function () {
 19696      return any(this);
 19697  };
 19698  
 19699  /**
 19700   * Waits for all promises to be settled, either fulfilled or
 19701   * rejected.  This is distinct from `all` since that would stop
 19702   * waiting at the first rejection.  The promise returned by
 19703   * `allResolved` will never be rejected.
 19704   * @param promises a promise for an array (or an array) of promises
 19705   * (or values)
 19706   * @return a promise for an array of promises
 19707   */
 19708  Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
 19709  function allResolved(promises) {
 19710      return when(promises, function (promises) {
 19711          promises = array_map(promises, Q);
 19712          return when(all(array_map(promises, function (promise) {
 19713              return when(promise, noop, noop);
 19714          })), function () {
 19715              return promises;
 19716          });
 19717      });
 19718  }
 19719  
 19720  Promise.prototype.allResolved = function () {
 19721      return allResolved(this);
 19722  };
 19723  
 19724  /**
 19725   * @see Promise#allSettled
 19726   */
 19727  Q.allSettled = allSettled;
 19728  function allSettled(promises) {
 19729      return Q(promises).allSettled();
 19730  }
 19731  
 19732  /**
 19733   * Turns an array of promises into a promise for an array of their states (as
 19734   * returned by `inspect`) when they have all settled.
 19735   * @param {Array[Any*]} values an array (or promise for an array) of values (or
 19736   * promises for values)
 19737   * @returns {Array[State]} an array of states for the respective values.
 19738   */
 19739  Promise.prototype.allSettled = function () {
 19740      return this.then(function (promises) {
 19741          return all(array_map(promises, function (promise) {
 19742              promise = Q(promise);
 19743              function regardless() {
 19744                  return promise.inspect();
 19745              }
 19746              return promise.then(regardless, regardless);
 19747          }));
 19748      });
 19749  };
 19750  
 19751  /**
 19752   * Captures the failure of a promise, giving an oportunity to recover
 19753   * with a callback.  If the given promise is fulfilled, the returned
 19754   * promise is fulfilled.
 19755   * @param {Any*} promise for something
 19756   * @param {Function} callback to fulfill the returned promise if the
 19757   * given promise is rejected
 19758   * @returns a promise for the return value of the callback
 19759   */
 19760  Q.fail = // XXX legacy
 19761  Q["catch"] = function (object, rejected) {
 19762      return Q(object).then(void 0, rejected);
 19763  };
 19764  
 19765  Promise.prototype.fail = // XXX legacy
 19766  Promise.prototype["catch"] = function (rejected) {
 19767      return this.then(void 0, rejected);
 19768  };
 19769  
 19770  /**
 19771   * Attaches a listener that can respond to progress notifications from a
 19772   * promise's originating deferred. This listener receives the exact arguments
 19773   * passed to ``deferred.notify``.
 19774   * @param {Any*} promise for something
 19775   * @param {Function} callback to receive any progress notifications
 19776   * @returns the given promise, unchanged
 19777   */
 19778  Q.progress = progress;
 19779  function progress(object, progressed) {
 19780      return Q(object).then(void 0, void 0, progressed);
 19781  }
 19782  
 19783  Promise.prototype.progress = function (progressed) {
 19784      return this.then(void 0, void 0, progressed);
 19785  };
 19786  
 19787  /**
 19788   * Provides an opportunity to observe the settling of a promise,
 19789   * regardless of whether the promise is fulfilled or rejected.  Forwards
 19790   * the resolution to the returned promise when the callback is done.
 19791   * The callback can return a promise to defer completion.
 19792   * @param {Any*} promise
 19793   * @param {Function} callback to observe the resolution of the given
 19794   * promise, takes no arguments.
 19795   * @returns a promise for the resolution of the given promise when
 19796   * ``fin`` is done.
 19797   */
 19798  Q.fin = // XXX legacy
 19799  Q["finally"] = function (object, callback) {
 19800      return Q(object)["finally"](callback);
 19801  };
 19802  
 19803  Promise.prototype.fin = // XXX legacy
 19804  Promise.prototype["finally"] = function (callback) {
 19805      callback = Q(callback);
 19806      return this.then(function (value) {
 19807          return callback.fcall().then(function () {
 19808              return value;
 19809          });
 19810      }, function (reason) {
 19811          // TODO attempt to recycle the rejection with "this".
 19812          return callback.fcall().then(function () {
 19813              throw reason;
 19814          });
 19815      });
 19816  };
 19817  
 19818  /**
 19819   * Terminates a chain of promises, forcing rejections to be
 19820   * thrown as exceptions.
 19821   * @param {Any*} promise at the end of a chain of promises
 19822   * @returns nothing
 19823   */
 19824  Q.done = function (object, fulfilled, rejected, progress) {
 19825      return Q(object).done(fulfilled, rejected, progress);
 19826  };
 19827  
 19828  Promise.prototype.done = function (fulfilled, rejected, progress) {
 19829      var onUnhandledError = function (error) {
 19830          // forward to a future turn so that ``when``
 19831          // does not catch it and turn it into a rejection.
 19832          Q.nextTick(function () {
 19833              makeStackTraceLong(error, promise);
 19834              if (Q.onerror) {
 19835                  Q.onerror(error);
 19836              } else {
 19837                  throw error;
 19838              }
 19839          });
 19840      };
 19841  
 19842      // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
 19843      var promise = fulfilled || rejected || progress ?
 19844          this.then(fulfilled, rejected, progress) :
 19845          this;
 19846  
 19847      if (typeof process === "object" && process && process.domain) {
 19848          onUnhandledError = process.domain.bind(onUnhandledError);
 19849      }
 19850  
 19851      promise.then(void 0, onUnhandledError);
 19852  };
 19853  
 19854  /**
 19855   * Causes a promise to be rejected if it does not get fulfilled before
 19856   * some milliseconds time out.
 19857   * @param {Any*} promise
 19858   * @param {Number} milliseconds timeout
 19859   * @param {Any*} custom error message or Error object (optional)
 19860   * @returns a promise for the resolution of the given promise if it is
 19861   * fulfilled before the timeout, otherwise rejected.
 19862   */
 19863  Q.timeout = function (object, ms, error) {
 19864      return Q(object).timeout(ms, error);
 19865  };
 19866  
 19867  Promise.prototype.timeout = function (ms, error) {
 19868      var deferred = defer();
 19869      var timeoutId = setTimeout(function () {
 19870          if (!error || "string" === typeof error) {
 19871              error = new Error(error || "Timed out after " + ms + " ms");
 19872              error.code = "ETIMEDOUT";
 19873          }
 19874          deferred.reject(error);
 19875      }, ms);
 19876  
 19877      this.then(function (value) {
 19878          clearTimeout(timeoutId);
 19879          deferred.resolve(value);
 19880      }, function (exception) {
 19881          clearTimeout(timeoutId);
 19882          deferred.reject(exception);
 19883      }, deferred.notify);
 19884  
 19885      return deferred.promise;
 19886  };
 19887  
 19888  /**
 19889   * Returns a promise for the given value (or promised value), some
 19890   * milliseconds after it resolved. Passes rejections immediately.
 19891   * @param {Any*} promise
 19892   * @param {Number} milliseconds
 19893   * @returns a promise for the resolution of the given promise after milliseconds
 19894   * time has elapsed since the resolution of the given promise.
 19895   * If the given promise rejects, that is passed immediately.
 19896   */
 19897  Q.delay = function (object, timeout) {
 19898      if (timeout === void 0) {
 19899          timeout = object;
 19900          object = void 0;
 19901      }
 19902      return Q(object).delay(timeout);
 19903  };
 19904  
 19905  Promise.prototype.delay = function (timeout) {
 19906      return this.then(function (value) {
 19907          var deferred = defer();
 19908          setTimeout(function () {
 19909              deferred.resolve(value);
 19910          }, timeout);
 19911          return deferred.promise;
 19912      });
 19913  };
 19914  
 19915  /**
 19916   * Passes a continuation to a Node function, which is called with the given
 19917   * arguments provided as an array, and returns a promise.
 19918   *
 19919   *      Q.nfapply(FS.readFile, [__filename])
 19920   *      .then(function (content) {
 19921   *      })
 19922   *
 19923   */
 19924  Q.nfapply = function (callback, args) {
 19925      return Q(callback).nfapply(args);
 19926  };
 19927  
 19928  Promise.prototype.nfapply = function (args) {
 19929      var deferred = defer();
 19930      var nodeArgs = array_slice(args);
 19931      nodeArgs.push(deferred.makeNodeResolver());
 19932      this.fapply(nodeArgs).fail(deferred.reject);
 19933      return deferred.promise;
 19934  };
 19935  
 19936  /**
 19937   * Passes a continuation to a Node function, which is called with the given
 19938   * arguments provided individually, and returns a promise.
 19939   * @example
 19940   * Q.nfcall(FS.readFile, __filename)
 19941   * .then(function (content) {
 19942   * })
 19943   *
 19944   */
 19945  Q.nfcall = function (callback /*...args*/) {
 19946      var args = array_slice(arguments, 1);
 19947      return Q(callback).nfapply(args);
 19948  };
 19949  
 19950  Promise.prototype.nfcall = function (/*...args*/) {
 19951      var nodeArgs = array_slice(arguments);
 19952      var deferred = defer();
 19953      nodeArgs.push(deferred.makeNodeResolver());
 19954      this.fapply(nodeArgs).fail(deferred.reject);
 19955      return deferred.promise;
 19956  };
 19957  
 19958  /**
 19959   * Wraps a NodeJS continuation passing function and returns an equivalent
 19960   * version that returns a promise.
 19961   * @example
 19962   * Q.nfbind(FS.readFile, __filename)("utf-8")
 19963   * .then(console.log)
 19964   * .done()
 19965   */
 19966  Q.nfbind =
 19967  Q.denodeify = function (callback /*...args*/) {
 19968      var baseArgs = array_slice(arguments, 1);
 19969      return function () {
 19970          var nodeArgs = baseArgs.concat(array_slice(arguments));
 19971          var deferred = defer();
 19972          nodeArgs.push(deferred.makeNodeResolver());
 19973          Q(callback).fapply(nodeArgs).fail(deferred.reject);
 19974          return deferred.promise;
 19975      };
 19976  };
 19977  
 19978  Promise.prototype.nfbind =
 19979  Promise.prototype.denodeify = function (/*...args*/) {
 19980      var args = array_slice(arguments);
 19981      args.unshift(this);
 19982      return Q.denodeify.apply(void 0, args);
 19983  };
 19984  
 19985  Q.nbind = function (callback, thisp /*...args*/) {
 19986      var baseArgs = array_slice(arguments, 2);
 19987      return function () {
 19988          var nodeArgs = baseArgs.concat(array_slice(arguments));
 19989          var deferred = defer();
 19990          nodeArgs.push(deferred.makeNodeResolver());
 19991          function bound() {
 19992              return callback.apply(thisp, arguments);
 19993          }
 19994          Q(bound).fapply(nodeArgs).fail(deferred.reject);
 19995          return deferred.promise;
 19996      };
 19997  };
 19998  
 19999  Promise.prototype.nbind = function (/*thisp, ...args*/) {
 20000      var args = array_slice(arguments, 0);
 20001      args.unshift(this);
 20002      return Q.nbind.apply(void 0, args);
 20003  };
 20004  
 20005  /**
 20006   * Calls a method of a Node-style object that accepts a Node-style
 20007   * callback with a given array of arguments, plus a provided callback.
 20008   * @param object an object that has the named method
 20009   * @param {String} name name of the method of object
 20010   * @param {Array} args arguments to pass to the method; the callback
 20011   * will be provided by Q and appended to these arguments.
 20012   * @returns a promise for the value or error
 20013   */
 20014  Q.nmapply = // XXX As proposed by "Redsandro"
 20015  Q.npost = function (object, name, args) {
 20016      return Q(object).npost(name, args);
 20017  };
 20018  
 20019  Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
 20020  Promise.prototype.npost = function (name, args) {
 20021      var nodeArgs = array_slice(args || []);
 20022      var deferred = defer();
 20023      nodeArgs.push(deferred.makeNodeResolver());
 20024      this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 20025      return deferred.promise;
 20026  };
 20027  
 20028  /**
 20029   * Calls a method of a Node-style object that accepts a Node-style
 20030   * callback, forwarding the given variadic arguments, plus a provided
 20031   * callback argument.
 20032   * @param object an object that has the named method
 20033   * @param {String} name name of the method of object
 20034   * @param ...args arguments to pass to the method; the callback will
 20035   * be provided by Q and appended to these arguments.
 20036   * @returns a promise for the value or error
 20037   */
 20038  Q.nsend = // XXX Based on Mark Miller's proposed "send"
 20039  Q.nmcall = // XXX Based on "Redsandro's" proposal
 20040  Q.ninvoke = function (object, name /*...args*/) {
 20041      var nodeArgs = array_slice(arguments, 2);
 20042      var deferred = defer();
 20043      nodeArgs.push(deferred.makeNodeResolver());
 20044      Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 20045      return deferred.promise;
 20046  };
 20047  
 20048  Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
 20049  Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
 20050  Promise.prototype.ninvoke = function (name /*...args*/) {
 20051      var nodeArgs = array_slice(arguments, 1);
 20052      var deferred = defer();
 20053      nodeArgs.push(deferred.makeNodeResolver());
 20054      this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 20055      return deferred.promise;
 20056  };
 20057  
 20058  /**
 20059   * If a function would like to support both Node continuation-passing-style and
 20060   * promise-returning-style, it can end its internal promise chain with
 20061   * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user
 20062   * elects to use a nodeback, the result will be sent there.  If they do not
 20063   * pass a nodeback, they will receive the result promise.
 20064   * @param object a result (or a promise for a result)
 20065   * @param {Function} nodeback a Node.js-style callback
 20066   * @returns either the promise or nothing
 20067   */
 20068  Q.nodeify = nodeify;
 20069  function nodeify(object, nodeback) {
 20070      return Q(object).nodeify(nodeback);
 20071  }
 20072  
 20073  Promise.prototype.nodeify = function (nodeback) {
 20074      if (nodeback) {
 20075          this.then(function (value) {
 20076              Q.nextTick(function () {
 20077                  nodeback(null, value);
 20078              });
 20079          }, function (error) {
 20080              Q.nextTick(function () {
 20081                  nodeback(error);
 20082              });
 20083          });
 20084      } else {
 20085          return this;
 20086      }
 20087  };
 20088  
 20089  Q.noConflict = function() {
 20090      throw new Error("Q.noConflict only works when Q is used as a global");
 20091  };
 20092  
 20093  // All code before this point will be filtered from stack traces.
 20094  var qEndingLine = captureLine();
 20095  
 20096  return Q;
 20097  
 20098  });
 20099  
 20100  }).call(this,require('_process'))
 20101  
 20102  },{"_process":12}],158:[function(require,module,exports){
 20103  /**
 20104   * Root reference for iframes.
 20105   */
 20106  
 20107  var root;
 20108  if (typeof window !== 'undefined') { // Browser window
 20109    root = window;
 20110  } else if (typeof self !== 'undefined') { // Web Worker
 20111    root = self;
 20112  } else { // Other environments
 20113    console.warn("Using browser-only version of superagent in non-browser environment");
 20114    root = this;
 20115  }
 20116  
 20117  var Emitter = require('emitter');
 20118  var requestBase = require('./request-base');
 20119  var isObject = require('./is-object');
 20120  
 20121  /**
 20122   * Noop.
 20123   */
 20124  
 20125  function noop(){};
 20126  
 20127  /**
 20128   * Expose `request`.
 20129   */
 20130  
 20131  var request = module.exports = require('./request').bind(null, Request);
 20132  
 20133  /**
 20134   * Determine XHR.
 20135   */
 20136  
 20137  request.getXHR = function () {
 20138    if (root.XMLHttpRequest
 20139        && (!root.location || 'file:' != root.location.protocol
 20140            || !root.ActiveXObject)) {
 20141      return new XMLHttpRequest;
 20142    } else {
 20143      try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
 20144      try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
 20145      try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
 20146      try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
 20147    }
 20148    throw Error("Browser-only verison of superagent could not find XHR");
 20149  };
 20150  
 20151  /**
 20152   * Removes leading and trailing whitespace, added to support IE.
 20153   *
 20154   * @param {String} s
 20155   * @return {String}
 20156   * @api private
 20157   */
 20158  
 20159  var trim = ''.trim
 20160    ? function(s) { return s.trim(); }
 20161    : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
 20162  
 20163  /**
 20164   * Serialize the given `obj`.
 20165   *
 20166   * @param {Object} obj
 20167   * @return {String}
 20168   * @api private
 20169   */
 20170  
 20171  function serialize(obj) {
 20172    if (!isObject(obj)) return obj;
 20173    var pairs = [];
 20174    for (var key in obj) {
 20175      pushEncodedKeyValuePair(pairs, key, obj[key]);
 20176    }
 20177    return pairs.join('&');
 20178  }
 20179  
 20180  /**
 20181   * Helps 'serialize' with serializing arrays.
 20182   * Mutates the pairs array.
 20183   *
 20184   * @param {Array} pairs
 20185   * @param {String} key
 20186   * @param {Mixed} val
 20187   */
 20188  
 20189  function pushEncodedKeyValuePair(pairs, key, val) {
 20190    if (val != null) {
 20191      if (Array.isArray(val)) {
 20192        val.forEach(function(v) {
 20193          pushEncodedKeyValuePair(pairs, key, v);
 20194        });
 20195      } else if (isObject(val)) {
 20196        for(var subkey in val) {
 20197          pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
 20198        }
 20199      } else {
 20200        pairs.push(encodeURIComponent(key)
 20201          + '=' + encodeURIComponent(val));
 20202      }
 20203    } else if (val === null) {
 20204      pairs.push(encodeURIComponent(key));
 20205    }
 20206  }
 20207  
 20208  /**
 20209   * Expose serialization method.
 20210   */
 20211  
 20212   request.serializeObject = serialize;
 20213  
 20214   /**
 20215    * Parse the given x-www-form-urlencoded `str`.
 20216    *
 20217    * @param {String} str
 20218    * @return {Object}
 20219    * @api private
 20220    */
 20221  
 20222  function parseString(str) {
 20223    var obj = {};
 20224    var pairs = str.split('&');
 20225    var pair;
 20226    var pos;
 20227  
 20228    for (var i = 0, len = pairs.length; i < len; ++i) {
 20229      pair = pairs[i];
 20230      pos = pair.indexOf('=');
 20231      if (pos == -1) {
 20232        obj[decodeURIComponent(pair)] = '';
 20233      } else {
 20234        obj[decodeURIComponent(pair.slice(0, pos))] =
 20235          decodeURIComponent(pair.slice(pos + 1));
 20236      }
 20237    }
 20238  
 20239    return obj;
 20240  }
 20241  
 20242  /**
 20243   * Expose parser.
 20244   */
 20245  
 20246  request.parseString = parseString;
 20247  
 20248  /**
 20249   * Default MIME type map.
 20250   *
 20251   *     superagent.types.xml = 'application/xml';
 20252   *
 20253   */
 20254  
 20255  request.types = {
 20256    html: 'text/html',
 20257    json: 'application/json',
 20258    xml: 'application/xml',
 20259    urlencoded: 'application/x-www-form-urlencoded',
 20260    'form': 'application/x-www-form-urlencoded',
 20261    'form-data': 'application/x-www-form-urlencoded'
 20262  };
 20263  
 20264  /**
 20265   * Default serialization map.
 20266   *
 20267   *     superagent.serialize['application/xml'] = function(obj){
 20268   *       return 'generated xml here';
 20269   *     };
 20270   *
 20271   */
 20272  
 20273   request.serialize = {
 20274     'application/x-www-form-urlencoded': serialize,
 20275     'application/json': JSON.stringify
 20276   };
 20277  
 20278   /**
 20279    * Default parsers.
 20280    *
 20281    *     superagent.parse['application/xml'] = function(str){
 20282    *       return { object parsed from str };
 20283    *     };
 20284    *
 20285    */
 20286  
 20287  request.parse = {
 20288    'application/x-www-form-urlencoded': parseString,
 20289    'application/json': JSON.parse
 20290  };
 20291  
 20292  /**
 20293   * Parse the given header `str` into
 20294   * an object containing the mapped fields.
 20295   *
 20296   * @param {String} str
 20297   * @return {Object}
 20298   * @api private
 20299   */
 20300  
 20301  function parseHeader(str) {
 20302    var lines = str.split(/\r?\n/);
 20303    var fields = {};
 20304    var index;
 20305    var line;
 20306    var field;
 20307    var val;
 20308  
 20309    lines.pop(); // trailing CRLF
 20310  
 20311    for (var i = 0, len = lines.length; i < len; ++i) {
 20312      line = lines[i];
 20313      index = line.indexOf(':');
 20314      field = line.slice(0, index).toLowerCase();
 20315      val = trim(line.slice(index + 1));
 20316      fields[field] = val;
 20317    }
 20318  
 20319    return fields;
 20320  }
 20321  
 20322  /**
 20323   * Check if `mime` is json or has +json structured syntax suffix.
 20324   *
 20325   * @param {String} mime
 20326   * @return {Boolean}
 20327   * @api private
 20328   */
 20329  
 20330  function isJSON(mime) {
 20331    return /[\/+]json\b/.test(mime);
 20332  }
 20333  
 20334  /**
 20335   * Return the mime type for the given `str`.
 20336   *
 20337   * @param {String} str
 20338   * @return {String}
 20339   * @api private
 20340   */
 20341  
 20342  function type(str){
 20343    return str.split(/ *; */).shift();
 20344  };
 20345  
 20346  /**
 20347   * Return header field parameters.
 20348   *
 20349   * @param {String} str
 20350   * @return {Object}
 20351   * @api private
 20352   */
 20353  
 20354  function params(str){
 20355    return str.split(/ *; */).reduce(function(obj, str){
 20356      var parts = str.split(/ *= */),
 20357          key = parts.shift(),
 20358          val = parts.shift();
 20359  
 20360      if (key && val) obj[key] = val;
 20361      return obj;
 20362    }, {});
 20363  };
 20364  
 20365  /**
 20366   * Initialize a new `Response` with the given `xhr`.
 20367   *
 20368   *  - set flags (.ok, .error, etc)
 20369   *  - parse header
 20370   *
 20371   * Examples:
 20372   *
 20373   *  Aliasing `superagent` as `request` is nice:
 20374   *
 20375   *      request = superagent;
 20376   *
 20377   *  We can use the promise-like API, or pass callbacks:
 20378   *
 20379   *      request.get('/').end(function(res){});
 20380   *      request.get('/', function(res){});
 20381   *
 20382   *  Sending data can be chained:
 20383   *
 20384   *      request
 20385   *        .post('/user')
 20386   *        .send({ name: 'tj' })
 20387   *        .end(function(res){});
 20388   *
 20389   *  Or passed to `.send()`:
 20390   *
 20391   *      request
 20392   *        .post('/user')
 20393   *        .send({ name: 'tj' }, function(res){});
 20394   *
 20395   *  Or passed to `.post()`:
 20396   *
 20397   *      request
 20398   *        .post('/user', { name: 'tj' })
 20399   *        .end(function(res){});
 20400   *
 20401   * Or further reduced to a single call for simple cases:
 20402   *
 20403   *      request
 20404   *        .post('/user', { name: 'tj' }, function(res){});
 20405   *
 20406   * @param {XMLHTTPRequest} xhr
 20407   * @param {Object} options
 20408   * @api private
 20409   */
 20410  
 20411  function Response(req, options) {
 20412    options = options || {};
 20413    this.req = req;
 20414    this.xhr = this.req.xhr;
 20415    // responseText is accessible only if responseType is '' or 'text' and on older browsers
 20416    this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
 20417       ? this.xhr.responseText
 20418       : null;
 20419    this.statusText = this.req.xhr.statusText;
 20420    this._setStatusProperties(this.xhr.status);
 20421    this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
 20422    // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
 20423    // getResponseHeader still works. so we get content-type even if getting
 20424    // other headers fails.
 20425    this.header['content-type'] = this.xhr.getResponseHeader('content-type');
 20426    this._setHeaderProperties(this.header);
 20427    this.body = this.req.method != 'HEAD'
 20428      ? this._parseBody(this.text ? this.text : this.xhr.response)
 20429      : null;
 20430  }
 20431  
 20432  /**
 20433   * Get case-insensitive `field` value.
 20434   *
 20435   * @param {String} field
 20436   * @return {String}
 20437   * @api public
 20438   */
 20439  
 20440  Response.prototype.get = function(field){
 20441    return this.header[field.toLowerCase()];
 20442  };
 20443  
 20444  /**
 20445   * Set header related properties:
 20446   *
 20447   *   - `.type` the content type without params
 20448   *
 20449   * A response of "Content-Type: text/plain; charset=utf-8"
 20450   * will provide you with a `.type` of "text/plain".
 20451   *
 20452   * @param {Object} header
 20453   * @api private
 20454   */
 20455  
 20456  Response.prototype._setHeaderProperties = function(header){
 20457    // content-type
 20458    var ct = this.header['content-type'] || '';
 20459    this.type = type(ct);
 20460  
 20461    // params
 20462    var obj = params(ct);
 20463    for (var key in obj) this[key] = obj[key];
 20464  };
 20465  
 20466  /**
 20467   * Parse the given body `str`.
 20468   *
 20469   * Used for auto-parsing of bodies. Parsers
 20470   * are defined on the `superagent.parse` object.
 20471   *
 20472   * @param {String} str
 20473   * @return {Mixed}
 20474   * @api private
 20475   */
 20476  
 20477  Response.prototype._parseBody = function(str){
 20478    var parse = request.parse[this.type];
 20479    if (!parse && isJSON(this.type)) {
 20480      parse = request.parse['application/json'];
 20481    }
 20482    return parse && str && (str.length || str instanceof Object)
 20483      ? parse(str)
 20484      : null;
 20485  };
 20486  
 20487  /**
 20488   * Set flags such as `.ok` based on `status`.
 20489   *
 20490   * For example a 2xx response will give you a `.ok` of __true__
 20491   * whereas 5xx will be __false__ and `.error` will be __true__. The
 20492   * `.clientError` and `.serverError` are also available to be more
 20493   * specific, and `.statusType` is the class of error ranging from 1..5
 20494   * sometimes useful for mapping respond colors etc.
 20495   *
 20496   * "sugar" properties are also defined for common cases. Currently providing:
 20497   *
 20498   *   - .noContent
 20499   *   - .badRequest
 20500   *   - .unauthorized
 20501   *   - .notAcceptable
 20502   *   - .notFound
 20503   *
 20504   * @param {Number} status
 20505   * @api private
 20506   */
 20507  
 20508  Response.prototype._setStatusProperties = function(status){
 20509    // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
 20510    if (status === 1223) {
 20511      status = 204;
 20512    }
 20513  
 20514    var type = status / 100 | 0;
 20515  
 20516    // status / class
 20517    this.status = this.statusCode = status;
 20518    this.statusType = type;
 20519  
 20520    // basics
 20521    this.info = 1 == type;
 20522    this.ok = 2 == type;
 20523    this.clientError = 4 == type;
 20524    this.serverError = 5 == type;
 20525    this.error = (4 == type || 5 == type)
 20526      ? this.toError()
 20527      : false;
 20528  
 20529    // sugar
 20530    this.accepted = 202 == status;
 20531    this.noContent = 204 == status;
 20532    this.badRequest = 400 == status;
 20533    this.unauthorized = 401 == status;
 20534    this.notAcceptable = 406 == status;
 20535    this.notFound = 404 == status;
 20536    this.forbidden = 403 == status;
 20537  };
 20538  
 20539  /**
 20540   * Return an `Error` representative of this response.
 20541   *
 20542   * @return {Error}
 20543   * @api public
 20544   */
 20545  
 20546  Response.prototype.toError = function(){
 20547    var req = this.req;
 20548    var method = req.method;
 20549    var url = req.url;
 20550  
 20551    var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
 20552    var err = new Error(msg);
 20553    err.status = this.status;
 20554    err.method = method;
 20555    err.url = url;
 20556  
 20557    return err;
 20558  };
 20559  
 20560  /**
 20561   * Expose `Response`.
 20562   */
 20563  
 20564  request.Response = Response;
 20565  
 20566  /**
 20567   * Initialize a new `Request` with the given `method` and `url`.
 20568   *
 20569   * @param {String} method
 20570   * @param {String} url
 20571   * @api public
 20572   */
 20573  
 20574  function Request(method, url) {
 20575    var self = this;
 20576    this._query = this._query || [];
 20577    this.method = method;
 20578    this.url = url;
 20579    this.header = {}; // preserves header name case
 20580    this._header = {}; // coerces header names to lowercase
 20581    this.on('end', function(){
 20582      var err = null;
 20583      var res = null;
 20584  
 20585      try {
 20586        res = new Response(self);
 20587      } catch(e) {
 20588        err = new Error('Parser is unable to parse the response');
 20589        err.parse = true;
 20590        err.original = e;
 20591        // issue #675: return the raw response if the response parsing fails
 20592        err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;
 20593        // issue #876: return the http status code if the response parsing fails
 20594        err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null;
 20595        return self.callback(err);
 20596      }
 20597  
 20598      self.emit('response', res);
 20599  
 20600      var new_err;
 20601      try {
 20602        if (res.status < 200 || res.status >= 300) {
 20603          new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
 20604          new_err.original = err;
 20605          new_err.response = res;
 20606          new_err.status = res.status;
 20607        }
 20608      } catch(e) {
 20609        new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android
 20610      }
 20611  
 20612      // #1000 don't catch errors from the callback to avoid double calling it
 20613      if (new_err) {
 20614        self.callback(new_err, res);
 20615      } else {
 20616        self.callback(null, res);
 20617      }
 20618    });
 20619  }
 20620  
 20621  /**
 20622   * Mixin `Emitter` and `requestBase`.
 20623   */
 20624  
 20625  Emitter(Request.prototype);
 20626  for (var key in requestBase) {
 20627    Request.prototype[key] = requestBase[key];
 20628  }
 20629  
 20630  /**
 20631   * Set Content-Type to `type`, mapping values from `request.types`.
 20632   *
 20633   * Examples:
 20634   *
 20635   *      superagent.types.xml = 'application/xml';
 20636   *
 20637   *      request.post('/')
 20638   *        .type('xml')
 20639   *        .send(xmlstring)
 20640   *        .end(callback);
 20641   *
 20642   *      request.post('/')
 20643   *        .type('application/xml')
 20644   *        .send(xmlstring)
 20645   *        .end(callback);
 20646   *
 20647   * @param {String} type
 20648   * @return {Request} for chaining
 20649   * @api public
 20650   */
 20651  
 20652  Request.prototype.type = function(type){
 20653    this.set('Content-Type', request.types[type] || type);
 20654    return this;
 20655  };
 20656  
 20657  /**
 20658   * Set responseType to `val`. Presently valid responseTypes are 'blob' and
 20659   * 'arraybuffer'.
 20660   *
 20661   * Examples:
 20662   *
 20663   *      req.get('/')
 20664   *        .responseType('blob')
 20665   *        .end(callback);
 20666   *
 20667   * @param {String} val
 20668   * @return {Request} for chaining
 20669   * @api public
 20670   */
 20671  
 20672  Request.prototype.responseType = function(val){
 20673    this._responseType = val;
 20674    return this;
 20675  };
 20676  
 20677  /**
 20678   * Set Accept to `type`, mapping values from `request.types`.
 20679   *
 20680   * Examples:
 20681   *
 20682   *      superagent.types.json = 'application/json';
 20683   *
 20684   *      request.get('/agent')
 20685   *        .accept('json')
 20686   *        .end(callback);
 20687   *
 20688   *      request.get('/agent')
 20689   *        .accept('application/json')
 20690   *        .end(callback);
 20691   *
 20692   * @param {String} accept
 20693   * @return {Request} for chaining
 20694   * @api public
 20695   */
 20696  
 20697  Request.prototype.accept = function(type){
 20698    this.set('Accept', request.types[type] || type);
 20699    return this;
 20700  };
 20701  
 20702  /**
 20703   * Set Authorization field value with `user` and `pass`.
 20704   *
 20705   * @param {String} user
 20706   * @param {String} pass
 20707   * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
 20708   * @return {Request} for chaining
 20709   * @api public
 20710   */
 20711  
 20712  Request.prototype.auth = function(user, pass, options){
 20713    if (!options) {
 20714      options = {
 20715        type: 'basic'
 20716      }
 20717    }
 20718  
 20719    switch (options.type) {
 20720      case 'basic':
 20721        var str = btoa(user + ':' + pass);
 20722        this.set('Authorization', 'Basic ' + str);
 20723      break;
 20724  
 20725      case 'auto':
 20726        this.username = user;
 20727        this.password = pass;
 20728      break;
 20729    }
 20730    return this;
 20731  };
 20732  
 20733  /**
 20734  * Add query-string `val`.
 20735  *
 20736  * Examples:
 20737  *
 20738  *   request.get('/shoes')
 20739  *     .query('size=10')
 20740  *     .query({ color: 'blue' })
 20741  *
 20742  * @param {Object|String} val
 20743  * @return {Request} for chaining
 20744  * @api public
 20745  */
 20746  
 20747  Request.prototype.query = function(val){
 20748    if ('string' != typeof val) val = serialize(val);
 20749    if (val) this._query.push(val);
 20750    return this;
 20751  };
 20752  
 20753  /**
 20754   * Queue the given `file` as an attachment to the specified `field`,
 20755   * with optional `filename`.
 20756   *
 20757   * ``` js
 20758   * request.post('/upload')
 20759   *   .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
 20760   *   .end(callback);
 20761   * ```
 20762   *
 20763   * @param {String} field
 20764   * @param {Blob|File} file
 20765   * @param {String} filename
 20766   * @return {Request} for chaining
 20767   * @api public
 20768   */
 20769  
 20770  Request.prototype.attach = function(field, file, filename){
 20771    this._getFormData().append(field, file, filename || file.name);
 20772    return this;
 20773  };
 20774  
 20775  Request.prototype._getFormData = function(){
 20776    if (!this._formData) {
 20777      this._formData = new root.FormData();
 20778    }
 20779    return this._formData;
 20780  };
 20781  
 20782  /**
 20783   * Invoke the callback with `err` and `res`
 20784   * and handle arity check.
 20785   *
 20786   * @param {Error} err
 20787   * @param {Response} res
 20788   * @api private
 20789   */
 20790  
 20791  Request.prototype.callback = function(err, res){
 20792    var fn = this._callback;
 20793    this.clearTimeout();
 20794    fn(err, res);
 20795  };
 20796  
 20797  /**
 20798   * Invoke callback with x-domain error.
 20799   *
 20800   * @api private
 20801   */
 20802  
 20803  Request.prototype.crossDomainError = function(){
 20804    var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
 20805    err.crossDomain = true;
 20806  
 20807    err.status = this.status;
 20808    err.method = this.method;
 20809    err.url = this.url;
 20810  
 20811    this.callback(err);
 20812  };
 20813  
 20814  /**
 20815   * Invoke callback with timeout error.
 20816   *
 20817   * @api private
 20818   */
 20819  
 20820  Request.prototype._timeoutError = function(){
 20821    var timeout = this._timeout;
 20822    var err = new Error('timeout of ' + timeout + 'ms exceeded');
 20823    err.timeout = timeout;
 20824    this.callback(err);
 20825  };
 20826  
 20827  /**
 20828   * Compose querystring to append to req.url
 20829   *
 20830   * @api private
 20831   */
 20832  
 20833  Request.prototype._appendQueryString = function(){
 20834    var query = this._query.join('&');
 20835    if (query) {
 20836      this.url += ~this.url.indexOf('?')
 20837        ? '&' + query
 20838        : '?' + query;
 20839    }
 20840  };
 20841  
 20842  /**
 20843   * Initiate request, invoking callback `fn(res)`
 20844   * with an instanceof `Response`.
 20845   *
 20846   * @param {Function} fn
 20847   * @return {Request} for chaining
 20848   * @api public
 20849   */
 20850  
 20851  Request.prototype.end = function(fn){
 20852    var self = this;
 20853    var xhr = this.xhr = request.getXHR();
 20854    var timeout = this._timeout;
 20855    var data = this._formData || this._data;
 20856  
 20857    // store callback
 20858    this._callback = fn || noop;
 20859  
 20860    // state change
 20861    xhr.onreadystatechange = function(){
 20862      if (4 != xhr.readyState) return;
 20863  
 20864      // In IE9, reads to any property (e.g. status) off of an aborted XHR will
 20865      // result in the error "Could not complete the operation due to error c00c023f"
 20866      var status;
 20867      try { status = xhr.status } catch(e) { status = 0; }
 20868  
 20869      if (0 == status) {
 20870        if (self.timedout) return self._timeoutError();
 20871        if (self._aborted) return;
 20872        return self.crossDomainError();
 20873      }
 20874      self.emit('end');
 20875    };
 20876  
 20877    // progress
 20878    var handleProgress = function(e){
 20879      if (e.total > 0) {
 20880        e.percent = e.loaded / e.total * 100;
 20881      }
 20882      e.direction = 'download';
 20883      self.emit('progress', e);
 20884    };
 20885    if (this.hasListeners('progress')) {
 20886      xhr.onprogress = handleProgress;
 20887    }
 20888    try {
 20889      if (xhr.upload && this.hasListeners('progress')) {
 20890        xhr.upload.onprogress = handleProgress;
 20891      }
 20892    } catch(e) {
 20893      // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
 20894      // Reported here:
 20895      // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
 20896    }
 20897  
 20898    // timeout
 20899    if (timeout && !this._timer) {
 20900      this._timer = setTimeout(function(){
 20901        self.timedout = true;
 20902        self.abort();
 20903      }, timeout);
 20904    }
 20905  
 20906    // querystring
 20907    this._appendQueryString();
 20908  
 20909    // initiate request
 20910    if (this.username && this.password) {
 20911      xhr.open(this.method, this.url, true, this.username, this.password);
 20912    } else {
 20913      xhr.open(this.method, this.url, true);
 20914    }
 20915  
 20916    // CORS
 20917    if (this._withCredentials) xhr.withCredentials = true;
 20918  
 20919    // body
 20920    if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
 20921      // serialize stuff
 20922      var contentType = this._header['content-type'];
 20923      var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
 20924      if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
 20925      if (serialize) data = serialize(data);
 20926    }
 20927  
 20928    // set header fields
 20929    for (var field in this.header) {
 20930      if (null == this.header[field]) continue;
 20931      xhr.setRequestHeader(field, this.header[field]);
 20932    }
 20933  
 20934    if (this._responseType) {
 20935      xhr.responseType = this._responseType;
 20936    }
 20937  
 20938    // send stuff
 20939    this.emit('request', this);
 20940  
 20941    // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
 20942    // We need null here if data is undefined
 20943    xhr.send(typeof data !== 'undefined' ? data : null);
 20944    return this;
 20945  };
 20946  
 20947  
 20948  /**
 20949   * Expose `Request`.
 20950   */
 20951  
 20952  request.Request = Request;
 20953  
 20954  /**
 20955   * GET `url` with optional callback `fn(res)`.
 20956   *
 20957   * @param {String} url
 20958   * @param {Mixed|Function} [data] or fn
 20959   * @param {Function} [fn]
 20960   * @return {Request}
 20961   * @api public
 20962   */
 20963  
 20964  request.get = function(url, data, fn){
 20965    var req = request('GET', url);
 20966    if ('function' == typeof data) fn = data, data = null;
 20967    if (data) req.query(data);
 20968    if (fn) req.end(fn);
 20969    return req;
 20970  };
 20971  
 20972  /**
 20973   * HEAD `url` with optional callback `fn(res)`.
 20974   *
 20975   * @param {String} url
 20976   * @param {Mixed|Function} [data] or fn
 20977   * @param {Function} [fn]
 20978   * @return {Request}
 20979   * @api public
 20980   */
 20981  
 20982  request.head = function(url, data, fn){
 20983    var req = request('HEAD', url);
 20984    if ('function' == typeof data) fn = data, data = null;
 20985    if (data) req.send(data);
 20986    if (fn) req.end(fn);
 20987    return req;
 20988  };
 20989  
 20990  /**
 20991   * OPTIONS query to `url` with optional callback `fn(res)`.
 20992   *
 20993   * @param {String} url
 20994   * @param {Mixed|Function} [data] or fn
 20995   * @param {Function} [fn]
 20996   * @return {Request}
 20997   * @api public
 20998   */
 20999  
 21000  request.options = function(url, data, fn){
 21001    var req = request('OPTIONS', url);
 21002    if ('function' == typeof data) fn = data, data = null;
 21003    if (data) req.send(data);
 21004    if (fn) req.end(fn);
 21005    return req;
 21006  };
 21007  
 21008  /**
 21009   * DELETE `url` with optional callback `fn(res)`.
 21010   *
 21011   * @param {String} url
 21012   * @param {Function} [fn]
 21013   * @return {Request}
 21014   * @api public
 21015   */
 21016  
 21017  function del(url, fn){
 21018    var req = request('DELETE', url);
 21019    if (fn) req.end(fn);
 21020    return req;
 21021  };
 21022  
 21023  request['del'] = del;
 21024  request['delete'] = del;
 21025  
 21026  /**
 21027   * PATCH `url` with optional `data` and callback `fn(res)`.
 21028   *
 21029   * @param {String} url
 21030   * @param {Mixed} [data]
 21031   * @param {Function} [fn]
 21032   * @return {Request}
 21033   * @api public
 21034   */
 21035  
 21036  request.patch = function(url, data, fn){
 21037    var req = request('PATCH', url);
 21038    if ('function' == typeof data) fn = data, data = null;
 21039    if (data) req.send(data);
 21040    if (fn) req.end(fn);
 21041    return req;
 21042  };
 21043  
 21044  /**
 21045   * POST `url` with optional `data` and callback `fn(res)`.
 21046   *
 21047   * @param {String} url
 21048   * @param {Mixed} [data]
 21049   * @param {Function} [fn]
 21050   * @return {Request}
 21051   * @api public
 21052   */
 21053  
 21054  request.post = function(url, data, fn){
 21055    var req = request('POST', url);
 21056    if ('function' == typeof data) fn = data, data = null;
 21057    if (data) req.send(data);
 21058    if (fn) req.end(fn);
 21059    return req;
 21060  };
 21061  
 21062  /**
 21063   * PUT `url` with optional `data` and callback `fn(res)`.
 21064   *
 21065   * @param {String} url
 21066   * @param {Mixed|Function} [data] or fn
 21067   * @param {Function} [fn]
 21068   * @return {Request}
 21069   * @api public
 21070   */
 21071  
 21072  request.put = function(url, data, fn){
 21073    var req = request('PUT', url);
 21074    if ('function' == typeof data) fn = data, data = null;
 21075    if (data) req.send(data);
 21076    if (fn) req.end(fn);
 21077    return req;
 21078  };
 21079  
 21080  },{"./is-object":159,"./request":161,"./request-base":160,"emitter":162}],159:[function(require,module,exports){
 21081  /**
 21082   * Check if `obj` is an object.
 21083   *
 21084   * @param {Object} obj
 21085   * @return {Boolean}
 21086   * @api private
 21087   */
 21088  
 21089  function isObject(obj) {
 21090    return null !== obj && 'object' === typeof obj;
 21091  }
 21092  
 21093  module.exports = isObject;
 21094  
 21095  },{}],160:[function(require,module,exports){
 21096  /**
 21097   * Module of mixed-in functions shared between node and client code
 21098   */
 21099  var isObject = require('./is-object');
 21100  
 21101  /**
 21102   * Clear previous timeout.
 21103   *
 21104   * @return {Request} for chaining
 21105   * @api public
 21106   */
 21107  
 21108  exports.clearTimeout = function _clearTimeout(){
 21109    this._timeout = 0;
 21110    clearTimeout(this._timer);
 21111    return this;
 21112  };
 21113  
 21114  /**
 21115   * Override default response body parser
 21116   *
 21117   * This function will be called to convert incoming data into request.body
 21118   *
 21119   * @param {Function}
 21120   * @api public
 21121   */
 21122  
 21123  exports.parse = function parse(fn){
 21124    this._parser = fn;
 21125    return this;
 21126  };
 21127  
 21128  /**
 21129   * Override default request body serializer
 21130   *
 21131   * This function will be called to convert data set via .send or .attach into payload to send
 21132   *
 21133   * @param {Function}
 21134   * @api public
 21135   */
 21136  
 21137  exports.serialize = function serialize(fn){
 21138    this._serializer = fn;
 21139    return this;
 21140  };
 21141  
 21142  /**
 21143   * Set timeout to `ms`.
 21144   *
 21145   * @param {Number} ms
 21146   * @return {Request} for chaining
 21147   * @api public
 21148   */
 21149  
 21150  exports.timeout = function timeout(ms){
 21151    this._timeout = ms;
 21152    return this;
 21153  };
 21154  
 21155  /**
 21156   * Promise support
 21157   *
 21158   * @param {Function} resolve
 21159   * @param {Function} reject
 21160   * @return {Request}
 21161   */
 21162  
 21163  exports.then = function then(resolve, reject) {
 21164    if (!this._fullfilledPromise) {
 21165      var self = this;
 21166      this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
 21167        self.end(function(err, res){
 21168          if (err) innerReject(err); else innerResolve(res);
 21169        });
 21170      });
 21171    }
 21172    return this._fullfilledPromise.then(resolve, reject);
 21173  }
 21174  
 21175  /**
 21176   * Allow for extension
 21177   */
 21178  
 21179  exports.use = function use(fn) {
 21180    fn(this);
 21181    return this;
 21182  }
 21183  
 21184  
 21185  /**
 21186   * Get request header `field`.
 21187   * Case-insensitive.
 21188   *
 21189   * @param {String} field
 21190   * @return {String}
 21191   * @api public
 21192   */
 21193  
 21194  exports.get = function(field){
 21195    return this._header[field.toLowerCase()];
 21196  };
 21197  
 21198  /**
 21199   * Get case-insensitive header `field` value.
 21200   * This is a deprecated internal API. Use `.get(field)` instead.
 21201   *
 21202   * (getHeader is no longer used internally by the superagent code base)
 21203   *
 21204   * @param {String} field
 21205   * @return {String}
 21206   * @api private
 21207   * @deprecated
 21208   */
 21209  
 21210  exports.getHeader = exports.get;
 21211  
 21212  /**
 21213   * Set header `field` to `val`, or multiple fields with one object.
 21214   * Case-insensitive.
 21215   *
 21216   * Examples:
 21217   *
 21218   *      req.get('/')
 21219   *        .set('Accept', 'application/json')
 21220   *        .set('X-API-Key', 'foobar')
 21221   *        .end(callback);
 21222   *
 21223   *      req.get('/')
 21224   *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
 21225   *        .end(callback);
 21226   *
 21227   * @param {String|Object} field
 21228   * @param {String} val
 21229   * @return {Request} for chaining
 21230   * @api public
 21231   */
 21232  
 21233  exports.set = function(field, val){
 21234    if (isObject(field)) {
 21235      for (var key in field) {
 21236        this.set(key, field[key]);
 21237      }
 21238      return this;
 21239    }
 21240    this._header[field.toLowerCase()] = val;
 21241    this.header[field] = val;
 21242    return this;
 21243  };
 21244  
 21245  /**
 21246   * Remove header `field`.
 21247   * Case-insensitive.
 21248   *
 21249   * Example:
 21250   *
 21251   *      req.get('/')
 21252   *        .unset('User-Agent')
 21253   *        .end(callback);
 21254   *
 21255   * @param {String} field
 21256   */
 21257  exports.unset = function(field){
 21258    delete this._header[field.toLowerCase()];
 21259    delete this.header[field];
 21260    return this;
 21261  };
 21262  
 21263  /**
 21264   * Write the field `name` and `val` for "multipart/form-data"
 21265   * request bodies.
 21266   *
 21267   * ``` js
 21268   * request.post('/upload')
 21269   *   .field('foo', 'bar')
 21270   *   .end(callback);
 21271   * ```
 21272   *
 21273   * @param {String} name
 21274   * @param {String|Blob|File|Buffer|fs.ReadStream} val
 21275   * @return {Request} for chaining
 21276   * @api public
 21277   */
 21278  exports.field = function(name, val) {
 21279    this._getFormData().append(name, val);
 21280    return this;
 21281  };
 21282  
 21283  /**
 21284   * Abort the request, and clear potential timeout.
 21285   *
 21286   * @return {Request}
 21287   * @api public
 21288   */
 21289  exports.abort = function(){
 21290    if (this._aborted) {
 21291      return this;
 21292    }
 21293    this._aborted = true;
 21294    this.xhr && this.xhr.abort(); // browser
 21295    this.req && this.req.abort(); // node
 21296    this.clearTimeout();
 21297    this.emit('abort');
 21298    return this;
 21299  };
 21300  
 21301  /**
 21302   * Enable transmission of cookies with x-domain requests.
 21303   *
 21304   * Note that for this to work the origin must not be
 21305   * using "Access-Control-Allow-Origin" with a wildcard,
 21306   * and also must set "Access-Control-Allow-Credentials"
 21307   * to "true".
 21308   *
 21309   * @api public
 21310   */
 21311  
 21312  exports.withCredentials = function(){
 21313    // This is browser-only functionality. Node side is no-op.
 21314    this._withCredentials = true;
 21315    return this;
 21316  };
 21317  
 21318  /**
 21319   * Set the max redirects to `n`. Does noting in browser XHR implementation.
 21320   *
 21321   * @param {Number} n
 21322   * @return {Request} for chaining
 21323   * @api public
 21324   */
 21325  
 21326  exports.redirects = function(n){
 21327    this._maxRedirects = n;
 21328    return this;
 21329  };
 21330  
 21331  /**
 21332   * Convert to a plain javascript object (not JSON string) of scalar properties.
 21333   * Note as this method is designed to return a useful non-this value,
 21334   * it cannot be chained.
 21335   *
 21336   * @return {Object} describing method, url, and data of this request
 21337   * @api public
 21338   */
 21339  
 21340  exports.toJSON = function(){
 21341    return {
 21342      method: this.method,
 21343      url: this.url,
 21344      data: this._data,
 21345      headers: this._header
 21346    };
 21347  };
 21348  
 21349  /**
 21350   * Check if `obj` is a host object,
 21351   * we don't want to serialize these :)
 21352   *
 21353   * TODO: future proof, move to compoent land
 21354   *
 21355   * @param {Object} obj
 21356   * @return {Boolean}
 21357   * @api private
 21358   */
 21359  
 21360  exports._isHost = function _isHost(obj) {
 21361    var str = {}.toString.call(obj);
 21362  
 21363    switch (str) {
 21364      case '[object File]':
 21365      case '[object Blob]':
 21366      case '[object FormData]':
 21367        return true;
 21368      default:
 21369        return false;
 21370    }
 21371  }
 21372  
 21373  /**
 21374   * Send `data` as the request body, defaulting the `.type()` to "json" when
 21375   * an object is given.
 21376   *
 21377   * Examples:
 21378   *
 21379   *       // manual json
 21380   *       request.post('/user')
 21381   *         .type('json')
 21382   *         .send('{"name":"tj"}')
 21383   *         .end(callback)
 21384   *
 21385   *       // auto json
 21386   *       request.post('/user')
 21387   *         .send({ name: 'tj' })
 21388   *         .end(callback)
 21389   *
 21390   *       // manual x-www-form-urlencoded
 21391   *       request.post('/user')
 21392   *         .type('form')
 21393   *         .send('name=tj')
 21394   *         .end(callback)
 21395   *
 21396   *       // auto x-www-form-urlencoded
 21397   *       request.post('/user')
 21398   *         .type('form')
 21399   *         .send({ name: 'tj' })
 21400   *         .end(callback)
 21401   *
 21402   *       // defaults to x-www-form-urlencoded
 21403   *      request.post('/user')
 21404   *        .send('name=tobi')
 21405   *        .send('species=ferret')
 21406   *        .end(callback)
 21407   *
 21408   * @param {String|Object} data
 21409   * @return {Request} for chaining
 21410   * @api public
 21411   */
 21412  
 21413  exports.send = function(data){
 21414    var obj = isObject(data);
 21415    var type = this._header['content-type'];
 21416  
 21417    // merge
 21418    if (obj && isObject(this._data)) {
 21419      for (var key in data) {
 21420        this._data[key] = data[key];
 21421      }
 21422    } else if ('string' == typeof data) {
 21423      // default to x-www-form-urlencoded
 21424      if (!type) this.type('form');
 21425      type = this._header['content-type'];
 21426      if ('application/x-www-form-urlencoded' == type) {
 21427        this._data = this._data
 21428          ? this._data + '&' + data
 21429          : data;
 21430      } else {
 21431        this._data = (this._data || '') + data;
 21432      }
 21433    } else {
 21434      this._data = data;
 21435    }
 21436  
 21437    if (!obj || this._isHost(data)) return this;
 21438  
 21439    // default to json
 21440    if (!type) this.type('json');
 21441    return this;
 21442  };
 21443  
 21444  },{"./is-object":159}],161:[function(require,module,exports){
 21445  // The node and browser modules expose versions of this with the
 21446  // appropriate constructor function bound as first argument
 21447  /**
 21448   * Issue a request:
 21449   *
 21450   * Examples:
 21451   *
 21452   *    request('GET', '/users').end(callback)
 21453   *    request('/users').end(callback)
 21454   *    request('/users', callback)
 21455   *
 21456   * @param {String} method
 21457   * @param {String|Function} url or callback
 21458   * @return {Request}
 21459   * @api public
 21460   */
 21461  
 21462  function request(RequestConstructor, method, url) {
 21463    // callback
 21464    if ('function' == typeof url) {
 21465      return new RequestConstructor('GET', method).end(url);
 21466    }
 21467  
 21468    // url first
 21469    if (2 == arguments.length) {
 21470      return new RequestConstructor('GET', method);
 21471    }
 21472  
 21473    return new RequestConstructor(method, url);
 21474  }
 21475  
 21476  module.exports = request;
 21477  
 21478  },{}],162:[function(require,module,exports){
 21479  
 21480  /**
 21481   * Expose `Emitter`.
 21482   */
 21483  
 21484  if (typeof module !== 'undefined') {
 21485    module.exports = Emitter;
 21486  }
 21487  
 21488  /**
 21489   * Initialize a new `Emitter`.
 21490   *
 21491   * @api public
 21492   */
 21493  
 21494  function Emitter(obj) {
 21495    if (obj) return mixin(obj);
 21496  };
 21497  
 21498  /**
 21499   * Mixin the emitter properties.
 21500   *
 21501   * @param {Object} obj
 21502   * @return {Object}
 21503   * @api private
 21504   */
 21505  
 21506  function mixin(obj) {
 21507    for (var key in Emitter.prototype) {
 21508      obj[key] = Emitter.prototype[key];
 21509    }
 21510    return obj;
 21511  }
 21512  
 21513  /**
 21514   * Listen on the given `event` with `fn`.
 21515   *
 21516   * @param {String} event
 21517   * @param {Function} fn
 21518   * @return {Emitter}
 21519   * @api public
 21520   */
 21521  
 21522  Emitter.prototype.on =
 21523  Emitter.prototype.addEventListener = function(event, fn){
 21524    this._callbacks = this._callbacks || {};
 21525    (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
 21526      .push(fn);
 21527    return this;
 21528  };
 21529  
 21530  /**
 21531   * Adds an `event` listener that will be invoked a single
 21532   * time then automatically removed.
 21533   *
 21534   * @param {String} event
 21535   * @param {Function} fn
 21536   * @return {Emitter}
 21537   * @api public
 21538   */
 21539  
 21540  Emitter.prototype.once = function(event, fn){
 21541    function on() {
 21542      this.off(event, on);
 21543      fn.apply(this, arguments);
 21544    }
 21545  
 21546    on.fn = fn;
 21547    this.on(event, on);
 21548    return this;
 21549  };
 21550  
 21551  /**
 21552   * Remove the given callback for `event` or all
 21553   * registered callbacks.
 21554   *
 21555   * @param {String} event
 21556   * @param {Function} fn
 21557   * @return {Emitter}
 21558   * @api public
 21559   */
 21560  
 21561  Emitter.prototype.off =
 21562  Emitter.prototype.removeListener =
 21563  Emitter.prototype.removeAllListeners =
 21564  Emitter.prototype.removeEventListener = function(event, fn){
 21565    this._callbacks = this._callbacks || {};
 21566  
 21567    // all
 21568    if (0 == arguments.length) {
 21569      this._callbacks = {};
 21570      return this;
 21571    }
 21572  
 21573    // specific event
 21574    var callbacks = this._callbacks['$' + event];
 21575    if (!callbacks) return this;
 21576  
 21577    // remove all handlers
 21578    if (1 == arguments.length) {
 21579      delete this._callbacks['$' + event];
 21580      return this;
 21581    }
 21582  
 21583    // remove specific handler
 21584    var cb;
 21585    for (var i = 0; i < callbacks.length; i++) {
 21586      cb = callbacks[i];
 21587      if (cb === fn || cb.fn === fn) {
 21588        callbacks.splice(i, 1);
 21589        break;
 21590      }
 21591    }
 21592    return this;
 21593  };
 21594  
 21595  /**
 21596   * Emit `event` with the given args.
 21597   *
 21598   * @param {String} event
 21599   * @param {Mixed} ...
 21600   * @return {Emitter}
 21601   */
 21602  
 21603  Emitter.prototype.emit = function(event){
 21604    this._callbacks = this._callbacks || {};
 21605    var args = [].slice.call(arguments, 1)
 21606      , callbacks = this._callbacks['$' + event];
 21607  
 21608    if (callbacks) {
 21609      callbacks = callbacks.slice(0);
 21610      for (var i = 0, len = callbacks.length; i < len; ++i) {
 21611        callbacks[i].apply(this, args);
 21612      }
 21613    }
 21614  
 21615    return this;
 21616  };
 21617  
 21618  /**
 21619   * Return array of callbacks for `event`.
 21620   *
 21621   * @param {String} event
 21622   * @return {Array}
 21623   * @api public
 21624   */
 21625  
 21626  Emitter.prototype.listeners = function(event){
 21627    this._callbacks = this._callbacks || {};
 21628    return this._callbacks['$' + event] || [];
 21629  };
 21630  
 21631  /**
 21632   * Check if this emitter has `event` handlers.
 21633   *
 21634   * @param {String} event
 21635   * @return {Boolean}
 21636   * @api public
 21637   */
 21638  
 21639  Emitter.prototype.hasListeners = function(event){
 21640    return !! this.listeners(event).length;
 21641  };
 21642  
 21643  },{}]},{},[1])(1)
 21644  });
 21645  
 21646  
 21647   /*global JSONEditor*/
 21648  'use strict';
 21649  
 21650  window.SwaggerUi = Backbone.Router.extend({
 21651  
 21652    dom_id: 'swagger_ui',
 21653  
 21654    // Attributes
 21655    options: null,
 21656    api: null,
 21657    headerView: null,
 21658    mainView: null,
 21659  
 21660    // SwaggerUi accepts all the same options as SwaggerApi
 21661    initialize: function(options) {
 21662      options = options || {};
 21663  
 21664      if (options.defaultModelRendering !== 'model') {
 21665        options.defaultModelRendering = 'schema';
 21666      }
 21667  
 21668      if (!options.highlightSizeThreshold) {
 21669        options.highlightSizeThreshold = 100000;
 21670      }
 21671  
 21672      // Allow dom_id to be overridden
 21673      if (options.dom_id) {
 21674        this.dom_id = options.dom_id;
 21675        delete options.dom_id;
 21676      }
 21677  
 21678      if (!options.supportedSubmitMethods){
 21679        options.supportedSubmitMethods = [
 21680          'get',
 21681          'put',
 21682          'post',
 21683          'delete',
 21684          'head',
 21685          'options',
 21686          'patch'
 21687        ];
 21688      }
 21689  
 21690      if (typeof options.oauth2RedirectUrl === 'string') {
 21691        window.oAuthRedirectUrl = options.oauth2RedirectUrl;
 21692      }
 21693  
 21694      // Create an empty div which contains the dom_id
 21695      if (! $('#' + this.dom_id).length){
 21696        $('body').append('<div id="' + this.dom_id + '"></div>') ;
 21697      }
 21698  
 21699      this.options = options;
 21700  
 21701      // set marked options
 21702      marked.setOptions({gfm: true});
 21703  
 21704      // Set the callbacks
 21705      var that = this;
 21706      this.options.success = function() { return that.render(); };
 21707      this.options.progress = function(d) { return that.showMessage(d); };
 21708      this.options.failure = function(d) { return that.onLoadFailure(d); };
 21709  
 21710      // Create view to handle the header inputs
 21711      this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});
 21712  
 21713      // Event handler for when the baseUrl/apiKey is entered by user
 21714      this.headerView.on('update-swagger-ui', function(data) {
 21715        return that.updateSwaggerUi(data);
 21716      });
 21717  
 21718      // JSon Editor custom theming
 21719       JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({
 21720        mapping: {
 21721          collapse: 'collapse',
 21722          expand: 'expand'
 21723          },
 21724        icon_prefix: 'swagger-'
 21725        });
 21726  
 21727    },
 21728  
 21729    // Set an option after initializing
 21730    setOption: function(option, value) {
 21731      this.options[option] = value;
 21732    },
 21733  
 21734    // Get the value of a previously set option
 21735    getOption: function(option) {
 21736      return this.options[option];
 21737    },
 21738  
 21739    // Event handler for when url/key is received from user
 21740    updateSwaggerUi: function(data){
 21741      this.options.url = data.url;
 21742      this.load();
 21743    },
 21744  
 21745    // Create an api and render
 21746    load: function(){
 21747      // Initialize the API object
 21748      if (this.mainView) {
 21749        this.mainView.clear();
 21750      }
 21751  
 21752      if (this.authView) {
 21753        this.authView.remove();
 21754      }
 21755      var url = this.options.url;
 21756      if (url && url.indexOf('http') !== 0) {
 21757        url = this.buildUrl(window.location.href.toString(), url);
 21758      }
 21759      if(this.api) {
 21760        this.options.authorizations = this.api.clientAuthorizations.authz;
 21761      }
 21762      this.options.url = url;
 21763      this.headerView.update(url);
 21764  
 21765      this.api = new SwaggerClient(this.options);
 21766    },
 21767  
 21768    // collapse all sections
 21769    collapseAll: function(){
 21770      Docs.collapseEndpointListForResource('');
 21771    },
 21772  
 21773    // list operations for all sections
 21774    listAll: function(){
 21775      Docs.collapseOperationsForResource('');
 21776    },
 21777  
 21778    // expand operations for all sections
 21779    expandAll: function(){
 21780      Docs.expandOperationsForResource('');
 21781    },
 21782  
 21783    // This is bound to success handler for SwaggerApi
 21784    //  so it gets called when SwaggerApi completes loading
 21785    render: function(){
 21786      var authsModel;
 21787      this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');
 21788      this.mainView = new SwaggerUi.Views.MainView({
 21789        model: this.api,
 21790        el: $('#' + this.dom_id),
 21791        swaggerOptions: this.options,
 21792        router: this
 21793      }).render();
 21794      if (!_.isEmpty(this.api.securityDefinitions)){
 21795        authsModel = _.map(this.api.securityDefinitions, function (auth, name) {
 21796          var result = {};
 21797          result[name] = auth;
 21798          return result;
 21799        });
 21800        this.authView = new SwaggerUi.Views.AuthButtonView({
 21801          data: SwaggerUi.utils.parseSecurityDefinitions(authsModel),
 21802          router: this
 21803        });
 21804        $('#auth_container').append(this.authView.render().el);
 21805      }
 21806      this.showMessage();
 21807      switch (this.options.docExpansion) {
 21808        case 'full':
 21809          this.expandAll(); break;
 21810        case 'list':
 21811          this.listAll(); break;
 21812        default:
 21813          break;
 21814      }
 21815      this.renderGFM();
 21816  
 21817      if (this.options.onComplete){
 21818        this.options.onComplete(this.api, this);
 21819      }
 21820  
 21821      setTimeout(Docs.shebang.bind(this), 100);
 21822    },
 21823  
 21824    buildUrl: function(base, url){
 21825      if (url.indexOf('/') === 0) {
 21826        var parts = base.split('/');
 21827        base = parts[0] + '//' + parts[2];
 21828        return base + url;
 21829      } else {
 21830        var endOfPath = base.length;
 21831  
 21832        if (base.indexOf('?') > -1){
 21833          endOfPath = Math.min(endOfPath, base.indexOf('?'));
 21834        }
 21835  
 21836        if (base.indexOf('#') > -1){
 21837          endOfPath = Math.min(endOfPath, base.indexOf('#'));
 21838        }
 21839  
 21840        base = base.substring(0, endOfPath);
 21841  
 21842        if (base.indexOf('/', base.length - 1 ) !== -1){
 21843          return base + url;
 21844        }
 21845  
 21846        return base + '/' + url;
 21847      }
 21848    },
 21849  
 21850    // Shows message on topbar of the ui
 21851    showMessage: function(data){
 21852      if (data === undefined) {
 21853        data = '';
 21854      }
 21855      var $msgbar = $('#message-bar');
 21856      $msgbar.removeClass('message-fail');
 21857      $msgbar.addClass('message-success');
 21858      $msgbar.text(data);
 21859      if(window.SwaggerTranslator) {
 21860        window.SwaggerTranslator.translate($msgbar);
 21861      }
 21862    },
 21863  
 21864    // shows message in red
 21865    onLoadFailure: function(data){
 21866      if (data === undefined) {
 21867        data = '';
 21868      }
 21869      $('#message-bar').removeClass('message-success');
 21870      $('#message-bar').addClass('message-fail');
 21871  
 21872      var val = $('#message-bar').text(data);
 21873  
 21874      if (this.options.onFailure) {
 21875        this.options.onFailure(data);
 21876      }
 21877  
 21878      return val;
 21879    },
 21880  
 21881    // Renders GFM for elements with 'markdown' class
 21882    renderGFM: function(){
 21883      $('.markdown').each(function(){
 21884        $(this).html(marked($(this).html()));
 21885      });
 21886  
 21887      $('.propDesc', '.model-signature .description').each(function () {
 21888        $(this).html(marked($(this).html())).addClass('markdown');
 21889      });
 21890    }
 21891  
 21892  });
 21893  
 21894  window.SwaggerUi.Views = {};
 21895  window.SwaggerUi.Models = {};
 21896  window.SwaggerUi.Collections = {};
 21897  window.SwaggerUi.partials = {};
 21898  window.SwaggerUi.utils = {};
 21899  
 21900  // don't break backward compatibility with previous versions and warn users to upgrade their code
 21901  (function(){
 21902    window.authorizations = {
 21903      add: function() {
 21904        warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().');
 21905  
 21906        if (typeof window.swaggerUi === 'undefined') {
 21907          throw new TypeError('window.swaggerUi is not defined');
 21908        }
 21909  
 21910        if (window.swaggerUi instanceof SwaggerUi) {
 21911          window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments);
 21912        }
 21913      }
 21914    };
 21915  
 21916    window.ApiKeyAuthorization = function() {
 21917      warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.');
 21918      SwaggerClient.ApiKeyAuthorization.apply(window, arguments);
 21919    };
 21920  
 21921    window.PasswordAuthorization = function() {
 21922      warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.');
 21923      SwaggerClient.PasswordAuthorization.apply(window, arguments);
 21924    };
 21925  
 21926    function warn(message) {
 21927      if ('console' in window && typeof window.console.warn === 'function') {
 21928        console.warn(message);
 21929      }
 21930    }
 21931  })();
 21932  
 21933  
 21934  // UMD
 21935  (function (root, factory) {
 21936      if (typeof define === 'function' && define.amd) {
 21937          // AMD. Register as an anonymous module.
 21938          define(['b'], function (b) {
 21939              return (root.SwaggerUi = factory(b));
 21940          });
 21941      } else if (typeof exports === 'object') {
 21942          // Node. Does not work with strict CommonJS, but
 21943          // only CommonJS-like environments that support module.exports,
 21944          // like Node.
 21945          module.exports = factory(require('b'));
 21946      } else {
 21947          // Browser globals
 21948          root.SwaggerUi = factory(root.b);
 21949      }
 21950  }(this, function () {
 21951      return SwaggerUi;
 21952  }));
 21953  
 21954  'use strict';
 21955  
 21956  window.SwaggerUi.utils = {
 21957      parseSecurityDefinitions: function (security, securityDefinitions) {
 21958          var auths = Object.assign({}, securityDefinitions);
 21959          var oauth2Arr = [];
 21960          var authsArr = [];
 21961          var scopes = [];
 21962          var utils = window.SwaggerUi.utils;
 21963  
 21964          if (!Array.isArray(security)) { return null; }
 21965  
 21966          security.forEach(function (item) {
 21967              var singleSecurity = {};
 21968              var singleOauth2Security = {};
 21969  
 21970              for (var key in item) {
 21971                  if (Array.isArray(item[key])) {
 21972                      if (!auths[key]) { continue; }
 21973                      auths[key] = auths[key] || {};
 21974                      if (auths[key].type === 'oauth2') {
 21975                          singleOauth2Security[key] = Object.assign({}, auths[key]);
 21976                          singleOauth2Security[key].scopes = Object.assign({}, auths[key].scopes);
 21977                          for (var i in singleOauth2Security[key].scopes) {
 21978                              if (item[key].indexOf(i) < 0) {
 21979                                  delete singleOauth2Security[key].scopes[i];
 21980                              }
 21981                          }
 21982                          singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
 21983                          scopes = _.merge(scopes, singleOauth2Security[key].scopes);
 21984                      } else {
 21985                          singleSecurity[key] = Object.assign({}, auths[key]);
 21986                      }
 21987                  } else {
 21988                      if (item[key].type === 'oauth2') {
 21989                          singleOauth2Security[key] = Object.assign({}, item[key]);
 21990                          singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
 21991                          scopes = _.merge(scopes, singleOauth2Security[key].scopes);
 21992                      } else {
 21993                          singleSecurity[key] = item[key];
 21994                      }
 21995                  }
 21996              }
 21997  
 21998              if (!_.isEmpty(singleSecurity)) {
 21999                  authsArr.push(singleSecurity);
 22000              }
 22001  
 22002              if (!_.isEmpty(singleOauth2Security)){
 22003                  oauth2Arr.push(singleOauth2Security);
 22004              }
 22005          });
 22006  
 22007          return {
 22008              auths : authsArr,
 22009              oauth2: oauth2Arr,
 22010              scopes: scopes
 22011          };
 22012      },
 22013  
 22014      parseOauth2Scopes: function (data) {
 22015          var scopes = Object.assign({}, data);
 22016          var result = [];
 22017          var key;
 22018  
 22019          for (key in scopes) {
 22020              result.push({scope: key, description: scopes[key]});
 22021          }
 22022  
 22023          return result;
 22024      },
 22025  
 22026      sanitize: function(html) {
 22027          // Strip the script tags from the html and inline evenhandlers
 22028          html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
 22029          html = html.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi, '');
 22030  
 22031          return html;
 22032      }
 22033  };
 22034  'use strict';
 22035  
 22036  SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({
 22037      defaults: {
 22038          'in': '',
 22039          name: '',
 22040          title: '',
 22041          value: ''
 22042      },
 22043  
 22044      initialize: function () {
 22045          this.on('change', this.validate);
 22046      },
 22047  
 22048      validate: function () {
 22049          var valid = !!this.get('value');
 22050  
 22051          this.set('valid', valid);
 22052  
 22053          return valid;
 22054      }
 22055  });
 22056  'use strict';
 22057  
 22058  SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi
 22059  
 22060      events: {
 22061          'change .input_apiKey_entry': 'apiKeyChange'
 22062      },
 22063  
 22064      selectors: {
 22065          apikeyInput: '.input_apiKey_entry'
 22066      },
 22067  
 22068      template: Handlebars.templates.apikey_auth,
 22069  
 22070      initialize: function(opts) {
 22071          this.options = opts || {};
 22072          this.router = this.options.router;
 22073      },
 22074  
 22075      render: function (){
 22076          this.$el.html(this.template(this.model.toJSON()));
 22077  
 22078          return this;
 22079      },
 22080  
 22081      apiKeyChange: function (e) {
 22082          var val = $(e.target).val();
 22083          if (val) {
 22084              this.$(this.selectors.apikeyInput).removeClass('error');
 22085          }
 22086  
 22087          this.model.set('value', val);
 22088      },
 22089  
 22090      isValid: function () {
 22091          return this.model.validate();
 22092      },
 22093  
 22094      highlightInvalid: function () {
 22095          if (!this.isValid()) {
 22096              this.$(this.selectors.apikeyInput).addClass('error');
 22097          }
 22098      }
 22099  
 22100  });
 22101  'use strict';
 22102  
 22103  SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
 22104      events: {
 22105          'click .authorize__btn': 'authorizeBtnClick'
 22106      },
 22107  
 22108      tpls: {
 22109          popup: Handlebars.templates.popup,
 22110          authBtn: Handlebars.templates.auth_button,
 22111          authBtnOperation: Handlebars.templates.auth_button_operation
 22112      },
 22113  
 22114      initialize: function(opts) {
 22115          this.options = opts || {};
 22116          this.options.data = this.options.data || {};
 22117          this.isOperation = this.options.isOperation;
 22118          this.model = this.model || {};
 22119          this.router = this.options.router;
 22120          this.auths = this.options.data.oauth2.concat(this.options.data.auths);
 22121      },
 22122  
 22123      render: function () {
 22124          var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn';
 22125  
 22126          this.$authEl = this.renderAuths(this.auths);
 22127          this.$el.html(this.tpls[tplName](this.model));
 22128  
 22129          return this;
 22130      },
 22131  
 22132      authorizeBtnClick: function (e) {
 22133          var authsModel;
 22134  
 22135          e.preventDefault();
 22136  
 22137          authsModel = {
 22138              title: 'Available authorizations',
 22139              content: this.$authEl
 22140          };
 22141  
 22142          // The content of the popup is removed and all events unbound after clicking the 'Cancel' button of the popup.
 22143          // We'll have to re-render the contents before creating a new popup view.
 22144          this.render();
 22145  
 22146          this.popup = new SwaggerUi.Views.PopupView({model: authsModel});
 22147          this.popup.render();
 22148      },
 22149  
 22150      renderAuths: function (auths) {
 22151          var $el = $('<div>');
 22152          var isLogout = false;
 22153  
 22154          auths.forEach(function (auth) {
 22155              var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router});
 22156              var authEl = authView.render().el;
 22157              $el.append(authEl);
 22158              if (authView.isLogout) {
 22159                  isLogout = true;
 22160              }
 22161          }, this);
 22162  
 22163          this.model.isLogout = isLogout;
 22164  
 22165          return $el;
 22166      }
 22167  
 22168  });
 22169  
 22170  'use strict';
 22171  
 22172  SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({
 22173      constructor: function() {
 22174          var args = Array.prototype.slice.call(arguments);
 22175  
 22176          args[0] = this.parse(args[0]);
 22177  
 22178          Backbone.Collection.apply(this, args);
 22179      },
 22180  
 22181      add: function (model) {
 22182          var args = Array.prototype.slice.call(arguments);
 22183  
 22184          if (Array.isArray(model)) {
 22185              args[0] = _.map(model, function(val) {
 22186                  return this.handleOne(val);
 22187              }, this);
 22188          } else {
 22189              args[0] = this.handleOne(model);
 22190          }
 22191  
 22192          Backbone.Collection.prototype.add.apply(this, args);
 22193      },
 22194  
 22195      handleOne: function (model) {
 22196          var result = model;
 22197  
 22198          if (! (model instanceof Backbone.Model) ) {
 22199              switch (model.type) {
 22200                  case 'oauth2':
 22201                      result = new SwaggerUi.Models.Oauth2Model(model);
 22202                      break;
 22203                  case 'basic':
 22204                      result = new SwaggerUi.Models.BasicAuthModel(model);
 22205                      break;
 22206                  case 'apiKey':
 22207                      result = new SwaggerUi.Models.ApiKeyAuthModel(model);
 22208                      break;
 22209                  default:
 22210                      result = new Backbone.Model(model);
 22211              }
 22212          }
 22213  
 22214          return result;
 22215      },
 22216  
 22217      isValid: function () {
 22218          var valid = true;
 22219  
 22220          this.models.forEach(function(model) {
 22221              if (!model.validate()) {
 22222                  valid = false;
 22223              }
 22224          });
 22225  
 22226          return valid;
 22227      },
 22228  
 22229      isAuthorized: function () {
 22230          return this.length === this.where({ isLogout: true }).length;
 22231      },
 22232  
 22233      isPartiallyAuthorized: function () {
 22234          return this.where({ isLogout: true }).length > 0;
 22235      },
 22236  
 22237      parse: function (data) {
 22238          var authz = {};
 22239  
 22240          if(typeof window.swaggerUi !== 'undefined') {
 22241              authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz);
 22242          }
 22243  
 22244          return _.map(data, function (auth, name) {
 22245              var isBasic = authz[name] && auth.type === 'basic' && authz[name].username && authz[name].password;
 22246  
 22247              _.extend(auth, {
 22248                  title: name
 22249              });
 22250  
 22251              if (authz[name] || isBasic) {
 22252                  _.extend(auth, {
 22253                      isLogout: true,
 22254                      value: isBasic ? undefined : authz[name].value,
 22255                      username: isBasic ? authz[name].username : undefined,
 22256                      password: isBasic ? authz[name].password : undefined,
 22257                      valid: true
 22258                  });
 22259              }
 22260  
 22261              return auth;
 22262          });
 22263      }
 22264  });
 22265  'use strict';
 22266  
 22267  SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({
 22268  
 22269      initialize: function(opts) {
 22270          this.options = opts || {};
 22271          this.options.data = this.options.data || {};
 22272          this.router = this.options.router;
 22273  
 22274          this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data);
 22275  
 22276          this.$innerEl = $('<div>');
 22277          this.authViews = [];
 22278      },
 22279  
 22280      render: function () {
 22281          this.collection.each(function (auth) {
 22282              this.renderOneAuth(auth);
 22283          }, this);
 22284  
 22285          this.$el.html(this.$innerEl.html() ? this.$innerEl : '');
 22286  
 22287          return this;
 22288      },
 22289  
 22290      renderOneAuth: function (authModel) {
 22291          var authViewEl, authView, authViewName;
 22292          var type = authModel.get('type');
 22293  
 22294          if (type === 'apiKey') {
 22295              authViewName = 'ApiKeyAuthView';
 22296          } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {
 22297              authViewName = 'BasicAuthView';
 22298          } else if (type === 'oauth2') {
 22299              authViewName = 'Oauth2View';
 22300          }
 22301  
 22302          if (authViewName) {
 22303              authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router});
 22304              authViewEl = authView.render().el;
 22305              this.authViews.push(authView);
 22306          }
 22307  
 22308          this.$innerEl.append(authViewEl);
 22309      },
 22310  
 22311      highlightInvalid: function () {
 22312          this.authViews.forEach(function (view) {
 22313              view.highlightInvalid();
 22314          }, this);
 22315      }
 22316  
 22317  });
 22318  
 22319  'use strict';
 22320  
 22321  /* global redirect_uri:true */
 22322  /* global clientId */
 22323  /* global scopeSeparator */
 22324  /* global additionalQueryStringParams */
 22325  /* global clientSecret */
 22326  /* global onOAuthComplete */
 22327  /* global realm */
 22328  /*jshint unused:false*/
 22329  
 22330  SwaggerUi.Views.AuthView = Backbone.View.extend({
 22331      events: {
 22332          'click .auth_submit__button': 'authorizeClick',
 22333          'click .auth_logout__button': 'logoutClick'
 22334      },
 22335  
 22336      tpls: {
 22337          main: Handlebars.templates.auth_view
 22338      },
 22339  
 22340      selectors: {
 22341          innerEl: '.auth_inner',
 22342          authBtn: '.auth_submit__button'
 22343      },
 22344  
 22345      initialize: function(opts) {
 22346          this.options = opts || {};
 22347          opts.data = opts.data || {};
 22348          this.router = this.options.router;
 22349  
 22350          this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data});
 22351  
 22352          this.$el.html(this.tpls.main({
 22353              isLogout: this.authsCollectionView.collection.isAuthorized(),
 22354              isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized()
 22355          }));
 22356          this.$innerEl = this.$(this.selectors.innerEl);
 22357          this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized();
 22358      },
 22359  
 22360      render: function () {
 22361          this.$innerEl.html(this.authsCollectionView.render().el);
 22362  
 22363          return this;
 22364      },
 22365  
 22366      authorizeClick: function (e) {
 22367          e.preventDefault();
 22368          e.stopPropagation();
 22369  
 22370          if (this.authsCollectionView.collection.isValid()) {
 22371              this.authorize();
 22372          } else {
 22373              this.authsCollectionView.highlightInvalid();
 22374          }
 22375      },
 22376  
 22377      authorize: function () {
 22378          this.authsCollectionView.collection.forEach(function (auth) {
 22379              var keyAuth, basicAuth;
 22380              var type = auth.get('type');
 22381  
 22382              if (type === 'apiKey') {
 22383                  keyAuth = new SwaggerClient.ApiKeyAuthorization(
 22384                      auth.get('name'),
 22385                      auth.get('value'),
 22386                      auth.get('in')
 22387                  );
 22388  
 22389                  this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth);
 22390              } else if (type === 'basic') {
 22391                  basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));
 22392                  this.router.api.clientAuthorizations.add(auth.get('title'), basicAuth);
 22393              } else if (type === 'oauth2') {
 22394                  this.handleOauth2Login(auth);
 22395              }
 22396          }, this);
 22397  
 22398          this.router.load();
 22399      },
 22400  
 22401      logoutClick: function (e) {
 22402          e.preventDefault();
 22403  
 22404          this.authsCollectionView.collection.forEach(function (auth) {
 22405              window.swaggerUi.api.clientAuthorizations.remove(auth.get('title'));
 22406          });
 22407  
 22408          this.router.load();
 22409      },
 22410  
 22411      // taken from lib/swagger-oauth.js
 22412      handleOauth2Login: function (auth) {
 22413          var host = window.location;
 22414          var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/'));
 22415          var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
 22416          var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
 22417          var url = null;
 22418          var scopes = _.map(auth.get('scopes'), function (scope) {
 22419              if(scope.checked) {
 22420                  return scope.scope;
 22421              }
 22422          });
 22423          var container = window.swaggerUiAuth || (window.swaggerUiAuth = {});
 22424          var state, dets, ep;
 22425          container.OAuthSchemeKey = auth.get('title');
 22426  
 22427          window.enabledScopes = scopes;
 22428          var flow = auth.get('flow');
 22429  
 22430          if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
 22431              dets = auth.attributes;
 22432              url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
 22433              container.tokenName = dets.tokenName || 'access_token';
 22434              container.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
 22435              state = container.OAuthSchemeKey;
 22436          }
 22437          else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
 22438              dets = auth.attributes;
 22439              container.tokenName = dets.tokenName || 'access_token';
 22440              this.clientCredentialsFlow(scopes, dets.tokenUrl, container.OAuthSchemeKey);
 22441              return;
 22442          }
 22443          else if(auth.get('grantTypes')) {
 22444              // 1.2 support
 22445              var o = auth.get('grantTypes');
 22446              for(var t in o) {
 22447                  if(o.hasOwnProperty(t) && t === 'implicit') {
 22448                      dets = o[t];
 22449                      ep = dets.loginEndpoint.url;
 22450                      url = dets.loginEndpoint.url + '?response_type=token';
 22451                      container.tokenName = dets.tokenName;
 22452                  }
 22453                  else if (o.hasOwnProperty(t) && t === 'accessCode') {
 22454                      dets = o[t];
 22455                      ep = dets.tokenRequestEndpoint.url;
 22456                      url = dets.tokenRequestEndpoint.url + '?response_type=code';
 22457                      container.tokenName = dets.tokenName;
 22458                  }
 22459              }
 22460          }
 22461  
 22462          redirect_uri = redirectUrl;
 22463  
 22464          url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
 22465          url += '&realm=' + encodeURIComponent(realm);
 22466          url += '&client_id=' + encodeURIComponent(clientId);
 22467          url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
 22468          url += '&state=' + encodeURIComponent(state);
 22469          for (var key in additionalQueryStringParams) {
 22470              url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
 22471          }
 22472  
 22473          window.open(url);
 22474      },
 22475  
 22476      // taken from lib/swagger-oauth.js
 22477      clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) {
 22478          var params = {
 22479              'client_id': clientId,
 22480              'client_secret': clientSecret,
 22481              'scope': scopes.join(' '),
 22482              'grant_type': 'client_credentials'
 22483          };
 22484          $.ajax({
 22485              url : tokenUrl,
 22486              type: 'POST',
 22487              data: params,
 22488              success: function (data)
 22489              {
 22490                  onOAuthComplete(data, OAuthSchemeKey);
 22491              },
 22492              error: function ()
 22493              {
 22494                  onOAuthComplete('');
 22495              }
 22496          });
 22497      }
 22498  
 22499  });
 22500  
 22501  'use strict';
 22502  
 22503  SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({
 22504      defaults: {
 22505          username: '',
 22506          password: '',
 22507          title: 'basic'
 22508      },
 22509  
 22510      initialize: function () {
 22511          this.on('change', this.validate);
 22512      },
 22513  
 22514      validate: function () {
 22515          var valid = !!this.get('password') && !!this.get('username');
 22516  
 22517          this.set('valid', valid);
 22518  
 22519          return valid;
 22520      }
 22521  });
 22522  'use strict';
 22523  
 22524  SwaggerUi.Views.BasicAuthView = Backbone.View.extend({
 22525  
 22526      initialize: function (opts) {
 22527          this.options = opts || {};
 22528          this.router = this.options.router;
 22529      },
 22530  
 22531      events: {
 22532          'change .auth_input': 'inputChange'
 22533      },
 22534  
 22535      selectors: {
 22536          usernameInput: '.basic_auth__username',
 22537          passwordInput: '.basic_auth__password'
 22538      },
 22539  
 22540      cls: {
 22541          error: 'error'
 22542      },
 22543  
 22544      template: Handlebars.templates.basic_auth,
 22545  
 22546      render: function(){
 22547          $(this.el).html(this.template(this.model.toJSON()));
 22548  
 22549          return this;
 22550      },
 22551  
 22552      inputChange: function (e) {
 22553          var $el = $(e.target);
 22554          var val = $el.val();
 22555          var attr = $el.prop('name');
 22556  
 22557          if (val) {
 22558              $el.removeClass(this.cls.error);
 22559          }
 22560  
 22561          this.model.set(attr, val);
 22562      },
 22563  
 22564      isValid: function () {
 22565          return this.model.validate();
 22566      },
 22567  
 22568      highlightInvalid: function () {
 22569          if (!this.model.get('username')) {
 22570              this.$(this.selectors.usernameInput).addClass(this.cls.error);
 22571          }
 22572      }
 22573  });
 22574  
 22575  'use strict';
 22576  
 22577  SwaggerUi.Views.ContentTypeView = Backbone.View.extend({
 22578    initialize: function() {},
 22579  
 22580    render: function(){
 22581    	this.model.contentTypeId = 'ct' + Math.random();
 22582      $(this.el).html(Handlebars.templates.content_type(this.model));
 22583      return this;
 22584    }
 22585  });
 22586  'use strict';
 22587  
 22588  SwaggerUi.Views.HeaderView = Backbone.View.extend({
 22589    events: {
 22590      'click #show-pet-store-icon'    : 'showPetStore',
 22591      'click #explore'                : 'showCustom',
 22592      'submit #api_selector'          : 'showCustom',
 22593      'keyup #input_baseUrl'          : 'showCustomOnKeyup',
 22594      'keyup #input_apiKey'           : 'showCustomOnKeyup'
 22595    },
 22596  
 22597    initialize: function(){},
 22598  
 22599    showPetStore: function(){
 22600      this.trigger('update-swagger-ui', {
 22601        url:'http://petstore.swagger.io/v2/swagger.json'
 22602      });
 22603    },
 22604  
 22605    showCustomOnKeyup: function(e){
 22606      if (e.keyCode === 13) {
 22607        this.showCustom();
 22608      }
 22609    },
 22610  
 22611    showCustom: function(e){
 22612      if (e) {
 22613        e.preventDefault();
 22614      }
 22615  
 22616      this.trigger('update-swagger-ui', {
 22617        url: $('#input_baseUrl').val()
 22618      });
 22619    },
 22620  
 22621    update: function(url, apiKey, trigger){
 22622      if (trigger === undefined) {
 22623        trigger = false;
 22624      }
 22625  
 22626      $('#input_baseUrl').val(url);
 22627  
 22628      if (trigger) {
 22629        this.trigger('update-swagger-ui', {url:url});
 22630      }
 22631    }
 22632  });
 22633  
 22634  'use strict';
 22635  
 22636  SwaggerUi.Views.MainView = Backbone.View.extend({
 22637    apisSorter : {
 22638      alpha   : function(a,b){ return a.name.localeCompare(b.name); }
 22639    },
 22640    operationsSorters : {
 22641      alpha   : function(a,b){ return a.path.localeCompare(b.path); },
 22642      method  : function(a,b){ return a.method.localeCompare(b.method); }
 22643    },
 22644    initialize: function(opts){
 22645      var sorterOption, sorterFn, key, value;
 22646      opts = opts || {};
 22647  
 22648      this.router = opts.router;
 22649  
 22650      // Sort APIs
 22651      if (opts.swaggerOptions.apisSorter) {
 22652        sorterOption = opts.swaggerOptions.apisSorter;
 22653        if (_.isFunction(sorterOption)) {
 22654          sorterFn = sorterOption;
 22655        } else {
 22656          sorterFn = this.apisSorter[sorterOption];
 22657        }
 22658        if (_.isFunction(sorterFn)) {
 22659          this.model.apisArray.sort(sorterFn);
 22660        }
 22661      }
 22662      // Sort operations of each API
 22663      if (opts.swaggerOptions.operationsSorter) {
 22664        sorterOption = opts.swaggerOptions.operationsSorter;
 22665        if (_.isFunction(sorterOption)) {
 22666          sorterFn = sorterOption;
 22667        } else {
 22668          sorterFn = this.operationsSorters[sorterOption];
 22669        }
 22670        if (_.isFunction(sorterFn)) {
 22671          for (key in this.model.apisArray) {
 22672            this.model.apisArray[key].operationsArray.sort(sorterFn);
 22673          }
 22674        }
 22675      }
 22676  
 22677      // set up the UI for input
 22678      this.model.auths = [];
 22679  
 22680      for (key in this.model.securityDefinitions) {
 22681        value = this.model.securityDefinitions[key];
 22682  
 22683        this.model.auths.push({
 22684          name: key,
 22685          type: value.type,
 22686          value: value
 22687        });
 22688      }
 22689  
 22690      if ('validatorUrl' in opts.swaggerOptions) {
 22691        // Validator URL specified explicitly
 22692        this.model.validatorUrl = opts.swaggerOptions.validatorUrl;
 22693      } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) {
 22694        // Localhost override
 22695        this.model.validatorUrl = null;
 22696      } else {
 22697        this.model.validatorUrl = '//online.swagger.io/validator';
 22698      }
 22699  
 22700      // JSonEditor requires type='object' to be present on defined types, we add it if it's missing
 22701      // is there any valid case were it should not be added ?
 22702      var def;
 22703      for(def in this.model.definitions){
 22704        if (!this.model.definitions[def].type){
 22705          this.model.definitions[def].type = 'object';
 22706        }
 22707      }
 22708  
 22709    },
 22710  
 22711    render: function () {
 22712      $(this.el).html(Handlebars.templates.main(this.model));
 22713      this.info = this.$('.info')[0];
 22714  
 22715      if (this.info) {
 22716        this.info.addEventListener('click', this.onLinkClick, true);
 22717      }
 22718  
 22719      this.model.securityDefinitions = this.model.securityDefinitions || {};
 22720  
 22721      // Render each resource
 22722  
 22723      var resources = {};
 22724      var counter = 0;
 22725      for (var i = 0; i < this.model.apisArray.length; i++) {
 22726        var resource = this.model.apisArray[i];
 22727        var id = resource.name;
 22728        while (typeof resources[id] !== 'undefined') {
 22729          id = id + '_' + counter;
 22730          counter += 1;
 22731        }
 22732        resource.id = sanitizeHtml(id);
 22733        resources[id] = resource;
 22734        this.addResource(resource, this.model.auths);
 22735      }
 22736  
 22737      $('.propWrap').hover(function onHover(){
 22738        $('.optionsWrapper', $(this)).show();
 22739      }, function offhover(){
 22740        $('.optionsWrapper', $(this)).hide();
 22741      });
 22742      return this;
 22743    },
 22744  
 22745    addResource: function(resource, auths){
 22746      // Render a resource and add it to resources li
 22747      resource.id = resource.id.replace(/\s/g, '_');
 22748  
 22749      // Make all definitions available at the root of the resource so that they can
 22750      // be loaded by the JSonEditor
 22751      resource.definitions = this.model.definitions;
 22752  
 22753      var resourceView = new SwaggerUi.Views.ResourceView({
 22754        model: resource,
 22755        router: this.router,
 22756        tagName: 'li',
 22757        id: 'resource_' + resource.id,
 22758        className: 'resource',
 22759        auths: auths,
 22760        swaggerOptions: this.options.swaggerOptions
 22761      });
 22762      $('#resources', this.el).append(resourceView.render().el);
 22763    },
 22764  
 22765    clear: function(){
 22766      $(this.el).html('');
 22767    },
 22768  
 22769    onLinkClick: function (e) {
 22770      var el = e.target;
 22771  
 22772      if (el.tagName === 'A' && el.href && !el.target) {
 22773          e.preventDefault();
 22774          window.open(el.href, '_blank');
 22775      }
 22776    }
 22777  });
 22778  
 22779  'use strict';
 22780  
 22781  SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
 22782      defaults: {
 22783          scopes: {}
 22784      },
 22785  
 22786      initialize: function () {
 22787          if(this.attributes && this.attributes.scopes) {
 22788              var attributes = _.cloneDeep(this.attributes);
 22789              var i, scopes = [];
 22790              for(i in attributes.scopes) {
 22791                  var scope = attributes.scopes[i];
 22792                  if(typeof scope.description === 'string') {
 22793                      scopes[scope] = attributes.scopes[i];
 22794                      scopes.push(attributes.scopes[i]);
 22795                  }
 22796              }
 22797              attributes.scopes = scopes;
 22798              this.attributes = attributes;
 22799          }
 22800          this.on('change', this.validate);
 22801      },
 22802  
 22803      setScopes: function (name, val) {
 22804          var auth = _.extend({}, this.attributes);
 22805          var index = _.findIndex(auth.scopes, function(o) {
 22806              return o.scope === name;
 22807          });
 22808          auth.scopes[index].checked = val;
 22809  
 22810          this.set(auth);
 22811          this.validate();
 22812      },
 22813  
 22814      validate: function () {
 22815        var valid = false;
 22816        var scp = this.get('scopes');
 22817        var idx =  _.findIndex(scp, function (o) {
 22818           return o.checked === true;
 22819        });
 22820  
 22821        if(scp.length > 0 && idx >= 0) {
 22822            valid = true;
 22823        }
 22824  
 22825        if(scp.length === 0) {
 22826            valid = true;
 22827        }
 22828  
 22829        this.set('valid', valid);
 22830  
 22831        return valid;
 22832      }
 22833  });
 22834  
 22835  'use strict';
 22836  
 22837  SwaggerUi.Views.Oauth2View = Backbone.View.extend({
 22838      events: {
 22839          'change .oauth-scope': 'scopeChange'
 22840      },
 22841  
 22842      template: Handlebars.templates.oauth2,
 22843  
 22844      render: function () {
 22845          this.$el.html(this.template(this.model.toJSON()));
 22846  
 22847          return this;
 22848      },
 22849  
 22850      scopeChange: function (e) {
 22851          var val = $(e.target).prop('checked');
 22852          var scope = $(e.target).data('scope');
 22853  
 22854          this.model.setScopes(scope, val);
 22855      }
 22856  });
 22857  'use strict';
 22858  
 22859  SwaggerUi.Views.OperationView = Backbone.View.extend({
 22860    invocationUrl: null,
 22861  
 22862    events: {
 22863      'submit .sandbox'         : 'submitOperation',
 22864      'click .submit'           : 'submitOperation',
 22865      'click .response_hider'   : 'hideResponse',
 22866      'click .toggleOperation'  : 'toggleOperationContent',
 22867      'mouseenter .api-ic'      : 'mouseEnter',
 22868      'dblclick .curl'          : 'selectText',
 22869      'change [name=responseContentType]' : 'showSnippet'
 22870    },
 22871  
 22872    initialize: function(opts) {
 22873      opts = opts || {};
 22874      this.router = opts.router;
 22875      this.auths = opts.auths;
 22876      this.parentId = this.model.parentId;
 22877      this.nickname = this.model.nickname;
 22878      this.model.encodedParentId = encodeURIComponent(this.parentId);
 22879  
 22880      if (opts.swaggerOptions) {
 22881        this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering;
 22882  
 22883        if (opts.swaggerOptions.showRequestHeaders) {
 22884          this.model.showRequestHeaders = true;
 22885        }
 22886      }
 22887      return this;
 22888    },
 22889  
 22890    selectText: function(event) {
 22891      var doc = document,
 22892          text = event.target.firstChild,
 22893          range,
 22894          selection;
 22895      if (doc.body.createTextRange) {
 22896        range = document.body.createTextRange();
 22897        range.moveToElementText(text);
 22898        range.select();
 22899      } else if (window.getSelection) {
 22900        selection = window.getSelection();
 22901        range = document.createRange();
 22902        range.selectNodeContents(text);
 22903        selection.removeAllRanges();
 22904        selection.addRange(range);
 22905      }
 22906    },
 22907  
 22908    mouseEnter: function(e) {
 22909      var elem = $(this.el).find('.content');
 22910      var x = e.pageX;
 22911      var y = e.pageY;
 22912      var scX = $(window).scrollLeft();
 22913      var scY = $(window).scrollTop();
 22914      var scMaxX = scX + $(window).width();
 22915      var scMaxY = scY + $(window).height();
 22916      var wd = elem.width();
 22917      var hgh = elem.height();
 22918  
 22919      if (x + wd > scMaxX) {
 22920        x = scMaxX - wd;
 22921      }
 22922  
 22923      if (x < scX) {
 22924        x = scX;
 22925      }
 22926  
 22927      if (y + hgh > scMaxY) {
 22928        y = scMaxY - hgh;
 22929      }
 22930  
 22931      if (y < scY) {
 22932        y = scY;
 22933      }
 22934  
 22935      var pos = {};
 22936      pos.top = y;
 22937      pos.left = x;
 22938      elem.css(pos);
 22939    },
 22940  
 22941    // Note: copied from CoffeeScript compiled file
 22942    // TODO: refactor
 22943    render: function() {
 22944      var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON;
 22945      isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
 22946      if (!isMethodSubmissionSupported) {
 22947        this.model.isReadOnly = true;
 22948      }
 22949      this.model.description = this.model.description || this.model.notes;
 22950      this.model.oauth = null;
 22951      modelAuths = this.model.authorizations || this.model.security;
 22952      if (modelAuths) {
 22953        if (Array.isArray(modelAuths)) {
 22954          for (l = 0, len = modelAuths.length; l < len; l++) {
 22955            auths = modelAuths[l];
 22956            for (key in auths) {
 22957              for (a in this.auths) {
 22958                auth = this.auths[a];
 22959                if (key === auth.name) {
 22960                  if (auth.type === 'oauth2') {
 22961                    this.model.oauth = {};
 22962                    this.model.oauth.scopes = [];
 22963                    ref1 = auth.value.scopes;
 22964                    for (k in ref1) {
 22965                      v = ref1[k];
 22966                      scopeIndex = auths[key].indexOf(k);
 22967                      if (scopeIndex >= 0) {
 22968                        o = {
 22969                          scope: k,
 22970                          description: v
 22971                        };
 22972                        this.model.oauth.scopes.push(o);
 22973                      }
 22974                    }
 22975                  }
 22976                }
 22977              }
 22978            }
 22979          }
 22980        } else {
 22981          for (k in modelAuths) {
 22982            v = modelAuths[k];
 22983            if (k === 'oauth2') {
 22984              if (this.model.oauth === null) {
 22985                this.model.oauth = {};
 22986              }
 22987              if (this.model.oauth.scopes === void 0) {
 22988                this.model.oauth.scopes = [];
 22989              }
 22990              for (m = 0, len1 = v.length; m < len1; m++) {
 22991                o = v[m];
 22992                this.model.oauth.scopes.push(o);
 22993              }
 22994            }
 22995          }
 22996        }
 22997      }
 22998      if (typeof this.model.responses !== 'undefined') {
 22999        this.model.responseMessages = [];
 23000        ref2 = this.model.responses;
 23001        for (code in ref2) {
 23002          value = ref2[code];
 23003          schema = null;
 23004          schemaObj = this.model.responses[code].schema;
 23005          if (schemaObj && schemaObj.$ref) {
 23006            schema = schemaObj.$ref;
 23007            if (schema.indexOf('#/definitions/') !== -1) {
 23008              schema = schema.replace(/^.*#\/definitions\//, '');
 23009            }
 23010          }
 23011          this.model.responseMessages.push({
 23012            code: code,
 23013            message: value.description,
 23014            responseModel: schema,
 23015            headers: value.headers,
 23016            schema: schemaObj
 23017          });
 23018        }
 23019      }
 23020      if (typeof this.model.responseMessages === 'undefined') {
 23021        this.model.responseMessages = [];
 23022      }
 23023      signatureModel = null;
 23024      produces = this.model.produces;
 23025      isXML = this.contains(produces, 'xml');
 23026      isJSON = isXML ? this.contains(produces, 'json') : true;
 23027  
 23028      if (this.model.successResponse) {
 23029        successResponse = this.model.successResponse;
 23030        for (key in successResponse) {
 23031          value = successResponse[key];
 23032          this.model.successCode = key;
 23033          if (typeof value === 'object' && typeof value.createJSONSample === 'function') {
 23034            this.model.successDescription = value.description;
 23035            this.model.headers = this.parseResponseHeaders(value.headers);
 23036            signatureModel = {
 23037              sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false,
 23038              isParam: false,
 23039              sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false,
 23040              signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro)
 23041            };
 23042          } else {
 23043            signatureModel = {
 23044              signature: SwaggerUi.partials.signature.getPrimitiveSignature(value)
 23045            };
 23046          }
 23047        }
 23048      } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {
 23049        signatureModel = {
 23050          sampleJSON: this.model.responseSampleJSON,
 23051          isParam: false,
 23052          signature: this.model.responseClassSignature
 23053        };
 23054      }
 23055      $(this.el).html(Handlebars.templates.operation(this.model));
 23056      if (signatureModel) {
 23057        signatureModel.defaultRendering = this.model.defaultRendering;
 23058        responseSignatureView = new SwaggerUi.Views.SignatureView({
 23059          model: signatureModel,
 23060          router: this.router,
 23061          tagName: 'div'
 23062        });
 23063        $('.model-signature', $(this.el)).append(responseSignatureView.render().el);
 23064      } else {
 23065        this.model.responseClassSignature = 'string';
 23066        $('.model-signature', $(this.el)).html(this.model.type);
 23067      }
 23068      contentTypeModel = {
 23069        isParam: false
 23070      };
 23071      contentTypeModel.consumes = this.model.consumes;
 23072      contentTypeModel.produces = this.model.produces;
 23073      ref3 = this.model.parameters;
 23074      for (n = 0, len2 = ref3.length; n < len2; n++) {
 23075        param = ref3[n];
 23076        type = param.type || param.dataType || '';
 23077        if (typeof type === 'undefined') {
 23078          schema = param.schema;
 23079          if (schema && schema.$ref) {
 23080            ref = schema.$ref;
 23081            if (ref.indexOf('#/definitions/') === 0) {
 23082              type = ref.substring('#/definitions/'.length);
 23083            } else {
 23084              type = ref;
 23085            }
 23086          }
 23087        }
 23088        if (type && type.toLowerCase() === 'file') {
 23089          if (!contentTypeModel.consumes) {
 23090            contentTypeModel.consumes = 'multipart/form-data';
 23091          }
 23092        }
 23093        param.type = type;
 23094      }
 23095      responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({
 23096        model: contentTypeModel,
 23097        router: this.router
 23098      });
 23099      $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
 23100      ref4 = this.model.parameters;
 23101      for (p = 0, len3 = ref4.length; p < len3; p++) {
 23102        param = ref4[p];
 23103        this.addParameter(param, contentTypeModel.consumes);
 23104      }
 23105      ref5 = this.model.responseMessages;
 23106      for (q = 0, len4 = ref5.length; q < len4; q++) {
 23107        statusCode = ref5[q];
 23108        statusCode.isXML = isXML;
 23109        statusCode.isJSON = isJSON;
 23110        if (!_.isUndefined(statusCode.headers)) {
 23111          statusCode.headers = this.parseHeadersType(statusCode.headers);
 23112        }
 23113        this.addStatusCode(statusCode);
 23114      }
 23115  
 23116      if (Array.isArray(this.model.security)) {
 23117        var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security, this.model.parent.securityDefinitions);
 23118  
 23119        authsModel.isLogout = !_.isEmpty(this.model.clientAuthorizations.authz);
 23120        this.authView = new SwaggerUi.Views.AuthButtonView({
 23121          data: authsModel,
 23122          router: this.router,
 23123          isOperation: true,
 23124          model: {
 23125            scopes: authsModel.scopes
 23126          }
 23127        });
 23128        this.$('.authorize-wrapper').append(this.authView.render().el);
 23129      }
 23130  
 23131      this.showSnippet();
 23132      return this;
 23133    },
 23134  
 23135    parseHeadersType: function (headers) {
 23136      var map = {
 23137        'string': {
 23138          'date-time': 'dateTime',
 23139          'date'     : 'date'
 23140        }
 23141      };
 23142  
 23143      _.forEach(headers, function (header) {
 23144        var value;
 23145        header = header || {};
 23146        value = map[header.type] && map[header.type][header.format];
 23147        if (!_.isUndefined(value)) {
 23148          header.type = value;
 23149        }
 23150      });
 23151  
 23152      return headers;
 23153    },
 23154  
 23155    contains: function (produces, type) {
 23156      return produces.filter(function (val) {
 23157        if (val.indexOf(type) > -1) {
 23158          return true;
 23159        }
 23160      }).length;
 23161    },
 23162  
 23163    parseResponseHeaders: function (data) {
 23164      var HEADERS_SEPARATOR = '; ';
 23165      var headers = _.clone(data);
 23166  
 23167      _.forEach(headers, function (header) {
 23168        var other = [];
 23169        _.forEach(header, function (value, key) {
 23170          var properties = ['type', 'description'];
 23171          if (properties.indexOf(key.toLowerCase()) === -1) {
 23172            other.push(key + ': ' + value);
 23173          }
 23174        });
 23175  
 23176        other.join(HEADERS_SEPARATOR);
 23177        header.other = other;
 23178      });
 23179  
 23180      return headers;
 23181    },
 23182  
 23183    addParameter: function(param, consumes) {
 23184      // Render a parameter
 23185      param.consumes = consumes;
 23186      param.defaultRendering = this.model.defaultRendering;
 23187  
 23188      // Copy this param JSON spec so that it will be available for JsonEditor
 23189      if(param.schema){
 23190        $.extend(true, param.schema, this.model.definitions[param.type]);
 23191        param.schema.definitions = this.model.definitions;
 23192        // This is required for JsonEditor to display the root properly
 23193        if(!param.schema.type){
 23194          param.schema.type = 'object';
 23195        }
 23196        // This is the title that will be used by JsonEditor for the root
 23197        // Since we already display the parameter's name in the Parameter column
 23198        // We set this to space, we can't set it to null or space otherwise JsonEditor
 23199        // will replace it with the text "root" which won't look good on screen
 23200        if(!param.schema.title){
 23201          param.schema.title = ' ';
 23202        }
 23203      }
 23204  
 23205      var paramView = new SwaggerUi.Views.ParameterView({
 23206        model: param,
 23207        tagName: 'tr',
 23208        readOnly: this.model.isReadOnly,
 23209        swaggerOptions: this.options.swaggerOptions
 23210      });
 23211      $('.operation-params', $(this.el)).append(paramView.render().el);
 23212    },
 23213  
 23214    addStatusCode: function(statusCode) {
 23215      // Render status codes
 23216      statusCode.defaultRendering = this.model.defaultRendering;
 23217      var statusCodeView = new SwaggerUi.Views.StatusCodeView({
 23218        model: statusCode,
 23219        tagName: 'tr',
 23220        router: this.router
 23221      });
 23222      $('.operation-status', $(this.el)).append(statusCodeView.render().el);
 23223    },
 23224  
 23225    // Note: copied from CoffeeScript compiled file
 23226    // TODO: redactor
 23227    submitOperation: function(e) {
 23228      var error_free, form, isFileUpload, map, opts;
 23229      if (e !== null) {
 23230        e.preventDefault();
 23231      }
 23232      form = $('.sandbox', $(this.el));
 23233      error_free = true;
 23234      form.find('input.required').each(function() {
 23235        $(this).removeClass('error');
 23236        if (jQuery.trim($(this).val()) === '') {
 23237          $(this).addClass('error');
 23238          $(this).wiggle({
 23239            callback: (function(_this) {
 23240              return function() {
 23241                $(_this).focus();
 23242              };
 23243            })(this)
 23244          });
 23245          error_free = false;
 23246        }
 23247      });
 23248      form.find('textarea.required:visible').each(function() {
 23249        $(this).removeClass('error');
 23250        if (jQuery.trim($(this).val()) === '') {
 23251          $(this).addClass('error');
 23252          $(this).wiggle({
 23253            callback: (function(_this) {
 23254              return function() {
 23255                return $(_this).focus();
 23256              };
 23257            })(this)
 23258          });
 23259          error_free = false;
 23260        }
 23261      });
 23262      form.find('select.required').each(function() {
 23263        $(this).removeClass('error');
 23264        if (this.selectedIndex === -1) {
 23265          $(this).addClass('error');
 23266          $(this).wiggle({
 23267            callback: (function(_this) {
 23268              return function() {
 23269                $(_this).focus();
 23270              };
 23271            })(this)
 23272          });
 23273          error_free = false;
 23274        }
 23275      });
 23276      if (error_free) {
 23277        map = this.getInputMap(form);
 23278        isFileUpload = this.isFileUpload(form);
 23279        opts = {
 23280          parent: this
 23281        };
 23282        if (this.options.swaggerOptions) {
 23283          for(var key in this.options.swaggerOptions) {
 23284            opts[key] = this.options.swaggerOptions[key];
 23285          }
 23286        }
 23287  
 23288        var pi;
 23289        for(pi = 0; pi < this.model.parameters.length; pi++){
 23290          var p = this.model.parameters[pi];
 23291          if( p.jsonEditor && p.jsonEditor.isEnabled()){
 23292            var json = p.jsonEditor.getValue();
 23293            map[p.name] = JSON.stringify(json);
 23294          }
 23295        }
 23296  
 23297        opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();
 23298        opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();
 23299        $('.response_throbber', $(this.el)).show();
 23300        if (isFileUpload) {
 23301          $('.request_url', $(this.el)).html('<pre></pre>');
 23302          $('.request_url pre', $(this.el)).text(this.invocationUrl);
 23303  
 23304          opts.useJQuery = true;
 23305          map.parameterContentType = 'multipart/form-data';
 23306          this.map = map;
 23307          return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
 23308        } else {
 23309          this.map = map;
 23310          return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
 23311        }
 23312      }
 23313    },
 23314  
 23315    getInputMap: function (form) {
 23316      var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2;
 23317      map = {};
 23318      ref1 = form.find('input');
 23319      for (l = 0, len = ref1.length; l < len; l++) {
 23320        o = ref1[l];
 23321        if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
 23322          map[o.name] = o.value;
 23323        }
 23324        if (o.type === 'file') {
 23325          map[o.name] = o.files[0];
 23326        }
 23327      }
 23328      ref2 = form.find('textarea');
 23329      for (m = 0, len1 = ref2.length; m < len1; m++) {
 23330        o = ref2[m];
 23331        val = this.getTextAreaValue(o);
 23332        if ((val !== null) && jQuery.trim(val).length > 0) {
 23333          map[o.name] = val;
 23334        }
 23335      }
 23336      ref3 = form.find('select');
 23337      for (n = 0, len2 = ref3.length; n < len2; n++) {
 23338        o = ref3[n];
 23339        val = this.getSelectedValue(o);
 23340        if ((val !== null) && jQuery.trim(val).length > 0) {
 23341          map[o.name] = val;
 23342        }
 23343      }
 23344      return map;
 23345    },
 23346  
 23347    isFileUpload: function (form) {
 23348      var ref1, l, len, o;
 23349      var isFileUpload = false;
 23350      ref1 = form.find('input');
 23351      for (l = 0, len = ref1.length; l < len; l++) {
 23352        o = ref1[l];
 23353        if (o.type === 'file') {
 23354          isFileUpload = true;
 23355        }
 23356      }
 23357      return isFileUpload;
 23358    },
 23359  
 23360    success: function(response, parent) {
 23361      parent.showCompleteStatus(response);
 23362    },
 23363  
 23364    // wraps a jquery response as a shred response
 23365    wrap: function(data) {
 23366      var h, headerArray, headers, i, l, len, o;
 23367      headers = {};
 23368      headerArray = data.getAllResponseHeaders().split('\r');
 23369      for (l = 0, len = headerArray.length; l < len; l++) {
 23370        i = headerArray[l];
 23371        h = i.match(/^([^:]*?):(.*)$/);
 23372        if (!h) {
 23373          h = [];
 23374        }
 23375        h.shift();
 23376        if (h[0] !== void 0 && h[1] !== void 0) {
 23377          headers[h[0].trim()] = h[1].trim();
 23378        }
 23379      }
 23380      o = {};
 23381      o.content = {};
 23382      o.content.data = data.responseText;
 23383      o.headers = headers;
 23384      o.request = {};
 23385      o.request.url = this.invocationUrl;
 23386      o.status = data.status;
 23387      return o;
 23388    },
 23389  
 23390    getSelectedValue: function(select) {
 23391      if (!select.multiple) {
 23392        return select.value;
 23393      } else {
 23394        var options = [];
 23395        for (var l = 0, len = select.options.length; l < len; l++) {
 23396          var opt = select.options[l];
 23397          if (opt.selected) {
 23398            options.push(opt.value);
 23399          }
 23400        }
 23401        if (options.length > 0) {
 23402          return options;
 23403        } else {
 23404          return null;
 23405        }
 23406      }
 23407    },
 23408  
 23409    // handler for hide response link
 23410    hideResponse: function(e) {
 23411      if (e) { e.preventDefault(); }
 23412      $('.response', $(this.el)).slideUp();
 23413      $('.response_hider', $(this.el)).fadeOut();
 23414    },
 23415  
 23416    // Show response from server
 23417    showResponse: function(response) {
 23418      var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');
 23419      $('.response_body', $(this.el)).html(_.escape(prettyJson));
 23420    },
 23421  
 23422    // Show error from server
 23423    showErrorStatus: function(data, parent) {
 23424      parent.showStatus(data);
 23425    },
 23426  
 23427    // show the status codes
 23428    showCompleteStatus: function(data, parent){
 23429      parent.showStatus(data);
 23430    },
 23431  
 23432    // Adapted from http://stackoverflow.com/a/2893259/454004
 23433    // Note: directly ported from CoffeeScript
 23434    // TODO: Cleanup CoffeeScript artifacts
 23435    formatXml: function(xml) {
 23436      var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
 23437      reg = /(>)(<)(\/*)/g;
 23438      wsexp = /[ ]*(.*)[ ]+\n/g;
 23439      contexp = /(<.+>)(.+\n)/g;
 23440      xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
 23441      pad = 0;
 23442      formatted = '';
 23443      lines = xml.split('\n');
 23444      indent = 0;
 23445      lastType = 'other';
 23446      transitions = {
 23447        'single->single': 0,
 23448        'single->closing': -1,
 23449        'single->opening': 0,
 23450        'single->other': 0,
 23451        'closing->single': 0,
 23452        'closing->closing': -1,
 23453        'closing->opening': 0,
 23454        'closing->other': 0,
 23455        'opening->single': 1,
 23456        'opening->closing': 0,
 23457        'opening->opening': 1,
 23458        'opening->other': 1,
 23459        'other->single': 0,
 23460        'other->closing': -1,
 23461        'other->opening': 0,
 23462        'other->other': 0
 23463      };
 23464      fn = function(ln) {
 23465        var fromTo, j, key, padding, type, types, value;
 23466        types = {
 23467          single: Boolean(ln.match(/<.+\/>/)),
 23468          closing: Boolean(ln.match(/<\/.+>/)),
 23469          opening: Boolean(ln.match(/<[^!?].*>/))
 23470        };
 23471        type = ((function() {
 23472          var results;
 23473          results = [];
 23474          for (key in types) {
 23475            value = types[key];
 23476            if (value) {
 23477              results.push(key);
 23478            }
 23479          }
 23480          return results;
 23481        })())[0];
 23482        type = type === void 0 ? 'other' : type;
 23483        fromTo = lastType + '->' + type;
 23484        lastType = type;
 23485        padding = '';
 23486        indent += transitions[fromTo];
 23487        padding = ((function() {
 23488          var m, ref1, results;
 23489          results = [];
 23490          for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
 23491            results.push('  ');
 23492          }
 23493          return results;
 23494        })()).join('');
 23495        if (fromTo === 'opening->closing') {
 23496          formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
 23497        } else {
 23498          formatted += padding + ln + '\n';
 23499        }
 23500      };
 23501      for (l = 0, len = lines.length; l < len; l++) {
 23502        ln = lines[l];
 23503        fn(ln);
 23504      }
 23505      return formatted;
 23506    },
 23507  
 23508    // puts the response data in UI
 23509    showStatus: function(response) {
 23510      var url, content;
 23511      if (response.content === undefined) {
 23512        content = response.data;
 23513        url = response.url;
 23514      } else {
 23515        content = response.content.data;
 23516        url = response.request.url;
 23517      }
 23518      var headers = response.headers;
 23519      if(typeof content === 'string') {
 23520        content = jQuery.trim(content);
 23521      }
 23522  
 23523      // if server is nice, and sends content-type back, we can use it
 23524      var contentType = null;
 23525      if (headers) {
 23526        contentType = headers['Content-Type'] || headers['content-type'];
 23527        if (contentType) {
 23528          contentType = contentType.split(';')[0].trim();
 23529        }
 23530      }
 23531  
 23532      $('.response_body', $(this.el)).removeClass('json');
 23533      $('.response_body', $(this.el)).removeClass('xml');
 23534  
 23535      var supportsAudioPlayback = function(contentType){
 23536        var audioElement = document.createElement('audio');
 23537        return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));
 23538      };
 23539  
 23540      var pre;
 23541      var code;
 23542      if (!content) {
 23543        code = $('<code />').text('no content');
 23544        pre = $('<pre class="json" />').append(code);
 23545  
 23546        // JSON
 23547      } else if (
 23548          contentType === 'application/octet-stream' ||
 23549          headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||
 23550          headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||
 23551          headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||
 23552          headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {
 23553  
 23554        if ('Blob' in window) {
 23555          var type = contentType || 'text/html';
 23556          var a = document.createElement('a');
 23557          var href;
 23558  
 23559          if({}.toString.apply(content) === '[object Blob]') {
 23560            href = window.URL.createObjectURL(content);
 23561          }
 23562          else {
 23563            var binaryData = [];
 23564            binaryData.push(content);
 23565            href = window.URL.createObjectURL(new Blob(binaryData, {type: type}));
 23566          }
 23567          var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);
 23568          var download = [type, fileName, href].join(':');
 23569  
 23570          // Use filename from response header
 23571          var disposition = headers['content-disposition'] || headers['Content-Disposition'];
 23572          if(typeof disposition !== 'undefined') {
 23573            var responseFilename = /filename=([^;]*);?/.exec(disposition);
 23574            if(responseFilename !== null && responseFilename.length > 1) {
 23575              download = responseFilename[1];
 23576            }
 23577          }
 23578  
 23579          a.setAttribute('href', href);
 23580          a.setAttribute('download', download);
 23581          a.innerText = 'Download ' + fileName;
 23582  
 23583          pre = $('<div/>').append(a);
 23584        } else {
 23585          pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');
 23586        }
 23587      } else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
 23588        var json = null;
 23589        try {
 23590          json = JSON.stringify(JSON.parse(content), null, '  ');
 23591        } catch (_error) {
 23592          json = 'can\'t parse JSON.  Raw result:\n\n' + content;
 23593        }
 23594        code = $('<code />').text(json);
 23595        pre = $('<pre class="json" />').append(code);
 23596  
 23597        // XML
 23598      } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
 23599        code = $('<code />').text(this.formatXml(content));
 23600        pre = $('<pre class="xml" />').append(code);
 23601  
 23602        // HTML
 23603      } else if (contentType === 'text/html') {
 23604        code = $('<code />').html(_.escape(content));
 23605        pre = $('<pre class="xml" />').append(code);
 23606  
 23607        // Plain Text
 23608      } else if (/text\/plain/.test(contentType)) {
 23609        code = $('<code />').text(content);
 23610        pre = $('<pre class="plain" />').append(code);
 23611  
 23612        // Image
 23613      } else if (/^image\//.test(contentType)) {
 23614        var urlCreator = window.URL || window.webkitURL;
 23615        var imageUrl = urlCreator.createObjectURL(content);
 23616  
 23617        pre = $('<img>').attr( 'src', imageUrl);
 23618        // Audio
 23619      } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
 23620        pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));
 23621      } else if(headers.location || headers.Location) {
 23622        // Location header based redirect download
 23623        window.location = response.url;
 23624  
 23625        // Anything else (CORS)
 23626      } else {
 23627        code = $('<code />').text(content);
 23628        pre = $('<pre class="json" />').append(code);
 23629      }
 23630      var response_body = pre;
 23631      $('.request_url', $(this.el)).html('<pre></pre>');
 23632      $('.request_url pre', $(this.el)).text(url);
 23633      $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');
 23634      $('.response_body', $(this.el)).html(response_body);
 23635      $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
 23636      $('.response', $(this.el)).slideDown();
 23637      $('.response_hider', $(this.el)).show();
 23638      $('.response_throbber', $(this.el)).hide();
 23639  
 23640  
 23641      // adds curl output
 23642      var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType});
 23643      curlCommand = curlCommand.replace('!', '&#33;');
 23644      $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>');
 23645  
 23646      // only highlight the response if response is less than threshold, default state is highlight response
 23647      var opts = this.options.swaggerOptions;
 23648  
 23649      if (opts.showRequestHeaders) {
 23650        var form = $('.sandbox', $(this.el)),
 23651            map = this.getInputMap(form),
 23652            requestHeaders = this.model.getHeaderParams(map);
 23653        delete requestHeaders['Content-Type'];
 23654        $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
 23655      }
 23656  
 23657      var response_body_el = $('.response_body', $(this.el))[0];
 23658      // only highlight the response if response is less than threshold, default state is highlight response
 23659      if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) {
 23660        return response_body_el;
 23661      } else {
 23662        return hljs.highlightBlock(response_body_el);
 23663      }
 23664    },
 23665  
 23666    toggleOperationContent: function (event) {
 23667      var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));
 23668      if (elem.is(':visible')){
 23669        $.bbq.pushState('#/', 2);
 23670        event.preventDefault();
 23671        Docs.collapseOperation(elem);
 23672      } else {
 23673        Docs.expandOperation(elem);
 23674      }
 23675    },
 23676  
 23677    getTextAreaValue: function(textArea) {
 23678      var param, parsed, result, i;
 23679      if (textArea.value === null || jQuery.trim(textArea.value).length === 0) {
 23680        return null;
 23681      }
 23682      param = this.getParamByName(textArea.name);
 23683      if (param && param.type && param.type.toLowerCase() === 'array') {
 23684        parsed = textArea.value.split('\n');
 23685        result = [];
 23686        for (i = 0; i < parsed.length; i++) {
 23687          if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) {
 23688            result.push(parsed[i]);
 23689          }
 23690        }
 23691        return result.length > 0 ? result : null;
 23692      } else {
 23693        return textArea.value;
 23694      }
 23695    },
 23696  
 23697    showSnippet: function () {
 23698      var contentTypeEl = this.$('[name=responseContentType]');
 23699      var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml');
 23700      var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json');
 23701      var contentType;
 23702  
 23703      if (!contentTypeEl.length) { return; }
 23704      contentType = contentTypeEl.val();
 23705  
 23706      if (contentType.indexOf('xml') > -1) {
 23707        xmlSnippetEl.show();
 23708        jsonSnippetEl.hide();
 23709      } else {
 23710        jsonSnippetEl.show();
 23711        xmlSnippetEl.hide();
 23712      }
 23713    },
 23714  
 23715    getParamByName: function(name) {
 23716      var i;
 23717      if (this.model.parameters) {
 23718        for(i = 0; i < this.model.parameters.length; i++) {
 23719          if (this.model.parameters[i].name === name) {
 23720            return this.model.parameters[i];
 23721          }
 23722        }
 23723      }
 23724      return null;
 23725    }
 23726  
 23727  });
 23728  
 23729  'use strict';
 23730  
 23731  SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
 23732    initialize: function  () {},
 23733  
 23734    render: function(){
 23735      this.model.parameterContentTypeId = 'pct' + Math.random();
 23736      $(this.el).html(Handlebars.templates.parameter_content_type(this.model));
 23737      return this;
 23738    }
 23739  
 23740  });
 23741  'use strict';
 23742  
 23743  SwaggerUi.Views.ParameterView = Backbone.View.extend({
 23744    events: {
 23745      'change [name=parameterContentType]' : 'toggleParameterSnippet'
 23746    },
 23747  
 23748    initialize: function(){
 23749      Handlebars.registerHelper('isArray', function(param, opts) {
 23750        var paramType = param.type && param.type.toLowerCase();
 23751        if (paramType === 'array' || param.allowMultiple) {
 23752          return opts.fn(this);
 23753        } else {
 23754          return opts.inverse(this);
 23755        }
 23756      });
 23757    },
 23758  
 23759    render: function() {
 23760      var type = this.model.type || this.model.dataType;
 23761      var modelType = this.model.modelSignature.type;
 23762      var modelDefinitions = this.model.modelSignature.definitions;
 23763      var schema = this.model.schema || {};
 23764      var consumes = this.model.consumes || [];
 23765      var sampleJSON, signatureView;
 23766  
 23767      if (typeof type === 'undefined') {
 23768        if (schema.$ref) {
 23769          var ref = schema.$ref;
 23770          if (ref.indexOf('#/definitions/') === 0) {
 23771            type = ref.substring('#/definitions/'.length);
 23772          } else {
 23773            type = ref;
 23774          }
 23775        }
 23776      }
 23777  
 23778      this.model.type = type;
 23779      this.model.paramType = this.model.in || this.model.paramType;
 23780      this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';
 23781      this.model.isFile = type && type.toLowerCase() === 'file';
 23782  
 23783      // Allow for default === false
 23784      if(typeof this.model.default === 'undefined') {
 23785        this.model.default = this.model.defaultValue;
 23786      }
 23787  
 23788      this.model.hasDefault = (typeof this.model.default !== 'undefined');
 23789      this.model.valueId = 'm' + this.model.name + Math.random();
 23790  
 23791      if (this.model.allowableValues) {
 23792        this.model.isList = true;
 23793      }
 23794  
 23795      var isXML = this.contains(consumes, 'xml');
 23796      var isJSON = isXML ? this.contains(consumes, 'json') : true;
 23797      sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions);
 23798  
 23799      var template = this.template();
 23800      $(this.el).html(template(this.model));
 23801  
 23802      var signatureModel = {
 23803        sampleJSON: isJSON ? sampleJSON : false,
 23804        sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false,
 23805        isParam: true,
 23806        signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions),
 23807        defaultRendering: this.model.defaultRendering
 23808      };
 23809  
 23810      if (sampleJSON) {
 23811        signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});
 23812        $('.model-signature', $(this.el)).append(signatureView.render().el);
 23813      }
 23814      else {
 23815        $('.model-signature', $(this.el)).html(this.model.signature);
 23816      }
 23817  
 23818      var isParam = false;
 23819  
 23820      if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){
 23821        var $self = $(this.el);
 23822        this.model.jsonEditor =
 23823          /* global JSONEditor */
 23824          new JSONEditor($('.editor_holder', $self)[0],
 23825                         {schema: this.model.schema, startval : this.model.default,
 23826                          ajax:true,
 23827                          disable_properties:true,
 23828                          disable_edit_json:true,
 23829                          iconlib: 'swagger' });
 23830        // This is so that the signature can send back the sample to the json editor
 23831        // TODO: SignatureView should expose an event "onSampleClicked" instead
 23832        signatureModel.jsonEditor = this.model.jsonEditor;
 23833        $('.body-textarea', $self).hide();
 23834        $('.editor_holder', $self).show();
 23835        $('.parameter-content-type', $self)
 23836          .change(function(e){
 23837              if(e.target.value === 'application/xml'){
 23838                $('.body-textarea', $self).show();
 23839                $('.editor_holder', $self).hide();
 23840                this.model.jsonEditor.disable();
 23841              }
 23842              else {
 23843                $('.body-textarea', $self).hide();
 23844                $('.editor_holder', $self).show();
 23845                this.model.jsonEditor.enable();
 23846              }
 23847          });
 23848        }
 23849  
 23850  
 23851      if (this.model.isBody) {
 23852        isParam = true;
 23853      }
 23854  
 23855      var contentTypeModel = {
 23856        isParam: isParam
 23857      };
 23858  
 23859      contentTypeModel.consumes = this.model.consumes;
 23860  
 23861      if (isParam) {
 23862        var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});
 23863        $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);
 23864        this.toggleParameterSnippet();
 23865      }
 23866  
 23867      else {
 23868        var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});
 23869        $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
 23870        this.toggleResponseSnippet();
 23871      }
 23872  
 23873      return this;
 23874    },
 23875  
 23876    contains: function (consumes, type) {
 23877      return consumes.filter(function (val) {
 23878        if (val.indexOf(type) > -1) {
 23879          return true;
 23880        }
 23881      }).length;
 23882    },
 23883  
 23884    toggleParameterSnippet: function () {
 23885      var contentType = this.$('[name=parameterContentType]').val();
 23886  
 23887      this.toggleSnippet(contentType);
 23888    },
 23889  
 23890    toggleResponseSnippet: function () {
 23891      var contentEl = this.$('[name=responseContentType]');
 23892  
 23893      if (!contentEl.length) { return; }
 23894  
 23895      this.toggleSnippet(contentEl.val());
 23896    },
 23897  
 23898    toggleSnippet: function (type) {
 23899      type = type || '';
 23900      if (type.indexOf('xml') > -1) {
 23901        this.$('.snippet_xml').show();
 23902        this.$('.snippet_json').hide();
 23903      } else {
 23904        this.$('.snippet_json').show();
 23905        this.$('.snippet_xml').hide();
 23906      }
 23907    },
 23908  
 23909    // Return an appropriate template based on if the parameter is a list, readonly, required
 23910    template: function(){
 23911      if (this.model.isList) {
 23912        return Handlebars.templates.param_list;
 23913      } else {
 23914        if (this.options.readOnly) {
 23915          if (this.model.required) {
 23916            return Handlebars.templates.param_readonly_required;
 23917          } else {
 23918            return Handlebars.templates.param_readonly;
 23919          }
 23920        } else {
 23921          if (this.model.required) {
 23922            return Handlebars.templates.param_required;
 23923          } else {
 23924            return Handlebars.templates.param;
 23925          }
 23926        }
 23927      }
 23928    }
 23929  });
 23930  
 23931  'use strict';
 23932  
 23933  /* jshint -W122 */
 23934  SwaggerUi.partials.signature = (function () {
 23935    // copy-pasted from swagger-js
 23936    var resolveSchema = function (schema) {
 23937      if (_.isPlainObject(schema.schema)) {
 23938        schema = resolveSchema(schema.schema);
 23939      }
 23940  
 23941      return schema;
 23942    };
 23943  
 23944    // copy-pasted from swagger-js
 23945    var simpleRef = function (name) {
 23946      if (typeof name === 'undefined') {
 23947        return null;
 23948      }
 23949  
 23950      if (name.indexOf('#/definitions/') === 0) {
 23951        return name.substring('#/definitions/'.length);
 23952      } else {
 23953        return name;
 23954      }
 23955    };
 23956  
 23957    // copy-pasted from swagger-js
 23958    var getInlineModel = function(inlineStr) {
 23959      if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) {
 23960        var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
 23961        var model = this.inlineModels[id];
 23962        return model;
 23963      }
 23964      // I'm returning null here, should I rather throw an error?
 23965      return null;
 23966    };
 23967  
 23968    // copy-pasted from swagger-js
 23969    var formatXml = function(xml) {
 23970      var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
 23971      reg = /(>)(<)(\/*)/g;
 23972      wsexp = /[ ]*(.*)[ ]+\n/g;
 23973      contexp = /(<.+>)(.+\n)/g;
 23974      xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
 23975      pad = 0;
 23976      formatted = '';
 23977      lines = xml.split('\n');
 23978      indent = 0;
 23979      lastType = 'other';
 23980      transitions = {
 23981        'single->single': 0,
 23982        'single->closing': -1,
 23983        'single->opening': 0,
 23984        'single->other': 0,
 23985        'closing->single': 0,
 23986        'closing->closing': -1,
 23987        'closing->opening': 0,
 23988        'closing->other': 0,
 23989        'opening->single': 1,
 23990        'opening->closing': 0,
 23991        'opening->opening': 1,
 23992        'opening->other': 1,
 23993        'other->single': 0,
 23994        'other->closing': -1,
 23995        'other->opening': 0,
 23996        'other->other': 0
 23997      };
 23998      fn = function(ln) {
 23999        var fromTo, j, key, padding, type, types, value;
 24000        types = {
 24001          single: Boolean(ln.match(/<.+\/>/)),
 24002          closing: Boolean(ln.match(/<\/.+>/)),
 24003          opening: Boolean(ln.match(/<[^!?].*>/))
 24004        };
 24005        type = ((function() {
 24006          var results;
 24007          results = [];
 24008          for (key in types) {
 24009            value = types[key];
 24010            if (value) {
 24011              results.push(key);
 24012            }
 24013          }
 24014          return results;
 24015        })())[0];
 24016        type = type === void 0 ? 'other' : type;
 24017        fromTo = lastType + '->' + type;
 24018        lastType = type;
 24019        padding = '';
 24020        indent += transitions[fromTo];
 24021        padding = ((function() {
 24022          var m, ref1, results;
 24023          results = [];
 24024          for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
 24025            results.push('  ');
 24026          }
 24027          return results;
 24028        })()).join('');
 24029        if (fromTo === 'opening->closing') {
 24030          formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
 24031        } else {
 24032          formatted += padding + ln + '\n';
 24033        }
 24034      };
 24035      for (l = 0, len = lines.length; l < len; l++) {
 24036        ln = lines[l];
 24037        fn(ln);
 24038      }
 24039      return formatted;
 24040    };
 24041  
 24042    // copy-pasted from swagger-js
 24043    var getModelSignature = function (name, schema, models, modelPropertyMacro) {
 24044      var strongOpen = '<span class="strong">';
 24045      var strongClose = '</span>';
 24046  
 24047      var optionHtml = function (label, value) {
 24048        return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
 24049      };
 24050  
 24051  
 24052      // Allow for ignoring the 'name' argument.... shifting the rest
 24053      if(_.isObject(arguments[0])) {
 24054        name = void 0;
 24055        schema = arguments[0];
 24056        models = arguments[1];
 24057        modelPropertyMacro = arguments[2];
 24058      }
 24059  
 24060      models = models || {};
 24061  
 24062      // Resolve the schema (Handle nested schemas)
 24063      schema = resolveSchema(schema);
 24064  
 24065      // Return for empty object
 24066      if(_.isEmpty(schema)) {
 24067        return strongOpen + 'Empty' + strongClose;
 24068      }
 24069  
 24070      // Dereference $ref from 'models'
 24071      if(typeof schema.$ref === 'string') {
 24072        name = simpleRef(schema.$ref);
 24073        schema = models[name];
 24074        if(typeof schema === 'undefined')
 24075        {
 24076          return strongOpen + name + ' is not defined!' + strongClose;
 24077        }
 24078      }
 24079  
 24080      if(typeof name !== 'string') {
 24081        name = schema.title || 'Inline Model';
 24082      }
 24083  
 24084      // If we are a Model object... adjust accordingly
 24085      if(schema.definition) {
 24086        schema = schema.definition;
 24087      }
 24088  
 24089      if(typeof modelPropertyMacro !== 'function') {
 24090        modelPropertyMacro = function(prop){
 24091          return (prop || {}).default;
 24092        };
 24093      }
 24094  
 24095      var references = {};
 24096      var seenModels = [];
 24097      var inlineModels = 0;
 24098  
 24099      // Generate current HTML
 24100      var html = processModel(schema, name);
 24101  
 24102      // Generate references HTML
 24103      while (_.keys(references).length > 0) {
 24104        /* jshint ignore:start */
 24105        _.forEach(references, function (schema, name) {
 24106          var seenModel = _.indexOf(seenModels, name) > -1;
 24107  
 24108          delete references[name];
 24109  
 24110          if (!seenModel) {
 24111            seenModels.push(name);
 24112  
 24113            html += '<br />' + processModel(schema, name);
 24114          }
 24115        });
 24116        /* jshint ignore:end */
 24117      }
 24118  
 24119      return html;
 24120  
 24121  
 24122      function addReference(schema, name, skipRef) {
 24123        var modelName = name;
 24124        var model;
 24125  
 24126        if (schema.$ref) {
 24127          modelName = schema.title || simpleRef(schema.$ref);
 24128          model = models[simpleRef(schema.$ref)];
 24129        } else if (_.isUndefined(name)) {
 24130          modelName = schema.title || 'Inline Model ' + (++inlineModels);
 24131          model = {definition: schema};
 24132        }
 24133  
 24134        if (skipRef !== true) {
 24135          references[modelName] = _.isUndefined(model) ? {} : model.definition;
 24136        }
 24137  
 24138        return modelName;
 24139      }
 24140  
 24141      function primitiveToHTML(schema) {
 24142        var html = '<span class="propType">';
 24143        var type = schema.type || 'object';
 24144  
 24145        if (schema.$ref) {
 24146          html += addReference(schema, simpleRef(schema.$ref));
 24147        } else if (type === 'object') {
 24148          if (!_.isUndefined(schema.properties)) {
 24149            html += addReference(schema);
 24150          } else {
 24151            html += 'object';
 24152          }
 24153        } else if (type === 'array') {
 24154          html += 'Array[';
 24155  
 24156          if (_.isArray(schema.items)) {
 24157            html += _.map(schema.items, addReference).join(',');
 24158          } else if (_.isPlainObject(schema.items)) {
 24159            if (_.isUndefined(schema.items.$ref)) {
 24160              if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
 24161                html += schema.items.type;
 24162              } else {
 24163                html += addReference(schema.items);
 24164              }
 24165            } else {
 24166              html += addReference(schema.items, simpleRef(schema.items.$ref));
 24167            }
 24168          } else {
 24169            console.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
 24170            html += 'object';
 24171          }
 24172  
 24173          html += ']';
 24174        } else {
 24175          html += schema.type;
 24176        }
 24177  
 24178        html += '</span>';
 24179  
 24180        return html;
 24181      }
 24182  
 24183      function primitiveToOptionsHTML(schema, html) {
 24184        var options = '';
 24185        var type = schema.type || 'object';
 24186        var isArray = type === 'array';
 24187  
 24188        if (!_.isUndefined(schema.description)) {
 24189          html += ': ' + '<span class="propDesc">' + schema.description + '</span>';
 24190        }
 24191  
 24192        if (schema.enum) {
 24193          html += ' = <span class="propVals">[\'' + schema.enum.join('\', \'') + '\']</span>';
 24194        }
 24195  
 24196        if (isArray) {
 24197          if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
 24198            type = schema.items.type;
 24199          } else {
 24200            type = 'object';
 24201          }
 24202        }
 24203  
 24204        if (!_.isUndefined(schema.default)) {
 24205          options += optionHtml('Default', schema.default);
 24206        }
 24207  
 24208        switch (type) {
 24209        case 'string':
 24210          if (schema.minLength) {
 24211            options += optionHtml('Min. Length', schema.minLength);
 24212          }
 24213  
 24214          if (schema.maxLength) {
 24215            options += optionHtml('Max. Length', schema.maxLength);
 24216          }
 24217  
 24218          if (schema.pattern) {
 24219            options += optionHtml('Reg. Exp.', schema.pattern);
 24220          }
 24221          break;
 24222        case 'integer':
 24223        case 'number':
 24224          if (schema.minimum) {
 24225            options += optionHtml('Min. Value', schema.minimum);
 24226          }
 24227  
 24228          if (schema.exclusiveMinimum) {
 24229            options += optionHtml('Exclusive Min.', 'true');
 24230          }
 24231  
 24232          if (schema.maximum) {
 24233            options += optionHtml('Max. Value', schema.maximum);
 24234          }
 24235  
 24236          if (schema.exclusiveMaximum) {
 24237            options += optionHtml('Exclusive Max.', 'true');
 24238          }
 24239  
 24240          if (schema.multipleOf) {
 24241            options += optionHtml('Multiple Of', schema.multipleOf);
 24242          }
 24243  
 24244          break;
 24245        }
 24246  
 24247        if (isArray) {
 24248          if (schema.minItems) {
 24249            options += optionHtml('Min. Items', schema.minItems);
 24250          }
 24251  
 24252          if (schema.maxItems) {
 24253            options += optionHtml('Max. Items', schema.maxItems);
 24254          }
 24255  
 24256          if (schema.uniqueItems) {
 24257            options += optionHtml('Unique Items', 'true');
 24258          }
 24259  
 24260          if (schema.collectionFormat) {
 24261            options += optionHtml('Coll. Format', schema.collectionFormat);
 24262          }
 24263        }
 24264  
 24265        if (_.isUndefined(schema.items)) {
 24266          if (_.isArray(schema.enum)) {
 24267            var enumString;
 24268  
 24269            if (type === 'number' || type === 'integer') {
 24270              enumString = schema.enum.join(', ');
 24271            } else {
 24272              enumString = '"' + schema.enum.join('", "') + '"';
 24273            }
 24274  
 24275            options += optionHtml('Enum', enumString);
 24276          }
 24277        }
 24278  
 24279        if (options.length > 0) {
 24280          html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
 24281        }
 24282  
 24283        return html;
 24284      }
 24285  
 24286      function processModel(schema, name) {
 24287        var type = schema.type || 'object';
 24288        var isArray = schema.type === 'array';
 24289        var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
 24290        var contents;
 24291  
 24292        if (name) {
 24293          seenModels.push(name);
 24294        }
 24295  
 24296        if (isArray) {
 24297          if (_.isArray(schema.items)) {
 24298            html += '<div>' + _.map(schema.items, function (item) {
 24299              var type = item.type || 'object';
 24300  
 24301              if (_.isUndefined(item.$ref)) {
 24302                if (_.indexOf(['array', 'object'], type) > -1) {
 24303                  if (type === 'object' && _.isUndefined(item.properties)) {
 24304                    return 'object';
 24305                  } else {
 24306                    return addReference(item);
 24307                  }
 24308                } else {
 24309                  return primitiveToOptionsHTML(item, type);
 24310                }
 24311              } else {
 24312                return addReference(item, simpleRef(item.$ref));
 24313              }
 24314            }).join(',</div><div>');
 24315          } else if (_.isPlainObject(schema.items)) {
 24316            if (_.isUndefined(schema.items.$ref)) {
 24317              if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
 24318                if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
 24319                  html += '<div>object</div>';
 24320                } else {
 24321                  html += '<div>' + addReference(schema.items) + '</div>';
 24322                }
 24323              } else {
 24324                html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
 24325              }
 24326            } else {
 24327              html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>';
 24328            }
 24329          } else {
 24330            console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
 24331            html += '<div>object</div>';
 24332          }
 24333        } else {
 24334          if (schema.$ref) {
 24335            html += '<div>' + addReference(schema, name) + '</div>';
 24336          } else if (type === 'object') {
 24337            if (_.isPlainObject(schema.properties)) {
 24338              contents = _.map(schema.properties, function (property, name) {
 24339                var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
 24340                var cProperty = _.cloneDeep(property);
 24341  
 24342                var requiredClass = propertyIsRequired ? 'required' : '';
 24343                var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
 24344                var model;
 24345  
 24346                // Allow macro to set the default value
 24347                cProperty.default = modelPropertyMacro(cProperty);
 24348  
 24349                // Resolve the schema (Handle nested schemas)
 24350                cProperty = resolveSchema(cProperty);
 24351  
 24352                // We need to handle property references to primitives (Issue 339)
 24353                if (!_.isUndefined(cProperty.$ref)) {
 24354                  model = models[simpleRef(cProperty.$ref)];
 24355  
 24356                  if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
 24357                    // Use referenced schema
 24358                    cProperty = resolveSchema(model.definition);
 24359                  }
 24360                }
 24361  
 24362                html += primitiveToHTML(cProperty);
 24363  
 24364                if(!propertyIsRequired) {
 24365                  html += ', <span class="propOptKey">optional</span>';
 24366                }
 24367  
 24368                if(property.readOnly) {
 24369                    html += ', <span class="propReadOnly">read only</span>';
 24370                }
 24371  
 24372                html += ')';
 24373  
 24374                return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
 24375              }).join(',</div>');
 24376            }
 24377  
 24378            if (contents) {
 24379              html += contents + '</div>';
 24380            }
 24381          } else {
 24382            html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
 24383          }
 24384        }
 24385  
 24386        return html + strongOpen + (isArray ? ']' : '}') + strongClose;
 24387      }
 24388  
 24389    };
 24390  
 24391    // copy-pasted from swagger-js
 24392    var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
 24393      // Resolve the schema (Handle nested schemas)
 24394      schema = resolveSchema(schema);
 24395  
 24396      if(typeof modelPropertyMacro !== 'function') {
 24397        modelPropertyMacro = function(prop){
 24398          return (prop || {}).default;
 24399        };
 24400      }
 24401  
 24402      modelsToIgnore= modelsToIgnore || {};
 24403  
 24404      var type = schema.type || 'object';
 24405      var format = schema.format;
 24406      var model;
 24407      var output;
 24408  
 24409      if (!_.isUndefined(schema.example)) {
 24410        output = schema.example;
 24411      } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
 24412        output = schema.enum[0];
 24413      }
 24414  
 24415      if (_.isUndefined(output)) {
 24416        if (schema.$ref) {
 24417          model = models[simpleRef(schema.$ref)];
 24418  
 24419          if (!_.isUndefined(model)) {
 24420            if (_.isUndefined(modelsToIgnore[model.name])) {
 24421              modelsToIgnore[model.name] = model;
 24422              output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
 24423              delete modelsToIgnore[model.name];
 24424            } else {
 24425              if (model.type === 'array') {
 24426                output = [];
 24427              } else {
 24428                output = {};
 24429              }
 24430            }
 24431          }
 24432        } else if (!_.isUndefined(schema.default)) {
 24433          output = schema.default;
 24434        } else if (type === 'string') {
 24435          if (format === 'date-time') {
 24436            output = new Date().toISOString();
 24437          } else if (format === 'date') {
 24438            output = new Date().toISOString().split('T')[0];
 24439          } else {
 24440            output = 'string';
 24441          }
 24442        } else if (type === 'integer') {
 24443          output = 0;
 24444        } else if (type === 'number') {
 24445          output = 0.0;
 24446        } else if (type === 'boolean') {
 24447          output = true;
 24448        } else if (type === 'object') {
 24449          output = {};
 24450  
 24451          _.forEach(schema.properties, function (property, name) {
 24452            var cProperty = _.cloneDeep(property);
 24453  
 24454            // Allow macro to set the default value
 24455            cProperty.default = modelPropertyMacro(property);
 24456  
 24457            output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
 24458          });
 24459        } else if (type === 'array') {
 24460          output = [];
 24461  
 24462          if (_.isArray(schema.items)) {
 24463            _.forEach(schema.items, function (item) {
 24464              output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
 24465            });
 24466          } else if (_.isPlainObject(schema.items)) {
 24467            output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
 24468          } else if (_.isUndefined(schema.items)) {
 24469            output.push({});
 24470          } else {
 24471            console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
 24472          }
 24473        }
 24474      }
 24475  
 24476      return output;
 24477    };
 24478  
 24479    // copy-pasted from swagger-js
 24480    var createJSONSample = function (value, modelsToIgnore) {
 24481      modelsToIgnore = modelsToIgnore || {};
 24482  
 24483      modelsToIgnore[value.name] = value;
 24484  
 24485      // Response support
 24486      if (value.examples && _.isPlainObject(value.examples)) {
 24487        value = _.cloneDeep(value);
 24488        var keys = Object.keys(value.examples);
 24489  
 24490        _.forEach(keys, function(key) {
 24491          if(key.indexOf('application/json') === 0) {
 24492            var example = value.examples[key];
 24493            if (_.isString(example)) {
 24494              example = jsyaml.safeLoad(example);
 24495            }
 24496            value.definition.example = example;
 24497            return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
 24498          }
 24499        });
 24500      }
 24501  
 24502      if (value.examples) {
 24503        value = _.cloneDeep(value);
 24504        var example = value.examples;
 24505        if (_.isString(example)) {
 24506          example = jsyaml.safeLoad(example);
 24507        }
 24508        value.definition.example = example;
 24509        return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
 24510      }
 24511  
 24512      return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);
 24513    };
 24514  
 24515    // copy-pasted from swagger-js
 24516    var getParameterModelSignature = function (type, definitions) {
 24517        var isPrimitive, listType;
 24518  
 24519        if (type instanceof Array) {
 24520          listType = true;
 24521          type = type[0];
 24522        }
 24523  
 24524        // Convert undefined to string of 'undefined'
 24525        if (typeof type === 'undefined') {
 24526          type = 'undefined';
 24527          isPrimitive = true;
 24528  
 24529        } else if (definitions[type]){
 24530          // a model def exists?
 24531          type = definitions[type]; /* Model */
 24532          isPrimitive = false;
 24533  
 24534        } else if (getInlineModel(type)) {
 24535          type = getInlineModel(type); /* Model */
 24536          isPrimitive = false;
 24537  
 24538        } else {
 24539          // We default to primitive
 24540          isPrimitive = true;
 24541        }
 24542  
 24543        if (isPrimitive) {
 24544          if (listType) {
 24545            return 'Array[' + type + ']';
 24546          } else {
 24547            return type.toString();
 24548          }
 24549        } else {
 24550          if (listType) {
 24551            return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']';
 24552          } else {
 24553            return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro);
 24554          }
 24555        }
 24556    };
 24557  
 24558    // copy-pasted from swagger-js
 24559    var createParameterJSONSample = function (type, models) {
 24560      var listType, sampleJson, innerType;
 24561      models = models || {};
 24562  
 24563      listType = (type instanceof Array);
 24564      innerType = listType ? type[0] : type;
 24565  
 24566      if(models[innerType]) {
 24567        sampleJson = createJSONSample(models[innerType]);
 24568      } else if (getInlineModel(innerType)){
 24569        sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct
 24570      }
 24571  
 24572  
 24573      if (sampleJson) {
 24574        sampleJson = listType ? [sampleJson] : sampleJson;
 24575  
 24576        if (typeof sampleJson === 'string') {
 24577          return sampleJson;
 24578        } else if (_.isObject(sampleJson)) {
 24579          var t = sampleJson;
 24580  
 24581          if (sampleJson instanceof Array && sampleJson.length > 0) {
 24582            t = sampleJson[0];
 24583          }
 24584  
 24585          if (t.nodeName && typeof t === 'Node') {
 24586            var xmlString = new XMLSerializer().serializeToString(t);
 24587  
 24588            return formatXml(xmlString);
 24589          } else {
 24590            return JSON.stringify(sampleJson, null, 2);
 24591          }
 24592        } else {
 24593          return sampleJson;
 24594        }
 24595      }
 24596    };
 24597  
 24598    var wrapTag = function (name, value, attrs) {
 24599      var str, attributes;
 24600  
 24601      attrs = attrs || [];
 24602  
 24603      attributes = attrs.map(function (attr) {
 24604        return ' ' + attr.name + '="' + attr.value + '"';
 24605      }).join('');
 24606  
 24607      if (!name) {
 24608        return getErrorMessage('Node name is not provided');
 24609      }
 24610  
 24611      str = [
 24612        '<', name,
 24613        attributes,
 24614        '>',
 24615        value,
 24616        '</', name, '>'
 24617      ];
 24618  
 24619      return str.join('');
 24620    };
 24621  
 24622    var getName = function (name, xml) {
 24623      var result = name || '';
 24624  
 24625      xml = xml || {};
 24626  
 24627      if (xml.name) {
 24628        result = xml.name;
 24629      }
 24630  
 24631      if (xml.prefix) {
 24632        result = xml.prefix + ':' + result;
 24633      }
 24634  
 24635      return result;
 24636    };
 24637  
 24638    var getNamespace = function (xml) {
 24639      var namespace = '';
 24640      var name = 'xmlns';
 24641  
 24642      xml = xml || {};
 24643  
 24644      if (xml.namespace) {
 24645        namespace = xml.namespace;
 24646      } else {
 24647        return namespace;
 24648      }
 24649  
 24650      if (xml.prefix) {
 24651        name += ':' + xml.prefix;
 24652      }
 24653  
 24654      return {
 24655        name: name,
 24656        value: namespace
 24657      };
 24658    };
 24659  
 24660    var createArrayXML = function (descriptor) {
 24661      var name = descriptor.name;
 24662      var config = descriptor.config;
 24663      var definition = descriptor.definition;
 24664      var models = descriptor.models;
 24665      var value;
 24666      var items = definition.items;
 24667      var xml = definition.xml || {};
 24668      var namespace = getNamespace(xml);
 24669      var attributes = [];
 24670  
 24671      if (!items) { return getErrorMessage(); }
 24672  
 24673      value = createSchemaXML(name, items, models, config);
 24674  
 24675      if (namespace) {
 24676        attributes.push(namespace);
 24677      }
 24678  
 24679      if (xml.wrapped) {
 24680        value = wrapTag(name, value, attributes);
 24681      }
 24682  
 24683      return value;
 24684    };
 24685  
 24686    var getPrimitiveSignature = function (schema) {
 24687      var type, items;
 24688  
 24689      schema = schema || {};
 24690      items = schema.items || {};
 24691      type = schema.type || '';
 24692  
 24693      switch (type) {
 24694        case 'object': return 'Object is not a primitive';
 24695        case 'array' : return 'Array[' + (items.format || items.type) + ']';
 24696        default: return schema.format || type;
 24697      }
 24698    };
 24699  
 24700    var createPrimitiveXML = function (descriptor) {
 24701      var name = descriptor.name;
 24702      var definition = descriptor.definition;
 24703      var primitivesMap = {
 24704        'string': {
 24705          'date': new Date(1).toISOString().split('T')[0],
 24706          'date-time' : new Date(1).toISOString(),
 24707          'default': 'string'
 24708        },
 24709        'integer': {
 24710          'default': 1
 24711        },
 24712        'number': {
 24713          'default': 1.1
 24714        },
 24715        'boolean': {
 24716          'default': true
 24717        }
 24718      };
 24719      var type = definition.type;
 24720      var format = definition.format;
 24721      var xml = definition.xml || {};
 24722      var namespace = getNamespace(xml);
 24723      var attributes = [];
 24724      var value;
 24725  
 24726      if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); }
 24727  
 24728      if (_.isArray(definition.enum)){
 24729        value = definition.enum[0];
 24730      } else {
 24731        value = definition.example || primitivesMap[type][format] || primitivesMap[type].default;
 24732      }
 24733  
 24734      if (xml.attribute) {
 24735        return {name: name, value: value};
 24736      }
 24737  
 24738      if (namespace) {
 24739        attributes.push(namespace);
 24740      }
 24741  
 24742      return wrapTag(name, value, attributes);
 24743    };
 24744  
 24745    function createObjectXML (descriptor) {
 24746      var name = descriptor.name;
 24747      var definition = descriptor.definition;
 24748      var config = descriptor.config;
 24749      var models = descriptor.models;
 24750      var isParam = descriptor.config.isParam;
 24751      var serializedProperties;
 24752      var attrs = [];
 24753      var properties = definition.properties;
 24754      var additionalProperties = definition.additionalProperties;
 24755      var xml = definition.xml;
 24756      var namespace = getNamespace(xml);
 24757  
 24758      if (namespace) {
 24759        attrs.push(namespace);
 24760      }
 24761  
 24762      if (!properties && !additionalProperties) { return getErrorMessage(); }
 24763  
 24764      properties = properties || {};
 24765  
 24766      serializedProperties = _.map(properties, function (prop, key) {
 24767        var xml, result;
 24768  
 24769        if (isParam && prop.readOnly) {
 24770          return '';
 24771        }
 24772  
 24773        xml = prop.xml || {};
 24774        result = createSchemaXML(key, prop, models, config);
 24775  
 24776        if (xml.attribute) {
 24777          attrs.push(result);
 24778          return '';
 24779        }
 24780  
 24781        return result;
 24782      }).join('');
 24783  
 24784      if (additionalProperties) {
 24785        serializedProperties += '<!-- additional elements allowed -->';
 24786      }
 24787  
 24788      return wrapTag(name, serializedProperties, attrs);
 24789    }
 24790  
 24791    function getInfiniteLoopMessage (name, loopTo) {
 24792      return wrapTag(name, '<!-- Infinite loop $ref:' + loopTo + ' -->');
 24793    }
 24794  
 24795    function getErrorMessage (details) {
 24796      details = details ? ': ' + details : '';
 24797      return '<!-- invalid XML' + details + ' -->';
 24798    }
 24799  
 24800    function createSchemaXML (name, definition, models, config) {
 24801      var $ref = _.isObject(definition) ? definition.$ref : null;
 24802      var output, index;
 24803      config = config || {};
 24804      config.modelsToIgnore = config.modelsToIgnore || [];
 24805      var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)
 24806          : getDescriptor(name, definition, models, config);
 24807  
 24808      if (!descriptor) {
 24809        return getErrorMessage();
 24810      }
 24811  
 24812      switch (descriptor.type) {
 24813        case 'array':
 24814          output = createArrayXML(descriptor); break;
 24815        case 'object':
 24816          output = createObjectXML(descriptor); break;
 24817        case 'loop':
 24818          output = getInfiniteLoopMessage(descriptor.name, descriptor.config.loopTo); break;
 24819        default:
 24820          output = createPrimitiveXML(descriptor);
 24821      }
 24822  
 24823      if ($ref && descriptor.type !== 'loop') {
 24824        index = config.modelsToIgnore.indexOf($ref);
 24825        if (index > -1) {
 24826          config.modelsToIgnore.splice(index, 1);
 24827        }
 24828      }
 24829  
 24830      return output;
 24831    }
 24832  
 24833    function Descriptor (name, type, definition, models, config) {
 24834      if (arguments.length < 4) {
 24835        throw new Error();
 24836      }
 24837  
 24838      this.config = config || {};
 24839      this.config.modelsToIgnore = this.config.modelsToIgnore || [];
 24840      this.name = getName(name, definition.xml);
 24841      this.definition = definition;
 24842      this.models = models;
 24843      this.type = type;
 24844    }
 24845  
 24846    function getDescriptorByRef($ref, name, models, config) {
 24847      var modelType = simpleRef($ref);
 24848      var model = models[modelType] || {};
 24849      var type = model.definition && model.definition.type ? model.definition.type : 'object';
 24850      name = name || model.name;
 24851  
 24852      if (config.modelsToIgnore.indexOf($ref) > -1) {
 24853        type = 'loop';
 24854        config.loopTo = modelType;
 24855      } else {
 24856        config.modelsToIgnore.push($ref);
 24857      }
 24858  
 24859      if (!model.definition) {
 24860        return null;
 24861      }
 24862  
 24863      return new Descriptor(name, type, model.definition, models, config);
 24864    }
 24865  
 24866    function getDescriptor (name, definition, models, config){
 24867      var type = definition.type || 'object';
 24868  
 24869      if (!definition) {
 24870        return null;
 24871      }
 24872  
 24873      return new Descriptor(name, type, definition, models, config);
 24874    }
 24875  
 24876    function createXMLSample (name, definition, models, isParam) {
 24877      var prolog = '<?xml version="1.0"?>';
 24878  
 24879      return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } ));
 24880    }
 24881  
 24882    return {
 24883        getModelSignature: getModelSignature,
 24884        createJSONSample: createJSONSample,
 24885        getParameterModelSignature: getParameterModelSignature,
 24886        createParameterJSONSample: createParameterJSONSample,
 24887        createSchemaXML: createSchemaXML,
 24888        createXMLSample: createXMLSample,
 24889        getPrimitiveSignature: getPrimitiveSignature
 24890    };
 24891  
 24892  })();
 24893  
 24894  'use strict';
 24895  
 24896  SwaggerUi.Views.PopupView = Backbone.View.extend({
 24897      events: {
 24898          'click .api-popup-cancel': 'cancelClick'
 24899      },
 24900  
 24901      template: Handlebars.templates.popup,
 24902      className: 'api-popup-dialog',
 24903  
 24904      selectors: {
 24905          content: '.api-popup-content',
 24906          main   : '#swagger-ui-container'
 24907      },
 24908  
 24909      initialize: function(){
 24910          this.$el.html(this.template(this.model));
 24911      },
 24912  
 24913      render: function () {
 24914          this.$(this.selectors.content).append(this.model.content);
 24915          $(this.selectors.main).first().append(this.el);
 24916          this.showPopup();
 24917  
 24918          return this;
 24919      },
 24920  
 24921      showPopup: function () {
 24922          this.$el.show();
 24923      },
 24924  
 24925      cancelClick: function () {
 24926          this.remove();
 24927      }
 24928  
 24929  });
 24930  
 24931  'use strict';
 24932  
 24933  SwaggerUi.Views.ResourceView = Backbone.View.extend({
 24934    initialize: function(opts) {
 24935      opts = opts || {};
 24936      this.router = opts.router;
 24937      this.auths = opts.auths;
 24938      if ('' === this.model.description) {
 24939        this.model.description = null;
 24940      }
 24941      if (this.model.description) {
 24942        this.model.summary = this.model.description;
 24943      }
 24944      this.number = 0;
 24945    },
 24946  
 24947    render: function(){
 24948      var methods = {};
 24949  
 24950  
 24951      $(this.el).html(Handlebars.templates.resource(this.model));
 24952  
 24953      // Render each operation
 24954      for (var i = 0; i < this.model.operationsArray.length; i++) {
 24955        var operation = this.model.operationsArray[i];
 24956        var counter = 0;
 24957        var id = operation.nickname;
 24958  
 24959        while (typeof methods[id] !== 'undefined') {
 24960          id = id + '_' + counter;
 24961          counter += 1;
 24962        }
 24963  
 24964        methods[id] = operation;
 24965  
 24966        operation.nickname = id;
 24967        operation.parentId = this.model.id;
 24968        operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation
 24969        this.addOperation(operation);
 24970      }
 24971  
 24972      $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));
 24973      $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));
 24974      $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));
 24975  
 24976      return this;
 24977    },
 24978  
 24979    addOperation: function(operation) {
 24980  
 24981      operation.number = this.number;
 24982  
 24983      // Render an operation and add it to operations li
 24984      var operationView = new SwaggerUi.Views.OperationView({
 24985        model: operation,
 24986        router: this.router,
 24987        tagName: 'li',
 24988        className: 'endpoint',
 24989        swaggerOptions: this.options.swaggerOptions,
 24990        auths: this.auths
 24991      });
 24992  
 24993      $('.endpoints', $(this.el)).append(operationView.render().el);
 24994  
 24995      this.number++;
 24996  
 24997    },
 24998    // Generic Event handler (`Docs` is global)
 24999  
 25000  
 25001    callDocs: function(fnName, e) {
 25002      e.preventDefault();
 25003      Docs[fnName](e.currentTarget.getAttribute('data-id'));
 25004    }
 25005  });
 25006  
 25007  'use strict';
 25008  
 25009  SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({
 25010    initialize: function(){},
 25011  
 25012    render: function(){
 25013      this.model.responseContentTypeId = 'rct' + Math.random();
 25014      $(this.el).html(Handlebars.templates.response_content_type(this.model));
 25015      return this;
 25016    }
 25017  });
 25018  'use strict';
 25019  
 25020  SwaggerUi.Views.SignatureView = Backbone.View.extend({
 25021    events: {
 25022      'click a.description-link'       : 'switchToDescription',
 25023      'click a.snippet-link'           : 'switchToSnippet',
 25024      'mousedown .snippet_json'          : 'jsonSnippetMouseDown',
 25025      'mousedown .snippet_xml'          : 'xmlSnippetMouseDown'
 25026    },
 25027  
 25028    initialize: function () {
 25029    },
 25030  
 25031    render: function(){
 25032  
 25033      $(this.el).html(Handlebars.templates.signature(this.model));
 25034  
 25035      if (this.model.defaultRendering === 'model') {
 25036        this.switchToDescription();
 25037      } else {
 25038        this.switchToSnippet();
 25039      }
 25040  
 25041      return this;
 25042    },
 25043  
 25044    // handler for show signature
 25045    switchToDescription: function(e){
 25046      if (e) { e.preventDefault(); }
 25047  
 25048      $('.snippet', $(this.el)).hide();
 25049      $('.description', $(this.el)).show();
 25050      $('.description-link', $(this.el)).addClass('selected');
 25051      $('.snippet-link', $(this.el)).removeClass('selected');
 25052    },
 25053  
 25054    // handler for show sample
 25055    switchToSnippet: function(e){
 25056      if (e) { e.preventDefault(); }
 25057  
 25058      $('.snippet', $(this.el)).show();
 25059      $('.description', $(this.el)).hide();
 25060      $('.snippet-link', $(this.el)).addClass('selected');
 25061      $('.description-link', $(this.el)).removeClass('selected');
 25062    },
 25063  
 25064    // handler for snippet to text area
 25065    snippetToTextArea: function(val) {
 25066      var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));
 25067  
 25068      // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value"
 25069      if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) {
 25070        textArea.val(val);
 25071        // TODO move this code outside of the view and expose an event instead
 25072        if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){
 25073          this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON));
 25074        }
 25075      }
 25076    },
 25077  
 25078    jsonSnippetMouseDown: function (e) {
 25079      if (this.model.isParam) {
 25080        if (e) { e.preventDefault(); }
 25081  
 25082        this.snippetToTextArea(this.model.sampleJSON);
 25083      }
 25084    },
 25085  
 25086    xmlSnippetMouseDown: function (e) {
 25087      if (this.model.isParam) {
 25088        if (e) { e.preventDefault(); }
 25089  
 25090        this.snippetToTextArea(this.model.sampleXML);
 25091      }
 25092    }
 25093  });
 25094  'use strict';
 25095  
 25096  SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
 25097    initialize: function (opts) {
 25098      this.options = opts || {};
 25099      this.router = this.options.router;
 25100    },
 25101  
 25102    render: function(){
 25103      var responseModel, responseModelView;
 25104      var value = this.router.api.models[this.model.responseModel];
 25105      $(this.el).html(Handlebars.templates.status_code(this.model));
 25106  
 25107      if (this.router.api.models.hasOwnProperty(this.model.responseModel)) {
 25108        responseModel = {
 25109          sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2),
 25110          sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false,
 25111          isParam: false,
 25112          signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models),
 25113          defaultRendering: this.model.defaultRendering
 25114        };
 25115      } else {
 25116        responseModel = {
 25117          signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)
 25118        };
 25119      }
 25120  
 25121      responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});
 25122      $('.model-signature', this.$el).append(responseModelView.render().el);
 25123      return this;
 25124    }
 25125  });}).call(this);
 25126  //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlbXBsYXRlcy5qcyIsImRvYy5qcyIsImVzNS1zaGltLmpzIiwiaGVscGVycy9oYW5kbGViYXJzLmpzIiwic2FuaXRpemUtaHRtbC5taW4uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiaW5kZXguanMiLCJsaWIvYXV0aC5qcyIsImxpYi9jbGllbnQuanMiLCJsaWIvaGVscGVycy5qcyIsImxpYi9odHRwLmpzIiwibGliL3Jlc29sdmVyLmpzIiwibGliL3NjaGVtYS1tYXJrdXAuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJTd2FnZ2VyVWkuanMiLCJ1dGlscy91dGlscy5qcyIsInZpZXcvQXBpS2V5QXV0aE1vZGVsLmpzIiwidmlldy9BcGlLZXlBdXRoVmlldy5qcyIsInZpZXcvQXV0aEJ1dHRvblZpZXcuanMiLCJ2aWV3L0F1dGhzQ29sbGVjdGlvbi5qcyIsInZpZXcvQXV0aHNDb2xsZWN0aW9uVmlldy5qcyIsInZpZXcvQXV0aFZpZXcuanMiLCJ2aWV3L0Jhc2ljQXV0aE1vZGVsLmpzIiwidmlldy9CYXNpY0F1dGhWaWV3LmpzIiwidmlldy9Db250ZW50VHlwZVZpZXcuanMiLCJ2aWV3L0hlYWRlclZpZXcuanMiLCJ2aWV3L01haW5WaWV3LmpzIiwidmlldy9PYXV0aDJNb2RlbC5qcyIsInZpZXcvT2F1dGgyVmlldy5qcyIsInZpZXcvT3BlcmF0aW9uVmlldy5qcyIsInZpZXcvUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LmpzIiwidmlldy9QYXJhbWV0ZXJWaWV3LmpzIiwidmlldy9wYXJ0aWFscy9zaWduYXR1cmUuanMiLCJ2aWV3L1BvcHVwVmlldy5qcyIsInZpZXcvUmVzb3VyY2VWaWV3LmpzIiwidmlldy9SZXNwb25zZUNvbnRlbnRUeXBlVmlldy5qcyIsInZpZXcvU2lnbmF0dXJlVmlldy5qcyIsInZpZXcvU3RhdHVzQ29kZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDL3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2poRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNOQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN3NCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzk0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2dCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzb0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzcvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2x5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0hBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25nRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDckxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNoSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDdjJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsOEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6InN3YWdnZXItdWkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovIFxuIHsoZnVuY3Rpb24oKSB7XG4gIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUsIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307XG50ZW1wbGF0ZXNbJ2FwaWtleV9hdXRoJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPGlucHV0IHBsYWNlaG9sZGVyPVxcXCJhcGlfa2V5XFxcIiBjbGFzcz1cXFwiYXV0aF9pbnB1dCBpbnB1dF9hcGlLZXlfZW50cnlcXFwiIG5hbWU9XFxcImFwaUtleVxcXCIgdHlwZT1cXFwidGV4dFxcXCIvPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImtleV9pbnB1dF9jb250YWluZXJcXFwiPlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5BcGkga2V5IGF1dGhvcml6YXRpb248L2gzPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX19kZXNjcmlwdGlvblxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbiAgICA8ZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj5uYW1lOjwvc3Bhbj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImtleV9hdXRoX19maWVsZFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX19sYWJlbFxcXCI+aW46PC9zcGFuPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiaW5cIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj52YWx1ZTo8L3NwYW4+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYXV0aF9idXR0b24nXSA9IHRlbXBsYXRlKHtcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjxhIGNsYXNzPSdhdXRob3JpemVfX2J0bicgaHJlZj1cXFwiI1xcXCI+QXV0aG9yaXplPC9hPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2F1dGhfYnV0dG9uX29wZXJhdGlvbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25fbG9naW5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIGF1dGhvcml6ZV9fYnRuX29wZXJhdGlvbl9sb2dvdXRcXG5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHVsIGNsYXNzPVxcXCJhdXRob3JpemUtc2NvcGVzXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L3VsPlxcblwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XFxcImF1dGhvcml6ZV9fc2NvcGVcXFwiIHRpdGxlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9saT5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJhdXRob3JpemVfX2J0biBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydhdXRoX3ZpZXcnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfc3VibWl0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkF1dGhvcml6ZTwvYnV0dG9uPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfbG9nb3V0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkxvZ291dDwvYnV0dG9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImF1dGhfY29udGFpbmVyXFxcIj5cXG5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9pbm5lclxcXCI+PC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfc3VibWl0XFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQXV0aG9yaXplZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvZGl2PlxcblxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2Jhc2ljX2F1dGgnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAtIGF1dGhvcml6ZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51c2VybmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcblwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgICAgICA8aW5wdXQgcmVxdWlyZWQgcGxhY2Vob2xkZXI9XFxcInVzZXJuYW1lXFxcIiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdXNlcm5hbWUgYXV0aF9pbnB1dFxcXCIgbmFtZT1cXFwidXNlcm5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJhc2ljX2F1dGhfX2xhYmVsXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5wYXNzd29yZDo8L3NwYW4+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCByZXF1aXJlZCBwbGFjZWhvbGRlcj1cXFwicGFzc3dvcmRcXFwiIGNsYXNzPVxcXCJiYXNpY19hdXRoX19wYXNzd29yZCBhdXRoX2lucHV0XFxcIiBuYW1lPVxcXCJwYXNzd29yZFxcXCIgdHlwZT1cXFwicGFzc3dvcmRcXFwiLz48L2xhYmVsPlxcbiAgICAgICAgICAgIDwvZGl2PlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2Jhc2ljX2F1dGhfY29udGFpbmVyJz5cXG4gICAgPGgzIGNsYXNzPVxcXCJhdXRoX190aXRsZVxcXCI+QmFzaWMgYXV0aGVudGljYXRpb25cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2gzPlxcbiAgICA8Zm9ybSBjbGFzcz1cXFwiYmFzaWNfaW5wdXRfY29udGFpbmVyXFxcIj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfX2Rlc2NyaXB0aW9uXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fbGFiZWxcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPnVzZXJuYW1lOjwvc3Bhbj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L2Zvcm0+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snY29udGVudF90eXBlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0PG9wdGlvbiB2YWx1ZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L29wdGlvbj5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcImFwcGxpY2F0aW9uL2pzb25cXFwiPmFwcGxpY2F0aW9uL2pzb248L29wdGlvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50VHlwZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJjb250ZW50VHlwZVxcXCIgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnRlbnRUeXBlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zZWxlY3Q+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snbWFpbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8ZGl2IGNsYXNzPVxcXCJpbmZvX3RpdGxlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50aXRsZSA6IHN0YWNrMSkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImluZm9fZGVzY3JpcHRpb24gbWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5lbWFpbCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmxpY2Vuc2UgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxwPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuZGVzY3JpcHRpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcbiAgPGEgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiB0YXJnZXQ9XFxcIl9ibGFua1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiaW5mb190b3NcXFwiPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5UZXJtcyBvZiBzZXJ2aWNlPC9hPjwvZGl2PlwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdj48ZGl2IGNsYXNzPSdpbmZvX25hbWUnIHN0eWxlPVxcXCJkaXNwbGF5OiBpbmxpbmVcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkNyZWF0ZWQgYnkgPC9kaXY+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEubmFtZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mb191cmwnIGRhdGEtc3ctdHJhbnNsYXRlPlNlZSBtb3JlIGF0IDxhIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPjwvZGl2PlwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2VtYWlsJz48YSB0YXJnZXQ9XFxcIl9wYXJlbnRcXFwiIGhyZWY9XFxcIm1haWx0bzpcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEuZW1haWwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIj9zdWJqZWN0PVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGl0bGUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+Q29udGFjdCB0aGUgZGV2ZWxvcGVyPC9hPjwvZGl2PlwiO1xufSxcIjEyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2xpY2Vuc2UnPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEubGljZW5zZSA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5saWNlbnNlIDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+PC9kaXY+XCI7XG59LFwiMTRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAsIDxzcGFuIHN0eWxlPVxcXCJmb250LXZhcmlhbnQ6IHNtYWxsLWNhcHNcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPmFwaSB2ZXJzaW9uPC9zcGFuPjogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudmVyc2lvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIFwiO1xufSxcIjE2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgPHNwYW4gc3R5bGU9XFxcImZsb2F0OnJpZ2h0XFxcIj48YSB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIvZGVidWc/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48aW1nIGlkPVxcXCJ2YWxpZGF0b3JcXFwiIHNyYz1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48L2E+XFxuICAgIDwvc3Bhbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvJyBpZD0nYXBpX2luZm8nPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuPGRpdiBjbGFzcz0nY29udGFpbmVyJyBpZD0ncmVzb3VyY2VzX2NvbnRhaW5lcic+XFxuICA8ZGl2IGNsYXNzPSdhdXRob3JpemUtd3JhcHBlcic+PC9kaXY+XFxuXFxuICA8dWwgaWQ9J3Jlc291cmNlcyc+PC91bD5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcImZvb3RlclxcXCI+XFxuICAgIDxoNCBzdHlsZT1cXFwiY29sb3I6ICM5OTlcXFwiPlsgPHNwYW4gc3R5bGU9XFxcImZvbnQtdmFyaWFudDogc21hbGwtY2Fwc1xcXCI+YmFzZSB1cmw8L3NwYW4+OiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5iYXNlUGF0aCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnZlcnNpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJdXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWxpZGF0b3JVcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC9oND5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snb2F1dGgyJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtc2NvcGVcXFwiIHR5cGU9XFxcImNoZWNrYm94XFxcIiBkYXRhLXNjb3BlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBvYXV0aHR5cGU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLk9BdXRoU2NoZW1lS2V5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiLz5cXG4gICAgICAgICAgICAgICAgPGxhYmVsPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjxici8+XFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJhcGktc2NvcGUtZGVzY1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgPC9saT5cXG5cIjtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICAgICAgICAgIChcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIilcXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2PlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5TZWxlY3QgT0F1dGgyLjAgU2NvcGVzPC9oMz5cXG4gICAgPHA+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgPHA+U2NvcGVzIGFyZSB1c2VkIHRvIGdyYW50IGFuIGFwcGxpY2F0aW9uIGRpZmZlcmVudCBsZXZlbHMgb2YgYWNjZXNzIHRvIGRhdGEgb24gYmVoYWxmIG9mIHRoZSBlbmQgdXNlci4gRWFjaCBBUEkgbWF5IGRlY2xhcmUgb25lIG9yIG1vcmUgc2NvcGVzLlxcbiAgICAgICAgPGEgaHJlZj1cXFwiI1xcXCI+TGVhcm4gaG93IHRvIHVzZTwvYT5cXG4gICAgPC9wPlxcbiAgICA8cD48c3Ryb25nPiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hcHBOYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgPC9zdHJvbmc+IEFQSSByZXF1aXJlcyB0aGUgZm9sbG93aW5nIHNjb3Blcy4gU2VsZWN0IHdoaWNoIG9uZXMgeW91IHdhbnQgdG8gZ3JhbnQgdG8gU3dhZ2dlciBVSS48L3A+XFxuICAgIDxwPkF1dGhvcml6YXRpb24gVVJMOiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYXV0aG9yaXphdGlvblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XFxuICAgIDxwPmZsb3c6IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmZsb3cgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgPHVsIGNsYXNzPVxcXCJhcGktcG9wdXAtc2NvcGVzXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC91bD5cXG48L2Rpdj5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydvcGVyYXRpb24nXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcImRlcHJlY2F0ZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8aDQ+PHNwYW4gZGF0YS1zdy10cmFuc2xhdGU+V2FybmluZzogRGVwcmVjYXRlZDwvc3Bhbj48L2g0PlxcblwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICA8aDQ+PHNwYW4gZGF0YS1zdy10cmFuc2xhdGU+SW1wbGVtZW50YXRpb24gTm90ZXM8L3NwYW4+PC9oND5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxkaXYgY2xhc3M9J2F1dGhvcml6ZS13cmFwcGVyIGF1dGhvcml6ZS13cmFwcGVyX29wZXJhdGlvbic+PC9kaXY+XFxuXCI7XG59LFwiOVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInJlc3BvbnNlLWNsYXNzXFxcIj5cXG4gICAgICAgICAgICA8aDQ+PHNwYW4gZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgQ2xhc3M8L3NwYW4+ICg8c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5TdGF0dXM8L3NwYW4+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1Y2Nlc3NDb2RlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIpPC9oND5cXG4gICAgICAgICAgICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VjY2Vzc0Rlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgICAgICAgICAgPHA+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCIgLz48L3A+XFxuICAgICAgICAgICAgPGJyLz5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJyZXNwb25zZS1jb250ZW50LXR5cGVcXFwiIC8+XFxuICAgICAgICAgICAgPC9kaXY+XFxuXCI7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VjY2Vzc0Rlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlwiO1xufSxcIjEyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+SGVhZGVyczwvaDQ+XFxuICAgICAgICAgIDx0YWJsZSBjbGFzcz1cXFwiaGVhZGVyc1xcXCI+XFxuICAgICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAxMDBweDsgbWF4LXdpZHRoOiAxMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+SGVhZGVyPC90aD5cXG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMzEwcHg7IG1heC13aWR0aDogMzEwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkRlc2NyaXB0aW9uPC90aD5cXG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMjAwcHg7IG1heC13aWR0aDogMjAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlR5cGU8L3RoPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAzMjBweDsgbWF4LXdpZHRoOiAzMjBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+T3RoZXI8L3RoPlxcbiAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICAgIDx0Ym9keT5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICA8L3RhYmxlPlxcblwiO1xufSxcIjEzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMua2V5IHx8IChkYXRhICYmIGRhdGEua2V5KSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJrZXlcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC90ZD5cXG4gICAgICAgICAgICAgICAgPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgICAgICAgICAgPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm90aGVyIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgPC90cj5cXG5cIjtcbn0sXCIxNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5QYXJhbWV0ZXJzPC9oND5cXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPSdmdWxsd2lkdGggcGFyYW1ldGVycyc+XFxuICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMTAwcHg7IG1heC13aWR0aDogMTAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlcjwvdGg+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMzEwcHg7IG1heC13aWR0aDogMzEwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlZhbHVlPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAyMDBweDsgbWF4LXdpZHRoOiAyMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+RGVzY3JpcHRpb248L3RoPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDEwMHB4OyBtYXgtd2lkdGg6IDEwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5QYXJhbWV0ZXIgVHlwZTwvdGg+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMjIwcHg7IG1heC13aWR0aDogMjMwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkRhdGEgVHlwZTwvdGg+XFxuICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgPC90aGVhZD5cXG4gICAgICAgICAgPHRib2R5IGNsYXNzPVxcXCJvcGVyYXRpb24tcGFyYW1zXFxcIj5cXG5cXG4gICAgICAgICAgPC90Ym9keT5cXG4gICAgICAgICAgPC90YWJsZT5cXG5cIjtcbn0sXCIxN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgIDxkaXYgc3R5bGU9J21hcmdpbjowO3BhZGRpbmc6MDtkaXNwbGF5OmlubGluZSc+PC9kaXY+XFxuICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBNZXNzYWdlczwvaDQ+XFxuICAgICAgICAgIDx0YWJsZSBjbGFzcz0nZnVsbHdpZHRoIHJlc3BvbnNlLW1lc3NhZ2VzJz5cXG4gICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgPHRoIGRhdGEtc3ctdHJhbnNsYXRlPkhUVFAgU3RhdHVzIENvZGU8L3RoPlxcbiAgICAgICAgICAgICAgPHRoIGRhdGEtc3ctdHJhbnNsYXRlPlJlYXNvbjwvdGg+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgTW9kZWw8L3RoPlxcbiAgICAgICAgICAgICAgPHRoIGRhdGEtc3ctdHJhbnNsYXRlPkhlYWRlcnM8L3RoPlxcbiAgICAgICAgICAgIDwvdHI+XFxuICAgICAgICAgICAgPC90aGVhZD5cXG4gICAgICAgICAgICA8dGJvZHkgY2xhc3M9XFxcIm9wZXJhdGlvbi1zdGF0dXNcXFwiPlxcbiAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgIDwvdGFibGU+XFxuXCI7XG59LFwiMTlcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIlwiO1xufSxcIjIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGRpdiBjbGFzcz0nc2FuZGJveF9oZWFkZXInPlxcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0nc3VibWl0JyB0eXBlPSdzdWJtaXQnIHZhbHVlPSdUcnkgaXQgb3V0IScgZGF0YS1zdy10cmFuc2xhdGUvPlxcbiAgICAgICAgICAgIDxhIGhyZWY9JyMnIGNsYXNzPSdyZXNwb25zZV9oaWRlcicgc3R5bGU9J2Rpc3BsYXk6bm9uZScgZGF0YS1zdy10cmFuc2xhdGU+SGlkZSBSZXNwb25zZTwvYT5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz0ncmVzcG9uc2VfdGhyb2JiZXInIHN0eWxlPSdkaXNwbGF5Om5vbmUnPjwvc3Bhbj5cXG4gICAgICAgICAgPC9kaXY+XFxuXCI7XG59LFwiMjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVxdWVzdCBIZWFkZXJzPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgcmVxdWVzdF9oZWFkZXJzJz48L2Rpdj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZywgYWxpYXMzPWNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uO1xuXG4gIHJldHVybiBcIiAgPHVsIGNsYXNzPSdvcGVyYXRpb25zJyA+XFxuICAgIDxsaSBjbGFzcz0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubWV0aG9kIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgb3BlcmF0aW9uJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIl9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cXG4gICAgICA8ZGl2IGNsYXNzPSdoZWFkaW5nJz5cXG4gICAgICAgIDxoMz5cXG4gICAgICAgICAgPHNwYW4gY2xhc3M9J2h0dHBfbWV0aG9kJz5cXG4gICAgICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlT3BlcmF0aW9uXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5tZXRob2QgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT5cXG4gICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICA8c3BhbiBjbGFzcz0ncGF0aCc+XFxuICAgICAgICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVuY29kZWRQYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIi9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZU9wZXJhdGlvbiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlcHJlY2F0ZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGF0aCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcbiAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICA8L2gzPlxcbiAgICAgICAgPHVsIGNsYXNzPSdvcHRpb25zJz5cXG4gICAgICAgICAgPGxpPlxcbiAgICAgICAgICA8YSBocmVmPScjIS9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbmNvZGVkUGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCIvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVPcGVyYXRpb25cXFwiPjxzcGFuIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPjwvYT5cXG4gICAgICAgICAgPC9saT5cXG4gICAgICAgIDwvdWw+XFxuICAgICAgPC9kaXY+XFxuICAgICAgPGRpdiBjbGFzcz0nY29udGVudCcgaWQ9J1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVuY29kZWRQYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIl9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIl9jb250ZW50JyBzdHlsZT0nZGlzcGxheTpub25lJz5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlcHJlY2F0ZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2VjdXJpdHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgICAgICA8Zm9ybSBhY2NlcHQtY2hhcnNldD0nVVRGLTgnIGNsYXNzPSdzYW5kYm94Jz5cXG4gICAgICAgICAgPGRpdiBzdHlsZT0nbWFyZ2luOjA7cGFkZGluZzowO2Rpc3BsYXk6aW5saW5lJz48L2Rpdj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtZXRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlc3BvbnNlTWVzc2FnZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzUmVhZE9ubHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE5LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgyMSwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L2Zvcm0+XFxuICAgICAgICA8ZGl2IGNsYXNzPSdyZXNwb25zZScgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+XFxuICAgICAgICAgIDxoNCBjbGFzcz0nY3VybCc+Q3VybDwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIGN1cmwnPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVxdWVzdCBVUkw8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXF1ZXN0X3VybCc+PC9kaXY+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zaG93UmVxdWVzdEhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIEJvZHk8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXNwb25zZV9ib2R5Jz48L2Rpdj5cXG4gICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIENvZGU8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXNwb25zZV9jb2RlJz48L2Rpdj5cXG4gICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIEhlYWRlcnM8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXNwb25zZV9oZWFkZXJzJz48L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgIDwvZGl2PlxcbiAgICA8L2xpPlxcbiAgPC91bD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0ZpbGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdDxpbnB1dCB0eXBlPVxcXCJmaWxlXFxcIiBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInLz5cXG5cdFx0XHQ8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHRcdDxkaXYgY2xhc3M9XFxcImVkaXRvcl9ob2xkZXJcXFwiPjwvZGl2Plxcblx0XHRcdFx0PHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG4gICAgICAgIDxiciAvPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHRcdDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz48L3RleHRhcmVhPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8YnIgLz5cXG5cdFx0XHRcdDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiOVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0ZpbGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSAoaGVscGVycy5yZW5kZXJUZXh0UGFyYW0gfHwgKGRlcHRoMCAmJiBkZXB0aDAucmVuZGVyVGV4dFBhcmFtKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSxkZXB0aDAse1wibmFtZVwiOlwicmVuZGVyVGV4dFBhcmFtXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDExLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIxMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDksIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XFxuXHQ8c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIj48L3NwYW4+XFxuPC90ZD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbV9saXN0J10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgcmVxdWlyZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgbXVsdGlwbGU9XFxcIm11bHRpcGxlXFxcIlwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiByZXF1aXJlZCBcIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgIDxvcHRpb24gXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy51bmxlc3MuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oYXNEZWZhdWx0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJ1bmxlc3NcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIHZhbHVlPScnPjwvb3B0aW9uPlxcblwiO1xufSxcIjhcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgc2VsZWN0ZWQ9XFxcIlxcXCIgXCI7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlxcbiAgICAgIDxvcHRpb24gXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0RlZmF1bHQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDExLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIHZhbHVlPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRGVmYXVsdCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiA8L29wdGlvbj5cXG5cXG5cIjtcbn0sXCIxMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIHNlbGVjdGVkPVxcXCJcXFwiICBcIjtcbn0sXCIxM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIChkZWZhdWx0KSBcIjtcbn0sXCIxNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiPHN0cm9uZz5cIjtcbn0sXCIxN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiPC9zdHJvbmc+XCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGVcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG4gIDxzZWxlY3QgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuaXNBcnJheSB8fCAoZGVwdGgwICYmIGRlcHRoMC5pc0FycmF5KSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJpc0FycmF5XCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiBjbGFzcz1cXFwicGFyYW1ldGVyIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgbmFtZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBpZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cXG5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYWxsb3dhYmxlVmFsdWVzIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5kZXNjcmlwdGl2ZVZhbHVlcyA6IHN0YWNrMSkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICA8L3NlbGVjdD5cXG48L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSAoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmRlc2NyaXB0aW9uIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbVR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtX3JlYWRvbmx5J10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYScgcmVhZG9ubHk9J3JlYWRvbmx5JyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDYsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiNlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgKGVtcHR5KVxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbVR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtX3JlYWRvbmx5X3JlcXVpcmVkJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYScgcmVhZG9ubHk9J3JlYWRvbmx5JyBwbGFjZWhvbGRlcj0nKHJlcXVpcmVkKScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGV4dGFyZWE+XFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDYsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiNlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgKGVtcHR5KVxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSByZXF1aXJlZCc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbVR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtX3JlcXVpcmVkJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0PGlucHV0IHR5cGU9XFxcImZpbGVcXFwiIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicvPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHRcdDxkaXYgY2xhc3M9XFxcImVkaXRvcl9ob2xkZXJcXFwiPjwvZGl2Plxcblx0XHRcdFx0PHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhIHJlcXVpcmVkJyBwbGFjZWhvbGRlcj0nKHJlcXVpcmVkKScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGV4dGFyZWE+XFxuICAgICAgICA8YnIgLz5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEgcmVxdWlyZWQnIHBsYWNlaG9sZGVyPScocmVxdWlyZWQpJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPjwvdGV4dGFyZWE+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDxiciAvPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0PGlucHV0IGNsYXNzPSdwYXJhbWV0ZXInIGNsYXNzPSdyZXF1aXJlZCcgdHlwZT0nZmlsZScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gKGhlbHBlcnMucmVuZGVyVGV4dFBhcmFtIHx8IChkZXB0aDAgJiYgZGVwdGgwLnJlbmRlclRleHRQYXJhbSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sZGVwdGgwLHtcIm5hbWVcIjpcInJlbmRlclRleHRQYXJhbVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIlwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSByZXF1aXJlZCc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cXG5cdDxzdHJvbmc+PHNwYW4gY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPjwvc3Ryb25nPlxcbjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1ldGVyX2NvbnRlbnRfdHlwZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb25zdW1lcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9vcHRpb24+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJhcHBsaWNhdGlvbi9qc29uXFxcIj5hcHBsaWNhdGlvbi9qc29uPC9vcHRpb24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZm9yPVxcXCJcIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJwYXJhbWV0ZXJDb250ZW50VHlwZUlkXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyIGNvbnRlbnQgdHlwZTo8L2xhYmVsPlxcbjxzZWxlY3QgbmFtZT1cXFwicGFyYW1ldGVyQ29udGVudFR5cGVcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVyQ29udGVudFR5cGVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29uc3VtZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc2VsZWN0PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BvcHVwJ10gPSB0ZW1wbGF0ZSh7XCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgaGVscGVyO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1kaWFsb2ctd3JhcHBlclxcXCI+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC10aXRsZVxcXCI+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMudGl0bGUgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRpdGxlIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30se1wibmFtZVwiOlwidGl0bGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1jb250ZW50XFxcIj48L2Rpdj5cXG4gICAgPHAgY2xhc3M9XFxcImVycm9yLW1zZ1xcXCI+PC9wPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtYWN0aW9uc1xcXCI+XFxuICAgICAgICA8YnV0dG9uIGNsYXNzPVxcXCJhcGktcG9wdXAtY2FuY2VsIGFwaS1idXR0b24gZ3JheVxcXCIgdHlwZT1cXFwiYnV0dG9uXFxcIj5DYW5jZWw8L2J1dHRvbj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWRpYWxvZy1zaGFkb3dcXFwiPjwvZGl2PlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3Jlc291cmNlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgOiBcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBkYXRhLXN3LXRyYW5zbGF0ZT5SYXc8L2E+XFxuICAgIDwvbGk+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBvcHRpb25zLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZywgYnVmZmVyID0gXG4gIFwiPGRpdiBjbGFzcz0naGVhZGluZyc+XFxuICA8aDI+XFxuICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVFbmRwb2ludExpc3RcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT4gXCI7XG4gIHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuc3VtbWFyeSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLChvcHRpb25zPXtcIm5hbWVcIjpcInN1bW1hcnlcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEsb3B0aW9ucykgOiBoZWxwZXIpKTtcbiAgaWYgKCFoZWxwZXJzLnN1bW1hcnkpIHsgc3RhY2sxID0gaGVscGVycy5ibG9ja0hlbHBlck1pc3NpbmcuY2FsbChkZXB0aDAsc3RhY2sxLG9wdGlvbnMpfVxuICBpZiAoc3RhY2sxICE9IG51bGwpIHsgYnVmZmVyICs9IHN0YWNrMTsgfVxuICByZXR1cm4gYnVmZmVyICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIDwvaDI+XFxuICA8dWwgY2xhc3M9J29wdGlvbnMnPlxcbiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J2VuZHBvaW50TGlzdFRvZ2dlcl9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlRW5kcG9pbnRMaXN0XFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5TaG93L0hpZGU8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiY29sbGFwc2VSZXNvdXJjZVxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+XFxuICAgICAgICBMaXN0IE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiZXhwYW5kUmVzb3VyY2VcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlxcbiAgICAgICAgRXhwYW5kIE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC91bD5cXG48L2Rpdj5cXG48dWwgY2xhc3M9J2VuZHBvaW50cycgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJfZW5kcG9pbnRfbGlzdCcgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+XFxuXFxuPC91bD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydyZXNwb25zZV9jb250ZW50X3R5cGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvb3B0aW9uPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiYXBwbGljYXRpb24vanNvblxcXCI+YXBwbGljYXRpb24vanNvbjwvb3B0aW9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3NpbmcsIGFsaWFzMz1cImZ1bmN0aW9uXCIsIGFsaWFzND1jb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbjtcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgYWxpYXM0KCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucmVzcG9uc2VDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gYWxpYXMzID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcInJlc3BvbnNlQ29udGVudFR5cGVJZFwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJyZXNwb25zZUNvbnRlbnRUeXBlXFxcIiBpZD1cXFwiXCJcbiAgICArIGFsaWFzNCgoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnJlc3BvbnNlQ29udGVudFR5cGVJZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IGFsaWFzMyA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJyZXNwb25zZUNvbnRlbnRUeXBlSWRcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NlbGVjdD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzaWduYXR1cmUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIlxcbjxkaXY+XFxuPHVsIGNsYXNzPVxcXCJzaWduYXR1cmUtbmF2XFxcIj5cXG4gIDxsaT48YSBjbGFzcz1cXFwiZGVzY3JpcHRpb24tbGlua1xcXCIgaHJlZj1cXFwiI1xcXCIgZGF0YS1zdy10cmFuc2xhdGU+TW9kZWw8L2E+PC9saT5cXG4gIDxsaT48YSBjbGFzcz1cXFwic25pcHBldC1saW5rXFxcIiBocmVmPVxcXCIjXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5FeGFtcGxlIFZhbHVlPC9hPjwvbGk+XFxuPC91bD5cXG48ZGl2PlxcblxcbjxkaXYgY2xhc3M9XFxcInNpZ25hdHVyZS1jb250YWluZXJcXFwiPlxcbiAgPGRpdiBjbGFzcz1cXFwiZGVzY3JpcHRpb25cXFwiPlxcbiAgICAgIFwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2lnbmF0dXJlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiXFxuICA8L2Rpdj5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcInNuaXBwZXRcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiICAgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF9qc29uXFxcIj5cXG4gICAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9jb2RlPjwvcHJlPlxcbiAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8c21hbGwgY2xhc3M9XFxcIm5vdGljZVxcXCIgZGF0YS1zdy10cmFuc2xhdGU+PC9zbWFsbD5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF94bWxcXFwiPlxcbiAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlWE1MIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2NvZGU+PC9wcmU+XFxuICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgPC9kaXY+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNpZ25hdHVyZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSAoaGVscGVycy5pZkNvbmQgfHwgKGRlcHRoMCAmJiBkZXB0aDAuaWZDb25kKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCksXCJ8fFwiLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmQ29uZFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzdGF0dXNfY29kZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICA8dHI+XFxuICAgICAgICA8dGQ+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMua2V5IHx8IChkYXRhICYmIGRhdGEua2V5KSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJrZXlcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgIDwvdHI+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIHdpZHRoPScxNSUnIGNsYXNzPSdjb2RlJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb2RlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1lc3NhZ2UgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIHdpZHRoPSc1MCUnPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiIC8+PC90ZD5cXG48dGQgY2xhc3M9XFxcImhlYWRlcnNcXFwiPlxcbiAgPHRhYmxlPlxcbiAgICA8dGJvZHk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L3Rib2R5PlxcbiAgPC90YWJsZT5cXG48L3RkPlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG59KSgpO30gXG4gLyoganNoaW50IGlnbm9yZTplbmQgKi8iLCIndXNlIHN0cmljdCc7XG5cblxuJChmdW5jdGlvbigpIHtcblxuXHQvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHZlcnRpY2FsbHkgYWxpZ25pbmcgRE9NIGVsZW1lbnRzXG5cdC8vIGh0dHA6Ly93d3cuc2VvZGVudmVyLmNvbS9zaW1wbGUtdmVydGljYWwtYWxpZ24tcGx1Z2luLWZvci1qcXVlcnkvXG5cdCQuZm4udkFsaWduID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xuXHRcdFx0dmFyIGFoID0gJCh0aGlzKS5oZWlnaHQoKTtcblx0XHRcdHZhciBwaCA9ICQodGhpcykucGFyZW50KCkuaGVpZ2h0KCk7XG5cdFx0XHR2YXIgbWggPSAocGggLSBhaCkgLyAyO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ21hcmdpbi10b3AnLCBtaCk7XG5cdFx0fSk7XG5cdH07XG5cblx0JC5mbi5zdHJldGNoRm9ybXRhc3RpY0lucHV0V2lkdGhUb1BhcmVudCA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcblx0XHRcdHZhciBwX3dpZHRoID0gJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5pbm5lcldpZHRoKCk7XG5cdFx0XHR2YXIgcF9wYWRkaW5nID0gcGFyc2VJbnQoJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5jc3MoJ3BhZGRpbmctbGVmdCcpICwxMCkgKyBwYXJzZUludCgkKHRoaXMpLmNsb3Nlc3QoJ2Zvcm0nKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0dmFyIHRoaXNfcGFkZGluZyA9IHBhcnNlSW50KCQodGhpcykuY3NzKCdwYWRkaW5nLWxlZnQnKSwgMTApICsgcGFyc2VJbnQoJCh0aGlzKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ3dpZHRoJywgcF93aWR0aCAtIHBfcGFkZGluZyAtIHRoaXNfcGFkZGluZyk7XG5cdFx0fSk7XG5cdH07XG5cblx0JCgnZm9ybS5mb3JtdGFzdGljIGxpLnN0cmluZyBpbnB1dCwgZm9ybS5mb3JtdGFzdGljIHRleHRhcmVhJykuc3RyZXRjaEZvcm10YXN0aWNJbnB1dFdpZHRoVG9QYXJlbnQoKTtcblxuXHQvLyBWZXJ0aWNhbGx5IGNlbnRlciB0aGVzZSBwYXJhZ3JhcGhzXG5cdC8vIFBhcmVudCBtYXkgbmVlZCBhIG1pbi1oZWlnaHQgZm9yIHRoaXMgdG8gd29yay4uXG5cdCQoJ3VsLmRvd25wbGF5ZWQgbGkgZGl2LmNvbnRlbnQgcCcpLnZBbGlnbigpO1xuXG5cdC8vIFdoZW4gYSBzYW5kYm94IGZvcm0gaXMgc3VibWl0dGVkLi5cblx0JChcImZvcm0uc2FuZGJveFwiKS5zdWJtaXQoZnVuY3Rpb24oKXtcblxuXHRcdHZhciBlcnJvcl9mcmVlID0gdHJ1ZTtcblxuXHRcdC8vIEN5Y2xlIHRocm91Z2ggdGhlIGZvcm1zIHJlcXVpcmVkIGlucHV0c1xuIFx0XHQkKHRoaXMpLmZpbmQoXCJpbnB1dC5yZXF1aXJlZFwiKS5lYWNoKGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBSZW1vdmUgYW55IGV4aXN0aW5nIGVycm9yIHN0eWxlcyBmcm9tIHRoZSBpbnB1dFxuXHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcblxuXHRcdFx0Ly8gVGFjayB0aGUgZXJyb3Igc3R5bGUgb24gaWYgdGhlIGlucHV0IGlzIGVtcHR5Li5cblx0XHRcdGlmICgkKHRoaXMpLnZhbCgpID09PSAnJykge1xuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuXHRcdFx0XHQkKHRoaXMpLndpZ2dsZSgpO1xuXHRcdFx0XHRlcnJvcl9mcmVlID0gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHR9KTtcblxuXHRcdHJldHVybiBlcnJvcl9mcmVlO1xuXHR9KTtcblxufSk7XG5cbmZ1bmN0aW9uIGNsaXBweUNvcGllZENhbGxiYWNrKCkge1xuICAkKCcjYXBpX2tleV9jb3BpZWQnKS5mYWRlSW4oKS5kZWxheSgxMDAwKS5mYWRlT3V0KCk7XG5cbiAgLy8gdmFyIGIgPSAkKFwiI2NsaXBweV90b29sdGlwX1wiICsgYSk7XG4gIC8vIGIubGVuZ3RoICE9IDAgJiYgKGIuYXR0cihcInRpdGxlXCIsIFwiY29waWVkIVwiKS50cmlnZ2VyKFwidGlwc3kucmVsb2FkXCIpLCBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAvLyAgIGIuYXR0cihcInRpdGxlXCIsIFwiY29weSB0byBjbGlwYm9hcmRcIilcbiAgLy8gfSxcbiAgLy8gNTAwKSlcbn1cblxuLy8gTG9nZ2luZyBmdW5jdGlvbiB0aGF0IGFjY291bnRzIGZvciBicm93c2VycyB0aGF0IGRvbid0IGhhdmUgd2luZG93LmNvbnNvbGVcbmZ1bmN0aW9uIGxvZygpe1xuICBsb2cuaGlzdG9yeSA9IGxvZy5oaXN0b3J5IHx8IFtdO1xuICBsb2cuaGlzdG9yeS5wdXNoKGFyZ3VtZW50cyk7XG4gIGlmKHRoaXMuY29uc29sZSl7XG4gICAgY29uc29sZS5sb2coIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cylbMF0gKTtcbiAgfVxufVxuXG4vLyBIYW5kbGUgYnJvd3NlcnMgdGhhdCBkbyBjb25zb2xlIGluY29ycmVjdGx5IChJRTkgYW5kIGJlbG93LCBzZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTUzOTM3OC83OTEzKVxuaWYgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kICYmIGNvbnNvbGUgJiYgdHlwZW9mIGNvbnNvbGUubG9nID09PSBcIm9iamVjdFwiKSB7XG4gICAgW1xuICAgICAgXCJsb2dcIixcImluZm9cIixcIndhcm5cIixcImVycm9yXCIsXCJhc3NlcnRcIixcImRpclwiLFwiY2xlYXJcIixcInByb2ZpbGVcIixcInByb2ZpbGVFbmRcIlxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICAgIGNvbnNvbGVbbWV0aG9kXSA9IHRoaXMuYmluZChjb25zb2xlW21ldGhvZF0sIGNvbnNvbGUpO1xuICAgIH0sIEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsKTtcbn1cblxud2luZG93LkRvY3MgPSB7XG5cblx0c2hlYmFuZzogZnVuY3Rpb24oKSB7XG5cblx0XHQvLyBJZiBzaGViYW5nIGhhcyBhbiBvcGVyYXRpb24gbmlja25hbWUgaW4gaXQuLlxuXHRcdC8vIGUuZy4gL2RvY3MvIyEvd29yZHMvZ2V0X3NlYXJjaFxuXHRcdHZhciBmcmFnbWVudHMgPSAkLnBhcmFtLmZyYWdtZW50KCkuc3BsaXQoJy8nKTtcblx0XHRmcmFnbWVudHMuc2hpZnQoKTsgLy8gZ2V0IHJpZCBvZiB0aGUgYmFuZ1xuXG5cdFx0c3dpdGNoIChmcmFnbWVudHMubGVuZ3RoKSB7XG5cdFx0XHRjYXNlIDE6XG4gICAgICAgIGlmIChmcmFnbWVudHNbMF0ubGVuZ3RoID4gMCkgeyAvLyBwcmV2ZW50IG1hdGNoaW5nIFwiIy9cIlxuICAgICAgICAgIC8vIEV4cGFuZCBhbGwgb3BlcmF0aW9ucyBmb3IgdGhlIHJlc291cmNlIGFuZCBzY3JvbGwgdG8gaXRcbiAgICAgICAgICB2YXIgZG9tX2lkID0gJ3Jlc291cmNlXycgKyBmcmFnbWVudHNbMF07XG5cbiAgICAgICAgICBEb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKGZyYWdtZW50c1swXSk7XG4gICAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcbiAgICAgICAgfVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0Ly8gUmVmZXIgdG8gdGhlIGVuZHBvaW50IERPTSBlbGVtZW50LCBlLmcuICN3b3Jkc19nZXRfc2VhcmNoXG5cbiAgICAgICAgLy8gRXhwYW5kIFJlc291cmNlXG4gICAgICAgIERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoZnJhZ21lbnRzWzBdKTtcbiAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcblxuICAgICAgICAgICAgLy8gRXhwYW5kIG9wZXJhdGlvblxuICAgICAgICAgICAgdmFyIGxpX2RvbV9pZCA9IGZyYWdtZW50cy5qb2luKCdfJyk7XG4gICAgICAgICAgICB2YXIgbGlfY29udGVudF9kb21faWQgPSBsaV9kb21faWQgKyBcIl9jb250ZW50XCI7XG5cblxuICAgICAgICAgICAgRG9jcy5leHBhbmRPcGVyYXRpb24oJCgnIycrbGlfY29udGVudF9kb21faWQpKTtcbiAgICAgICAgICAgICQoJyMnK2xpX2RvbV9pZCkuc2xpZGV0byh7aGlnaGxpZ2h0OiBmYWxzZX0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cdFx0fVxuXHR9LFxuXG5cdHRvZ2dsZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciBlbGVtID0gJCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0aWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpIHtcblx0XHRcdCQuYmJxLnB1c2hTdGF0ZSgnIy8nLCAyKTtcblx0XHRcdERvY3MuY29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fSBlbHNlIHtcbiAgICAgICAgICAgICQuYmJxLnB1c2hTdGF0ZSgnIy8nICsgcmVzb3VyY2UsIDIpO1xuXHRcdFx0RG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIEV4cGFuZCByZXNvdXJjZVxuXHRleHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHR2YXIgcmVzb3VyY2UgPSBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSk7XG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzJykuc2xpZGVEb3duKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZURvd24oKTtcblx0fSxcblxuXHQvLyBDb2xsYXBzZSByZXNvdXJjZSBhbmQgbWFyayBhcyBleHBsaWNpdGx5IGNsb3NlZFxuXHRjb2xsYXBzZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciByZXNvdXJjZSA9IERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKTtcblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH0sXG5cblx0ZXhwYW5kT3BlcmF0aW9uc0ZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgcmVzb3VyY2UgY29udGFpbmVyIGlzIG9wZW4uLlxuXHRcdERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLnNsaWRlRG93bigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSkgKyAnIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHREb2NzLmV4cGFuZE9wZXJhdGlvbigkKHRoaXMpKTtcblx0XHR9KTtcblx0fSxcblxuXHRjb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhlIHJlc291cmNlIGNvbnRhaW5lciBpcyBvcGVuLi5cblx0XHREb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblxuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50JykuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdERvY3MuY29sbGFwc2VPcGVyYXRpb24oJCh0aGlzKSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0ZXNjYXBlUmVzb3VyY2VOYW1lOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHJldHVybiByZXNvdXJjZS5yZXBsYWNlKC9bIVwiIyQlJicoKSorLC5cXC86Ozw9Pj9AXFxbXFxcXFxcXVxcXmB7fH1+XS9nLCBcIlxcXFwkJlwiKTtcblx0fSxcblxuXHRleHBhbmRPcGVyYXRpb246IGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRlbGVtLnNsaWRlRG93bigpO1xuXHR9LFxuXG5cdGNvbGxhcHNlT3BlcmF0aW9uOiBmdW5jdGlvbihlbGVtKSB7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH1cbn07XG4iLCIvKiFcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxuICogQGxpY2Vuc2UgZXM1LXNoaW0gQ29weXJpZ2h0IDIwMDktMjAxNSBieSBjb250cmlidXRvcnMsIE1JVCBMaWNlbnNlXG4gKiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vLyB2aW06IHRzPTQgc3RzPTQgc3c9NCBleHBhbmR0YWJcblxuLy8gQWRkIHNlbWljb2xvbiB0byBwcmV2ZW50IElJRkUgZnJvbSBiZWluZyBwYXNzZWQgYXMgYXJndW1lbnQgdG8gY29uY2F0ZW5hdGVkIGNvZGUuXG47XG5cbi8vIFVNRCAoVW5pdmVyc2FsIE1vZHVsZSBEZWZpbml0aW9uKVxuLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91bWRqcy91bWQvYmxvYi9tYXN0ZXIvdGVtcGxhdGVzL3JldHVybkV4cG9ydHMuanNcbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qIGdsb2JhbCBkZWZpbmUsIGV4cG9ydHMsIG1vZHVsZSAqL1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuICAgICAgICBkZWZpbmUoZmFjdG9yeSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgLy8gTm9kZS4gRG9lcyBub3Qgd29yayB3aXRoIHN0cmljdCBDb21tb25KUywgYnV0XG4gICAgICAgIC8vIG9ubHkgQ29tbW9uSlMtbGlrZSBlbnZpcm9tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgIC8vIGxpa2UgTm9kZS5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzIChyb290IGlzIHdpbmRvdylcbiAgICAgICAgcm9vdC5yZXR1cm5FeHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEJyaW5ncyBhbiBlbnZpcm9ubWVudCBhcyBjbG9zZSB0byBFQ01BU2NyaXB0IDUgY29tcGxpYW5jZVxuICAgICAqIGFzIGlzIHBvc3NpYmxlIHdpdGggdGhlIGZhY2lsaXRpZXMgb2YgZXJzdHdoaWxlIGVuZ2luZXMuXG4gICAgICpcbiAgICAgKiBBbm5vdGF0ZWQgRVM1OiBodHRwOi8vZXM1LmdpdGh1Yi5jb20vIChzcGVjaWZpYyBsaW5rcyBiZWxvdylcbiAgICAgKiBFUzUgU3BlYzogaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL3B1YmxpY2F0aW9ucy9maWxlcy9FQ01BLVNUL0VjbWEtMjYyLnBkZlxuICAgICAqIFJlcXVpcmVkIHJlYWRpbmc6IGh0dHA6Ly9qYXZhc2NyaXB0d2VibG9nLndvcmRwcmVzcy5jb20vMjAxMS8xMi8wNS9leHRlbmRpbmctamF2YXNjcmlwdC1uYXRpdmVzL1xuICAgICAqL1xuXG4gICAgLy8gU2hvcnRjdXQgdG8gYW4gb2Z0ZW4gYWNjZXNzZWQgcHJvcGVydGllcywgaW4gb3JkZXIgdG8gYXZvaWQgbXVsdGlwbGVcbiAgICAvLyBkZXJlZmVyZW5jZSB0aGF0IGNvc3RzIHVuaXZlcnNhbGx5LiBUaGlzIGFsc28gaG9sZHMgYSByZWZlcmVuY2UgdG8ga25vd24tZ29vZFxuICAgIC8vIGZ1bmN0aW9ucy5cbiAgICB2YXIgJEFycmF5ID0gQXJyYXk7XG4gICAgdmFyIEFycmF5UHJvdG90eXBlID0gJEFycmF5LnByb3RvdHlwZTtcbiAgICB2YXIgJE9iamVjdCA9IE9iamVjdDtcbiAgICB2YXIgT2JqZWN0UHJvdG90eXBlID0gJE9iamVjdC5wcm90b3R5cGU7XG4gICAgdmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xuICAgIHZhciBGdW5jdGlvblByb3RvdHlwZSA9ICRGdW5jdGlvbi5wcm90b3R5cGU7XG4gICAgdmFyICRTdHJpbmcgPSBTdHJpbmc7XG4gICAgdmFyIFN0cmluZ1Byb3RvdHlwZSA9ICRTdHJpbmcucHJvdG90eXBlO1xuICAgIHZhciAkTnVtYmVyID0gTnVtYmVyO1xuICAgIHZhciBOdW1iZXJQcm90b3R5cGUgPSAkTnVtYmVyLnByb3RvdHlwZTtcbiAgICB2YXIgYXJyYXlfc2xpY2UgPSBBcnJheVByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgYXJyYXlfc3BsaWNlID0gQXJyYXlQcm90b3R5cGUuc3BsaWNlO1xuICAgIHZhciBhcnJheV9wdXNoID0gQXJyYXlQcm90b3R5cGUucHVzaDtcbiAgICB2YXIgYXJyYXlfdW5zaGlmdCA9IEFycmF5UHJvdG90eXBlLnVuc2hpZnQ7XG4gICAgdmFyIGFycmF5X2NvbmNhdCA9IEFycmF5UHJvdG90eXBlLmNvbmNhdDtcbiAgICB2YXIgYXJyYXlfam9pbiA9IEFycmF5UHJvdG90eXBlLmpvaW47XG4gICAgdmFyIGNhbGwgPSBGdW5jdGlvblByb3RvdHlwZS5jYWxsO1xuICAgIHZhciBhcHBseSA9IEZ1bmN0aW9uUHJvdG90eXBlLmFwcGx5O1xuICAgIHZhciBtYXggPSBNYXRoLm1heDtcbiAgICB2YXIgbWluID0gTWF0aC5taW47XG5cbiAgICAvLyBIYXZpbmcgYSB0b1N0cmluZyBsb2NhbCB2YXJpYWJsZSBuYW1lIGJyZWFrcyBpbiBPcGVyYSBzbyB1c2UgdG9fc3RyaW5nLlxuICAgIHZhciB0b19zdHJpbmcgPSBPYmplY3RQcm90b3R5cGUudG9TdHJpbmc7XG5cbiAgICAvKiBnbG9iYWwgU3ltYm9sICovXG4gICAgLyogZXNsaW50LWRpc2FibGUgb25lLXZhci1kZWNsYXJhdGlvbi1wZXItbGluZSwgbm8tcmVkZWNsYXJlLCBtYXgtc3RhdGVtZW50cy1wZXItbGluZSAqL1xuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCc7XG4gICAgdmFyIGlzQ2FsbGFibGU7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1jYWxsYWJsZSAqLyB2YXIgZm5Ub1N0ciA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZywgY29uc3RydWN0b3JSZWdleCA9IC9eXFxzKmNsYXNzIC8sIGlzRVM2Q2xhc3NGbiA9IGZ1bmN0aW9uIGlzRVM2Q2xhc3NGbih2YWx1ZSkgeyB0cnkgeyB2YXIgZm5TdHIgPSBmblRvU3RyLmNhbGwodmFsdWUpOyB2YXIgc2luZ2xlU3RyaXBwZWQgPSBmblN0ci5yZXBsYWNlKC9cXC9cXC8uKlxcbi9nLCAnJyk7IHZhciBtdWx0aVN0cmlwcGVkID0gc2luZ2xlU3RyaXBwZWQucmVwbGFjZSgvXFwvXFwqWy5cXHNcXFNdKlxcKlxcLy9nLCAnJyk7IHZhciBzcGFjZVN0cmlwcGVkID0gbXVsdGlTdHJpcHBlZC5yZXBsYWNlKC9cXG4vbWcsICcgJykucmVwbGFjZSgvIHsyfS9nLCAnICcpOyByZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KHNwYWNlU3RyaXBwZWQpOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgLyogbm90IGEgZnVuY3Rpb24gKi8gfSB9LCB0cnlGdW5jdGlvbk9iamVjdCA9IGZ1bmN0aW9uIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKSB7IHRyeSB7IGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfSBmblRvU3RyLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgZm5DbGFzcyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJywgaXNDYWxsYWJsZSA9IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHsgaWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH0gaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSBpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfSBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH0gdmFyIHN0ckNsYXNzID0gdG9fc3RyaW5nLmNhbGwodmFsdWUpOyByZXR1cm4gc3RyQ2xhc3MgPT09IGZuQ2xhc3MgfHwgc3RyQ2xhc3MgPT09IGdlbkNsYXNzOyB9O1xuXG4gICAgdmFyIGlzUmVnZXg7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1yZWdleCAqLyB2YXIgcmVnZXhFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjLCB0cnlSZWdleEV4ZWMgPSBmdW5jdGlvbiB0cnlSZWdleEV4ZWModmFsdWUpIHsgdHJ5IHsgcmVnZXhFeGVjLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgcmVnZXhDbGFzcyA9ICdbb2JqZWN0IFJlZ0V4cF0nOyBpc1JlZ2V4ID0gZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkgeyBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH0gcmV0dXJuIGhhc1RvU3RyaW5nVGFnID8gdHJ5UmVnZXhFeGVjKHZhbHVlKSA6IHRvX3N0cmluZy5jYWxsKHZhbHVlKSA9PT0gcmVnZXhDbGFzczsgfTtcbiAgICB2YXIgaXNTdHJpbmc7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1zdHJpbmcgKi8gdmFyIHN0clZhbHVlID0gU3RyaW5nLnByb3RvdHlwZS52YWx1ZU9mLCB0cnlTdHJpbmdPYmplY3QgPSBmdW5jdGlvbiB0cnlTdHJpbmdPYmplY3QodmFsdWUpIHsgdHJ5IHsgc3RyVmFsdWUuY2FsbCh2YWx1ZSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9LCBzdHJpbmdDbGFzcyA9ICdbb2JqZWN0IFN0cmluZ10nOyBpc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7IGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7IHJldHVybiB0cnVlOyB9IGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSByZXR1cm4gaGFzVG9TdHJpbmdUYWcgPyB0cnlTdHJpbmdPYmplY3QodmFsdWUpIDogdG9fc3RyaW5nLmNhbGwodmFsdWUpID09PSBzdHJpbmdDbGFzczsgfTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG9uZS12YXItZGVjbGFyYXRpb24tcGVyLWxpbmUsIG5vLXJlZGVjbGFyZSwgbWF4LXN0YXRlbWVudHMtcGVyLWxpbmUgKi9cblxuICAgIC8qIGlubGluZWQgZnJvbSBodHRwOi8vbnBtanMuY29tL2RlZmluZS1wcm9wZXJ0aWVzICovXG4gICAgdmFyIHN1cHBvcnRzRGVzY3JpcHRvcnMgPSAkT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgb2JqID0ge307XG4gICAgICAgICAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ3gnLCB7IGVudW1lcmFibGU6IGZhbHNlLCB2YWx1ZTogb2JqIH0pO1xuICAgICAgICAgICAgZm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqLnggPT09IG9iajtcbiAgICAgICAgfSBjYXRjaCAoZSkgeyAvKiB0aGlzIGlzIEVTMyAqL1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSgpKTtcbiAgICB2YXIgZGVmaW5lUHJvcGVydGllcyA9IChmdW5jdGlvbiAoaGFzKSB7XG4gICAgICAgIC8vIERlZmluZSBjb25maWd1cmFibGUsIHdyaXRhYmxlLCBhbmQgbm9uLWVudW1lcmFibGUgcHJvcHNcbiAgICAgICAgLy8gaWYgdGhleSBkb24ndCBleGlzdC5cbiAgICAgICAgdmFyIGRlZmluZVByb3BlcnR5O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBtZXRob2QsIGZvcmNlQXNzaWduKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFmb3JjZUFzc2lnbiAmJiAobmFtZSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBtZXRob2RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIG1ldGhvZCwgZm9yY2VBc3NpZ24pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWZvcmNlQXNzaWduICYmIChuYW1lIGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3RbbmFtZV0gPSBtZXRob2Q7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKG9iamVjdCwgbWFwLCBmb3JjZUFzc2lnbikge1xuICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBtYXApIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzLmNhbGwobWFwLCBuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIG1hcFtuYW1lXSwgZm9yY2VBc3NpZ24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KE9iamVjdFByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSkpO1xuXG4gICAgLy9cbiAgICAvLyBVdGlsXG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCAvaGVscGVycy9pc1ByaW1pdGl2ZSAqL1xuICAgIHZhciBpc1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKGlucHV0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGlucHV0O1xuICAgICAgICByZXR1cm4gaW5wdXQgPT09IG51bGwgfHwgKHR5cGUgIT09ICdvYmplY3QnICYmIHR5cGUgIT09ICdmdW5jdGlvbicpO1xuICAgIH07XG5cbiAgICB2YXIgaXNBY3R1YWxOYU4gPSAkTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzQWN0dWFsTmFOKHgpIHtcbiAgICAgICAgcmV0dXJuIHggIT09IHg7XG4gICAgfTtcblxuICAgIHZhciBFUyA9IHtcbiAgICAgICAgLy8gRVM1IDkuNFxuICAgICAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3g5LjRcbiAgICAgICAgLy8gaHR0cDovL2pzcGVyZi5jb20vdG8taW50ZWdlclxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvSW50ZWdlciAqL1xuICAgICAgICBUb0ludGVnZXI6IGZ1bmN0aW9uIFRvSW50ZWdlcihudW0pIHtcbiAgICAgICAgICAgIHZhciBuID0gK251bTtcbiAgICAgICAgICAgIGlmIChpc0FjdHVhbE5hTihuKSkge1xuICAgICAgICAgICAgICAgIG4gPSAwO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChuICE9PSAwICYmIG4gIT09ICgxIC8gMCkgJiYgbiAhPT0gLSgxIC8gMCkpIHtcbiAgICAgICAgICAgICAgICBuID0gKG4gPiAwIHx8IC0xKSAqIE1hdGguZmxvb3IoTWF0aC5hYnMobikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub1ByaW1pdGl2ZSAqL1xuICAgICAgICBUb1ByaW1pdGl2ZTogZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB2YWwsIHZhbHVlT2YsIHRvU3RyO1xuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbHVlT2YgPSBpbnB1dC52YWx1ZU9mO1xuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWx1ZU9mLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9TdHIgPSBpbnB1dC50b1N0cmluZztcbiAgICAgICAgICAgIGlmIChpc0NhbGxhYmxlKHRvU3RyKSkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHRvU3RyLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEVTNSA5LjlcbiAgICAgICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4OS45XG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9PYmplY3QgKi9cbiAgICAgICAgVG9PYmplY3Q6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgICBpZiAobyA9PSBudWxsKSB7IC8vIHRoaXMgbWF0Y2hlcyBib3RoIG51bGwgYW5kIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgbyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJE9iamVjdChvKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvVWludDMyICovXG4gICAgICAgIFRvVWludDMyOiBmdW5jdGlvbiBUb1VpbnQzMih4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA+Pj4gMDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvL1xuICAgIC8vIEZ1bmN0aW9uXG4gICAgLy8gPT09PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVMtNSAxNS4zLjQuNVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjMuNC41XG5cbiAgICB2YXIgRW1wdHkgPSBmdW5jdGlvbiBFbXB0eSgpIHt9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhGdW5jdGlvblByb3RvdHlwZSwge1xuICAgICAgICBiaW5kOiBmdW5jdGlvbiBiaW5kKHRoYXQpIHsgLy8gLmxlbmd0aCBpcyAxXG4gICAgICAgICAgICAvLyAxLiBMZXQgVGFyZ2V0IGJlIHRoZSB0aGlzIHZhbHVlLlxuICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXM7XG4gICAgICAgICAgICAvLyAyLiBJZiBJc0NhbGxhYmxlKFRhcmdldCkgaXMgZmFsc2UsIHRocm93IGEgVHlwZUVycm9yIGV4Y2VwdGlvbi5cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgY2FsbGVkIG9uIGluY29tcGF0aWJsZSAnICsgdGFyZ2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIDMuIExldCBBIGJlIGEgbmV3IChwb3NzaWJseSBlbXB0eSkgaW50ZXJuYWwgbGlzdCBvZiBhbGwgb2YgdGhlXG4gICAgICAgICAgICAvLyAgIGFyZ3VtZW50IHZhbHVlcyBwcm92aWRlZCBhZnRlciB0aGlzQXJnIChhcmcxLCBhcmcyIGV0YyksIGluIG9yZGVyLlxuICAgICAgICAgICAgLy8gWFhYIHNsaWNlZEFyZ3Mgd2lsbCBzdGFuZCBpbiBmb3IgXCJBXCIgaWYgdXNlZFxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7IC8vIGZvciBub3JtYWwgY2FsbFxuICAgICAgICAgICAgLy8gNC4gTGV0IEYgYmUgYSBuZXcgbmF0aXZlIEVDTUFTY3JpcHQgb2JqZWN0LlxuICAgICAgICAgICAgLy8gMTEuIFNldCB0aGUgW1tQcm90b3R5cGVdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIHRvIHRoZSBzdGFuZGFyZFxuICAgICAgICAgICAgLy8gICBidWlsdC1pbiBGdW5jdGlvbiBwcm90b3R5cGUgb2JqZWN0IGFzIHNwZWNpZmllZCBpbiAxNS4zLjMuMS5cbiAgICAgICAgICAgIC8vIDEyLiBTZXQgdGhlIFtbQ2FsbF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjEuXG4gICAgICAgICAgICAvLyAxMy4gU2V0IHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjIuXG4gICAgICAgICAgICAvLyAxNC4gU2V0IHRoZSBbW0hhc0luc3RhbmNlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiBhcyBkZXNjcmliZWQgaW5cbiAgICAgICAgICAgIC8vICAgMTUuMy40LjUuMy5cbiAgICAgICAgICAgIHZhciBib3VuZDtcbiAgICAgICAgICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDE1LjMuNC41LjIgW1tDb25zdHJ1Y3RdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZCBvZiBhIGZ1bmN0aW9uIG9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgLy8gRiB0aGF0IHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCBvZiBhcmd1bWVudHMgRXh0cmFBcmdzLCB0aGUgZm9sbG93aW5nIHN0ZXBzIGFyZSB0YWtlbjpcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gTGV0IHRhcmdldCBiZSB0aGUgdmFsdWUgb2YgRidzIFtbVGFyZ2V0RnVuY3Rpb25dXVxuICAgICAgICAgICAgICAgICAgICAvLyAgIGludGVybmFsIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBJZiB0YXJnZXQgaGFzIG5vIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgbWV0aG9kLCBhXG4gICAgICAgICAgICAgICAgICAgIC8vICAgVHlwZUVycm9yIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG4gICAgICAgICAgICAgICAgICAgIC8vIDMuIExldCBib3VuZEFyZ3MgYmUgdGhlIHZhbHVlIG9mIEYncyBbW0JvdW5kQXJnc11dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbWV0aG9kIG9mIHRhcmdldCBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTUuMy40LjUuMSBbW0NhbGxdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2Qgb2YgYSBmdW5jdGlvbiBvYmplY3QsIEYsXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyB2YWx1ZSBhbmQgYSBsaXN0IG9mIGFyZ3VtZW50cyBFeHRyYUFyZ3MsIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RlcHMgYXJlIHRha2VuOlxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBMZXQgYm91bmRBcmdzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZEFyZ3NdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBMZXQgYm91bmRUaGlzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZFRoaXNdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAzLiBMZXQgdGFyZ2V0IGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tUYXJnZXRGdW5jdGlvbl1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2RcbiAgICAgICAgICAgICAgICAgICAgLy8gICBvZiB0YXJnZXQgcHJvdmlkaW5nIGJvdW5kVGhpcyBhcyB0aGUgdGhpcyB2YWx1ZSBhbmRcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGVxdWl2OiB0YXJnZXQuY2FsbCh0aGlzLCAuLi5ib3VuZEFyZ3MsIC4uLmFyZ3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuIElmIHRoZSBbW0NsYXNzXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgVGFyZ2V0IGlzIFwiRnVuY3Rpb25cIiwgdGhlblxuICAgICAgICAgICAgLy8gICAgIGEuIExldCBMIGJlIHRoZSBsZW5ndGggcHJvcGVydHkgb2YgVGFyZ2V0IG1pbnVzIHRoZSBsZW5ndGggb2YgQS5cbiAgICAgICAgICAgIC8vICAgICBiLiBTZXQgdGhlIGxlbmd0aCBvd24gcHJvcGVydHkgb2YgRiB0byBlaXRoZXIgMCBvciBMLCB3aGljaGV2ZXIgaXNcbiAgICAgICAgICAgIC8vICAgICAgIGxhcmdlci5cbiAgICAgICAgICAgIC8vIDE2LiBFbHNlIHNldCB0aGUgbGVuZ3RoIG93biBwcm9wZXJ0eSBvZiBGIHRvIDAuXG5cbiAgICAgICAgICAgIHZhciBib3VuZExlbmd0aCA9IG1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyAxNy4gU2V0IHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsZW5ndGggb3duIHByb3BlcnR5IG9mIEYgdG8gdGhlIHZhbHVlc1xuICAgICAgICAgICAgLy8gICBzcGVjaWZpZWQgaW4gMTUuMy41LjEuXG4gICAgICAgICAgICB2YXIgYm91bmRBcmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhcnJheV9wdXNoLmNhbGwoYm91bmRBcmdzLCAnJCcgKyBpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gWFhYIEJ1aWxkIGEgZHluYW1pYyBmdW5jdGlvbiB3aXRoIGRlc2lyZWQgYW1vdW50IG9mIGFyZ3VtZW50cyBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gd2F5IHRvIHNldCB0aGUgbGVuZ3RoIHByb3BlcnR5IG9mIGEgZnVuY3Rpb24uXG4gICAgICAgICAgICAvLyBJbiBlbnZpcm9ubWVudHMgd2hlcmUgQ29udGVudCBTZWN1cml0eSBQb2xpY2llcyBlbmFibGVkIChDaHJvbWUgZXh0ZW5zaW9ucyxcbiAgICAgICAgICAgIC8vIGZvciBleC4pIGFsbCB1c2Ugb2YgZXZhbCBvciBGdW5jdGlvbiBjb3N0cnVjdG9yIHRocm93cyBhbiBleGNlcHRpb24uXG4gICAgICAgICAgICAvLyBIb3dldmVyIGluIGFsbCBvZiB0aGVzZSBlbnZpcm9ubWVudHMgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgZXhpc3RzXG4gICAgICAgICAgICAvLyBhbmQgc28gdGhpcyBjb2RlIHdpbGwgbmV2ZXIgYmUgZXhlY3V0ZWQuXG4gICAgICAgICAgICBib3VuZCA9ICRGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGFycmF5X2pvaW4uY2FsbChib3VuZEFyZ3MsICcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9JykoYmluZGVyKTtcblxuICAgICAgICAgICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSB0YXJnZXQucHJvdG90eXBlO1xuICAgICAgICAgICAgICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBFbXB0eSgpO1xuICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIGRhbmdsaW5nIHJlZmVyZW5jZXMuXG4gICAgICAgICAgICAgICAgRW1wdHkucHJvdG90eXBlID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gMTguIFNldCB0aGUgW1tFeHRlbnNpYmxlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiB0byB0cnVlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyAxOS4gTGV0IHRocm93ZXIgYmUgdGhlIFtbVGhyb3dUeXBlRXJyb3JdXSBmdW5jdGlvbiBPYmplY3QgKDEzLjIuMykuXG4gICAgICAgICAgICAvLyAyMC4gQ2FsbCB0aGUgW1tEZWZpbmVPd25Qcm9wZXJ0eV1dIGludGVybmFsIG1ldGhvZCBvZiBGIHdpdGhcbiAgICAgICAgICAgIC8vICAgYXJndW1lbnRzIFwiY2FsbGVyXCIsIFByb3BlcnR5RGVzY3JpcHRvciB7W1tHZXRdXTogdGhyb3dlciwgW1tTZXRdXTpcbiAgICAgICAgICAgIC8vICAgdGhyb3dlciwgW1tFbnVtZXJhYmxlXV06IGZhbHNlLCBbW0NvbmZpZ3VyYWJsZV1dOiBmYWxzZX0sIGFuZFxuICAgICAgICAgICAgLy8gICBmYWxzZS5cbiAgICAgICAgICAgIC8vIDIxLiBDYWxsIHRoZSBbW0RlZmluZU93blByb3BlcnR5XV0gaW50ZXJuYWwgbWV0aG9kIG9mIEYgd2l0aFxuICAgICAgICAgICAgLy8gICBhcmd1bWVudHMgXCJhcmd1bWVudHNcIiwgUHJvcGVydHlEZXNjcmlwdG9yIHtbW0dldF1dOiB0aHJvd2VyLFxuICAgICAgICAgICAgLy8gICBbW1NldF1dOiB0aHJvd2VyLCBbW0VudW1lcmFibGVdXTogZmFsc2UsIFtbQ29uZmlndXJhYmxlXV06IGZhbHNlfSxcbiAgICAgICAgICAgIC8vICAgYW5kIGZhbHNlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyBOT1RFIEZ1bmN0aW9uIG9iamVjdHMgY3JlYXRlZCB1c2luZyBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBkbyBub3RcbiAgICAgICAgICAgIC8vIGhhdmUgYSBwcm90b3R5cGUgcHJvcGVydHkgb3IgdGhlIFtbQ29kZV1dLCBbW0Zvcm1hbFBhcmFtZXRlcnNdXSwgYW5kXG4gICAgICAgICAgICAvLyBbW1Njb3BlXV0gaW50ZXJuYWwgcHJvcGVydGllcy5cbiAgICAgICAgICAgIC8vIFhYWCBjYW4ndCBkZWxldGUgcHJvdG90eXBlIGluIHB1cmUtanMuXG5cbiAgICAgICAgICAgIC8vIDIyLiBSZXR1cm4gRi5cbiAgICAgICAgICAgIHJldHVybiBib3VuZDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gX1BsZWFzZSBub3RlOiBTaG9ydGN1dHMgYXJlIGRlZmluZWQgYWZ0ZXIgYEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kYCBhcyB3ZVxuICAgIC8vIHVzZSBpdCBpbiBkZWZpbmluZyBzaG9ydGN1dHMuXG4gICAgdmFyIG93bnMgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiAgICB2YXIgdG9TdHIgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLnRvU3RyaW5nKTtcbiAgICB2YXIgYXJyYXlTbGljZSA9IGNhbGwuYmluZChhcnJheV9zbGljZSk7XG4gICAgdmFyIGFycmF5U2xpY2VBcHBseSA9IGFwcGx5LmJpbmQoYXJyYXlfc2xpY2UpO1xuICAgIHZhciBzdHJTbGljZSA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc2xpY2UpO1xuICAgIHZhciBzdHJTcGxpdCA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc3BsaXQpO1xuICAgIHZhciBzdHJJbmRleE9mID0gY2FsbC5iaW5kKFN0cmluZ1Byb3RvdHlwZS5pbmRleE9mKTtcbiAgICB2YXIgcHVzaENhbGwgPSBjYWxsLmJpbmQoYXJyYXlfcHVzaCk7XG4gICAgdmFyIGlzRW51bSA9IGNhbGwuYmluZChPYmplY3RQcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUpO1xuICAgIHZhciBhcnJheVNvcnQgPSBjYWxsLmJpbmQoQXJyYXlQcm90b3R5cGUuc29ydCk7XG5cbiAgICAvL1xuICAgIC8vIEFycmF5XG4gICAgLy8gPT09PT1cbiAgICAvL1xuXG4gICAgdmFyIGlzQXJyYXkgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KG9iaikge1xuICAgICAgICByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgICB9O1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xM1xuICAgIC8vIFJldHVybiBsZW4rYXJnQ291bnQuXG4gICAgLy8gW2J1Z2ZpeCwgaWVsdDhdXG4gICAgLy8gSUUgPCA4IGJ1ZzogW10udW5zaGlmdCgwKSA9PT0gdW5kZWZpbmVkIGJ1dCBzaG91bGQgYmUgXCIxXCJcbiAgICB2YXIgaGFzVW5zaGlmdFJldHVyblZhbHVlQnVnID0gW10udW5zaGlmdCgwKSAhPT0gMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHVuc2hpZnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgIH0sIGhhc1Vuc2hpZnRSZXR1cm5WYWx1ZUJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC4zLjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjMuMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2lzQXJyYXlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKCRBcnJheSwgeyBpc0FycmF5OiBpc0FycmF5IH0pO1xuXG4gICAgLy8gVGhlIElzQ2FsbGFibGUoKSBjaGVjayBpbiB0aGUgQXJyYXkgZnVuY3Rpb25zXG4gICAgLy8gaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBhIHN0cmljdCBjaGVjayBvbiB0aGVcbiAgICAvLyBpbnRlcm5hbCBjbGFzcyBvZiB0aGUgb2JqZWN0IHRvIHRyYXAgY2FzZXMgd2hlcmVcbiAgICAvLyB0aGUgcHJvdmlkZWQgZnVuY3Rpb24gd2FzIGFjdHVhbGx5IGEgcmVndWxhclxuICAgIC8vIGV4cHJlc3Npb24gbGl0ZXJhbCwgd2hpY2ggaW4gVjggYW5kXG4gICAgLy8gSmF2YVNjcmlwdENvcmUgaXMgYSB0eXBlb2YgXCJmdW5jdGlvblwiLiAgT25seSBpblxuICAgIC8vIFY4IGFyZSByZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbHMgcGVybWl0dGVkIGFzXG4gICAgLy8gcmVkdWNlIHBhcmFtZXRlcnMsIHNvIGl0IGlzIGRlc2lyYWJsZSBpbiB0aGVcbiAgICAvLyBnZW5lcmFsIGNhc2UgZm9yIHRoZSBzaGltIHRvIG1hdGNoIHRoZSBtb3JlXG4gICAgLy8gc3RyaWN0IGFuZCBjb21tb24gYmVoYXZpb3Igb2YgcmVqZWN0aW5nIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9ucy5cblxuICAgIC8vIEVTNSAxNS40LjQuMThcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMThcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9hcnJheS9mb3JFYWNoXG5cbiAgICAvLyBDaGVjayBmYWlsdXJlIG9mIGJ5LWluZGV4IGFjY2VzcyBvZiBzdHJpbmcgY2hhcmFjdGVycyAoSUUgPCA5KVxuICAgIC8vIGFuZCBmYWlsdXJlIG9mIGAwIGluIGJveGVkU3RyaW5nYCAoUmhpbm8pXG4gICAgdmFyIGJveGVkU3RyaW5nID0gJE9iamVjdCgnYScpO1xuICAgIHZhciBzcGxpdFN0cmluZyA9IGJveGVkU3RyaW5nWzBdICE9PSAnYScgfHwgISgwIGluIGJveGVkU3RyaW5nKTtcblxuICAgIHZhciBwcm9wZXJseUJveGVzQ29udGV4dCA9IGZ1bmN0aW9uIHByb3Blcmx5Qm94ZWQobWV0aG9kKSB7XG4gICAgICAgIC8vIENoZWNrIG5vZGUgMC42LjIxIGJ1ZyB3aGVyZSB0aGlyZCBwYXJhbWV0ZXIgaXMgbm90IGJveGVkXG4gICAgICAgIHZhciBwcm9wZXJseUJveGVzTm9uU3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgdmFyIHByb3Blcmx5Qm94ZXNTdHJpY3QgPSB0cnVlO1xuICAgICAgICB2YXIgdGhyZXdFeGNlcHRpb24gPSBmYWxzZTtcbiAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtZXRob2QuY2FsbCgnZm9vJywgZnVuY3Rpb24gKF8sIF9fLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3Blcmx5Qm94ZXNOb25TdHJpY3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgbWV0aG9kLmNhbGwoWzFdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICd1c2Ugc3RyaWN0JztcblxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJseUJveGVzU3RyaWN0ID0gdHlwZW9mIHRoaXMgPT09ICdzdHJpbmcnO1xuICAgICAgICAgICAgICAgIH0sICd4Jyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyZXdFeGNlcHRpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIW1ldGhvZCAmJiAhdGhyZXdFeGNlcHRpb24gJiYgcHJvcGVybHlCb3hlc05vblN0cmljdCAmJiBwcm9wZXJseUJveGVzU3RyaWN0O1xuICAgIH07XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5mb3JFYWNoIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbnZva2UgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggY2FsbCwgcGFzc2luZyBhcmd1bWVudHM6XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRleHQsIHByb3BlcnR5IHZhbHVlLCBwcm9wZXJ0eSBrZXksIHRoaXNBcmcgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLmZvckVhY2gpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTlcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTlcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L21hcFxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbWFwOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9ICRBcnJheShsZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLm1hcCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLm1hcCkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvZmlsdGVyXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZmlsdGVyIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbGZbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcgPyBjYWxsYmFja2ZuKHZhbHVlLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHZhbHVlLCBpLCBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuZmlsdGVyKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE2XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE2XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZXZlcnlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZXZlcnkgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmICEodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5ldmVyeSkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xN1xuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xN1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L3NvbWVcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbi8qLCB0aGlzQXJnICovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5zb21lIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5zb21lKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjIxXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjIxXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9yZWR1Y2VcbiAgICB2YXIgcmVkdWNlQ29lcmNlc1RvT2JqZWN0ID0gZmFsc2U7XG4gICAgaWYgKEFycmF5UHJvdG90eXBlLnJlZHVjZSkge1xuICAgICAgICByZWR1Y2VDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlLmNhbGwoJ2VzNScsIGZ1bmN0aW9uIChfLCBfXywgX19fLCBsaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdDtcbiAgICAgICAgfSkgPT09ICdvYmplY3QnO1xuICAgIH1cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4vKiwgaW5pdGlhbFZhbHVlKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnJlZHVjZSBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUgYW5kIGFuIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNlbGZbaSsrXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYXJyYXkgY29udGFpbnMgbm8gdmFsdWVzLCBubyBpbml0aWFsIHZhbHVlIHRvIHJldHVyblxuICAgICAgICAgICAgICAgICAgICBpZiAoKytpID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrZm4ocmVzdWx0LCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFyZWR1Y2VDb2VyY2VzVG9PYmplY3QpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvcmVkdWNlUmlnaHRcbiAgICB2YXIgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSBmYWxzZTtcbiAgICBpZiAoQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQpIHtcbiAgICAgICAgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQuY2FsbCgnZXM1JywgZnVuY3Rpb24gKF8sIF9fLCBfX18sIGxpc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0O1xuICAgICAgICB9KSA9PT0gJ29iamVjdCc7XG4gICAgfVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4vKiwgaW5pdGlhbCovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5yZWR1Y2VSaWdodCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUsIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgICAgIHZhciBpID0gbGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2VsZltpLS1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBpZiBhcnJheSBjb250YWlucyBubyB2YWx1ZXMsIG5vIGluaXRpYWwgdmFsdWUgdG8gcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gd2hpbGUgKHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaSA8IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjYWxsYmFja2ZuKHJlc3VsdCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlIChpLS0pO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXJlZHVjZVJpZ2h0Q29lcmNlc1RvT2JqZWN0KTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTRcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9pbmRleE9mXG4gICAgdmFyIGhhc0ZpcmVmb3gySW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmluZGV4T2YgJiYgWzAsIDFdLmluZGV4T2YoMSwgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50LyosIGZyb21JbmRleCAqLykge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IEVTLlRvSW50ZWdlcihhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBtYXgoMCwgbGVuZ3RoICsgaSk7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiBzZWxmW2ldID09PSBzZWFyY2hFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH0sIGhhc0ZpcmVmb3gySW5kZXhPZkJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE1XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE1XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvbGFzdEluZGV4T2ZcbiAgICB2YXIgaGFzRmlyZWZveDJMYXN0SW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmxhc3RJbmRleE9mICYmIFswLCAxXS5sYXN0SW5kZXhPZigwLCAtMykgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQvKiwgZnJvbUluZGV4ICovKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGkgPSBsZW5ndGggLSAxO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IG1pbihpLCBFUy5Ub0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBsZW5ndGggLSBNYXRoLmFicyhpKTtcbiAgICAgICAgICAgIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgc2VhcmNoRWxlbWVudCA9PT0gc2VsZltpXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNGaXJlZm94Mkxhc3RJbmRleE9mQnVnKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTJcbiAgICB2YXIgc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGEgPSBbMSwgMl07XG4gICAgICAgIHZhciByZXN1bHQgPSBhLnNwbGljZSgpO1xuICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IDIgJiYgaXNBcnJheShyZXN1bHQpICYmIHJlc3VsdC5sZW5ndGggPT09IDA7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnIHdoZXJlIC5zcGxpY2UoKSByZXR1cm5zIHVuZGVmaW5lZFxuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAhc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5KTtcblxuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgQXJyYXlQcm90b3R5cGUuc3BsaWNlLmNhbGwob2JqLCAwLCAwLCAxKTtcbiAgICAgICAgcmV0dXJuIG9iai5sZW5ndGggPT09IDE7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNwbGljZTogZnVuY3Rpb24gc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gbWF4KEVTLlRvSW50ZWdlcih0aGlzLmxlbmd0aCksIDApO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIHR5cGVvZiBkZWxldGVDb3VudCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBhcmdzID0gYXJyYXlTbGljZShhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwoYXJncywgdGhpcy5sZW5ndGggLSBzdGFydCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IEVTLlRvSW50ZWdlcihkZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFycmF5X3NwbGljZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH0sICFzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCk7XG4gICAgdmFyIHNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gUGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMjk1XG4gICAgICAgIC8vIFNhZmFyaSA3LzggYnJlYWtzIHdpdGggc3BhcnNlIGFycmF5cyBvZiBzaXplIDFlNSBvciBncmVhdGVyXG4gICAgICAgIHZhciBhcnIgPSBuZXcgJEFycmF5KDFlNSk7XG4gICAgICAgIC8vIG5vdGU6IHRoZSBpbmRleCBNVVNUIGJlIDggb3IgbGFyZ2VyIG9yIHRoZSB0ZXN0IHdpbGwgZmFsc2UgcGFzc1xuICAgICAgICBhcnJbOF0gPSAneCc7XG4gICAgICAgIGFyci5zcGxpY2UoMSwgMSk7XG4gICAgICAgIC8vIG5vdGU6IHRoaXMgdGVzdCBtdXN0IGJlIGRlZmluZWQgKmFmdGVyKiB0aGUgaW5kZXhPZiBzaGltXG4gICAgICAgIC8vIHBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzMxM1xuICAgICAgICByZXR1cm4gYXJyLmluZGV4T2YoJ3gnKSA9PT0gNztcbiAgICB9KCkpO1xuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzI5NVxuICAgICAgICAvLyBPcGVyYSAxMi4xNSBicmVha3Mgb24gdGhpcywgbm8gaWRlYSB3aHkuXG4gICAgICAgIHZhciBuID0gMjU2O1xuICAgICAgICB2YXIgYXJyID0gW107XG4gICAgICAgIGFycltuXSA9ICdhJztcbiAgICAgICAgYXJyLnNwbGljZShuICsgMSwgMCwgJ2InKTtcbiAgICAgICAgcmV0dXJuIGFycltuXSA9PT0gJ2EnO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIHZhciBPID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgQSA9IFtdO1xuICAgICAgICAgICAgdmFyIGxlbiA9IEVTLlRvVWludDMyKE8ubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZVN0YXJ0ID0gRVMuVG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxTdGFydCA9IHJlbGF0aXZlU3RhcnQgPCAwID8gbWF4KChsZW4gKyByZWxhdGl2ZVN0YXJ0KSwgMCkgOiBtaW4ocmVsYXRpdmVTdGFydCwgbGVuKTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxEZWxldGVDb3VudCA9IG1pbihtYXgoRVMuVG9JbnRlZ2VyKGRlbGV0ZUNvdW50KSwgMCksIGxlbiAtIGFjdHVhbFN0YXJ0KTtcblxuICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgdmFyIGZyb207XG4gICAgICAgICAgICB3aGlsZSAoayA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgZnJvbSA9ICRTdHJpbmcoYWN0dWFsU3RhcnQgKyBrKTtcbiAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICBBW2tdID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgayArPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBhcnJheVNsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICB2YXIgaXRlbUNvdW50ID0gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHRvO1xuICAgICAgICAgICAgaWYgKGl0ZW1Db3VudCA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgayA9IGFjdHVhbFN0YXJ0O1xuICAgICAgICAgICAgICAgIHZhciBtYXhLID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGsgPCBtYXhLKSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gJFN0cmluZyhrICsgaXRlbUNvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG93bnMoTywgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE9bdG9dID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBPW3RvXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBrICs9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsgPSBsZW47XG4gICAgICAgICAgICAgICAgdmFyIG1pbksgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudCArIGl0ZW1Db3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IG1pbkspIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bayAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBrIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtQ291bnQgPiBhY3R1YWxEZWxldGVDb3VudCkge1xuICAgICAgICAgICAgICAgIGsgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IGFjdHVhbFN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICB0byA9ICRTdHJpbmcoayArIGl0ZW1Db3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgT1t0b10gPSBPW2Zyb21dO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bdG9dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGsgLT0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrID0gYWN0dWFsU3RhcnQ7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgT1trXSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIGsgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIE8ubGVuZ3RoID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQgKyBpdGVtQ291bnQ7XG5cbiAgICAgICAgICAgIHJldHVybiBBO1xuICAgICAgICB9XG4gICAgfSwgIXNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzIHx8ICFzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyk7XG5cbiAgICB2YXIgb3JpZ2luYWxKb2luID0gQXJyYXlQcm90b3R5cGUuam9pbjtcbiAgICB2YXIgaGFzU3RyaW5nSm9pbkJ1ZztcbiAgICB0cnkge1xuICAgICAgICBoYXNTdHJpbmdKb2luQnVnID0gQXJyYXkucHJvdG90eXBlLmpvaW4uY2FsbCgnMTIzJywgJywnKSAhPT0gJzEsMiwzJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGhhc1N0cmluZ0pvaW5CdWcgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoaGFzU3RyaW5nSm9pbkJ1Zykge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgICAgICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgIHZhciBzZXAgPSB0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyA/ICcsJyA6IHNlcGFyYXRvcjtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxKb2luLmNhbGwoaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNTdHJpbmdKb2luQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgaGFzSm9pblVuZGVmaW5lZEJ1ZyA9IFsxLCAyXS5qb2luKHVuZGVmaW5lZCkgIT09ICcxLDInO1xuICAgIGlmIChoYXNKb2luVW5kZWZpbmVkQnVnKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcCA9IHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnID8gJywnIDogc2VwYXJhdG9yO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEpvaW4uY2FsbCh0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNKb2luVW5kZWZpbmVkQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgcHVzaFNoaW0gPSBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgdmFyIE8gPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgdmFyIG4gPSBFUy5Ub1VpbnQzMihPLmxlbmd0aCk7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBPW24gKyBpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICBPLmxlbmd0aCA9IG4gKyBpO1xuICAgICAgICByZXR1cm4gbiArIGk7XG4gICAgfTtcblxuICAgIHZhciBwdXNoSXNOb3RHZW5lcmljID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICB2YXIgcmVzdWx0ID0gQXJyYXkucHJvdG90eXBlLnB1c2guY2FsbChvYmosIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgb2JqLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2Ygb2JqWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhvYmosIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBwdXNoOiBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3B1c2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwdXNoU2hpbS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfSwgcHVzaElzTm90R2VuZXJpYyk7XG5cbiAgICAvLyBUaGlzIGZpeGVzIGEgdmVyeSB3ZWlyZCBidWcgaW4gT3BlcmEgMTAuNiB3aGVuIHB1c2hpbmcgYHVuZGVmaW5lZFxuICAgIHZhciBwdXNoVW5kZWZpbmVkSXNXZWlyZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcnIgPSBbXTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGFyci5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgYXJyLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2YgYXJyWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhhcnIsIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwgeyBwdXNoOiBwdXNoU2hpbSB9LCBwdXNoVW5kZWZpbmVkSXNXZWlyZCk7XG5cbiAgICAvLyBFUzUgMTUuMi4zLjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS40LjQuMTBcbiAgICAvLyBGaXggYm94ZWQgc3RyaW5nIGJ1Z1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc2xpY2U6IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gICAgICAgICAgICB2YXIgYXJyID0gaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5U2xpY2VBcHBseShhcnIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9LCBzcGxpdFN0cmluZyk7XG5cbiAgICB2YXIgc29ydElnbm9yZXNOb25GdW5jdGlvbnMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQobnVsbCk7XG4gICAgICAgICAgICBbMSwgMl0uc29ydCh7fSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRUaHJvd3NPblJlZ2V4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdGhpcyBpcyBhIHByb2JsZW0gaW4gRmlyZWZveCA0LCBpbiB3aGljaCBgdHlwZW9mIC9hLyA9PT0gJ2Z1bmN0aW9uJ2BcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KC9hLyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRJZ25vcmVzVW5kZWZpbmVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gYXBwbGllcyBpbiBJRSA4LCBmb3Igb25lLlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQodW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZUZuKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbXBhcmVGbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlTb3J0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNvbXBhcmVGbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuc29ydCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhcnJheVNvcnQodGhpcywgY29tcGFyZUZuKTtcbiAgICAgICAgfVxuICAgIH0sIHNvcnRJZ25vcmVzTm9uRnVuY3Rpb25zIHx8ICFzb3J0SWdub3Jlc1VuZGVmaW5lZCB8fCAhc29ydFRocm93c09uUmVnZXgpO1xuXG4gICAgLy9cbiAgICAvLyBPYmplY3RcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1IDE1LjIuMy4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjIuMy4xNFxuXG4gICAgLy8gaHR0cDovL3doYXR0aGVoZWFkc2FpZC5jb20vMjAxMC8xMC9hLXNhZmVyLW9iamVjdC1rZXlzLWNvbXBhdGliaWxpdHktaW1wbGVtZW50YXRpb25cbiAgICB2YXIgaGFzRG9udEVudW1CdWcgPSAhaXNFbnVtKHsgJ3RvU3RyaW5nJzogbnVsbCB9LCAndG9TdHJpbmcnKTtcbiAgICB2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtKGZ1bmN0aW9uICgpIHt9LCAncHJvdG90eXBlJyk7XG4gICAgdmFyIGhhc1N0cmluZ0VudW1CdWcgPSAhb3ducygneCcsICcwJyk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgdmFyIGN0b3IgPSBvLmNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcbiAgICB9O1xuICAgIHZhciBibGFja2xpc3RlZEtleXMgPSB7XG4gICAgICAgICR3aW5kb3c6IHRydWUsXG4gICAgICAgICRjb25zb2xlOiB0cnVlLFxuICAgICAgICAkcGFyZW50OiB0cnVlLFxuICAgICAgICAkc2VsZjogdHJ1ZSxcbiAgICAgICAgJGZyYW1lOiB0cnVlLFxuICAgICAgICAkZnJhbWVzOiB0cnVlLFxuICAgICAgICAkZnJhbWVFbGVtZW50OiB0cnVlLFxuICAgICAgICAkd2Via2l0SW5kZXhlZERCOiB0cnVlLFxuICAgICAgICAkd2Via2l0U3RvcmFnZUluZm86IHRydWUsXG4gICAgICAgICRleHRlcm5hbDogdHJ1ZVxuICAgIH07XG4gICAgdmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8qIGdsb2JhbHMgd2luZG93ICovXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGsgaW4gd2luZG93KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghYmxhY2tsaXN0ZWRLZXlzWyckJyArIGtdICYmIG93bnMod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcpIHtcbiAgICAgICAgICAgIHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUob2JqZWN0KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgZG9udEVudW1zID0gW1xuICAgICAgICAndG9TdHJpbmcnLFxuICAgICAgICAndG9Mb2NhbGVTdHJpbmcnLFxuICAgICAgICAndmFsdWVPZicsXG4gICAgICAgICdoYXNPd25Qcm9wZXJ0eScsXG4gICAgICAgICdpc1Byb3RvdHlwZU9mJyxcbiAgICAgICAgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcbiAgICAgICAgJ2NvbnN0cnVjdG9yJ1xuICAgIF07XG4gICAgdmFyIGRvbnRFbnVtc0xlbmd0aCA9IGRvbnRFbnVtcy5sZW5ndGg7XG5cbiAgICAvLyB0YWtlbiBkaXJlY3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvaXMtYXJndW1lbnRzL2Jsb2IvbWFzdGVyL2luZGV4LmpzXG4gICAgLy8gY2FuIGJlIHJlcGxhY2VkIHdpdGggcmVxdWlyZSgnaXMtYXJndW1lbnRzJykgaWYgd2UgZXZlciB1c2UgYSBidWlsZCBwcm9jZXNzIGluc3RlYWRcbiAgICB2YXIgaXNTdGFuZGFyZEFyZ3VtZW50cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0b1N0cih2YWx1ZSkgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuICAgIH07XG4gICAgdmFyIGlzTGVnYWN5QXJndW1lbnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICAgdmFsdWUubGVuZ3RoID49IDAgJiZcbiAgICAgICAgICAgICFpc0FycmF5KHZhbHVlKSAmJlxuICAgICAgICAgICAgaXNDYWxsYWJsZSh2YWx1ZS5jYWxsZWUpO1xuICAgIH07XG4gICAgdmFyIGlzQXJndW1lbnRzID0gaXNTdGFuZGFyZEFyZ3VtZW50cyhhcmd1bWVudHMpID8gaXNTdGFuZGFyZEFyZ3VtZW50cyA6IGlzTGVnYWN5QXJndW1lbnRzO1xuXG4gICAgZGVmaW5lUHJvcGVydGllcygkT2JqZWN0LCB7XG4gICAgICAgIGtleXM6IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgaXNGbiA9IGlzQ2FsbGFibGUob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciBpc0FyZ3MgPSBpc0FyZ3VtZW50cyhvYmplY3QpO1xuICAgICAgICAgICAgdmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuICAgICAgICAgICAgdmFyIGlzU3RyID0gaXNPYmplY3QgJiYgaXNTdHJpbmcob2JqZWN0KTtcblxuICAgICAgICAgICAgaWYgKCFpc09iamVjdCAmJiAhaXNGbiAmJiAhaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgdGhlS2V5cyA9IFtdO1xuICAgICAgICAgICAgdmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0ZuO1xuICAgICAgICAgICAgaWYgKChpc1N0ciAmJiBoYXNTdHJpbmdFbnVtQnVnKSB8fCBpc0FyZ3MpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbCh0aGVLZXlzLCAkU3RyaW5nKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBvd25zKG9iamVjdCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHRoZUtleXMsICRTdHJpbmcobmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGFzRG9udEVudW1CdWcpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2tpcENvbnN0cnVjdG9yID0gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5KG9iamVjdCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBkb250RW51bXNMZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZG9udEVudW0gPSBkb250RW51bXNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmICghKHNraXBDb25zdHJ1Y3RvciAmJiBkb250RW51bSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgb3ducyhvYmplY3QsIGRvbnRFbnVtKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwodGhlS2V5cywgZG9udEVudW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoZUtleXM7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBrZXlzV29ya3NXaXRoQXJndW1lbnRzID0gJE9iamVjdC5rZXlzICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnXG4gICAgICAgIHJldHVybiAkT2JqZWN0LmtleXMoYXJndW1lbnRzKS5sZW5ndGggPT09IDI7XG4gICAgfSgxLCAyKSk7XG4gICAgdmFyIGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcgPSAkT2JqZWN0LmtleXMgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ0tleXMgPSAkT2JqZWN0LmtleXMoYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5c1swXSAhPT0gMTtcbiAgICB9KDEpKTtcbiAgICB2YXIgb3JpZ2luYWxLZXlzID0gJE9iamVjdC5rZXlzO1xuICAgIGRlZmluZVByb3BlcnRpZXMoJE9iamVjdCwge1xuICAgICAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKGlzQXJndW1lbnRzKG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxLZXlzKGFycmF5U2xpY2Uob2JqZWN0KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEtleXMob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sICFrZXlzV29ya3NXaXRoQXJndW1lbnRzIHx8IGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcpO1xuXG4gICAgLy9cbiAgICAvLyBEYXRlXG4gICAgLy8gPT09PVxuICAgIC8vXG5cbiAgICB2YXIgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgPSBuZXcgRGF0ZSgtMzUwOTgyNzMyOTYwMDI5MikuZ2V0VVRDTW9udGgoKSAhPT0gMDtcbiAgICB2YXIgYU5lZ2F0aXZlVGVzdERhdGUgPSBuZXcgRGF0ZSgtMTUwOTg0MjI4OTYwMDI5Mik7XG4gICAgdmFyIGFQb3NpdGl2ZVRlc3REYXRlID0gbmV3IERhdGUoMTQ0OTY2MjQwMDAwMCk7XG4gICAgdmFyIGhhc1RvVVRDU3RyaW5nRm9ybWF0QnVnID0gYU5lZ2F0aXZlVGVzdERhdGUudG9VVENTdHJpbmcoKSAhPT0gJ01vbiwgMDEgSmFuIC00NTg3NSAxMTo1OTo1OSBHTVQnO1xuICAgIHZhciBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWc7XG4gICAgdmFyIGhhc1RvU3RyaW5nRm9ybWF0QnVnO1xuICAgIHZhciB0aW1lWm9uZU9mZnNldCA9IGFOZWdhdGl2ZVRlc3REYXRlLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgaWYgKHRpbWVab25lT2Zmc2V0IDwgLTcyMCkge1xuICAgICAgICBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWcgPSBhTmVnYXRpdmVUZXN0RGF0ZS50b0RhdGVTdHJpbmcoKSAhPT0gJ1R1ZSBKYW4gMDIgLTQ1ODc1JztcbiAgICAgICAgaGFzVG9TdHJpbmdGb3JtYXRCdWcgPSAhKC9eVGh1IERlYyAxMCAyMDE1IFxcZFxcZDpcXGRcXGQ6XFxkXFxkIEdNVFstXFwrXVxcZFxcZFxcZFxcZCg/OiB8JCkvKS50ZXN0KGFQb3NpdGl2ZVRlc3REYXRlLnRvU3RyaW5nKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1ZyA9IGFOZWdhdGl2ZVRlc3REYXRlLnRvRGF0ZVN0cmluZygpICE9PSAnTW9uIEphbiAwMSAtNDU4NzUnO1xuICAgICAgICBoYXNUb1N0cmluZ0Zvcm1hdEJ1ZyA9ICEoL15XZWQgRGVjIDA5IDIwMTUgXFxkXFxkOlxcZFxcZDpcXGRcXGQgR01UWy1cXCtdXFxkXFxkXFxkXFxkKD86IHwkKS8pLnRlc3QoYVBvc2l0aXZlVGVzdERhdGUudG9TdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgdmFyIG9yaWdpbmFsR2V0RnVsbFllYXIgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0RnVsbFllYXIpO1xuICAgIHZhciBvcmlnaW5hbEdldE1vbnRoID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldE1vbnRoKTtcbiAgICB2YXIgb3JpZ2luYWxHZXREYXRlID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldERhdGUpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0Z1bGxZZWFyKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENNb250aCA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNb250aCk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDRGF0ZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENEYXRlKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENEYXkgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDRGF5KTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENIb3VycyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENIb3Vycyk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDTWludXRlcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaW51dGVzKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENTZWNvbmRzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ1NlY29uZHMpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ01pbGxpc2Vjb25kcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaWxsaXNlY29uZHMpO1xuICAgIHZhciBkYXlOYW1lID0gWydTdW4nLCAnTW9uJywgJ1R1ZScsICdXZWQnLCAnVGh1JywgJ0ZyaScsICdTYXQnXTtcbiAgICB2YXIgbW9udGhOYW1lID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgIHZhciBkYXlzSW5Nb250aCA9IGZ1bmN0aW9uIGRheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKSB7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbEdldERhdGUobmV3IERhdGUoeWVhciwgbW9udGgsIDApKTtcbiAgICB9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICBnZXRGdWxsWWVhcjogZnVuY3Rpb24gZ2V0RnVsbFllYXIoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG9yaWdpbmFsR2V0TW9udGgodGhpcykgPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB5ZWFyICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB5ZWFyO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNb250aDogZnVuY3Rpb24gZ2V0TW9udGgoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbW9udGg7XG4gICAgICAgIH0sXG4gICAgICAgIGdldERhdGU6IGZ1bmN0aW9uIGdldERhdGUoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gb3JpZ2luYWxHZXREYXRlKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICBpZiAobW9udGggPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZGF5cyA9IGRheXNJbk1vbnRoKDAsIHllYXIgKyAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGRheXMgLSBkYXRlKSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDRnVsbFllYXI6IGZ1bmN0aW9uIGdldFVUQ0Z1bGxZZWFyKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWVhciArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geWVhcjtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDTW9udGg6IGZ1bmN0aW9uIGdldFVUQ01vbnRoKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1vbnRoO1xuICAgICAgICB9LFxuICAgICAgICBnZXRVVENEYXRlOiBmdW5jdGlvbiBnZXRVVENEYXRlKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1vbnRoID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRheXMgPSBkYXlzSW5Nb250aCgwLCB5ZWFyICsgMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChkYXlzIC0gZGF0ZSkgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1Zyk7XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIHRvVVRDU3RyaW5nOiBmdW5jdGlvbiB0b1VUQ1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGF5ID0gb3JpZ2luYWxHZXRVVENEYXkodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyk7XG4gICAgICAgICAgICB2YXIgbWludXRlID0gb3JpZ2luYWxHZXRVVENNaW51dGVzKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlY29uZCA9IG9yaWdpbmFsR2V0VVRDU2Vjb25kcyh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnLCAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyICsgJyAnICtcbiAgICAgICAgICAgICAgICAoaG91ciA8IDEwID8gJzAnICsgaG91ciA6IGhvdXIpICsgJzonICtcbiAgICAgICAgICAgICAgICAobWludXRlIDwgMTAgPyAnMCcgKyBtaW51dGUgOiBtaW51dGUpICsgJzonICtcbiAgICAgICAgICAgICAgICAoc2Vjb25kIDwgMTAgPyAnMCcgKyBzZWNvbmQgOiBzZWNvbmQpICsgJyBHTVQnO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9VVENTdHJpbmdGb3JtYXRCdWcpO1xuXG4gICAgLy8gT3BlcmEgMTIgaGFzIGAsYFxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9EYXRlU3RyaW5nOiBmdW5jdGlvbiB0b0RhdGVTdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICByZXR1cm4gZGF5TmFtZVtkYXldICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnKTtcblxuICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgaWYgKGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnIHx8IGhhc1RvU3RyaW5nRm9ybWF0QnVnKSB7XG4gICAgICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IHRoaXMuZ2V0SG91cnMoKTtcbiAgICAgICAgICAgIHZhciBtaW51dGUgPSB0aGlzLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgICAgIHZhciBzZWNvbmQgPSB0aGlzLmdldFNlY29uZHMoKTtcbiAgICAgICAgICAgIHZhciB0aW1lem9uZU9mZnNldCA9IHRoaXMuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICAgICAgICAgIHZhciBob3Vyc09mZnNldCA9IE1hdGguZmxvb3IoTWF0aC5hYnModGltZXpvbmVPZmZzZXQpIC8gNjApO1xuICAgICAgICAgICAgdmFyIG1pbnV0ZXNPZmZzZXQgPSBNYXRoLmZsb29yKE1hdGguYWJzKHRpbWV6b25lT2Zmc2V0KSAlIDYwKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnICcgK1xuICAgICAgICAgICAgICAgIG1vbnRoTmFtZVttb250aF0gKyAnICcgK1xuICAgICAgICAgICAgICAgIChkYXRlIDwgMTAgPyAnMCcgKyBkYXRlIDogZGF0ZSkgKyAnICcgK1xuICAgICAgICAgICAgICAgIHllYXIgKyAnICcgK1xuICAgICAgICAgICAgICAgIChob3VyIDwgMTAgPyAnMCcgKyBob3VyIDogaG91cikgKyAnOicgK1xuICAgICAgICAgICAgICAgIChtaW51dGUgPCAxMCA/ICcwJyArIG1pbnV0ZSA6IG1pbnV0ZSkgKyAnOicgK1xuICAgICAgICAgICAgICAgIChzZWNvbmQgPCAxMCA/ICcwJyArIHNlY29uZCA6IHNlY29uZCkgKyAnIEdNVCcgK1xuICAgICAgICAgICAgICAgICh0aW1lem9uZU9mZnNldCA+IDAgPyAnLScgOiAnKycpICtcbiAgICAgICAgICAgICAgICAoaG91cnNPZmZzZXQgPCAxMCA/ICcwJyArIGhvdXJzT2Zmc2V0IDogaG91cnNPZmZzZXQpICtcbiAgICAgICAgICAgICAgICAobWludXRlc09mZnNldCA8IDEwID8gJzAnICsgbWludXRlc09mZnNldCA6IG1pbnV0ZXNPZmZzZXQpO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRlLnByb3RvdHlwZSwgJ3RvU3RyaW5nJywge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS41LjQzXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS41LjQzXG4gICAgLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgU3RyaW5nIHZhbHVlIHJlcHJlc2VudCB0aGUgaW5zdGFuY2UgaW4gdGltZVxuICAgIC8vIHJlcHJlc2VudGVkIGJ5IHRoaXMgRGF0ZSBvYmplY3QuIFRoZSBmb3JtYXQgb2YgdGhlIFN0cmluZyBpcyB0aGUgRGF0ZSBUaW1lXG4gICAgLy8gc3RyaW5nIGZvcm1hdCBkZWZpbmVkIGluIDE1LjkuMS4xNS4gQWxsIGZpZWxkcyBhcmUgcHJlc2VudCBpbiB0aGUgU3RyaW5nLlxuICAgIC8vIFRoZSB0aW1lIHpvbmUgaXMgYWx3YXlzIFVUQywgZGVub3RlZCBieSB0aGUgc3VmZml4IFouIElmIHRoZSB0aW1lIHZhbHVlIG9mXG4gICAgLy8gdGhpcyBvYmplY3QgaXMgbm90IGEgZmluaXRlIE51bWJlciBhIFJhbmdlRXJyb3IgZXhjZXB0aW9uIGlzIHRocm93bi5cbiAgICB2YXIgbmVnYXRpdmVEYXRlID0gLTYyMTk4NzU1MjAwMDAwO1xuICAgIHZhciBuZWdhdGl2ZVllYXJTdHJpbmcgPSAnLTAwMDAwMSc7XG4gICAgdmFyIGhhc05lZ2F0aXZlRGF0ZUJ1ZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICYmIG5ldyBEYXRlKG5lZ2F0aXZlRGF0ZSkudG9JU09TdHJpbmcoKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgPT09IC0xO1xuICAgIHZhciBoYXNTYWZhcmk1MURhdGVCdWcgPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAmJiBuZXcgRGF0ZSgtMSkudG9JU09TdHJpbmcoKSAhPT0gJzE5NjktMTItMzFUMjM6NTk6NTkuOTk5Wic7XG5cbiAgICB2YXIgZ2V0VGltZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRUaW1lKTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCFpc0Zpbml0ZSh0aGlzKSB8fCAhaXNGaW5pdGUoZ2V0VGltZSh0aGlzKSkpIHtcbiAgICAgICAgICAgICAgICAvLyBBZG9wZSBQaG90b3Nob3AgcmVxdWlyZXMgdGhlIHNlY29uZCBjaGVjay5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgY2FsbGVkIG9uIG5vbi1maW5pdGUgdmFsdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzExMVxuICAgICAgICAgICAgeWVhciArPSBNYXRoLmZsb29yKG1vbnRoIC8gMTIpO1xuICAgICAgICAgICAgbW9udGggPSAobW9udGggJSAxMiArIDEyKSAlIDEyO1xuXG4gICAgICAgICAgICAvLyB0aGUgZGF0ZSB0aW1lIHN0cmluZyBmb3JtYXQgaXMgc3BlY2lmaWVkIGluIDE1LjkuMS4xNS5cbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbbW9udGggKyAxLCBvcmlnaW5hbEdldFVUQ0RhdGUodGhpcyksIG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyksIG9yaWdpbmFsR2V0VVRDTWludXRlcyh0aGlzKSwgb3JpZ2luYWxHZXRVVENTZWNvbmRzKHRoaXMpXTtcbiAgICAgICAgICAgIHllYXIgPSAoXG4gICAgICAgICAgICAgICAgKHllYXIgPCAwID8gJy0nIDogKHllYXIgPiA5OTk5ID8gJysnIDogJycpKSArXG4gICAgICAgICAgICAgICAgc3RyU2xpY2UoJzAwMDAwJyArIE1hdGguYWJzKHllYXIpLCAoMCA8PSB5ZWFyICYmIHllYXIgPD0gOTk5OSkgPyAtNCA6IC02KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAvLyBwYWQgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgdG8gaGF2ZSB0d28gZGlnaXRzLlxuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IHN0clNsaWNlKCcwMCcgKyByZXN1bHRbaV0sIC0yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHBhZCBtaWxsaXNlY29uZHMgdG8gaGF2ZSB0aHJlZSBkaWdpdHMuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHllYXIgKyAnLScgKyBhcnJheVNsaWNlKHJlc3VsdCwgMCwgMikuam9pbignLScpICtcbiAgICAgICAgICAgICAgICAnVCcgKyBhcnJheVNsaWNlKHJlc3VsdCwgMikuam9pbignOicpICsgJy4nICtcbiAgICAgICAgICAgICAgICBzdHJTbGljZSgnMDAwJyArIG9yaWdpbmFsR2V0VVRDTWlsbGlzZWNvbmRzKHRoaXMpLCAtMykgKyAnWidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZURhdGVCdWcgfHwgaGFzU2FmYXJpNTFEYXRlQnVnKTtcblxuICAgIC8vIEVTNSAxNS45LjUuNDRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjUuNDRcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgRGF0ZSBvYmplY3QgZm9yIHVzZSBieVxuICAgIC8vIEpTT04uc3RyaW5naWZ5ICgxNS4xMi4zKS5cbiAgICB2YXIgZGF0ZVRvSlNPTklzU3VwcG9ydGVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBEYXRlLnByb3RvdHlwZS50b0pTT04gJiZcbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShOYU4pLnRvSlNPTigpID09PSBudWxsICYmXG4gICAgICAgICAgICAgICAgbmV3IERhdGUobmVnYXRpdmVEYXRlKS50b0pTT04oKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgIT09IC0xICYmXG4gICAgICAgICAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyAvLyBnZW5lcmljXG4gICAgICAgICAgICAgICAgICAgIHRvSVNPU3RyaW5nOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgaWYgKCFkYXRlVG9KU09OSXNTdXBwb3J0ZWQpIHtcbiAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgICAgICAgICAgLy8gV2hlbiB0aGUgdG9KU09OIG1ldGhvZCBpcyBjYWxsZWQgd2l0aCBhcmd1bWVudCBrZXksIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgIC8vIHN0ZXBzIGFyZSB0YWtlbjpcblxuICAgICAgICAgICAgLy8gMS4gIExldCBPIGJlIHRoZSByZXN1bHQgb2YgY2FsbGluZyBUb09iamVjdCwgZ2l2aW5nIGl0IHRoZSB0aGlzXG4gICAgICAgICAgICAvLyB2YWx1ZSBhcyBpdHMgYXJndW1lbnQuXG4gICAgICAgICAgICAvLyAyLiBMZXQgdHYgYmUgRVMuVG9QcmltaXRpdmUoTywgaGludCBOdW1iZXIpLlxuICAgICAgICAgICAgdmFyIE8gPSAkT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHR2ID0gRVMuVG9QcmltaXRpdmUoTyk7XG4gICAgICAgICAgICAvLyAzLiBJZiB0diBpcyBhIE51bWJlciBhbmQgaXMgbm90IGZpbml0ZSwgcmV0dXJuIG51bGwuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHR2ID09PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUodHYpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyA0LiBMZXQgdG9JU08gYmUgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0dldF1dIGludGVybmFsIG1ldGhvZCBvZlxuICAgICAgICAgICAgLy8gTyB3aXRoIGFyZ3VtZW50IFwidG9JU09TdHJpbmdcIi5cbiAgICAgICAgICAgIHZhciB0b0lTTyA9IE8udG9JU09TdHJpbmc7XG4gICAgICAgICAgICAvLyA1LiBJZiBJc0NhbGxhYmxlKHRvSVNPKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKHRvSVNPKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RvSVNPU3RyaW5nIHByb3BlcnR5IGlzIG5vdCBjYWxsYWJsZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gNi4gUmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kIG9mXG4gICAgICAgICAgICAvLyAgdG9JU08gd2l0aCBPIGFzIHRoZSB0aGlzIHZhbHVlIGFuZCBhbiBlbXB0eSBhcmd1bWVudCBsaXN0LlxuICAgICAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoTyk7XG5cbiAgICAgICAgICAgIC8vIE5PVEUgMSBUaGUgYXJndW1lbnQgaXMgaWdub3JlZC5cblxuICAgICAgICAgICAgLy8gTk9URSAyIFRoZSB0b0pTT04gZnVuY3Rpb24gaXMgaW50ZW50aW9uYWxseSBnZW5lcmljOyBpdCBkb2VzIG5vdFxuICAgICAgICAgICAgLy8gcmVxdWlyZSB0aGF0IGl0cyB0aGlzIHZhbHVlIGJlIGEgRGF0ZSBvYmplY3QuIFRoZXJlZm9yZSwgaXQgY2FuIGJlXG4gICAgICAgICAgICAvLyB0cmFuc2ZlcnJlZCB0byBvdGhlciBraW5kcyBvZiBvYmplY3RzIGZvciB1c2UgYXMgYSBtZXRob2QuIEhvd2V2ZXIsXG4gICAgICAgICAgICAvLyBpdCBkb2VzIHJlcXVpcmUgdGhhdCBhbnkgc3VjaCBvYmplY3QgaGF2ZSBhIHRvSVNPU3RyaW5nIG1ldGhvZC4gQW5cbiAgICAgICAgICAgIC8vIG9iamVjdCBpcyBmcmVlIHRvIHVzZSB0aGUgYXJndW1lbnQga2V5IHRvIGZpbHRlciBpdHNcbiAgICAgICAgICAgIC8vIHN0cmluZ2lmaWNhdGlvbi5cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuMlxuICAgIC8vIGJhc2VkIG9uIHdvcmsgc2hhcmVkIGJ5IERhbmllbCBGcmllc2VuIChkYW50bWFuKVxuICAgIC8vIGh0dHA6Ly9naXN0LmdpdGh1Yi5jb20vMzAzMjQ5XG4gICAgdmFyIHN1cHBvcnRzRXh0ZW5kZWRZZWFycyA9IERhdGUucGFyc2UoJyswMzM2NTgtMDktMjdUMDE6NDY6NDAuMDAwWicpID09PSAxZTE1O1xuICAgIHZhciBhY2NlcHRzSW52YWxpZERhdGVzID0gIWlzTmFOKERhdGUucGFyc2UoJzIwMTItMDQtMDRUMjQ6MDA6MDAuNTAwWicpKSB8fCAhaXNOYU4oRGF0ZS5wYXJzZSgnMjAxMi0xMS0zMVQyMzo1OTo1OS4wMDBaJykpIHx8ICFpc05hTihEYXRlLnBhcnNlKCcyMDEyLTEyLTMxVDIzOjU5OjYwLjAwMFonKSk7XG4gICAgdmFyIGRvZXNOb3RQYXJzZVkyS05ld1llYXIgPSBpc05hTihEYXRlLnBhcnNlKCcyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFonKSk7XG4gICAgaWYgKGRvZXNOb3RQYXJzZVkyS05ld1llYXIgfHwgYWNjZXB0c0ludmFsaWREYXRlcyB8fCAhc3VwcG9ydHNFeHRlbmRlZFllYXJzKSB7XG4gICAgICAgIC8vIFhYWCBnbG9iYWwgYXNzaWdubWVudCB3b24ndCB3b3JrIGluIGVtYmVkZGluZ3MgdGhhdCB1c2VcbiAgICAgICAgLy8gYW4gYWx0ZXJuYXRlIG9iamVjdCBmb3IgdGhlIGNvbnRleHQuXG4gICAgICAgIC8qIGdsb2JhbCBEYXRlOiB0cnVlICovXG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgIHZhciBtYXhTYWZlVW5zaWduZWQzMkJpdCA9IE1hdGgucG93KDIsIDMxKSAtIDE7XG4gICAgICAgIHZhciBoYXNTYWZhcmlTaWduZWRJbnRCdWcgPSBpc0FjdHVhbE5hTihuZXcgRGF0ZSgxOTcwLCAwLCAxLCAwLCAwLCAwLCBtYXhTYWZlVW5zaWduZWQzMkJpdCArIDEpLmdldFRpbWUoKSk7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgRGF0ZSA9IChmdW5jdGlvbiAoTmF0aXZlRGF0ZSkge1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgLy8gRGF0ZS5sZW5ndGggPT09IDdcbiAgICAgICAgICAgIHZhciBEYXRlU2hpbSA9IGZ1bmN0aW9uIERhdGUoWSwgTSwgRCwgaCwgbSwgcywgbXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIE5hdGl2ZURhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlY29uZHMgPSBzO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWlsbGlzID0gbXM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNTYWZhcmlTaWduZWRJbnRCdWcgJiYgbGVuZ3RoID49IDcgJiYgbXMgPiBtYXhTYWZlVW5zaWduZWQzMkJpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtcyAvIG1heFNhZmVVbnNpZ25lZDMyQml0KSAqIG1heFNhZmVVbnNpZ25lZDMyQml0O1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtc1RvU2hpZnQgLyAxZTMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbGxpcyAtPSBzVG9TaGlmdCAqIDFlMztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkYXRlID0gbGVuZ3RoID09PSAxICYmICRTdHJpbmcoWSkgPT09IFkgPyAvLyBpc1N0cmluZyhZKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgZXhwbGljaXRseSBwYXNzIGl0IHRocm91Z2ggcGFyc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZShEYXRlU2hpbS5wYXJzZShZKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBtYW51YWxseSBtYWtlIGNhbGxzIGRlcGVuZGluZyBvbiBhcmd1bWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGVuZ3RoIGhlcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA3ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSwgc2Vjb25kcywgbWlsbGlzKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNiA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgsIG0sIHNlY29uZHMpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA1ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDQgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gMyA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSAyID8gbmV3IE5hdGl2ZURhdGUoWSwgTSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDEgPyBuZXcgTmF0aXZlRGF0ZShZIGluc3RhbmNlb2YgTmF0aXZlRGF0ZSA/ICtZIDogWSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGUgPSBOYXRpdmVEYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghaXNQcmltaXRpdmUoZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJldmVudCBtaXh1cHMgd2l0aCB1bmZpeGVkIERhdGUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoZGF0ZSwgeyBjb25zdHJ1Y3RvcjogRGF0ZVNoaW0gfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuOS4xLjE1IERhdGUgVGltZSBTdHJpbmcgRm9ybWF0LlxuICAgICAgICAgICAgdmFyIGlzb0RhdGVFeHByZXNzaW9uID0gbmV3IFJlZ0V4cCgnXicgK1xuICAgICAgICAgICAgICAgICcoXFxcXGR7NH18WystXVxcXFxkezZ9KScgKyAvLyBmb3VyLWRpZ2l0IHllYXIgY2FwdHVyZSBvciBzaWduICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYtZGlnaXQgZXh0ZW5kZWQgeWVhclxuICAgICAgICAgICAgICAgICcoPzotKFxcXFxkezJ9KScgKyAvLyBvcHRpb25hbCBtb250aCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/Oi0oXFxcXGR7Mn0pJyArIC8vIG9wdGlvbmFsIGRheSBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/OicgKyAvLyBjYXB0dXJlIGhvdXJzOm1pbnV0ZXM6c2Vjb25kcy5taWxsaXNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgJ1QoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIG1pbnV0ZXMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9wdGlvbmFsIDpzZWNvbmRzLm1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIHNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OihcXFxcLlxcXFxkezEsfSkpPycgKyAvLyBtaWxsaXNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKT8nICtcbiAgICAgICAgICAgICAgICAnKCcgKyAvLyBjYXB0dXJlIFVUQyBvZmZzZXQgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICdafCcgKyAvLyBVVEMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9mZnNldCBzcGVjaWZpZXIgKy8taG91cnM6bWludXRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgJyhbLStdKScgKyAvLyBzaWduIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgICAgICcoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIG9mZnNldCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAnOihcXFxcZHsyfSknICsgLy8gbWludXRlcyBvZmZzZXQgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKScgK1xuICAgICAgICAgICAgICAgICcpPyk/KT8pPycgK1xuICAgICAgICAgICAgJyQnKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNCwgMzY1XTtcblxuICAgICAgICAgICAgdmFyIGRheUZyb21Nb250aCA9IGZ1bmN0aW9uIGRheUZyb21Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICAgICAgICAgIHZhciB0ID0gbW9udGggPiAxID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgbW9udGhzW21vbnRoXSArXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTY5ICsgdCkgLyA0KSAtXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTAxICsgdCkgLyAxMDApICtcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDE2MDEgKyB0KSAvIDQwMCkgK1xuICAgICAgICAgICAgICAgICAgICAzNjUgKiAoeWVhciAtIDE5NzApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciB0b1VUQyA9IGZ1bmN0aW9uIHRvVVRDKHQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcyA9IDA7XG4gICAgICAgICAgICAgICAgdmFyIG1zID0gdDtcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2FmYXJpU2lnbmVkSW50QnVnICYmIG1zID4gbWF4U2FmZVVuc2lnbmVkMzJCaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgIHZhciBtc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zIC8gbWF4U2FmZVVuc2lnbmVkMzJCaXQpICogbWF4U2FmZVVuc2lnbmVkMzJCaXQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzVG9TaGlmdCA9IE1hdGguZmxvb3IobXNUb1NoaWZ0IC8gMWUzKTtcbiAgICAgICAgICAgICAgICAgICAgcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgbXMgLT0gc1RvU2hpZnQgKiAxZTM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiAkTnVtYmVyKG5ldyBOYXRpdmVEYXRlKDE5NzAsIDAsIDEsIDAsIDAsIHMsIG1zKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBDb3B5IGFueSBjdXN0b20gbWV0aG9kcyBhIDNyZCBwYXJ0eSBsaWJyYXJ5IG1heSBoYXZlIGFkZGVkXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gTmF0aXZlRGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChvd25zKE5hdGl2ZURhdGUsIGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgRGF0ZVNoaW1ba2V5XSA9IE5hdGl2ZURhdGVba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENvcHkgXCJuYXRpdmVcIiBtZXRob2RzIGV4cGxpY2l0bHk7IHRoZXkgbWF5IGJlIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGVTaGltLCB7XG4gICAgICAgICAgICAgICAgbm93OiBOYXRpdmVEYXRlLm5vdyxcbiAgICAgICAgICAgICAgICBVVEM6IE5hdGl2ZURhdGUuVVRDXG4gICAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgICAgIERhdGVTaGltLnByb3RvdHlwZSA9IE5hdGl2ZURhdGUucHJvdG90eXBlO1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogRGF0ZVNoaW1cbiAgICAgICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgICAgICAvLyBVcGdyYWRlIERhdGUucGFyc2UgdG8gaGFuZGxlIHNpbXBsaWZpZWQgSVNPIDg2MDEgc3RyaW5nc1xuICAgICAgICAgICAgdmFyIHBhcnNlU2hpbSA9IGZ1bmN0aW9uIHBhcnNlKHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGlzb0RhdGVFeHByZXNzaW9uLmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAvLyBwcm92aWRlIGRlZmF1bHQgdmFsdWVzIGlmIG5lY2Vzc2FyeVxuICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZSB0aGUgVVRDIG9mZnNldCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgdmFyIHllYXIgPSAkTnVtYmVyKG1hdGNoWzFdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID0gJE51bWJlcihtYXRjaFsyXSB8fCAxKSAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPSAkTnVtYmVyKG1hdGNoWzNdIHx8IDEpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIgPSAkTnVtYmVyKG1hdGNoWzRdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlID0gJE51bWJlcihtYXRjaFs1XSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZCA9ICROdW1iZXIobWF0Y2hbNl0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZCA9IE1hdGguZmxvb3IoJE51bWJlcihtYXRjaFs3XSB8fCAwKSAqIDEwMDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aW1lIHpvbmUgaXMgbWlzc2VkLCBsb2NhbCBvZmZzZXQgc2hvdWxkIGJlIHVzZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIChFUyA1LjEgYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vYnVncy5lY21hc2NyaXB0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTEyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0xvY2FsVGltZSA9IEJvb2xlYW4obWF0Y2hbNF0gJiYgIW1hdGNoWzhdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25PZmZzZXQgPSBtYXRjaFs5XSA9PT0gJy0nID8gMSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCA9ICROdW1iZXIobWF0Y2hbMTBdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2Zmc2V0ID0gJE51bWJlcihtYXRjaFsxMV0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoYXNNaW51dGVzT3JTZWNvbmRzT3JNaWxsaXNlY29uZHMgPSBtaW51dGUgPiAwIHx8IHNlY29uZCA+IDAgfHwgbWlsbGlzZWNvbmQgPiAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBob3VyIDwgKGhhc01pbnV0ZXNPclNlY29uZHNPck1pbGxpc2Vjb25kcyA/IDI0IDogMjUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUgPCA2MCAmJiBzZWNvbmQgPCA2MCAmJiBtaWxsaXNlY29uZCA8IDEwMDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID4gLTEgJiYgbW9udGggPCAxMiAmJiBob3VyT2Zmc2V0IDwgMjQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mZnNldCA8IDYwICYmIC8vIGRldGVjdCBpbnZhbGlkIG9mZnNldHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheSA+IC0xICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPCAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoICsgMSkgLSBkYXlGcm9tTW9udGgoeWVhciwgbW9udGgpKVxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoKSArIGRheSkgKiAyNCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ciArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCAqIHNpZ25PZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgICkgKiA2MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVzdWx0ICsgbWludXRlICsgbWludXRlT2Zmc2V0ICogc2lnbk9mZnNldCkgKiA2MCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kXG4gICAgICAgICAgICAgICAgICAgICAgICApICogMTAwMCArIG1pbGxpc2Vjb25kO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTG9jYWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdG9VVEMocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtOC42NGUxNSA8PSByZXN1bHQgJiYgcmVzdWx0IDw9IDguNjRlMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBOYXRpdmVEYXRlLnBhcnNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbSwgeyBwYXJzZTogcGFyc2VTaGltIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gRGF0ZVNoaW07XG4gICAgICAgIH0oRGF0ZSkpO1xuICAgICAgICAvKiBnbG9iYWwgRGF0ZTogZmFsc2UgKi9cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuNFxuICAgIGlmICghRGF0ZS5ub3cpIHtcbiAgICAgICAgRGF0ZS5ub3cgPSBmdW5jdGlvbiBub3coKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBOdW1iZXJcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1LjEgMTUuNy40LjVcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS43LjQuNVxuICAgIHZhciBoYXNUb0ZpeGVkQnVncyA9IE51bWJlclByb3RvdHlwZS50b0ZpeGVkICYmIChcbiAgICAgICgwLjAwMDA4KS50b0ZpeGVkKDMpICE9PSAnMC4wMDAnIHx8XG4gICAgICAoMC45KS50b0ZpeGVkKDApICE9PSAnMScgfHxcbiAgICAgICgxLjI1NSkudG9GaXhlZCgyKSAhPT0gJzEuMjUnIHx8XG4gICAgICAoMTAwMDAwMDAwMDAwMDAwMDEyOCkudG9GaXhlZCgwKSAhPT0gJzEwMDAwMDAwMDAwMDAwMDAxMjgnXG4gICAgKTtcblxuICAgIHZhciB0b0ZpeGVkSGVscGVycyA9IHtcbiAgICAgICAgYmFzZTogMWU3LFxuICAgICAgICBzaXplOiA2LFxuICAgICAgICBkYXRhOiBbMCwgMCwgMCwgMCwgMCwgMF0sXG4gICAgICAgIG11bHRpcGx5OiBmdW5jdGlvbiBtdWx0aXBseShuLCBjKSB7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGMyID0gYztcbiAgICAgICAgICAgIHdoaWxlICgrK2kgPCB0b0ZpeGVkSGVscGVycy5zaXplKSB7XG4gICAgICAgICAgICAgICAgYzIgKz0gbiAqIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV07XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGF0YVtpXSA9IGMyICUgdG9GaXhlZEhlbHBlcnMuYmFzZTtcbiAgICAgICAgICAgICAgICBjMiA9IE1hdGguZmxvb3IoYzIgLyB0b0ZpeGVkSGVscGVycy5iYXNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZGl2aWRlOiBmdW5jdGlvbiBkaXZpZGUobikge1xuICAgICAgICAgICAgdmFyIGkgPSB0b0ZpeGVkSGVscGVycy5zaXplO1xuICAgICAgICAgICAgdmFyIGMgPSAwO1xuICAgICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgYyArPSB0b0ZpeGVkSGVscGVycy5kYXRhW2ldO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0gPSBNYXRoLmZsb29yKGMgLyBuKTtcbiAgICAgICAgICAgICAgICBjID0gKGMgJSBuKSAqIHRvRml4ZWRIZWxwZXJzLmJhc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG51bVRvU3RyaW5nOiBmdW5jdGlvbiBudW1Ub1N0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBpID0gdG9GaXhlZEhlbHBlcnMuc2l6ZTtcbiAgICAgICAgICAgIHZhciBzID0gJyc7XG4gICAgICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocyAhPT0gJycgfHwgaSA9PT0gMCB8fCB0b0ZpeGVkSGVscGVycy5kYXRhW2ldICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0ID0gJFN0cmluZyh0b0ZpeGVkSGVscGVycy5kYXRhW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzID0gdDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gc3RyU2xpY2UoJzAwMDAwMDAnLCAwLCA3IC0gdC5sZW5ndGgpICsgdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzO1xuICAgICAgICB9LFxuICAgICAgICBwb3c6IGZ1bmN0aW9uIHBvdyh4LCBuLCBhY2MpIHtcbiAgICAgICAgICAgIHJldHVybiAobiA9PT0gMCA/IGFjYyA6IChuICUgMiA9PT0gMSA/IHBvdyh4LCBuIC0gMSwgYWNjICogeCkgOiBwb3coeCAqIHgsIG4gLyAyLCBhY2MpKSk7XG4gICAgICAgIH0sXG4gICAgICAgIGxvZzogZnVuY3Rpb24gbG9nKHgpIHtcbiAgICAgICAgICAgIHZhciBuID0gMDtcbiAgICAgICAgICAgIHZhciB4MiA9IHg7XG4gICAgICAgICAgICB3aGlsZSAoeDIgPj0gNDA5Nikge1xuICAgICAgICAgICAgICAgIG4gKz0gMTI7XG4gICAgICAgICAgICAgICAgeDIgLz0gNDA5NjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdoaWxlICh4MiA+PSAyKSB7XG4gICAgICAgICAgICAgICAgbiArPSAxO1xuICAgICAgICAgICAgICAgIHgyIC89IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgdG9GaXhlZFNoaW0gPSBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgICAgIHZhciBmLCB4LCBzLCBtLCBlLCB6LCBqLCBrO1xuXG4gICAgICAgIC8vIFRlc3QgZm9yIE5hTiBhbmQgcm91bmQgZnJhY3Rpb25EaWdpdHMgZG93blxuICAgICAgICBmID0gJE51bWJlcihmcmFjdGlvbkRpZ2l0cyk7XG4gICAgICAgIGYgPSBpc0FjdHVhbE5hTihmKSA/IDAgOiBNYXRoLmZsb29yKGYpO1xuXG4gICAgICAgIGlmIChmIDwgMCB8fCBmID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdOdW1iZXIudG9GaXhlZCBjYWxsZWQgd2l0aCBpbnZhbGlkIG51bWJlciBvZiBkZWNpbWFscycpO1xuICAgICAgICB9XG5cbiAgICAgICAgeCA9ICROdW1iZXIodGhpcyk7XG5cbiAgICAgICAgaWYgKGlzQWN0dWFsTmFOKHgpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ05hTic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBpdCBpcyB0b28gYmlnIG9yIHNtYWxsLCByZXR1cm4gdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyXG4gICAgICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkge1xuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcoeCk7XG4gICAgICAgIH1cblxuICAgICAgICBzID0gJyc7XG5cbiAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICBzID0gJy0nO1xuICAgICAgICAgICAgeCA9IC14O1xuICAgICAgICB9XG5cbiAgICAgICAgbSA9ICcwJztcblxuICAgICAgICBpZiAoeCA+IDFlLTIxKSB7XG4gICAgICAgICAgICAvLyAxZS0yMSA8IHggPCAxZTIxXG4gICAgICAgICAgICAvLyAtNzAgPCBsb2cyKHgpIDwgNzBcbiAgICAgICAgICAgIGUgPSB0b0ZpeGVkSGVscGVycy5sb2coeCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICAgICAgICB6ID0gKGUgPCAwID8geCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCAtZSwgMSkgOiB4IC8gdG9GaXhlZEhlbHBlcnMucG93KDIsIGUsIDEpKTtcbiAgICAgICAgICAgIHogKj0gMHgxMDAwMDAwMDAwMDAwMDsgLy8gTWF0aC5wb3coMiwgNTIpO1xuICAgICAgICAgICAgZSA9IDUyIC0gZTtcblxuICAgICAgICAgICAgLy8gLTE4IDwgZSA8IDEyMlxuICAgICAgICAgICAgLy8geCA9IHogLyAyIF4gZVxuICAgICAgICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMCwgeik7XG4gICAgICAgICAgICAgICAgaiA9IGY7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSA3KSB7XG4gICAgICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gNztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSh0b0ZpeGVkSGVscGVycy5wb3coMTAsIGosIDEpLCAwKTtcbiAgICAgICAgICAgICAgICBqID0gZSAtIDE7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSAyMykge1xuICAgICAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kaXZpZGUoMSA8PCAyMyk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDEgPDwgaik7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMSwgMSk7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDIpO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgwLCB6KTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgxIDw8ICgtZSksIDApO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAyLCAyICsgZik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZiA+IDApIHtcbiAgICAgICAgICAgIGsgPSBtLmxlbmd0aDtcblxuICAgICAgICAgICAgaWYgKGsgPD0gZikge1xuICAgICAgICAgICAgICAgIG0gPSBzICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMCcsIDAsIGYgLSBrICsgMikgKyBtO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtID0gcyArIHN0clNsaWNlKG0sIDAsIGsgLSBmKSArICcuJyArIHN0clNsaWNlKG0sIGsgLSBmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG0gPSBzICsgbTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH07XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHsgdG9GaXhlZDogdG9GaXhlZFNoaW0gfSwgaGFzVG9GaXhlZEJ1Z3MpO1xuXG4gICAgdmFyIGhhc1RvUHJlY2lzaW9uVW5kZWZpbmVkQnVnID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiAxLjAudG9QcmVjaXNpb24odW5kZWZpbmVkKSA9PT0gJzEnO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgdmFyIG9yaWdpbmFsVG9QcmVjaXNpb24gPSBOdW1iZXJQcm90b3R5cGUudG9QcmVjaXNpb247XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHtcbiAgICAgICAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBwcmVjaXNpb24gPT09ICd1bmRlZmluZWQnID8gb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMpIDogb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMsIHByZWNpc2lvbik7XG4gICAgICAgIH1cbiAgICB9LCBoYXNUb1ByZWNpc2lvblVuZGVmaW5lZEJ1Zyk7XG5cbiAgICAvL1xuICAgIC8vIFN0cmluZ1xuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUzUgMTUuNS40LjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNS40LjE0XG5cbiAgICAvLyBbYnVnZml4LCBJRSBsdCA5LCBmaXJlZm94IDQsIEtvbnF1ZXJvciwgT3BlcmEsIG9ic2N1cmUgYnJvd3NlcnNdXG4gICAgLy8gTWFueSBicm93c2VycyBkbyBub3Qgc3BsaXQgcHJvcGVybHkgd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zIG9yIHRoZXlcbiAgICAvLyBkbyBub3QgcGVyZm9ybSB0aGUgc3BsaXQgY29ycmVjdGx5IHVuZGVyIG9ic2N1cmUgY29uZGl0aW9ucy5cbiAgICAvLyBTZWUgaHR0cDovL2Jsb2cuc3RldmVubGV2aXRoYW4uY29tL2FyY2hpdmVzL2Nyb3NzLWJyb3dzZXItc3BsaXRcbiAgICAvLyBJJ3ZlIHRlc3RlZCBpbiBtYW55IGJyb3dzZXJzIGFuZCB0aGlzIHNlZW1zIHRvIGNvdmVyIHRoZSBkZXZpYW50IG9uZXM6XG4gICAgLy8gICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pIHNob3VsZCBiZSBbXCJcIiwgXCJcIl0sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLyguPykoLj8pLykgc2hvdWxkIGJlIFtcIlwiLCBcIi5cIiwgXCJcIiwgXCJcIl0sIG5vdCBbXCJcIiwgXCJcIl1cbiAgICAvLyAgICAndGVzc3QnLnNwbGl0KC8ocykqLykgc2hvdWxkIGJlIFtcInRcIiwgdW5kZWZpbmVkLCBcImVcIiwgXCJzXCIsIFwidFwiXSwgbm90XG4gICAgLy8gICAgICAgW3VuZGVmaW5lZCwgXCJ0XCIsIHVuZGVmaW5lZCwgXCJlXCIsIC4uLl1cbiAgICAvLyAgICAnJy5zcGxpdCgvLj8vKSBzaG91bGQgYmUgW10sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLygpKCkvKSBzaG91bGQgYmUgW1wiLlwiXSwgbm90IFtcIlwiLCBcIlwiLCBcIi5cIl1cblxuICAgIGlmIChcbiAgICAgICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pLmxlbmd0aCAhPT0gMiB8fFxuICAgICAgICAnLicuc3BsaXQoLyguPykoLj8pLykubGVuZ3RoICE9PSA0IHx8XG4gICAgICAgICd0ZXNzdCcuc3BsaXQoLyhzKSovKVsxXSA9PT0gJ3QnIHx8XG4gICAgICAgICd0ZXN0Jy5zcGxpdCgvKD86KS8sIC0xKS5sZW5ndGggIT09IDQgfHxcbiAgICAgICAgJycuc3BsaXQoLy4/LykubGVuZ3RoIHx8XG4gICAgICAgICcuJy5zcGxpdCgvKCkoKS8pLmxlbmd0aCA+IDFcbiAgICApIHtcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBjb21wbGlhbnRFeGVjTnBjZyA9IHR5cGVvZiAoLygpPz8vKS5leGVjKCcnKVsxXSA9PT0gJ3VuZGVmaW5lZCc7IC8vIE5QQ0c6IG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgICAgICAgICB2YXIgbWF4U2FmZTMyQml0SW50ID0gTWF0aC5wb3coMiwgMzIpIC0gMTtcblxuICAgICAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyAmJiBsaW1pdCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSWYgYHNlcGFyYXRvcmAgaXMgbm90IGEgcmVnZXgsIHVzZSBuYXRpdmUgc3BsaXRcbiAgICAgICAgICAgICAgICBpZiAoIWlzUmVnZXgoc2VwYXJhdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyU3BsaXQodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIHZhciBmbGFncyA9IChzZXBhcmF0b3IuaWdub3JlQ2FzZSA/ICdpJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5tdWx0aWxpbmUgPyAnbScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArIC8vIGluIEVTNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gJ3knIDogJycpLCAvLyBGaXJlZm94IDMrIGFuZCBFUzZcbiAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IDAsXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIHNlcGFyYXRvckNvcHkgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgJ2cnKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBsaWFudEV4ZWNOcGNnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERvZXNuJ3QgbmVlZCBmbGFncyBneSwgYnV0IHRoZXkgZG9uJ3QgaHVydFxuICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IyID0gbmV3IFJlZ0V4cCgnXicgKyBzZXBhcmF0b3JDb3B5LnNvdXJjZSArICckKD8hXFxcXHMpJywgZmxhZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKiBWYWx1ZXMgZm9yIGBsaW1pdGAsIHBlciB0aGUgc3BlYzpcbiAgICAgICAgICAgICAgICAgKiBJZiB1bmRlZmluZWQ6IDQyOTQ5NjcyOTUgLy8gbWF4U2FmZTMyQml0SW50XG4gICAgICAgICAgICAgICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMFxuICAgICAgICAgICAgICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBNYXRoLmZsb29yKGxpbWl0KTsgaWYgKGxpbWl0ID4gNDI5NDk2NzI5NSkgbGltaXQgLT0gNDI5NDk2NzI5NjtcbiAgICAgICAgICAgICAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IDQyOTQ5NjcyOTYgLSBNYXRoLmZsb29yKE1hdGguYWJzKGxpbWl0KSlcbiAgICAgICAgICAgICAgICAgKiBJZiBvdGhlcjogVHlwZS1jb252ZXJ0LCB0aGVuIHVzZSB0aGUgYWJvdmUgcnVsZXNcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICB2YXIgc3BsaXRMaW1pdCA9IHR5cGVvZiBsaW1pdCA9PT0gJ3VuZGVmaW5lZCcgPyBtYXhTYWZlMzJCaXRJbnQgOiBFUy5Ub1VpbnQzMihsaW1pdCk7XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYHNlcGFyYXRvckNvcHkubGFzdEluZGV4YCBpcyBub3QgcmVsaWFibGUgY3Jvc3MtYnJvd3NlclxuICAgICAgICAgICAgICAgICAgICBsYXN0SW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgc3RyU2xpY2Uoc3RyaW5nLCBsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRml4IGJyb3dzZXJzIHdob3NlIGBleGVjYCBtZXRob2RzIGRvbid0IGNvbnNpc3RlbnRseSByZXR1cm4gYHVuZGVmaW5lZGAgZm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWxvb3AtZnVuYyAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoWzBdLnJlcGxhY2Uoc2VwYXJhdG9yMiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJndW1lbnRzW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoW2ldID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1sb29wLWZ1bmMgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaC5sZW5ndGggPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2guYXBwbHkob3V0cHV0LCBhcnJheVNsaWNlKG1hdGNoLCAxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXQubGVuZ3RoID49IHNwbGl0TGltaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VwYXJhdG9yQ29weS5sYXN0SW5kZXggPT09IG1hdGNoLmluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleCsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgJycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwob3V0cHV0LCBzdHJTbGljZShzdHJpbmcsIGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dC5sZW5ndGggPiBzcGxpdExpbWl0ID8gYXJyYXlTbGljZShvdXRwdXQsIDAsIHNwbGl0TGltaXQpIDogb3V0cHV0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSgpKTtcblxuICAgIC8vIFtidWdmaXgsIGNocm9tZV1cbiAgICAvLyBJZiBzZXBhcmF0b3IgaXMgdW5kZWZpbmVkLCB0aGVuIHRoZSByZXN1bHQgYXJyYXkgY29udGFpbnMganVzdCBvbmUgU3RyaW5nLFxuICAgIC8vIHdoaWNoIGlzIHRoZSB0aGlzIHZhbHVlIChjb252ZXJ0ZWQgdG8gYSBTdHJpbmcpLiBJZiBsaW1pdCBpcyBub3QgdW5kZWZpbmVkLFxuICAgIC8vIHRoZW4gdGhlIG91dHB1dCBhcnJheSBpcyB0cnVuY2F0ZWQgc28gdGhhdCBpdCBjb250YWlucyBubyBtb3JlIHRoYW4gbGltaXRcbiAgICAvLyBlbGVtZW50cy5cbiAgICAvLyBcIjBcIi5zcGxpdCh1bmRlZmluZWQsIDApIC0+IFtdXG4gICAgfSBlbHNlIGlmICgnMCcuc3BsaXQodm9pZCAwLCAwKS5sZW5ndGgpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnICYmIGxpbWl0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0clNwbGl0KHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBzdHJfcmVwbGFjZSA9IFN0cmluZ1Byb3RvdHlwZS5yZXBsYWNlO1xuICAgIHZhciByZXBsYWNlUmVwb3J0c0dyb3Vwc0NvcnJlY3RseSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cHMgPSBbXTtcbiAgICAgICAgJ3gnLnJlcGxhY2UoL3goLik/L2csIGZ1bmN0aW9uIChtYXRjaCwgZ3JvdXApIHtcbiAgICAgICAgICAgIHB1c2hDYWxsKGdyb3VwcywgZ3JvdXApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGdyb3Vwcy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGdyb3Vwc1swXSA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgfSgpKTtcblxuICAgIGlmICghcmVwbGFjZVJlcG9ydHNHcm91cHNDb3JyZWN0bHkpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpIHtcbiAgICAgICAgICAgIHZhciBpc0ZuID0gaXNDYWxsYWJsZShyZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgdmFyIGhhc0NhcHR1cmluZ0dyb3VwcyA9IGlzUmVnZXgoc2VhcmNoVmFsdWUpICYmICgvXFwpWyo/XS8pLnRlc3Qoc2VhcmNoVmFsdWUuc291cmNlKTtcbiAgICAgICAgICAgIGlmICghaXNGbiB8fCAhaGFzQ2FwdHVyaW5nR3JvdXBzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlLmNhbGwodGhpcywgc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB3cmFwcGVkUmVwbGFjZVZhbHVlID0gZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWxMYXN0SW5kZXggPSBzZWFyY2hWYWx1ZS5sYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gc2VhcmNoVmFsdWUuZXhlYyhtYXRjaCkgfHwgW107XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IG9yaWdpbmFsTGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChhcmdzLCBhcmd1bWVudHNbbGVuZ3RoIC0gMl0sIGFyZ3VtZW50c1tsZW5ndGggLSAxXSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXBsYWNlVmFsdWUuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UuY2FsbCh0aGlzLCBzZWFyY2hWYWx1ZSwgd3JhcHBlZFJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRUNNQS0yNjIsIDNyZCBCLjIuM1xuICAgIC8vIE5vdCBhbiBFQ01BU2NyaXB0IHN0YW5kYXJkLCBhbHRob3VnaCBFQ01BU2NyaXB0IDNyZCBFZGl0aW9uIGhhcyBhXG4gICAgLy8gbm9uLW5vcm1hdGl2ZSBzZWN0aW9uIHN1Z2dlc3RpbmcgdW5pZm9ybSBzZW1hbnRpY3MgYW5kIGl0IHNob3VsZCBiZVxuICAgIC8vIG5vcm1hbGl6ZWQgYWNyb3NzIGFsbCBicm93c2Vyc1xuICAgIC8vIFtidWdmaXgsIElFIGx0IDldIElFIDwgOSBzdWJzdHIoKSB3aXRoIG5lZ2F0aXZlIHZhbHVlIG5vdCB3b3JraW5nIGluIElFXG4gICAgdmFyIHN0cmluZ19zdWJzdHIgPSBTdHJpbmdQcm90b3R5cGUuc3Vic3RyO1xuICAgIHZhciBoYXNOZWdhdGl2ZVN1YnN0ckJ1ZyA9ICcnLnN1YnN0ciAmJiAnMGInLnN1YnN0cigtMSkgIT09ICdiJztcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICBzdWJzdHI6IGZ1bmN0aW9uIHN1YnN0cihzdGFydCwgbGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgbm9ybWFsaXplZFN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZFN0YXJ0ID0gbWF4KHRoaXMubGVuZ3RoICsgc3RhcnQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ19zdWJzdHIuY2FsbCh0aGlzLCBub3JtYWxpemVkU3RhcnQsIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZVN1YnN0ckJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNS40LjIwXG4gICAgLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjUuNC4yMFxuICAgIHZhciB3cyA9ICdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycgK1xuICAgICAgICAnXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwQVxcdTIwMkZcXHUyMDVGXFx1MzAwMFxcdTIwMjgnICtcbiAgICAgICAgJ1xcdTIwMjlcXHVGRUZGJztcbiAgICB2YXIgemVyb1dpZHRoID0gJ1xcdTIwMGInO1xuICAgIHZhciB3c1JlZ2V4Q2hhcnMgPSAnWycgKyB3cyArICddJztcbiAgICB2YXIgdHJpbUJlZ2luUmVnZXhwID0gbmV3IFJlZ0V4cCgnXicgKyB3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKicpO1xuICAgIHZhciB0cmltRW5kUmVnZXhwID0gbmV3IFJlZ0V4cCh3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKiQnKTtcbiAgICB2YXIgaGFzVHJpbVdoaXRlc3BhY2VCdWcgPSBTdHJpbmdQcm90b3R5cGUudHJpbSAmJiAod3MudHJpbSgpIHx8ICF6ZXJvV2lkdGgudHJpbSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICAvLyBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvZmFzdGVyLXRyaW0tamF2YXNjcmlwdFxuICAgICAgICAvLyBodHRwOi8vcGVyZmVjdGlvbmtpbGxzLmNvbS93aGl0ZXNwYWNlLWRldmlhdGlvbnMvXG4gICAgICAgIHRyaW06IGZ1bmN0aW9uIHRyaW0oKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIHRoaXMgKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcodGhpcykucmVwbGFjZSh0cmltQmVnaW5SZWdleHAsICcnKS5yZXBsYWNlKHRyaW1FbmRSZWdleHAsICcnKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc1RyaW1XaGl0ZXNwYWNlQnVnKTtcbiAgICB2YXIgdHJpbSA9IGNhbGwuYmluZChTdHJpbmcucHJvdG90eXBlLnRyaW0pO1xuXG4gICAgdmFyIGhhc0xhc3RJbmRleEJ1ZyA9IFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZiAmJiAnYWJj44GC44GEJy5sYXN0SW5kZXhPZign44GC44GEJywgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgdGhpcyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgUyA9ICRTdHJpbmcodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoU3RyID0gJFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgICAgICAgICAgdmFyIG51bVBvcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gJE51bWJlcihhcmd1bWVudHNbMV0pIDogTmFOO1xuICAgICAgICAgICAgdmFyIHBvcyA9IGlzQWN0dWFsTmFOKG51bVBvcykgPyBJbmZpbml0eSA6IEVTLlRvSW50ZWdlcihudW1Qb3MpO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gbWluKG1heChwb3MsIDApLCBTLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoTGVuID0gc2VhcmNoU3RyLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBrID0gc3RhcnQgKyBzZWFyY2hMZW47XG4gICAgICAgICAgICB3aGlsZSAoayA+IDApIHtcbiAgICAgICAgICAgICAgICBrID0gbWF4KDAsIGsgLSBzZWFyY2hMZW4pO1xuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHN0ckluZGV4T2Yoc3RyU2xpY2UoUywgaywgc3RhcnQgKyBzZWFyY2hMZW4pLCBzZWFyY2hTdHIpO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGsgKyBpbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNMYXN0SW5kZXhCdWcpO1xuXG4gICAgdmFyIG9yaWdpbmFsTGFzdEluZGV4T2YgPSBTdHJpbmdQcm90b3R5cGUubGFzdEluZGV4T2Y7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaFN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTGFzdEluZGV4T2YuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH0sIFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZi5sZW5ndGggIT09IDEpO1xuXG4gICAgLy8gRVMtNSAxNS4xLjIuMlxuICAgIC8qIGVzbGludC1kaXNhYmxlIHJhZGl4ICovXG4gICAgaWYgKHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgcGFyc2VJbnQod3MgKyAnMHgxNicpICE9PSAyMikge1xuICAgIC8qIGVzbGludC1lbmFibGUgcmFkaXggKi9cbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlSW50OiB0cnVlICovXG4gICAgICAgIHBhcnNlSW50ID0gKGZ1bmN0aW9uIChvcmlnUGFyc2VJbnQpIHtcbiAgICAgICAgICAgIHZhciBoZXhSZWdleCA9IC9eW1xcLStdPzBbeFhdLztcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cikpO1xuICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0ZWRSYWRpeCA9ICROdW1iZXIocmFkaXgpIHx8IChoZXhSZWdleC50ZXN0KHN0cmluZykgPyAxNiA6IDEwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ1BhcnNlSW50KHN0cmluZywgZGVmYXVsdGVkUmFkaXgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUludCkpO1xuICAgIH1cblxuICAgIC8vIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4zXG4gICAgaWYgKDEgLyBwYXJzZUZsb2F0KCctMCcpICE9PSAtSW5maW5pdHkpIHtcbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlRmxvYXQ6IHRydWUgKi9cbiAgICAgICAgcGFyc2VGbG9hdCA9IChmdW5jdGlvbiAob3JpZ1BhcnNlRmxvYXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUZsb2F0KHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBpbnB1dFN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cmluZykpO1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvcmlnUGFyc2VGbG9hdChpbnB1dFN0cmluZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gMCAmJiBzdHJTbGljZShpbnB1dFN0cmluZywgMCwgMSkgPT09ICctJyA/IC0wIDogcmVzdWx0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUZsb2F0KSk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZyhuZXcgUmFuZ2VFcnJvcigndGVzdCcpKSAhPT0gJ1JhbmdlRXJyb3I6IHRlc3QnKSB7XG4gICAgICAgIHZhciBlcnJvclRvU3RyaW5nU2hpbSA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyB0aGlzICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBuYW1lID0gdGhpcy5uYW1lO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIG5hbWUgPSAnRXJyb3InO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gJFN0cmluZyhuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBtc2cgPSB0aGlzLm1lc3NhZ2U7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1zZyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAkU3RyaW5nKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbXNnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtc2cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYW1lICsgJzogJyArIG1zZztcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY2FuJ3QgdXNlIGRlZmluZVByb3BlcnRpZXMgaGVyZSBiZWNhdXNlIG9mIHRvU3RyaW5nIGVudW1lcmF0aW9uIGlzc3VlIGluIElFIDw9IDhcbiAgICAgICAgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nID0gZXJyb3JUb1N0cmluZ1NoaW07XG4gICAgfVxuXG4gICAgaWYgKHN1cHBvcnRzRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgdmFyIGVuc3VyZU5vbkVudW1lcmFibGUgPSBmdW5jdGlvbiAob2JqLCBwcm9wKSB7XG4gICAgICAgICAgICBpZiAoaXNFbnVtKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIHByb3AsIGRlc2MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICdtZXNzYWdlJyk7XG4gICAgICAgIGlmIChFcnJvci5wcm90b3R5cGUubWVzc2FnZSAhPT0gJycpIHtcbiAgICAgICAgICAgIEVycm9yLnByb3RvdHlwZS5tZXNzYWdlID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICduYW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZygvYS9taWcpICE9PSAnL2EvZ2ltJykge1xuICAgICAgICB2YXIgcmVnZXhUb1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIHN0ciA9ICcvJyArIHRoaXMuc291cmNlICsgJy8nO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2xvYmFsKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmlnbm9yZUNhc2UpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJ2knO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMubXVsdGlsaW5lKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdtJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgICAgIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcgPSByZWdleFRvU3RyaW5nO1xuICAgIH1cbn0pKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8qanNsaW50IGVxZXE6IHRydWUqL1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdzYW5pdGl6ZScsIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIGlmICh0ZXh0ID09PSB1bmRlZmluZWQpIHsgcmV0dXJuICcnOyB9XG5cbiAgICByZXN1bHQgPSBzYW5pdGl6ZUh0bWwodGV4dCwge1xuICAgICAgICBhbGxvd2VkVGFnczogWyAnZGl2JywgJ3NwYW4nLCAnYicsICdpJywgJ2VtJywgJ3N0cm9uZycsICdhJywgJ2JyJywgJ3RhYmxlJywgJ3Rib2R5JywgJ3RyJywgJ3RoJywgJ3RkJyBdLFxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ2Rpdic6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3NwYW4nOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICd0YWJsZSc6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3RkJzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAndGgnOiBbICdjb2xzcGFuJyBdLFxuICAgICAgICAgICAgJ2EnOiBbICdocmVmJyBdXG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHJlc3VsdCk7XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigncmVuZGVyVGV4dFBhcmFtJywgZnVuY3Rpb24ocGFyYW0pIHtcbiAgICB2YXIgcmVzdWx0LCB0eXBlID0gJ3RleHQnLCBpZEF0dCA9ICcnO1xuICAgIHZhciBwYXJhbVR5cGUgPSBwYXJhbS50eXBlIHx8IHBhcmFtLnNjaGVtYSAmJiBwYXJhbS5zY2hlbWEudHlwZSB8fCAnJztcbiAgICB2YXIgaXNBcnJheSA9IHBhcmFtVHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknIHx8IHBhcmFtLmFsbG93TXVsdGlwbGU7XG4gICAgdmFyIGRlZmF1bHRWYWx1ZSA9IGlzQXJyYXkgJiYgQXJyYXkuaXNBcnJheShwYXJhbS5kZWZhdWx0KSA/IHBhcmFtLmRlZmF1bHQuam9pbignXFxuJykgOiBwYXJhbS5kZWZhdWx0O1xuICAgIHZhciBuYW1lID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLm5hbWUpO1xuICAgIHZhciB2YWx1ZUlkID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLnZhbHVlSWQpO1xuICAgIHBhcmFtVHlwZSA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbihwYXJhbVR5cGUpO1xuXG4gICAgdmFyIGRhdGFWZW5kb3JFeHRlbnNpb25zID0gT2JqZWN0LmtleXMocGFyYW0pLmZpbHRlcihmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgICAgICAvLyBmaWx0ZXIgWC1kYXRhLSBwcm9wZXJ0aWVzXG4gICAgICAgIHJldHVybiBwcm9wZXJ0eS5tYXRjaCgvXlgtZGF0YS0vaSkgIT09IG51bGw7XG4gICAgfSkucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwgcHJvcGVydHkpIHtcbiAgICAgICAgLy8gcmVtb3ZlIFgtIGZyb20gcHJvcGVydHkgbmFtZSwgc28gaXQgcmVzdWx0cyBpbiBodG1sIGF0dHJpYnV0ZXMgbGlrZSBkYXRhLWZvbz0nYmFyJ1xuICAgICAgICByZXR1cm4gcmVzdWx0ICs9ICcgJyArIHByb3BlcnR5LnN1YnN0cmluZygyLCBwcm9wZXJ0eS5sZW5ndGgpICsgJz1cXCcnICsgcGFyYW1bcHJvcGVydHldICsgJ1xcJyc7XG4gICAgfSwgJycpO1xuXG4gICAgaWYocGFyYW0uZm9ybWF0ICYmIHBhcmFtLmZvcm1hdCA9PT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICB0eXBlID0gJ3Bhc3N3b3JkJztcbiAgICB9XG5cbiAgICBpZih2YWx1ZUlkKSB7XG4gICAgICAgIGlkQXR0ID0gJyBpZD1cXCcnICsgdmFsdWVJZCArICdcXCcnO1xuICAgIH1cblxuICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZSA9IHNhbml0aXplSHRtbChkZWZhdWx0VmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBpZihpc0FycmF5KSB7XG4gICAgICAgIHJlc3VsdCA9ICc8dGV4dGFyZWEgY2xhc3M9XFwnYm9keS10ZXh0YXJlYScgKyAocGFyYW0ucmVxdWlyZWQgPyAnIHJlcXVpcmVkJyA6ICcnKSArICdcXCcgbmFtZT1cXCcnICsgbmFtZSArICdcXCcnICsgaWRBdHQgKyBkYXRhVmVuZG9yRXh0ZW5zaW9ucztcbiAgICAgICAgcmVzdWx0ICs9ICcgcGxhY2Vob2xkZXI9XFwnUHJvdmlkZSBtdWx0aXBsZSB2YWx1ZXMgaW4gbmV3IGxpbmVzJyArIChwYXJhbS5yZXF1aXJlZCA/ICcgKGF0IGxlYXN0IG9uZSByZXF1aXJlZCkuJyA6ICcuJykgKyAnXFwnPic7XG4gICAgICAgIHJlc3VsdCArPSBkZWZhdWx0VmFsdWUgKyAnPC90ZXh0YXJlYT4nO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBwYXJhbWV0ZXJDbGFzcyA9ICdwYXJhbWV0ZXInO1xuICAgICAgICBpZihwYXJhbS5yZXF1aXJlZCkge1xuICAgICAgICAgIHBhcmFtZXRlckNsYXNzICs9ICcgcmVxdWlyZWQnO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9ICc8aW5wdXQgY2xhc3M9XFwnJyArIHBhcmFtZXRlckNsYXNzICsgJ1xcJyBtaW5sZW5ndGg9XFwnJyArIChwYXJhbS5yZXF1aXJlZCA/IDEgOiAwKSArICdcXCcnO1xuICAgICAgICByZXN1bHQgKz0gJyBuYW1lPVxcJycgKyBuYW1lICsnXFwnIHBsYWNlaG9sZGVyPVxcJycgKyAocGFyYW0ucmVxdWlyZWQgPyAnKHJlcXVpcmVkKScgOiAnJykgKyAnXFwnJyArIGlkQXR0ICsgZGF0YVZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgIHJlc3VsdCArPSAnIHR5cGU9XFwnJyArIHR5cGUgKyAnXFwnIHZhbHVlPVxcJycgKyBkZWZhdWx0VmFsdWUgKyAnXFwnLz4nO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhyZXN1bHQpO1xufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lmQ29uZCcsIGZ1bmN0aW9uICh2MSwgb3BlcmF0b3IsIHYyLCBvcHRpb25zKSB7XG5cbiAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT09IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA8IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPD0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgICAgICByZXR1cm4gKHYxID4gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA+PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICcmJic6XG4gICAgICAgICAgICByZXR1cm4gKHYxICYmIHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJ3x8JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgfHwgdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgfVxufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2VzY2FwZScsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciB0ZXh0ID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHZhbHVlKTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHRleHQpO1xufSk7XG4iLCIoZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5zYW5pdGl6ZUh0bWw9ZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaHRtbHBhcnNlcj1yZXF1aXJlKFwiaHRtbHBhcnNlcjJcIik7dmFyIGV4dGVuZD1yZXF1aXJlKFwieHRlbmRcIik7dmFyIHF1b3RlUmVnZXhwPXJlcXVpcmUoXCJyZWdleHAtcXVvdGVcIik7ZnVuY3Rpb24gZWFjaChvYmosY2Ipe2lmKG9iailPYmplY3Qua2V5cyhvYmopLmZvckVhY2goZnVuY3Rpb24oa2V5KXtjYihvYmpba2V5XSxrZXkpfSl9ZnVuY3Rpb24gaGFzKG9iaixrZXkpe3JldHVybnt9Lmhhc093blByb3BlcnR5LmNhbGwob2JqLGtleSl9bW9kdWxlLmV4cG9ydHM9c2FuaXRpemVIdG1sO2Z1bmN0aW9uIHNhbml0aXplSHRtbChodG1sLG9wdGlvbnMsX3JlY3Vyc2luZyl7dmFyIHJlc3VsdD1cIlwiO2Z1bmN0aW9uIEZyYW1lKHRhZyxhdHRyaWJzKXt2YXIgdGhhdD10aGlzO3RoaXMudGFnPXRhZzt0aGlzLmF0dHJpYnM9YXR0cmlic3x8e307dGhpcy50YWdQb3NpdGlvbj1yZXN1bHQubGVuZ3RoO3RoaXMudGV4dD1cIlwiO3RoaXMudXBkYXRlUGFyZW50Tm9kZVRleHQ9ZnVuY3Rpb24oKXtpZihzdGFjay5sZW5ndGgpe3ZhciBwYXJlbnRGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07cGFyZW50RnJhbWUudGV4dCs9dGhhdC50ZXh0fX19aWYoIW9wdGlvbnMpe29wdGlvbnM9c2FuaXRpemVIdG1sLmRlZmF1bHRzO29wdGlvbnMucGFyc2VyPWh0bWxQYXJzZXJEZWZhdWx0c31lbHNle29wdGlvbnM9ZXh0ZW5kKHNhbml0aXplSHRtbC5kZWZhdWx0cyxvcHRpb25zKTtpZihvcHRpb25zLnBhcnNlcil7b3B0aW9ucy5wYXJzZXI9ZXh0ZW5kKGh0bWxQYXJzZXJEZWZhdWx0cyxvcHRpb25zLnBhcnNlcil9ZWxzZXtvcHRpb25zLnBhcnNlcj1odG1sUGFyc2VyRGVmYXVsdHN9fXZhciBub25UZXh0VGFnc0FycmF5PW9wdGlvbnMubm9uVGV4dFRhZ3N8fFtcInNjcmlwdFwiLFwic3R5bGVcIixcInRleHRhcmVhXCJdO3ZhciBhbGxvd2VkQXR0cmlidXRlc01hcDt2YXIgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwO2lmKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwPXt9O2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcD17fTtlYWNoKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMsZnVuY3Rpb24oYXR0cmlidXRlcyx0YWcpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ109W107dmFyIGdsb2JSZWdleD1bXTthdHRyaWJ1dGVzLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYobmFtZS5pbmRleE9mKFwiKlwiKT49MCl7Z2xvYlJlZ2V4LnB1c2gocXVvdGVSZWdleHAobmFtZSkucmVwbGFjZSgvXFxcXFxcKi9nLFwiLipcIikpfWVsc2V7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKG5hbWUpfX0pO2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFt0YWddPW5ldyBSZWdFeHAoXCJeKFwiK2dsb2JSZWdleC5qb2luKFwifFwiKStcIikkXCIpfSl9dmFyIGFsbG93ZWRDbGFzc2VzTWFwPXt9O2VhY2gob3B0aW9ucy5hbGxvd2VkQ2xhc3NlcyxmdW5jdGlvbihjbGFzc2VzLHRhZyl7aWYoYWxsb3dlZEF0dHJpYnV0ZXNNYXApe2lmKCFoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsdGFnKSl7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXT1bXX1hbGxvd2VkQXR0cmlidXRlc01hcFt0YWddLnB1c2goXCJjbGFzc1wiKX1hbGxvd2VkQ2xhc3Nlc01hcFt0YWddPWNsYXNzZXN9KTt2YXIgdHJhbnNmb3JtVGFnc01hcD17fTt2YXIgdHJhbnNmb3JtVGFnc0FsbDtlYWNoKG9wdGlvbnMudHJhbnNmb3JtVGFncyxmdW5jdGlvbih0cmFuc2Zvcm0sdGFnKXt2YXIgdHJhbnNGdW47aWYodHlwZW9mIHRyYW5zZm9ybT09PVwiZnVuY3Rpb25cIil7dHJhbnNGdW49dHJhbnNmb3JtfWVsc2UgaWYodHlwZW9mIHRyYW5zZm9ybT09PVwic3RyaW5nXCIpe3RyYW5zRnVuPXNhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm0odHJhbnNmb3JtKX1pZih0YWc9PT1cIipcIil7dHJhbnNmb3JtVGFnc0FsbD10cmFuc0Z1bn1lbHNle3RyYW5zZm9ybVRhZ3NNYXBbdGFnXT10cmFuc0Z1bn19KTt2YXIgZGVwdGg9MDt2YXIgc3RhY2s9W107dmFyIHNraXBNYXA9e307dmFyIHRyYW5zZm9ybU1hcD17fTt2YXIgc2tpcFRleHQ9ZmFsc2U7dmFyIHNraXBUZXh0RGVwdGg9MDt2YXIgcGFyc2VyPW5ldyBodG1scGFyc2VyLlBhcnNlcih7b25vcGVudGFnOmZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7aWYoc2tpcFRleHQpe3NraXBUZXh0RGVwdGgrKztyZXR1cm59dmFyIGZyYW1lPW5ldyBGcmFtZShuYW1lLGF0dHJpYnMpO3N0YWNrLnB1c2goZnJhbWUpO3ZhciBza2lwPWZhbHNlO3ZhciBoYXNUZXh0PWZyYW1lLnRleHQ/dHJ1ZTpmYWxzZTt2YXIgdHJhbnNmb3JtZWRUYWc7aWYoaGFzKHRyYW5zZm9ybVRhZ3NNYXAsbmFtZSkpe3RyYW5zZm9ybWVkVGFnPXRyYW5zZm9ybVRhZ3NNYXBbbmFtZV0obmFtZSxhdHRyaWJzKTtmcmFtZS5hdHRyaWJzPWF0dHJpYnM9dHJhbnNmb3JtZWRUYWcuYXR0cmlicztpZih0cmFuc2Zvcm1lZFRhZy50ZXh0IT09dW5kZWZpbmVkKXtmcmFtZS5pbm5lclRleHQ9dHJhbnNmb3JtZWRUYWcudGV4dH1pZihuYW1lIT09dHJhbnNmb3JtZWRUYWcudGFnTmFtZSl7ZnJhbWUubmFtZT1uYW1lPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7dHJhbnNmb3JtTWFwW2RlcHRoXT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lfX1pZih0cmFuc2Zvcm1UYWdzQWxsKXt0cmFuc2Zvcm1lZFRhZz10cmFuc2Zvcm1UYWdzQWxsKG5hbWUsYXR0cmlicyk7ZnJhbWUuYXR0cmlicz1hdHRyaWJzPXRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7aWYobmFtZSE9PXRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpe2ZyYW1lLm5hbWU9bmFtZT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lO3RyYW5zZm9ybU1hcFtkZXB0aF09dHJhbnNmb3JtZWRUYWcudGFnTmFtZX19aWYob3B0aW9ucy5hbGxvd2VkVGFncyYmb3B0aW9ucy5hbGxvd2VkVGFncy5pbmRleE9mKG5hbWUpPT09LTEpe3NraXA9dHJ1ZTtpZihub25UZXh0VGFnc0FycmF5LmluZGV4T2YobmFtZSkhPT0tMSl7c2tpcFRleHQ9dHJ1ZTtza2lwVGV4dERlcHRoPTF9c2tpcE1hcFtkZXB0aF09dHJ1ZX1kZXB0aCsrO2lmKHNraXApe3JldHVybn1yZXN1bHQrPVwiPFwiK25hbWU7aWYoIWFsbG93ZWRBdHRyaWJ1dGVzTWFwfHxoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsbmFtZSl8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSl7ZWFjaChhdHRyaWJzLGZ1bmN0aW9uKHZhbHVlLGEpe2lmKCFhbGxvd2VkQXR0cmlidXRlc01hcHx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLG5hbWUpJiZhbGxvd2VkQXR0cmlidXRlc01hcFtuYW1lXS5pbmRleE9mKGEpIT09LTF8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSYmYWxsb3dlZEF0dHJpYnV0ZXNNYXBbXCIqXCJdLmluZGV4T2YoYSkhPT0tMXx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcCxuYW1lKSYmYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW25hbWVdLnRlc3QoYSl8fGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0mJmFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0udGVzdChhKSl7aWYoYT09PVwiaHJlZlwifHxhPT09XCJzcmNcIil7aWYobmF1Z2h0eUhyZWYobmFtZSx2YWx1ZSkpe2RlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO3JldHVybn19aWYoYT09PVwiY2xhc3NcIil7dmFsdWU9ZmlsdGVyQ2xhc3Nlcyh2YWx1ZSxhbGxvd2VkQ2xhc3Nlc01hcFtuYW1lXSk7aWYoIXZhbHVlLmxlbmd0aCl7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07cmV0dXJufX1yZXN1bHQrPVwiIFwiK2E7aWYodmFsdWUubGVuZ3RoKXtyZXN1bHQrPSc9XCInK2VzY2FwZUh0bWwodmFsdWUpKydcIid9fWVsc2V7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV19fSl9aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3Jlc3VsdCs9XCIgLz5cIn1lbHNle3Jlc3VsdCs9XCI+XCI7aWYoZnJhbWUuaW5uZXJUZXh0JiYhaGFzVGV4dCYmIW9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1mcmFtZS5pbm5lclRleHR9fX0sb250ZXh0OmZ1bmN0aW9uKHRleHQpe2lmKHNraXBUZXh0KXtyZXR1cm59dmFyIGxhc3RGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07dmFyIHRhZztpZihsYXN0RnJhbWUpe3RhZz1sYXN0RnJhbWUudGFnO3RleHQ9bGFzdEZyYW1lLmlubmVyVGV4dCE9PXVuZGVmaW5lZD9sYXN0RnJhbWUuaW5uZXJUZXh0OnRleHR9aWYodGFnPT09XCJzY3JpcHRcInx8dGFnPT09XCJzdHlsZVwiKXtyZXN1bHQrPXRleHR9ZWxzZXt2YXIgZXNjYXBlZD1lc2NhcGVIdG1sKHRleHQpO2lmKG9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1vcHRpb25zLnRleHRGaWx0ZXIoZXNjYXBlZCl9ZWxzZXtyZXN1bHQrPWVzY2FwZWR9fWlmKHN0YWNrLmxlbmd0aCl7dmFyIGZyYW1lPXN0YWNrW3N0YWNrLmxlbmd0aC0xXTtmcmFtZS50ZXh0Kz10ZXh0fX0sb25jbG9zZXRhZzpmdW5jdGlvbihuYW1lKXtpZihza2lwVGV4dCl7c2tpcFRleHREZXB0aC0tO2lmKCFza2lwVGV4dERlcHRoKXtza2lwVGV4dD1mYWxzZX1lbHNle3JldHVybn19dmFyIGZyYW1lPXN0YWNrLnBvcCgpO2lmKCFmcmFtZSl7cmV0dXJufXNraXBUZXh0PWZhbHNlO2RlcHRoLS07aWYoc2tpcE1hcFtkZXB0aF0pe2RlbGV0ZSBza2lwTWFwW2RlcHRoXTtmcmFtZS51cGRhdGVQYXJlbnROb2RlVGV4dCgpO3JldHVybn1pZih0cmFuc2Zvcm1NYXBbZGVwdGhdKXtuYW1lPXRyYW5zZm9ybU1hcFtkZXB0aF07ZGVsZXRlIHRyYW5zZm9ybU1hcFtkZXB0aF19aWYob3B0aW9ucy5leGNsdXNpdmVGaWx0ZXImJm9wdGlvbnMuZXhjbHVzaXZlRmlsdGVyKGZyYW1lKSl7cmVzdWx0PXJlc3VsdC5zdWJzdHIoMCxmcmFtZS50YWdQb3NpdGlvbik7cmV0dXJufWZyYW1lLnVwZGF0ZVBhcmVudE5vZGVUZXh0KCk7aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3JldHVybn1yZXN1bHQrPVwiPC9cIituYW1lK1wiPlwifX0sb3B0aW9ucy5wYXJzZXIpO3BhcnNlci53cml0ZShodG1sKTtwYXJzZXIuZW5kKCk7cmV0dXJuIHJlc3VsdDtmdW5jdGlvbiBlc2NhcGVIdG1sKHMpe2lmKHR5cGVvZiBzIT09XCJzdHJpbmdcIil7cz1zK1wiXCJ9cmV0dXJuIHMucmVwbGFjZSgvXFwmL2csXCImYW1wO1wiKS5yZXBsYWNlKC88L2csXCImbHQ7XCIpLnJlcGxhY2UoL1xcPi9nLFwiJmd0O1wiKS5yZXBsYWNlKC9cXFwiL2csXCImcXVvdDtcIil9ZnVuY3Rpb24gbmF1Z2h0eUhyZWYobmFtZSxocmVmKXtocmVmPWhyZWYucmVwbGFjZSgvW1xceDAwLVxceDIwXSsvZyxcIlwiKTtocmVmPWhyZWYucmVwbGFjZSgvPFxcIVxcLVxcLS4qP1xcLVxcLVxcPi9nLFwiXCIpO3ZhciBtYXRjaGVzPWhyZWYubWF0Y2goL14oW2EtekEtWl0rKVxcOi8pO2lmKCFtYXRjaGVzKXtyZXR1cm4gZmFsc2V9dmFyIHNjaGVtZT1tYXRjaGVzWzFdLnRvTG93ZXJDYXNlKCk7aWYoaGFzKG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZyxuYW1lKSl7cmV0dXJuIG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZ1tuYW1lXS5pbmRleE9mKHNjaGVtZSk9PT0tMX1yZXR1cm4hb3B0aW9ucy5hbGxvd2VkU2NoZW1lc3x8b3B0aW9ucy5hbGxvd2VkU2NoZW1lcy5pbmRleE9mKHNjaGVtZSk9PT0tMX1mdW5jdGlvbiBmaWx0ZXJDbGFzc2VzKGNsYXNzZXMsYWxsb3dlZCl7aWYoIWFsbG93ZWQpe3JldHVybiBjbGFzc2VzfWNsYXNzZXM9Y2xhc3Nlcy5zcGxpdCgvXFxzKy8pO3JldHVybiBjbGFzc2VzLmZpbHRlcihmdW5jdGlvbihjbHNzKXtyZXR1cm4gYWxsb3dlZC5pbmRleE9mKGNsc3MpIT09LTF9KS5qb2luKFwiIFwiKX19dmFyIGh0bWxQYXJzZXJEZWZhdWx0cz17ZGVjb2RlRW50aXRpZXM6dHJ1ZX07c2FuaXRpemVIdG1sLmRlZmF1bHRzPXthbGxvd2VkVGFnczpbXCJoM1wiLFwiaDRcIixcImg1XCIsXCJoNlwiLFwiYmxvY2txdW90ZVwiLFwicFwiLFwiYVwiLFwidWxcIixcIm9sXCIsXCJubFwiLFwibGlcIixcImJcIixcImlcIixcInN0cm9uZ1wiLFwiZW1cIixcInN0cmlrZVwiLFwiY29kZVwiLFwiaHJcIixcImJyXCIsXCJkaXZcIixcInRhYmxlXCIsXCJ0aGVhZFwiLFwiY2FwdGlvblwiLFwidGJvZHlcIixcInRyXCIsXCJ0aFwiLFwidGRcIixcInByZVwiXSxhbGxvd2VkQXR0cmlidXRlczp7YTpbXCJocmVmXCIsXCJuYW1lXCIsXCJ0YXJnZXRcIl0saW1nOltcInNyY1wiXX0sc2VsZkNsb3Npbmc6W1wiaW1nXCIsXCJiclwiLFwiaHJcIixcImFyZWFcIixcImJhc2VcIixcImJhc2Vmb250XCIsXCJpbnB1dFwiLFwibGlua1wiLFwibWV0YVwiXSxhbGxvd2VkU2NoZW1lczpbXCJodHRwXCIsXCJodHRwc1wiLFwiZnRwXCIsXCJtYWlsdG9cIl0sYWxsb3dlZFNjaGVtZXNCeVRhZzp7fX07c2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybT1mdW5jdGlvbihuZXdUYWdOYW1lLG5ld0F0dHJpYnMsbWVyZ2Upe21lcmdlPW1lcmdlPT09dW5kZWZpbmVkP3RydWU6bWVyZ2U7bmV3QXR0cmlicz1uZXdBdHRyaWJzfHx7fTtyZXR1cm4gZnVuY3Rpb24odGFnTmFtZSxhdHRyaWJzKXt2YXIgYXR0cmliO2lmKG1lcmdlKXtmb3IoYXR0cmliIGluIG5ld0F0dHJpYnMpe2F0dHJpYnNbYXR0cmliXT1uZXdBdHRyaWJzW2F0dHJpYl19fWVsc2V7YXR0cmlicz1uZXdBdHRyaWJzfXJldHVybnt0YWdOYW1lOm5ld1RhZ05hbWUsYXR0cmliczphdHRyaWJzfX19fSx7aHRtbHBhcnNlcjI6MzYsXCJyZWdleHAtcXVvdGVcIjo1NCx4dGVuZDo1OH1dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO2V4cG9ydHMudG9CeXRlQXJyYXk9dG9CeXRlQXJyYXk7ZXhwb3J0cy5mcm9tQnl0ZUFycmF5PWZyb21CeXRlQXJyYXk7dmFyIGxvb2t1cD1bXTt2YXIgcmV2TG9va3VwPVtdO3ZhciBBcnI9dHlwZW9mIFVpbnQ4QXJyYXkhPT1cInVuZGVmaW5lZFwiP1VpbnQ4QXJyYXk6QXJyYXk7ZnVuY3Rpb24gaW5pdCgpe3ZhciBjb2RlPVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO2Zvcih2YXIgaT0wLGxlbj1jb2RlLmxlbmd0aDtpPGxlbjsrK2kpe2xvb2t1cFtpXT1jb2RlW2ldO3Jldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldPWl9cmV2TG9va3VwW1wiLVwiLmNoYXJDb2RlQXQoMCldPTYyO3Jldkxvb2t1cFtcIl9cIi5jaGFyQ29kZUF0KDApXT02M31pbml0KCk7ZnVuY3Rpb24gdG9CeXRlQXJyYXkoYjY0KXt2YXIgaSxqLGwsdG1wLHBsYWNlSG9sZGVycyxhcnI7dmFyIGxlbj1iNjQubGVuZ3RoO2lmKGxlbiU0PjApe3Rocm93IG5ldyBFcnJvcihcIkludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDRcIil9cGxhY2VIb2xkZXJzPWI2NFtsZW4tMl09PT1cIj1cIj8yOmI2NFtsZW4tMV09PT1cIj1cIj8xOjA7YXJyPW5ldyBBcnIobGVuKjMvNC1wbGFjZUhvbGRlcnMpO2w9cGxhY2VIb2xkZXJzPjA/bGVuLTQ6bGVuO3ZhciBMPTA7Zm9yKGk9MCxqPTA7aTxsO2krPTQsais9Myl7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDE4fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTw8MTJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildPDw2fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzMpXTthcnJbTCsrXT10bXA+PjE2JjI1NTthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9aWYocGxhY2VIb2xkZXJzPT09Mil7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPj40O2FycltMKytdPXRtcCYyNTV9ZWxzZSBpZihwbGFjZUhvbGRlcnM9PT0xKXt0bXA9cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MTB8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPDw0fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzIpXT4+MjthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9cmV0dXJuIGFycn1mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQobnVtKXtyZXR1cm4gbG9va3VwW251bT4+MTgmNjNdK2xvb2t1cFtudW0+PjEyJjYzXStsb29rdXBbbnVtPj42JjYzXStsb29rdXBbbnVtJjYzXX1mdW5jdGlvbiBlbmNvZGVDaHVuayh1aW50OCxzdGFydCxlbmQpe3ZhciB0bXA7dmFyIG91dHB1dD1bXTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7aSs9Myl7dG1wPSh1aW50OFtpXTw8MTYpKyh1aW50OFtpKzFdPDw4KSt1aW50OFtpKzJdO291dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKX1yZXR1cm4gb3V0cHV0LmpvaW4oXCJcIil9ZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSh1aW50OCl7dmFyIHRtcDt2YXIgbGVuPXVpbnQ4Lmxlbmd0aDt2YXIgZXh0cmFCeXRlcz1sZW4lMzt2YXIgb3V0cHV0PVwiXCI7dmFyIHBhcnRzPVtdO3ZhciBtYXhDaHVua0xlbmd0aD0xNjM4Mztmb3IodmFyIGk9MCxsZW4yPWxlbi1leHRyYUJ5dGVzO2k8bGVuMjtpKz1tYXhDaHVua0xlbmd0aCl7cGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCxpLGkrbWF4Q2h1bmtMZW5ndGg+bGVuMj9sZW4yOmkrbWF4Q2h1bmtMZW5ndGgpKX1pZihleHRyYUJ5dGVzPT09MSl7dG1wPXVpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjJdO291dHB1dCs9bG9va3VwW3RtcDw8NCY2M107b3V0cHV0Kz1cIj09XCJ9ZWxzZSBpZihleHRyYUJ5dGVzPT09Mil7dG1wPSh1aW50OFtsZW4tMl08PDgpK3VpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjEwXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjQmNjNdO291dHB1dCs9bG9va3VwW3RtcDw8MiY2M107b3V0cHV0Kz1cIj1cIn1wYXJ0cy5wdXNoKG91dHB1dCk7cmV0dXJuIHBhcnRzLmpvaW4oXCJcIil9fSx7fV0sMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7fSx7fV0sNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKGdsb2JhbCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpO3ZhciBCdWZmZXI9YnVmZmVyLkJ1ZmZlcjt2YXIgU2xvd0J1ZmZlcj1idWZmZXIuU2xvd0J1ZmZlcjt2YXIgTUFYX0xFTj1idWZmZXIua01heExlbmd0aHx8MjE0NzQ4MzY0NztleHBvcnRzLmFsbG9jPWZ1bmN0aW9uIGFsbG9jKHNpemUsZmlsbCxlbmNvZGluZyl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvYz09PVwiZnVuY3Rpb25cIil7cmV0dXJuIEJ1ZmZlci5hbGxvYyhzaXplLGZpbGwsZW5jb2RpbmcpfWlmKHR5cGVvZiBlbmNvZGluZz09PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJlbmNvZGluZyBtdXN0IG5vdCBiZSBudW1iZXJcIil9aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwic2l6ZSBtdXN0IGJlIGEgbnVtYmVyXCIpfWlmKHNpemU+TUFYX0xFTil7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzaXplIGlzIHRvbyBsYXJnZVwiKX12YXIgZW5jPWVuY29kaW5nO3ZhciBfZmlsbD1maWxsO2lmKF9maWxsPT09dW5kZWZpbmVkKXtlbmM9dW5kZWZpbmVkO19maWxsPTB9dmFyIGJ1Zj1uZXcgQnVmZmVyKHNpemUpO2lmKHR5cGVvZiBfZmlsbD09PVwic3RyaW5nXCIpe3ZhciBmaWxsQnVmPW5ldyBCdWZmZXIoX2ZpbGwsZW5jKTt2YXIgZmxlbj1maWxsQnVmLmxlbmd0aDt2YXIgaT0tMTt3aGlsZSgrK2k8c2l6ZSl7YnVmW2ldPWZpbGxCdWZbaSVmbGVuXX19ZWxzZXtidWYuZmlsbChfZmlsbCl9cmV0dXJuIGJ1Zn07ZXhwb3J0cy5hbGxvY1Vuc2FmZT1mdW5jdGlvbiBhbGxvY1Vuc2FmZShzaXplKXtpZih0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlKHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPk1BWF9MRU4pe3Rocm93IG5ldyBSYW5nZUVycm9yKFwic2l6ZSBpcyB0b28gbGFyZ2VcIil9cmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSl9O2V4cG9ydHMuZnJvbT1mdW5jdGlvbiBmcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgQnVmZmVyLmZyb209PT1cImZ1bmN0aW9uXCImJighZ2xvYmFsLlVpbnQ4QXJyYXl8fFVpbnQ4QXJyYXkuZnJvbSE9PUJ1ZmZlci5mcm9tKSl7cmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgdmFsdWU9PT1cInN0cmluZ1wiKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0KX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXt2YXIgb2Zmc2V0PWVuY29kaW5nT3JPZmZzZXQ7aWYoYXJndW1lbnRzLmxlbmd0aD09PTEpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlKX1pZih0eXBlb2Ygb2Zmc2V0PT09XCJ1bmRlZmluZWRcIil7b2Zmc2V0PTB9dmFyIGxlbj1sZW5ndGg7aWYodHlwZW9mIGxlbj09PVwidW5kZWZpbmVkXCIpe2xlbj12YWx1ZS5ieXRlTGVuZ3RoLW9mZnNldH1pZihvZmZzZXQ+PXZhbHVlLmJ5dGVMZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ29mZnNldCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1pZihsZW4+dmFsdWUuYnl0ZUxlbmd0aC1vZmZzZXQpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ2xlbmd0aCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1yZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5zbGljZShvZmZzZXQsb2Zmc2V0K2xlbikpfWlmKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpe3ZhciBvdXQ9bmV3IEJ1ZmZlcih2YWx1ZS5sZW5ndGgpO3ZhbHVlLmNvcHkob3V0LDAsMCx2YWx1ZS5sZW5ndGgpO3JldHVybiBvdXR9aWYodmFsdWUpe2lmKEFycmF5LmlzQXJyYXkodmFsdWUpfHx0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8XCJsZW5ndGhcImluIHZhbHVlKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSl9aWYodmFsdWUudHlwZT09PVwiQnVmZmVyXCImJkFycmF5LmlzQXJyYXkodmFsdWUuZGF0YSkpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBcIitcIkFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuXCIpfTtleHBvcnRzLmFsbG9jVW5zYWZlU2xvdz1mdW5jdGlvbiBhbGxvY1Vuc2FmZVNsb3coc2l6ZSl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3c9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPj1NQVhfTEVOKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNpemUgaXMgdG9vIGxhcmdlXCIpfXJldHVybiBuZXcgU2xvd0J1ZmZlcihzaXplKX19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtidWZmZXI6NX1dLDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihnbG9iYWwpe1widXNlIHN0cmljdFwiO3ZhciBiYXNlNjQ9cmVxdWlyZShcImJhc2U2NC1qc1wiKTt2YXIgaWVlZTc1ND1yZXF1aXJlKFwiaWVlZTc1NFwiKTt2YXIgaXNBcnJheT1yZXF1aXJlKFwiaXNhcnJheVwiKTtleHBvcnRzLkJ1ZmZlcj1CdWZmZXI7ZXhwb3J0cy5TbG93QnVmZmVyPVNsb3dCdWZmZXI7ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUz01MDtCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVD1nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCE9PXVuZGVmaW5lZD9nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVDp0eXBlZEFycmF5U3VwcG9ydCgpO2V4cG9ydHMua01heExlbmd0aD1rTWF4TGVuZ3RoKCk7ZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQoKXt0cnl7dmFyIGFycj1uZXcgVWludDhBcnJheSgxKTthcnIuX19wcm90b19fPXtfX3Byb3RvX186VWludDhBcnJheS5wcm90b3R5cGUsZm9vOmZ1bmN0aW9uKCl7cmV0dXJuIDQyfX07cmV0dXJuIGFyci5mb28oKT09PTQyJiZ0eXBlb2YgYXJyLnN1YmFycmF5PT09XCJmdW5jdGlvblwiJiZhcnIuc3ViYXJyYXkoMSwxKS5ieXRlTGVuZ3RoPT09MH1jYXRjaChlKXtyZXR1cm4gZmFsc2V9fWZ1bmN0aW9uIGtNYXhMZW5ndGgoKXtyZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQ/MjE0NzQ4MzY0NzoxMDczNzQxODIzfWZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCl7aWYoa01heExlbmd0aCgpPGxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aFwiKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1uZXcgVWludDhBcnJheShsZW5ndGgpO3RoYXQuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGV9ZWxzZXtpZih0aGF0PT09bnVsbCl7dGhhdD1uZXcgQnVmZmVyKGxlbmd0aCl9dGhhdC5sZW5ndGg9bGVuZ3RofXJldHVybiB0aGF0fWZ1bmN0aW9uIEJ1ZmZlcihhcmcsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCYmISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSl7cmV0dXJuIG5ldyBCdWZmZXIoYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgYXJnPT09XCJudW1iZXJcIil7aWYodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQ9PT1cInN0cmluZ1wiKXt0aHJvdyBuZXcgRXJyb3IoXCJJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZ1wiKX1yZXR1cm4gYWxsb2NVbnNhZmUodGhpcyxhcmcpfXJldHVybiBmcm9tKHRoaXMsYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1CdWZmZXIucG9vbFNpemU9ODE5MjtCdWZmZXIuX2F1Z21lbnQ9ZnVuY3Rpb24oYXJyKXthcnIuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGU7cmV0dXJuIGFycn07ZnVuY3Rpb24gZnJvbSh0aGF0LHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXtyZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfWlmKHR5cGVvZiB2YWx1ZT09PVwic3RyaW5nXCIpe3JldHVybiBmcm9tU3RyaW5nKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCl9cmV0dXJuIGZyb21PYmplY3QodGhhdCx2YWx1ZSl9QnVmZmVyLmZyb209ZnVuY3Rpb24odmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe3JldHVybiBmcm9tKG51bGwsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7QnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX189VWludDhBcnJheS5wcm90b3R5cGU7QnVmZmVyLl9fcHJvdG9fXz1VaW50OEFycmF5O2lmKHR5cGVvZiBTeW1ib2whPT1cInVuZGVmaW5lZFwiJiZTeW1ib2wuc3BlY2llcyYmQnVmZmVyW1N5bWJvbC5zcGVjaWVzXT09PUJ1ZmZlcil7T2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlcixTeW1ib2wuc3BlY2llcyx7dmFsdWU6bnVsbCxjb25maWd1cmFibGU6dHJ1ZX0pfX1mdW5jdGlvbiBhc3NlcnRTaXplKHNpemUpe2lmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpfWVsc2UgaWYoc2l6ZTwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKX19ZnVuY3Rpb24gYWxsb2ModGhhdCxzaXplLGZpbGwsZW5jb2Rpbmcpe2Fzc2VydFNpemUoc2l6ZSk7aWYoc2l6ZTw9MCl7cmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpfWlmKGZpbGwhPT11bmRlZmluZWQpe3JldHVybiB0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiP2NyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpLmZpbGwoZmlsbCxlbmNvZGluZyk6Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSkuZmlsbChmaWxsKX1yZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSl9QnVmZmVyLmFsbG9jPWZ1bmN0aW9uKHNpemUsZmlsbCxlbmNvZGluZyl7cmV0dXJuIGFsbG9jKG51bGwsc2l6ZSxmaWxsLGVuY29kaW5nKX07ZnVuY3Rpb24gYWxsb2NVbnNhZmUodGhhdCxzaXplKXthc3NlcnRTaXplKHNpemUpO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZTwwPzA6Y2hlY2tlZChzaXplKXwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2Zvcih2YXIgaT0wO2k8c2l6ZTsrK2kpe3RoYXRbaV09MH19cmV0dXJuIHRoYXR9QnVmZmVyLmFsbG9jVW5zYWZlPWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtCdWZmZXIuYWxsb2NVbnNhZmVTbG93PWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtmdW5jdGlvbiBmcm9tU3RyaW5nKHRoYXQsc3RyaW5nLGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2RpbmchPT1cInN0cmluZ1wifHxlbmNvZGluZz09PVwiXCIpe2VuY29kaW5nPVwidXRmOFwifWlmKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJyl9dmFyIGxlbmd0aD1ieXRlTGVuZ3RoKHN0cmluZyxlbmNvZGluZyl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCk7dmFyIGFjdHVhbD10aGF0LndyaXRlKHN0cmluZyxlbmNvZGluZyk7aWYoYWN0dWFsIT09bGVuZ3RoKXt0aGF0PXRoYXQuc2xpY2UoMCxhY3R1YWwpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21BcnJheUxpa2UodGhhdCxhcnJheSl7dmFyIGxlbmd0aD1hcnJheS5sZW5ndGg8MD8wOmNoZWNrZWQoYXJyYXkubGVuZ3RoKXwwO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsbGVuZ3RoKTtmb3IodmFyIGk9MDtpPGxlbmd0aDtpKz0xKXt0aGF0W2ldPWFycmF5W2ldJjI1NX1yZXR1cm4gdGhhdH1mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIodGhhdCxhcnJheSxieXRlT2Zmc2V0LGxlbmd0aCl7YXJyYXkuYnl0ZUxlbmd0aDtpZihieXRlT2Zmc2V0PDB8fGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInb2Zmc2V0JyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCsobGVuZ3RofHwwKSl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInbGVuZ3RoJyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGJ5dGVPZmZzZXQ9PT11bmRlZmluZWQmJmxlbmd0aD09PXVuZGVmaW5lZCl7YXJyYXk9bmV3IFVpbnQ4QXJyYXkoYXJyYXkpfWVsc2UgaWYobGVuZ3RoPT09dW5kZWZpbmVkKXthcnJheT1uZXcgVWludDhBcnJheShhcnJheSxieXRlT2Zmc2V0KX1lbHNle2FycmF5PW5ldyBVaW50OEFycmF5KGFycmF5LGJ5dGVPZmZzZXQsbGVuZ3RoKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1hcnJheTt0aGF0Ll9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlfWVsc2V7dGhhdD1mcm9tQXJyYXlMaWtlKHRoYXQsYXJyYXkpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21PYmplY3QodGhhdCxvYmope2lmKEJ1ZmZlci5pc0J1ZmZlcihvYmopKXt2YXIgbGVuPWNoZWNrZWQob2JqLmxlbmd0aCl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbik7aWYodGhhdC5sZW5ndGg9PT0wKXtyZXR1cm4gdGhhdH1vYmouY29weSh0aGF0LDAsMCxsZW4pO3JldHVybiB0aGF0fWlmKG9iail7aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxcImxlbmd0aFwiaW4gb2JqKXtpZih0eXBlb2Ygb2JqLmxlbmd0aCE9PVwibnVtYmVyXCJ8fGlzbmFuKG9iai5sZW5ndGgpKXtyZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsMCl9cmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCxvYmopfWlmKG9iai50eXBlPT09XCJCdWZmZXJcIiYmaXNBcnJheShvYmouZGF0YSkpe3JldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsb2JqLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LlwiKX1mdW5jdGlvbiBjaGVja2VkKGxlbmd0aCl7aWYobGVuZ3RoPj1rTWF4TGVuZ3RoKCkpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSBcIitcInNpemU6IDB4XCIra01heExlbmd0aCgpLnRvU3RyaW5nKDE2KStcIiBieXRlc1wiKX1yZXR1cm4gbGVuZ3RofDB9ZnVuY3Rpb24gU2xvd0J1ZmZlcihsZW5ndGgpe2lmKCtsZW5ndGghPWxlbmd0aCl7bGVuZ3RoPTB9cmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKX1CdWZmZXIuaXNCdWZmZXI9ZnVuY3Rpb24gaXNCdWZmZXIoYil7cmV0dXJuISEoYiE9bnVsbCYmYi5faXNCdWZmZXIpfTtCdWZmZXIuY29tcGFyZT1mdW5jdGlvbiBjb21wYXJlKGEsYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihhKXx8IUJ1ZmZlci5pc0J1ZmZlcihiKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnNcIil9aWYoYT09PWIpcmV0dXJuIDA7dmFyIHg9YS5sZW5ndGg7dmFyIHk9Yi5sZW5ndGg7Zm9yKHZhciBpPTAsbGVuPU1hdGgubWluKHgseSk7aTxsZW47KytpKXtpZihhW2ldIT09YltpXSl7eD1hW2ldO3k9YltpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07QnVmZmVyLmlzRW5jb2Rpbmc9ZnVuY3Rpb24gaXNFbmNvZGluZyhlbmNvZGluZyl7c3dpdGNoKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSl7Y2FzZVwiaGV4XCI6Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpjYXNlXCJiYXNlNjRcIjpjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdHJ1ZTtkZWZhdWx0OnJldHVybiBmYWxzZX19O0J1ZmZlci5jb25jYXQ9ZnVuY3Rpb24gY29uY2F0KGxpc3QsbGVuZ3RoKXtpZighaXNBcnJheShsaXN0KSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9aWYobGlzdC5sZW5ndGg9PT0wKXtyZXR1cm4gQnVmZmVyLmFsbG9jKDApfXZhciBpO2lmKGxlbmd0aD09PXVuZGVmaW5lZCl7bGVuZ3RoPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7bGVuZ3RoKz1saXN0W2ldLmxlbmd0aH19dmFyIGJ1ZmZlcj1CdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKTt2YXIgcG9zPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7dmFyIGJ1Zj1saXN0W2ldO2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9YnVmLmNvcHkoYnVmZmVyLHBvcyk7cG9zKz1idWYubGVuZ3RofXJldHVybiBidWZmZXJ9O2Z1bmN0aW9uIGJ5dGVMZW5ndGgoc3RyaW5nLGVuY29kaW5nKXtpZihCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSl7cmV0dXJuIHN0cmluZy5sZW5ndGh9aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldz09PVwiZnVuY3Rpb25cIiYmKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpfHxzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpe3JldHVybiBzdHJpbmcuYnl0ZUxlbmd0aH1pZih0eXBlb2Ygc3RyaW5nIT09XCJzdHJpbmdcIil7c3RyaW5nPVwiXCIrc3RyaW5nfXZhciBsZW49c3RyaW5nLmxlbmd0aDtpZihsZW49PT0wKXJldHVybiAwO3ZhciBsb3dlcmVkQ2FzZT1mYWxzZTtmb3IoOzspe3N3aXRjaChlbmNvZGluZyl7Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpyZXR1cm4gbGVuO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOmNhc2UgdW5kZWZpbmVkOnJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aDtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gbGVuKjI7Y2FzZVwiaGV4XCI6cmV0dXJuIGxlbj4+PjE7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZGVmYXVsdDppZihsb3dlcmVkQ2FzZSlyZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZW5jb2Rpbmc9KFwiXCIrZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5ieXRlTGVuZ3RoPWJ5dGVMZW5ndGg7ZnVuY3Rpb24gc2xvd1RvU3RyaW5nKGVuY29kaW5nLHN0YXJ0LGVuZCl7dmFyIGxvd2VyZWRDYXNlPWZhbHNlO2lmKHN0YXJ0PT09dW5kZWZpbmVkfHxzdGFydDwwKXtzdGFydD0wfWlmKHN0YXJ0PnRoaXMubGVuZ3RoKXtyZXR1cm5cIlwifWlmKGVuZD09PXVuZGVmaW5lZHx8ZW5kPnRoaXMubGVuZ3RoKXtlbmQ9dGhpcy5sZW5ndGh9aWYoZW5kPD0wKXtyZXR1cm5cIlwifWVuZD4+Pj0wO3N0YXJ0Pj4+PTA7aWYoZW5kPD1zdGFydCl7cmV0dXJuXCJcIn1pZighZW5jb2RpbmcpZW5jb2Rpbmc9XCJ1dGY4XCI7d2hpbGUodHJ1ZSl7c3dpdGNoKGVuY29kaW5nKXtjYXNlXCJoZXhcIjpyZXR1cm4gaGV4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOnJldHVybiB1dGY4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpU2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOnJldHVybiBsYXRpbjFTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsc3RhcnQsZW5kKTtkZWZhdWx0OmlmKGxvd2VyZWRDYXNlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyk7ZW5jb2Rpbmc9KGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyPXRydWU7ZnVuY3Rpb24gc3dhcChiLG4sbSl7dmFyIGk9YltuXTtiW25dPWJbbV07YlttXT1pfUJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2PWZ1bmN0aW9uIHN3YXAxNigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTIhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTIpe3N3YXAodGhpcyxpLGkrMSl9cmV0dXJuIHRoaXN9O0J1ZmZlci5wcm90b3R5cGUuc3dhcDMyPWZ1bmN0aW9uIHN3YXAzMigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTQhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTQpe3N3YXAodGhpcyxpLGkrMyk7c3dhcCh0aGlzLGkrMSxpKzIpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnN3YXA2ND1mdW5jdGlvbiBzd2FwNjQoKXt2YXIgbGVuPXRoaXMubGVuZ3RoO2lmKGxlbiU4IT09MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0c1wiKX1mb3IodmFyIGk9MDtpPGxlbjtpKz04KXtzd2FwKHRoaXMsaSxpKzcpO3N3YXAodGhpcyxpKzEsaSs2KTtzd2FwKHRoaXMsaSsyLGkrNSk7c3dhcCh0aGlzLGkrMyxpKzQpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uIHRvU3RyaW5nKCl7dmFyIGxlbmd0aD10aGlzLmxlbmd0aHwwO2lmKGxlbmd0aD09PTApcmV0dXJuXCJcIjtpZihhcmd1bWVudHMubGVuZ3RoPT09MClyZXR1cm4gdXRmOFNsaWNlKHRoaXMsMCxsZW5ndGgpO3JldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcyxhcmd1bWVudHMpfTtCdWZmZXIucHJvdG90eXBlLmVxdWFscz1mdW5jdGlvbiBlcXVhbHMoYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihiKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKTtpZih0aGlzPT09YilyZXR1cm4gdHJ1ZTtyZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcyxiKT09PTB9O0J1ZmZlci5wcm90b3R5cGUuaW5zcGVjdD1mdW5jdGlvbiBpbnNwZWN0KCl7dmFyIHN0cj1cIlwiO3ZhciBtYXg9ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUztpZih0aGlzLmxlbmd0aD4wKXtzdHI9dGhpcy50b1N0cmluZyhcImhleFwiLDAsbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKFwiIFwiKTtpZih0aGlzLmxlbmd0aD5tYXgpc3RyKz1cIiAuLi4gXCJ9cmV0dXJuXCI8QnVmZmVyIFwiK3N0citcIj5cIn07QnVmZmVyLnByb3RvdHlwZS5jb21wYXJlPWZ1bmN0aW9uIGNvbXBhcmUodGFyZ2V0LHN0YXJ0LGVuZCx0aGlzU3RhcnQsdGhpc0VuZCl7aWYoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKX1pZihzdGFydD09PXVuZGVmaW5lZCl7c3RhcnQ9MH1pZihlbmQ9PT11bmRlZmluZWQpe2VuZD10YXJnZXQ/dGFyZ2V0Lmxlbmd0aDowfWlmKHRoaXNTdGFydD09PXVuZGVmaW5lZCl7dGhpc1N0YXJ0PTB9aWYodGhpc0VuZD09PXVuZGVmaW5lZCl7dGhpc0VuZD10aGlzLmxlbmd0aH1pZihzdGFydDwwfHxlbmQ+dGFyZ2V0Lmxlbmd0aHx8dGhpc1N0YXJ0PDB8fHRoaXNFbmQ+dGhpcy5sZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwib3V0IG9mIHJhbmdlIGluZGV4XCIpfWlmKHRoaXNTdGFydD49dGhpc0VuZCYmc3RhcnQ+PWVuZCl7cmV0dXJuIDB9aWYodGhpc1N0YXJ0Pj10aGlzRW5kKXtyZXR1cm4tMX1pZihzdGFydD49ZW5kKXtyZXR1cm4gMX1zdGFydD4+Pj0wO2VuZD4+Pj0wO3RoaXNTdGFydD4+Pj0wO3RoaXNFbmQ+Pj49MDtpZih0aGlzPT09dGFyZ2V0KXJldHVybiAwO3ZhciB4PXRoaXNFbmQtdGhpc1N0YXJ0O3ZhciB5PWVuZC1zdGFydDt2YXIgbGVuPU1hdGgubWluKHgseSk7dmFyIHRoaXNDb3B5PXRoaXMuc2xpY2UodGhpc1N0YXJ0LHRoaXNFbmQpO3ZhciB0YXJnZXRDb3B5PXRhcmdldC5zbGljZShzdGFydCxlbmQpO2Zvcih2YXIgaT0wO2k8bGVuOysraSl7aWYodGhpc0NvcHlbaV0hPT10YXJnZXRDb3B5W2ldKXt4PXRoaXNDb3B5W2ldO3k9dGFyZ2V0Q29weVtpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07ZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YoYnVmZmVyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7aWYoYnVmZmVyLmxlbmd0aD09PTApcmV0dXJuLTE7aWYodHlwZW9mIGJ5dGVPZmZzZXQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1ieXRlT2Zmc2V0O2J5dGVPZmZzZXQ9MH1lbHNlIGlmKGJ5dGVPZmZzZXQ+MjE0NzQ4MzY0Nyl7Ynl0ZU9mZnNldD0yMTQ3NDgzNjQ3fWVsc2UgaWYoYnl0ZU9mZnNldDwtMjE0NzQ4MzY0OCl7Ynl0ZU9mZnNldD0tMjE0NzQ4MzY0OH1ieXRlT2Zmc2V0PStieXRlT2Zmc2V0O2lmKGlzTmFOKGJ5dGVPZmZzZXQpKXtieXRlT2Zmc2V0PWRpcj8wOmJ1ZmZlci5sZW5ndGgtMX1pZihieXRlT2Zmc2V0PDApYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoK2J5dGVPZmZzZXQ7aWYoYnl0ZU9mZnNldD49YnVmZmVyLmxlbmd0aCl7aWYoZGlyKXJldHVybi0xO2Vsc2UgYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoLTF9ZWxzZSBpZihieXRlT2Zmc2V0PDApe2lmKGRpcilieXRlT2Zmc2V0PTA7ZWxzZSByZXR1cm4tMX1pZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7dmFsPUJ1ZmZlci5mcm9tKHZhbCxlbmNvZGluZyl9aWYoQnVmZmVyLmlzQnVmZmVyKHZhbCkpe2lmKHZhbC5sZW5ndGg9PT0wKXtyZXR1cm4tMX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpfWVsc2UgaWYodHlwZW9mIHZhbD09PVwibnVtYmVyXCIpe3ZhbD12YWwmMjU1O2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUJiZ0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZj09PVwiZnVuY3Rpb25cIil7aWYoZGlyKXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCl9ZWxzZXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsdmFsLGJ5dGVPZmZzZXQpfX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcixbdmFsXSxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil9dGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlclwiKX1mdW5jdGlvbiBhcnJheUluZGV4T2YoYXJyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7dmFyIGluZGV4U2l6ZT0xO3ZhciBhcnJMZW5ndGg9YXJyLmxlbmd0aDt2YXIgdmFsTGVuZ3RoPXZhbC5sZW5ndGg7aWYoZW5jb2RpbmchPT11bmRlZmluZWQpe2VuY29kaW5nPVN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKTtpZihlbmNvZGluZz09PVwidWNzMlwifHxlbmNvZGluZz09PVwidWNzLTJcInx8ZW5jb2Rpbmc9PT1cInV0ZjE2bGVcInx8ZW5jb2Rpbmc9PT1cInV0Zi0xNmxlXCIpe2lmKGFyci5sZW5ndGg8Mnx8dmFsLmxlbmd0aDwyKXtyZXR1cm4tMX1pbmRleFNpemU9MjthcnJMZW5ndGgvPTI7dmFsTGVuZ3RoLz0yO2J5dGVPZmZzZXQvPTJ9fWZ1bmN0aW9uIHJlYWQoYnVmLGkpe2lmKGluZGV4U2l6ZT09PTEpe3JldHVybiBidWZbaV19ZWxzZXtyZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpKmluZGV4U2l6ZSl9fXZhciBpO2lmKGRpcil7dmFyIGZvdW5kSW5kZXg9LTE7Zm9yKGk9Ynl0ZU9mZnNldDtpPGFyckxlbmd0aDtpKyspe2lmKHJlYWQoYXJyLGkpPT09cmVhZCh2YWwsZm91bmRJbmRleD09PS0xPzA6aS1mb3VuZEluZGV4KSl7aWYoZm91bmRJbmRleD09PS0xKWZvdW5kSW5kZXg9aTtpZihpLWZvdW5kSW5kZXgrMT09PXZhbExlbmd0aClyZXR1cm4gZm91bmRJbmRleCppbmRleFNpemV9ZWxzZXtpZihmb3VuZEluZGV4IT09LTEpaS09aS1mb3VuZEluZGV4O2ZvdW5kSW5kZXg9LTF9fX1lbHNle2lmKGJ5dGVPZmZzZXQrdmFsTGVuZ3RoPmFyckxlbmd0aClieXRlT2Zmc2V0PWFyckxlbmd0aC12YWxMZW5ndGg7Zm9yKGk9Ynl0ZU9mZnNldDtpPj0wO2ktLSl7dmFyIGZvdW5kPXRydWU7Zm9yKHZhciBqPTA7ajx2YWxMZW5ndGg7aisrKXtpZihyZWFkKGFycixpK2opIT09cmVhZCh2YWwsaikpe2ZvdW5kPWZhbHNlO2JyZWFrfX1pZihmb3VuZClyZXR1cm4gaX19cmV0dXJuLTF9QnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcz1mdW5jdGlvbiBpbmNsdWRlcyh2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyl7cmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsYnl0ZU9mZnNldCxlbmNvZGluZykhPT0tMX07QnVmZmVyLnByb3RvdHlwZS5pbmRleE9mPWZ1bmN0aW9uIGluZGV4T2YodmFsLGJ5dGVPZmZzZXQsZW5jb2Rpbmcpe3JldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLHRydWUpfTtCdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mPWZ1bmN0aW9uIGxhc3RJbmRleE9mKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKXtyZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcyx2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxmYWxzZSl9O2Z1bmN0aW9uIGhleFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7b2Zmc2V0PU51bWJlcihvZmZzZXQpfHwwO3ZhciByZW1haW5pbmc9YnVmLmxlbmd0aC1vZmZzZXQ7aWYoIWxlbmd0aCl7bGVuZ3RoPXJlbWFpbmluZ31lbHNle2xlbmd0aD1OdW1iZXIobGVuZ3RoKTtpZihsZW5ndGg+cmVtYWluaW5nKXtsZW5ndGg9cmVtYWluaW5nfX12YXIgc3RyTGVuPXN0cmluZy5sZW5ndGg7aWYoc3RyTGVuJTIhPT0wKXRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGhleCBzdHJpbmdcIik7aWYobGVuZ3RoPnN0ckxlbi8yKXtsZW5ndGg9c3RyTGVuLzJ9Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXt2YXIgcGFyc2VkPXBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSoyLDIpLDE2KTtpZihpc05hTihwYXJzZWQpKXJldHVybiBpO2J1ZltvZmZzZXQraV09cGFyc2VkfXJldHVybiBpfWZ1bmN0aW9uIHV0ZjhXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyxidWYubGVuZ3RoLW9mZnNldCksYnVmLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGFzY2lpV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSxidWYsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gbGF0aW4xV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYXNjaWlXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGJhc2U2NFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiB1Y3MyV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsYnVmLmxlbmd0aC1vZmZzZXQpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1CdWZmZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uIHdyaXRlKHN0cmluZyxvZmZzZXQsbGVuZ3RoLGVuY29kaW5nKXtpZihvZmZzZXQ9PT11bmRlZmluZWQpe2VuY29kaW5nPVwidXRmOFwiO2xlbmd0aD10aGlzLmxlbmd0aDtvZmZzZXQ9MH1lbHNlIGlmKGxlbmd0aD09PXVuZGVmaW5lZCYmdHlwZW9mIG9mZnNldD09PVwic3RyaW5nXCIpe2VuY29kaW5nPW9mZnNldDtsZW5ndGg9dGhpcy5sZW5ndGg7b2Zmc2V0PTB9ZWxzZSBpZihpc0Zpbml0ZShvZmZzZXQpKXtvZmZzZXQ9b2Zmc2V0fDA7aWYoaXNGaW5pdGUobGVuZ3RoKSl7bGVuZ3RoPWxlbmd0aHwwO2lmKGVuY29kaW5nPT09dW5kZWZpbmVkKWVuY29kaW5nPVwidXRmOFwifWVsc2V7ZW5jb2Rpbmc9bGVuZ3RoO2xlbmd0aD11bmRlZmluZWR9fWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWRcIil9dmFyIHJlbWFpbmluZz10aGlzLmxlbmd0aC1vZmZzZXQ7aWYobGVuZ3RoPT09dW5kZWZpbmVkfHxsZW5ndGg+cmVtYWluaW5nKWxlbmd0aD1yZW1haW5pbmc7aWYoc3RyaW5nLmxlbmd0aD4wJiYobGVuZ3RoPDB8fG9mZnNldDwwKXx8b2Zmc2V0PnRoaXMubGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkF0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzXCIpfWlmKCFlbmNvZGluZyllbmNvZGluZz1cInV0ZjhcIjt2YXIgbG93ZXJlZENhc2U9ZmFsc2U7Zm9yKDs7KXtzd2l0Y2goZW5jb2Rpbmcpe2Nhc2VcImhleFwiOnJldHVybiBoZXhXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpyZXR1cm4gdXRmOFdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpV3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6cmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImJhc2U2NFwiOnJldHVybiBiYXNlNjRXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdWNzMldyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2RlZmF1bHQ6aWYobG93ZXJlZENhc2UpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtlbmNvZGluZz0oXCJcIitlbmNvZGluZykudG9Mb3dlckNhc2UoKTtsb3dlcmVkQ2FzZT10cnVlfX19O0J1ZmZlci5wcm90b3R5cGUudG9KU09OPWZ1bmN0aW9uIHRvSlNPTigpe3JldHVybnt0eXBlOlwiQnVmZmVyXCIsZGF0YTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnJ8fHRoaXMsMCl9fTtmdW5jdGlvbiBiYXNlNjRTbGljZShidWYsc3RhcnQsZW5kKXtpZihzdGFydD09PTAmJmVuZD09PWJ1Zi5sZW5ndGgpe3JldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpfWVsc2V7cmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCxlbmQpKX19ZnVuY3Rpb24gdXRmOFNsaWNlKGJ1ZixzdGFydCxlbmQpe2VuZD1NYXRoLm1pbihidWYubGVuZ3RoLGVuZCk7dmFyIHJlcz1bXTt2YXIgaT1zdGFydDt3aGlsZShpPGVuZCl7dmFyIGZpcnN0Qnl0ZT1idWZbaV07dmFyIGNvZGVQb2ludD1udWxsO3ZhciBieXRlc1BlclNlcXVlbmNlPWZpcnN0Qnl0ZT4yMzk/NDpmaXJzdEJ5dGU+MjIzPzM6Zmlyc3RCeXRlPjE5MT8yOjE7aWYoaStieXRlc1BlclNlcXVlbmNlPD1lbmQpe3ZhciBzZWNvbmRCeXRlLHRoaXJkQnl0ZSxmb3VydGhCeXRlLHRlbXBDb2RlUG9pbnQ7c3dpdGNoKGJ5dGVzUGVyU2VxdWVuY2Upe2Nhc2UgMTppZihmaXJzdEJ5dGU8MTI4KXtjb2RlUG9pbnQ9Zmlyc3RCeXRlfWJyZWFrO2Nhc2UgMjpzZWNvbmRCeXRlPWJ1ZltpKzFdO2lmKChzZWNvbmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYzMSk8PDZ8c2Vjb25kQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjEyNyl7Y29kZVBvaW50PXRlbXBDb2RlUG9pbnR9fWJyZWFrO2Nhc2UgMzpzZWNvbmRCeXRlPWJ1ZltpKzFdO3RoaXJkQnl0ZT1idWZbaSsyXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDEyfChzZWNvbmRCeXRlJjYzKTw8Nnx0aGlyZEJ5dGUmNjM7aWYodGVtcENvZGVQb2ludD4yMDQ3JiYodGVtcENvZGVQb2ludDw1NTI5Nnx8dGVtcENvZGVQb2ludD41NzM0Mykpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX1icmVhaztjYXNlIDQ6c2Vjb25kQnl0ZT1idWZbaSsxXTt0aGlyZEJ5dGU9YnVmW2krMl07Zm91cnRoQnl0ZT1idWZbaSszXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgmJihmb3VydGhCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDE4fChzZWNvbmRCeXRlJjYzKTw8MTJ8KHRoaXJkQnl0ZSY2Myk8PDZ8Zm91cnRoQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjY1NTM1JiZ0ZW1wQ29kZVBvaW50PDExMTQxMTIpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX19fWlmKGNvZGVQb2ludD09PW51bGwpe2NvZGVQb2ludD02NTUzMztieXRlc1BlclNlcXVlbmNlPTF9ZWxzZSBpZihjb2RlUG9pbnQ+NjU1MzUpe2NvZGVQb2ludC09NjU1MzY7cmVzLnB1c2goY29kZVBvaW50Pj4+MTAmMTAyM3w1NTI5Nik7Y29kZVBvaW50PTU2MzIwfGNvZGVQb2ludCYxMDIzfXJlcy5wdXNoKGNvZGVQb2ludCk7aSs9Ynl0ZXNQZXJTZXF1ZW5jZX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcyl9dmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIPTQwOTY7ZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5KGNvZGVQb2ludHMpe3ZhciBsZW49Y29kZVBvaW50cy5sZW5ndGg7aWYobGVuPD1NQVhfQVJHVU1FTlRTX0xFTkdUSCl7cmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMpfXZhciByZXM9XCJcIjt2YXIgaT0wO3doaWxlKGk8bGVuKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMuc2xpY2UoaSxpKz1NQVhfQVJHVU1FTlRTX0xFTkdUSCkpfXJldHVybiByZXN9ZnVuY3Rpb24gYXNjaWlTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldJjEyNyl9cmV0dXJuIHJldH1mdW5jdGlvbiBsYXRpbjFTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGhleFNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciBsZW49YnVmLmxlbmd0aDtpZighc3RhcnR8fHN0YXJ0PDApc3RhcnQ9MDtpZighZW5kfHxlbmQ8MHx8ZW5kPmxlbillbmQ9bGVuO3ZhciBvdXQ9XCJcIjtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtvdXQrPXRvSGV4KGJ1ZltpXSl9cmV0dXJuIG91dH1mdW5jdGlvbiB1dGYxNmxlU2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIGJ5dGVzPWJ1Zi5zbGljZShzdGFydCxlbmQpO3ZhciByZXM9XCJcIjtmb3IodmFyIGk9MDtpPGJ5dGVzLmxlbmd0aDtpKz0yKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0rYnl0ZXNbaSsxXSoyNTYpfXJldHVybiByZXN9QnVmZmVyLnByb3RvdHlwZS5zbGljZT1mdW5jdGlvbiBzbGljZShzdGFydCxlbmQpe3ZhciBsZW49dGhpcy5sZW5ndGg7c3RhcnQ9fn5zdGFydDtlbmQ9ZW5kPT09dW5kZWZpbmVkP2xlbjp+fmVuZDtpZihzdGFydDwwKXtzdGFydCs9bGVuO2lmKHN0YXJ0PDApc3RhcnQ9MH1lbHNlIGlmKHN0YXJ0Pmxlbil7c3RhcnQ9bGVufWlmKGVuZDwwKXtlbmQrPWxlbjtpZihlbmQ8MCllbmQ9MH1lbHNlIGlmKGVuZD5sZW4pe2VuZD1sZW59aWYoZW5kPHN0YXJ0KWVuZD1zdGFydDt2YXIgbmV3QnVmO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtuZXdCdWY9dGhpcy5zdWJhcnJheShzdGFydCxlbmQpO25ld0J1Zi5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZX1lbHNle3ZhciBzbGljZUxlbj1lbmQtc3RhcnQ7bmV3QnVmPW5ldyBCdWZmZXIoc2xpY2VMZW4sdW5kZWZpbmVkKTtmb3IodmFyIGk9MDtpPHNsaWNlTGVuOysraSl7bmV3QnVmW2ldPXRoaXNbaStzdGFydF19fXJldHVybiBuZXdCdWZ9O2Z1bmN0aW9uIGNoZWNrT2Zmc2V0KG9mZnNldCxleHQsbGVuZ3RoKXtpZihvZmZzZXQlMSE9PTB8fG9mZnNldDwwKXRocm93IG5ldyBSYW5nZUVycm9yKFwib2Zmc2V0IGlzIG5vdCB1aW50XCIpO2lmKG9mZnNldCtleHQ+bGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aFwiKX1CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEU9ZnVuY3Rpb24gcmVhZFVJbnRMRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldF07dmFyIG11bD0xO3ZhciBpPTA7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQraV0qbXVsfXJldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRT1mdW5jdGlvbiByZWFkVUludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KXtjaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCl9dmFyIHZhbD10aGlzW29mZnNldCstLWJ5dGVMZW5ndGhdO3ZhciBtdWw9MTt3aGlsZShieXRlTGVuZ3RoPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1ieXRlTGVuZ3RoXSptdWx9cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDg9ZnVuY3Rpb24gcmVhZFVJbnQ4KG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwxLHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRT1mdW5jdGlvbiByZWFkVUludDE2TEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFPWZ1bmN0aW9uIHJlYWRVSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8OHx0aGlzW29mZnNldCsxXX07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEU9ZnVuY3Rpb24gcmVhZFVJbnQzMkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4odGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4fHRoaXNbb2Zmc2V0KzJdPDwxNikrdGhpc1tvZmZzZXQrM10qMTY3NzcyMTZ9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFPWZ1bmN0aW9uIHJlYWRVSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XSoxNjc3NzIxNisodGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdKX07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEU9ZnVuY3Rpb24gcmVhZEludExFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XTt2YXIgbXVsPTE7dmFyIGk9MDt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCtpXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkU9ZnVuY3Rpb24gcmVhZEludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTtcbnZhciBpPWJ5dGVMZW5ndGg7dmFyIG11bD0xO3ZhciB2YWw9dGhpc1tvZmZzZXQrLS1pXTt3aGlsZShpPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1pXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OD1mdW5jdGlvbiByZWFkSW50OChvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMSx0aGlzLmxlbmd0aCk7aWYoISh0aGlzW29mZnNldF0mMTI4KSlyZXR1cm4gdGhpc1tvZmZzZXRdO3JldHVybigyNTUtdGhpc1tvZmZzZXRdKzEpKi0xfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFPWZ1bmN0aW9uIHJlYWRJbnQxNkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8ODtyZXR1cm4gdmFsJjMyNzY4P3ZhbHw0Mjk0OTAxNzYwOnZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRT1mdW5jdGlvbiByZWFkSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldCsxXXx0aGlzW29mZnNldF08PDg7cmV0dXJuIHZhbCYzMjc2OD92YWx8NDI5NDkwMTc2MDp2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEU9ZnVuY3Rpb24gcmVhZEludDMyTEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh8dGhpc1tvZmZzZXQrMl08PDE2fHRoaXNbb2Zmc2V0KzNdPDwyNH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRT1mdW5jdGlvbiByZWFkSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8MjR8dGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFPWZ1bmN0aW9uIHJlYWRGbG9hdExFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LHRydWUsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkU9ZnVuY3Rpb24gcmVhZEZsb2F0QkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFPWZ1bmN0aW9uIHJlYWREb3VibGVMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsOCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCx0cnVlLDUyLDgpfTtCdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRT1mdW5jdGlvbiByZWFkRG91YmxlQkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDgsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsNTIsOCl9O2Z1bmN0aW9uIGNoZWNrSW50KGJ1Zix2YWx1ZSxvZmZzZXQsZXh0LG1heCxtaW4pe2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKTtpZih2YWx1ZT5tYXh8fHZhbHVlPG1pbil0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKTtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRT1mdW5jdGlvbiB3cml0ZVVJbnRMRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpe3ZhciBtYXhCeXRlcz1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCktMTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG1heEJ5dGVzLDApfXZhciBtdWw9MTt2YXIgaT0wO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3RoaXNbb2Zmc2V0K2ldPXZhbHVlL211bCYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFPWZ1bmN0aW9uIHdyaXRlVUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCl7dmFyIG1heEJ5dGVzPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKS0xO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbWF4Qnl0ZXMsMCl9dmFyIGk9Ynl0ZUxlbmd0aC0xO3ZhciBtdWw9MTt0aGlzW29mZnNldCtpXT12YWx1ZSYyNTU7d2hpbGUoLS1pPj0wJiYobXVsKj0yNTYpKXt0aGlzW29mZnNldCtpXT12YWx1ZS9tdWwmMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4PWZ1bmN0aW9uIHdyaXRlVUludDgodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwxLDI1NSwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpdmFsdWU9TWF0aC5mbG9vcih2YWx1ZSk7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2KGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTY1NTM1K3ZhbHVlKzE7Zm9yKHZhciBpPTAsaj1NYXRoLm1pbihidWYubGVuZ3RoLW9mZnNldCwyKTtpPGo7KytpKXtidWZbb2Zmc2V0K2ldPSh2YWx1ZSYyNTU8PDgqKGxpdHRsZUVuZGlhbj9pOjEtaSkpPj4+KGxpdHRsZUVuZGlhbj9pOjEtaSkqOH19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlVUludDE2TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+OH1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrMn07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlVUludDE2QkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzFdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzJ9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTQyOTQ5NjcyOTUrdmFsdWUrMTtmb3IodmFyIGk9MCxqPU1hdGgubWluKGJ1Zi5sZW5ndGgtb2Zmc2V0LDQpO2k8ajsrK2kpe2J1ZltvZmZzZXQraV09dmFsdWU+Pj4obGl0dGxlRW5kaWFuP2k6My1pKSo4JjI1NX19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFPWZ1bmN0aW9uIHdyaXRlVUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjQ7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrNH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlVUludDMyQkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRT1mdW5jdGlvbiB3cml0ZUludExFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPTA7dmFyIG11bD0xO3ZhciBzdWI9MDt0aGlzW29mZnNldF09dmFsdWUmMjU1O3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXtpZih2YWx1ZTwwJiZzdWI9PT0wJiZ0aGlzW29mZnNldCtpLTFdIT09MCl7c3ViPTF9dGhpc1tvZmZzZXQraV09KHZhbHVlL211bD4+MCktc3ViJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRT1mdW5jdGlvbiB3cml0ZUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPWJ5dGVMZW5ndGgtMTt2YXIgbXVsPTE7dmFyIHN1Yj0wO3RoaXNbb2Zmc2V0K2ldPXZhbHVlJjI1NTt3aGlsZSgtLWk+PTAmJihtdWwqPTI1Nikpe2lmKHZhbHVlPDAmJnN1Yj09PTAmJnRoaXNbb2Zmc2V0K2krMV0hPT0wKXtzdWI9MX10aGlzW29mZnNldCtpXT0odmFsdWUvbXVsPj4wKS1zdWImMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDg9ZnVuY3Rpb24gd3JpdGVJbnQ4KHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMSwxMjcsLTEyOCk7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXZhbHVlPU1hdGguZmxvb3IodmFsdWUpO2lmKHZhbHVlPDApdmFsdWU9MjU1K3ZhbHVlKzE7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlSW50MTZMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjh9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzJ9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlSW50MTZCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsxXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCsyfTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRT1mdW5jdGlvbiB3cml0ZUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDIxNDc0ODM2NDcsLTIxNDc0ODM2NDgpO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsyXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjR9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlSW50MzJCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsMjE0NzQ4MzY0NywtMjE0NzQ4MzY0OCk7aWYodmFsdWU8MCl2YWx1ZT00Mjk0OTY3Mjk1K3ZhbHVlKzE7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O2Z1bmN0aW9uIGNoZWNrSUVFRTc1NChidWYsdmFsdWUsb2Zmc2V0LGV4dCxtYXgsbWluKXtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIik7aWYob2Zmc2V0PDApdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9ZnVuY3Rpb24gd3JpdGVGbG9hdChidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw0LDMuNDAyODIzNDY2Mzg1Mjg4NmUzOCwtMy40MDI4MjM0NjYzODUyODg2ZTM4KX1pZWVlNzU0LndyaXRlKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLDIzLDQpO3JldHVybiBvZmZzZXQrNH1CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRT1mdW5jdGlvbiB3cml0ZUZsb2F0TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVGbG9hdCh0aGlzLHZhbHVlLG9mZnNldCx0cnVlLG5vQXNzZXJ0KX07QnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkU9ZnVuY3Rpb24gd3JpdGVGbG9hdEJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRmxvYXQodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2Usbm9Bc3NlcnQpfTtmdW5jdGlvbiB3cml0ZURvdWJsZShidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw4LDEuNzk3NjkzMTM0ODYyMzE1N2UzMDgsLTEuNzk3NjkzMTM0ODYyMzE1N2UzMDgpfWllZWU3NTQud3JpdGUoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sNTIsOCk7cmV0dXJuIG9mZnNldCs4fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRT1mdW5jdGlvbiB3cml0ZURvdWJsZUxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUsbm9Bc3NlcnQpfTtCdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkU9ZnVuY3Rpb24gd3JpdGVEb3VibGVCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZURvdWJsZSh0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSxub0Fzc2VydCl9O0J1ZmZlci5wcm90b3R5cGUuY29weT1mdW5jdGlvbiBjb3B5KHRhcmdldCx0YXJnZXRTdGFydCxzdGFydCxlbmQpe2lmKCFzdGFydClzdGFydD0wO2lmKCFlbmQmJmVuZCE9PTApZW5kPXRoaXMubGVuZ3RoO2lmKHRhcmdldFN0YXJ0Pj10YXJnZXQubGVuZ3RoKXRhcmdldFN0YXJ0PXRhcmdldC5sZW5ndGg7aWYoIXRhcmdldFN0YXJ0KXRhcmdldFN0YXJ0PTA7aWYoZW5kPjAmJmVuZDxzdGFydCllbmQ9c3RhcnQ7aWYoZW5kPT09c3RhcnQpcmV0dXJuIDA7aWYodGFyZ2V0Lmxlbmd0aD09PTB8fHRoaXMubGVuZ3RoPT09MClyZXR1cm4gMDtpZih0YXJnZXRTdGFydDwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInRhcmdldFN0YXJ0IG91dCBvZiBib3VuZHNcIil9aWYoc3RhcnQ8MHx8c3RhcnQ+PXRoaXMubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwic291cmNlU3RhcnQgb3V0IG9mIGJvdW5kc1wiKTtpZihlbmQ8MCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNvdXJjZUVuZCBvdXQgb2YgYm91bmRzXCIpO2lmKGVuZD50aGlzLmxlbmd0aCllbmQ9dGhpcy5sZW5ndGg7aWYodGFyZ2V0Lmxlbmd0aC10YXJnZXRTdGFydDxlbmQtc3RhcnQpe2VuZD10YXJnZXQubGVuZ3RoLXRhcmdldFN0YXJ0K3N0YXJ0fXZhciBsZW49ZW5kLXN0YXJ0O3ZhciBpO2lmKHRoaXM9PT10YXJnZXQmJnN0YXJ0PHRhcmdldFN0YXJ0JiZ0YXJnZXRTdGFydDxlbmQpe2ZvcihpPWxlbi0xO2k+PTA7LS1pKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZSBpZihsZW48MWUzfHwhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2ZvcihpPTA7aTxsZW47KytpKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZXtVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbCh0YXJnZXQsdGhpcy5zdWJhcnJheShzdGFydCxzdGFydCtsZW4pLHRhcmdldFN0YXJ0KX1yZXR1cm4gbGVufTtCdWZmZXIucHJvdG90eXBlLmZpbGw9ZnVuY3Rpb24gZmlsbCh2YWwsc3RhcnQsZW5kLGVuY29kaW5nKXtpZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7aWYodHlwZW9mIHN0YXJ0PT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9c3RhcnQ7c3RhcnQ9MDtlbmQ9dGhpcy5sZW5ndGh9ZWxzZSBpZih0eXBlb2YgZW5kPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5kO2VuZD10aGlzLmxlbmd0aH1pZih2YWwubGVuZ3RoPT09MSl7dmFyIGNvZGU9dmFsLmNoYXJDb2RlQXQoMCk7aWYoY29kZTwyNTYpe3ZhbD1jb2RlfX1pZihlbmNvZGluZyE9PXVuZGVmaW5lZCYmdHlwZW9mIGVuY29kaW5nIT09XCJzdHJpbmdcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcImVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmdcIil9aWYodHlwZW9mIGVuY29kaW5nPT09XCJzdHJpbmdcIiYmIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19ZWxzZSBpZih0eXBlb2YgdmFsPT09XCJudW1iZXJcIil7dmFsPXZhbCYyNTV9aWYoc3RhcnQ8MHx8dGhpcy5sZW5ndGg8c3RhcnR8fHRoaXMubGVuZ3RoPGVuZCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJPdXQgb2YgcmFuZ2UgaW5kZXhcIil9aWYoZW5kPD1zdGFydCl7cmV0dXJuIHRoaXN9c3RhcnQ9c3RhcnQ+Pj4wO2VuZD1lbmQ9PT11bmRlZmluZWQ/dGhpcy5sZW5ndGg6ZW5kPj4+MDtpZighdmFsKXZhbD0wO3ZhciBpO2lmKHR5cGVvZiB2YWw9PT1cIm51bWJlclwiKXtmb3IoaT1zdGFydDtpPGVuZDsrK2kpe3RoaXNbaV09dmFsfX1lbHNle3ZhciBieXRlcz1CdWZmZXIuaXNCdWZmZXIodmFsKT92YWw6dXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsZW5jb2RpbmcpLnRvU3RyaW5nKCkpO3ZhciBsZW49Ynl0ZXMubGVuZ3RoO2ZvcihpPTA7aTxlbmQtc3RhcnQ7KytpKXt0aGlzW2krc3RhcnRdPWJ5dGVzW2klbGVuXX19cmV0dXJuIHRoaXN9O3ZhciBJTlZBTElEX0JBU0U2NF9SRT0vW14rXFwvMC05QS1aYS16LV9dL2c7ZnVuY3Rpb24gYmFzZTY0Y2xlYW4oc3RyKXtzdHI9c3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsXCJcIik7aWYoc3RyLmxlbmd0aDwyKXJldHVyblwiXCI7d2hpbGUoc3RyLmxlbmd0aCU0IT09MCl7c3RyPXN0citcIj1cIn1yZXR1cm4gc3RyfWZ1bmN0aW9uIHN0cmluZ3RyaW0oc3RyKXtpZihzdHIudHJpbSlyZXR1cm4gc3RyLnRyaW0oKTtyZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csXCJcIil9ZnVuY3Rpb24gdG9IZXgobil7aWYobjwxNilyZXR1cm5cIjBcIituLnRvU3RyaW5nKDE2KTtyZXR1cm4gbi50b1N0cmluZygxNil9ZnVuY3Rpb24gdXRmOFRvQnl0ZXMoc3RyaW5nLHVuaXRzKXt1bml0cz11bml0c3x8SW5maW5pdHk7dmFyIGNvZGVQb2ludDt2YXIgbGVuZ3RoPXN0cmluZy5sZW5ndGg7dmFyIGxlYWRTdXJyb2dhdGU9bnVsbDt2YXIgYnl0ZXM9W107Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtjb2RlUG9pbnQ9c3RyaW5nLmNoYXJDb2RlQXQoaSk7aWYoY29kZVBvaW50PjU1Mjk1JiZjb2RlUG9pbnQ8NTczNDQpe2lmKCFsZWFkU3Vycm9nYXRlKXtpZihjb2RlUG9pbnQ+NTYzMTkpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9ZWxzZSBpZihpKzE9PT1sZW5ndGgpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9bGVhZFN1cnJvZ2F0ZT1jb2RlUG9pbnQ7Y29udGludWV9aWYoY29kZVBvaW50PDU2MzIwKXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpO2xlYWRTdXJyb2dhdGU9Y29kZVBvaW50O2NvbnRpbnVlfWNvZGVQb2ludD0obGVhZFN1cnJvZ2F0ZS01NTI5Njw8MTB8Y29kZVBvaW50LTU2MzIwKSs2NTUzNn1lbHNlIGlmKGxlYWRTdXJyb2dhdGUpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSl9bGVhZFN1cnJvZ2F0ZT1udWxsO2lmKGNvZGVQb2ludDwxMjgpe2lmKCh1bml0cy09MSk8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludCl9ZWxzZSBpZihjb2RlUG9pbnQ8MjA0OCl7aWYoKHVuaXRzLT0yKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj42fDE5Mixjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDw2NTUzNil7aWYoKHVuaXRzLT0zKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj4xMnwyMjQsY29kZVBvaW50Pj42JjYzfDEyOCxjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDwxMTE0MTEyKXtpZigodW5pdHMtPTQpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQ+PjE4fDI0MCxjb2RlUG9pbnQ+PjEyJjYzfDEyOCxjb2RlUG9pbnQ+PjYmNjN8MTI4LGNvZGVQb2ludCY2M3wxMjgpfWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBjb2RlIHBvaW50XCIpfX1yZXR1cm4gYnl0ZXN9ZnVuY3Rpb24gYXNjaWlUb0J5dGVzKHN0cil7dmFyIGJ5dGVBcnJheT1bXTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXtieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSYyNTUpfXJldHVybiBieXRlQXJyYXl9ZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMoc3RyLHVuaXRzKXt2YXIgYyxoaSxsbzt2YXIgYnl0ZUFycmF5PVtdO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe2lmKCh1bml0cy09Mik8MClicmVhaztjPXN0ci5jaGFyQ29kZUF0KGkpO2hpPWM+Pjg7bG89YyUyNTY7Ynl0ZUFycmF5LnB1c2gobG8pO2J5dGVBcnJheS5wdXNoKGhpKX1yZXR1cm4gYnl0ZUFycmF5fWZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMoc3RyKXtyZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpfWZ1bmN0aW9uIGJsaXRCdWZmZXIoc3JjLGRzdCxvZmZzZXQsbGVuZ3RoKXtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe2lmKGkrb2Zmc2V0Pj1kc3QubGVuZ3RofHxpPj1zcmMubGVuZ3RoKWJyZWFrO2RzdFtpK29mZnNldF09c3JjW2ldfXJldHVybiBpfWZ1bmN0aW9uIGlzbmFuKHZhbCl7cmV0dXJuIHZhbCE9PXZhbH19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtcImJhc2U2NC1qc1wiOjIsaWVlZTc1NDozNyxpc2FycmF5OjQwfV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKEJ1ZmZlcil7ZnVuY3Rpb24gaXNBcnJheShhcmcpe2lmKEFycmF5LmlzQXJyYXkpe3JldHVybiBBcnJheS5pc0FycmF5KGFyZyl9cmV0dXJuIG9iamVjdFRvU3RyaW5nKGFyZyk9PT1cIltvYmplY3QgQXJyYXldXCJ9ZXhwb3J0cy5pc0FycmF5PWlzQXJyYXk7ZnVuY3Rpb24gaXNCb29sZWFuKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cImJvb2xlYW5cIn1leHBvcnRzLmlzQm9vbGVhbj1pc0Jvb2xlYW47ZnVuY3Rpb24gaXNOdWxsKGFyZyl7cmV0dXJuIGFyZz09PW51bGx9ZXhwb3J0cy5pc051bGw9aXNOdWxsO2Z1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09bnVsbH1leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkPWlzTnVsbE9yVW5kZWZpbmVkO2Z1bmN0aW9uIGlzTnVtYmVyKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm51bWJlclwifWV4cG9ydHMuaXNOdW1iZXI9aXNOdW1iZXI7ZnVuY3Rpb24gaXNTdHJpbmcoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwic3RyaW5nXCJ9ZXhwb3J0cy5pc1N0cmluZz1pc1N0cmluZztmdW5jdGlvbiBpc1N5bWJvbChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJzeW1ib2xcIn1leHBvcnRzLmlzU3ltYm9sPWlzU3ltYm9sO2Z1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09PXZvaWQgMH1leHBvcnRzLmlzVW5kZWZpbmVkPWlzVW5kZWZpbmVkO2Z1bmN0aW9uIGlzUmVnRXhwKHJlKXtyZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpPT09XCJbb2JqZWN0IFJlZ0V4cF1cIn1leHBvcnRzLmlzUmVnRXhwPWlzUmVnRXhwO2Z1bmN0aW9uIGlzT2JqZWN0KGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm9iamVjdFwiJiZhcmchPT1udWxsfWV4cG9ydHMuaXNPYmplY3Q9aXNPYmplY3Q7ZnVuY3Rpb24gaXNEYXRlKGQpe3JldHVybiBvYmplY3RUb1N0cmluZyhkKT09PVwiW29iamVjdCBEYXRlXVwifWV4cG9ydHMuaXNEYXRlPWlzRGF0ZTtmdW5jdGlvbiBpc0Vycm9yKGUpe3JldHVybiBvYmplY3RUb1N0cmluZyhlKT09PVwiW29iamVjdCBFcnJvcl1cInx8ZSBpbnN0YW5jZW9mIEVycm9yfWV4cG9ydHMuaXNFcnJvcj1pc0Vycm9yO2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1leHBvcnRzLmlzRnVuY3Rpb249aXNGdW5jdGlvbjtmdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpe3JldHVybiBhcmc9PT1udWxsfHx0eXBlb2YgYXJnPT09XCJib29sZWFuXCJ8fHR5cGVvZiBhcmc9PT1cIm51bWJlclwifHx0eXBlb2YgYXJnPT09XCJzdHJpbmdcInx8dHlwZW9mIGFyZz09PVwic3ltYm9sXCJ8fHR5cGVvZiBhcmc9PT1cInVuZGVmaW5lZFwifWV4cG9ydHMuaXNQcmltaXRpdmU9aXNQcmltaXRpdmU7ZXhwb3J0cy5pc0J1ZmZlcj1CdWZmZXIuaXNCdWZmZXI7ZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobyl7cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKX19KS5jYWxsKHRoaXMse2lzQnVmZmVyOnJlcXVpcmUoXCIuLi8uLi9pcy1idWZmZXIvaW5kZXguanNcIil9KX0se1wiLi4vLi4vaXMtYnVmZmVyL2luZGV4LmpzXCI6Mzl9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpO3ZhciBlbnRpdGllcz1yZXF1aXJlKFwiZW50aXRpZXNcIik7dmFyIGJvb2xlYW5BdHRyaWJ1dGVzPXtfX3Byb3RvX186bnVsbCxhbGxvd2Z1bGxzY3JlZW46dHJ1ZSxhc3luYzp0cnVlLGF1dG9mb2N1czp0cnVlLGF1dG9wbGF5OnRydWUsY2hlY2tlZDp0cnVlLGNvbnRyb2xzOnRydWUsZGVmYXVsdDp0cnVlLGRlZmVyOnRydWUsZGlzYWJsZWQ6dHJ1ZSxoaWRkZW46dHJ1ZSxpc21hcDp0cnVlLGxvb3A6dHJ1ZSxtdWx0aXBsZTp0cnVlLG11dGVkOnRydWUsb3Blbjp0cnVlLHJlYWRvbmx5OnRydWUscmVxdWlyZWQ6dHJ1ZSxyZXZlcnNlZDp0cnVlLHNjb3BlZDp0cnVlLHNlYW1sZXNzOnRydWUsc2VsZWN0ZWQ6dHJ1ZSx0eXBlbXVzdG1hdGNoOnRydWV9O3ZhciB1bmVuY29kZWRFbGVtZW50cz17X19wcm90b19fOm51bGwsc3R5bGU6dHJ1ZSxzY3JpcHQ6dHJ1ZSx4bXA6dHJ1ZSxpZnJhbWU6dHJ1ZSxub2VtYmVkOnRydWUsbm9mcmFtZXM6dHJ1ZSxwbGFpbnRleHQ6dHJ1ZSxub3NjcmlwdDp0cnVlfTtmdW5jdGlvbiBmb3JtYXRBdHRycyhhdHRyaWJ1dGVzLG9wdHMpe2lmKCFhdHRyaWJ1dGVzKXJldHVybjt2YXIgb3V0cHV0PVwiXCIsdmFsdWU7Zm9yKHZhciBrZXkgaW4gYXR0cmlidXRlcyl7dmFsdWU9YXR0cmlidXRlc1trZXldO2lmKG91dHB1dCl7b3V0cHV0Kz1cIiBcIn1pZighdmFsdWUmJmJvb2xlYW5BdHRyaWJ1dGVzW2tleV0pe291dHB1dCs9a2V5fWVsc2V7b3V0cHV0Kz1rZXkrJz1cIicrKG9wdHMuZGVjb2RlRW50aXRpZXM/ZW50aXRpZXMuZW5jb2RlWE1MKHZhbHVlKTp2YWx1ZSkrJ1wiJ319cmV0dXJuIG91dHB1dH12YXIgc2luZ2xlVGFnPXtfX3Byb3RvX186bnVsbCxhcmVhOnRydWUsYmFzZTp0cnVlLGJhc2Vmb250OnRydWUsYnI6dHJ1ZSxjb2w6dHJ1ZSxjb21tYW5kOnRydWUsZW1iZWQ6dHJ1ZSxmcmFtZTp0cnVlLGhyOnRydWUsaW1nOnRydWUsaW5wdXQ6dHJ1ZSxpc2luZGV4OnRydWUsa2V5Z2VuOnRydWUsbGluazp0cnVlLG1ldGE6dHJ1ZSxwYXJhbTp0cnVlLHNvdXJjZTp0cnVlLHRyYWNrOnRydWUsd2JyOnRydWV9O3ZhciByZW5kZXI9bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oZG9tLG9wdHMpe2lmKCFBcnJheS5pc0FycmF5KGRvbSkmJiFkb20uY2hlZXJpbylkb209W2RvbV07b3B0cz1vcHRzfHx7fTt2YXIgb3V0cHV0PVwiXCI7Zm9yKHZhciBpPTA7aTxkb20ubGVuZ3RoO2krKyl7dmFyIGVsZW09ZG9tW2ldO2lmKGVsZW0udHlwZT09PVwicm9vdFwiKW91dHB1dCs9cmVuZGVyKGVsZW0uY2hpbGRyZW4sb3B0cyk7ZWxzZSBpZihFbGVtZW50VHlwZS5pc1RhZyhlbGVtKSlvdXRwdXQrPXJlbmRlclRhZyhlbGVtLG9wdHMpO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuRGlyZWN0aXZlKW91dHB1dCs9cmVuZGVyRGlyZWN0aXZlKGVsZW0pO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudClvdXRwdXQrPXJlbmRlckNvbW1lbnQoZWxlbSk7ZWxzZSBpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5DREFUQSlvdXRwdXQrPXJlbmRlckNkYXRhKGVsZW0pO2Vsc2Ugb3V0cHV0Kz1yZW5kZXJUZXh0KGVsZW0sb3B0cyl9cmV0dXJuIG91dHB1dH07ZnVuY3Rpb24gcmVuZGVyVGFnKGVsZW0sb3B0cyl7aWYoZWxlbS5uYW1lPT09XCJzdmdcIilvcHRzPXtkZWNvZGVFbnRpdGllczpvcHRzLmRlY29kZUVudGl0aWVzLHhtbE1vZGU6dHJ1ZX07dmFyIHRhZz1cIjxcIitlbGVtLm5hbWUsYXR0cmlicz1mb3JtYXRBdHRycyhlbGVtLmF0dHJpYnMsb3B0cyk7aWYoYXR0cmlicyl7dGFnKz1cIiBcIithdHRyaWJzfWlmKG9wdHMueG1sTW9kZSYmKCFlbGVtLmNoaWxkcmVufHxlbGVtLmNoaWxkcmVuLmxlbmd0aD09PTApKXt0YWcrPVwiLz5cIn1lbHNle3RhZys9XCI+XCI7aWYoZWxlbS5jaGlsZHJlbil7dGFnKz1yZW5kZXIoZWxlbS5jaGlsZHJlbixvcHRzKX1pZighc2luZ2xlVGFnW2VsZW0ubmFtZV18fG9wdHMueG1sTW9kZSl7dGFnKz1cIjwvXCIrZWxlbS5uYW1lK1wiPlwifX1yZXR1cm4gdGFnfWZ1bmN0aW9uIHJlbmRlckRpcmVjdGl2ZShlbGVtKXtyZXR1cm5cIjxcIitlbGVtLmRhdGErXCI+XCJ9ZnVuY3Rpb24gcmVuZGVyVGV4dChlbGVtLG9wdHMpe3ZhciBkYXRhPWVsZW0uZGF0YXx8XCJcIjtpZihvcHRzLmRlY29kZUVudGl0aWVzJiYhKGVsZW0ucGFyZW50JiZlbGVtLnBhcmVudC5uYW1lIGluIHVuZW5jb2RlZEVsZW1lbnRzKSl7ZGF0YT1lbnRpdGllcy5lbmNvZGVYTUwoZGF0YSl9cmV0dXJuIGRhdGF9ZnVuY3Rpb24gcmVuZGVyQ2RhdGEoZWxlbSl7cmV0dXJuXCI8IVtDREFUQVtcIitlbGVtLmNoaWxkcmVuWzBdLmRhdGErXCJdXT5cIn1mdW5jdGlvbiByZW5kZXJDb21tZW50KGVsZW0pe3JldHVyblwiPCEtLVwiK2VsZW0uZGF0YStcIi0tPlwifX0se2RvbWVsZW1lbnR0eXBlOjgsZW50aXRpZXM6MjB9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17VGV4dDpcInRleHRcIixEaXJlY3RpdmU6XCJkaXJlY3RpdmVcIixDb21tZW50OlwiY29tbWVudFwiLFNjcmlwdDpcInNjcmlwdFwiLFN0eWxlOlwic3R5bGVcIixUYWc6XCJ0YWdcIixDREFUQTpcImNkYXRhXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e1RleHQ6XCJ0ZXh0XCIsRGlyZWN0aXZlOlwiZGlyZWN0aXZlXCIsQ29tbWVudDpcImNvbW1lbnRcIixTY3JpcHQ6XCJzY3JpcHRcIixTdHlsZTpcInN0eWxlXCIsVGFnOlwidGFnXCIsQ0RBVEE6XCJjZGF0YVwiLERvY3R5cGU6XCJkb2N0eXBlXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7dmFyIHJlX3doaXRlc3BhY2U9L1xccysvZzt2YXIgTm9kZVByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvZWxlbWVudFwiKTtmdW5jdGlvbiBEb21IYW5kbGVyKGNhbGxiYWNrLG9wdGlvbnMsZWxlbWVudENCKXtpZih0eXBlb2YgY2FsbGJhY2s9PT1cIm9iamVjdFwiKXtlbGVtZW50Q0I9b3B0aW9ucztvcHRpb25zPWNhbGxiYWNrO2NhbGxiYWNrPW51bGx9ZWxzZSBpZih0eXBlb2Ygb3B0aW9ucz09PVwiZnVuY3Rpb25cIil7ZWxlbWVudENCPW9wdGlvbnM7b3B0aW9ucz1kZWZhdWx0T3B0c310aGlzLl9jYWxsYmFjaz1jYWxsYmFjazt0aGlzLl9vcHRpb25zPW9wdGlvbnN8fGRlZmF1bHRPcHRzO3RoaXMuX2VsZW1lbnRDQj1lbGVtZW50Q0I7dGhpcy5kb209W107dGhpcy5fZG9uZT1mYWxzZTt0aGlzLl90YWdTdGFjaz1bXTt0aGlzLl9wYXJzZXI9dGhpcy5fcGFyc2VyfHxudWxsfXZhciBkZWZhdWx0T3B0cz17bm9ybWFsaXplV2hpdGVzcGFjZTpmYWxzZSx3aXRoU3RhcnRJbmRpY2VzOmZhbHNlfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnBhcnNlcmluaXQ9ZnVuY3Rpb24ocGFyc2VyKXt0aGlzLl9wYXJzZXI9cGFyc2VyfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnJlc2V0PWZ1bmN0aW9uKCl7RG9tSGFuZGxlci5jYWxsKHRoaXMsdGhpcy5fY2FsbGJhY2ssdGhpcy5fb3B0aW9ucyx0aGlzLl9lbGVtZW50Q0IpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe2lmKHRoaXMuX2RvbmUpcmV0dXJuO3RoaXMuX2RvbmU9dHJ1ZTt0aGlzLl9wYXJzZXI9bnVsbDt0aGlzLl9oYW5kbGVDYWxsYmFjayhudWxsKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2hhbmRsZUNhbGxiYWNrPURvbUhhbmRsZXIucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24oZXJyb3Ipe2lmKHR5cGVvZiB0aGlzLl9jYWxsYmFjaz09PVwiZnVuY3Rpb25cIil7dGhpcy5fY2FsbGJhY2soZXJyb3IsdGhpcy5kb20pfWVsc2V7aWYoZXJyb3IpdGhyb3cgZXJyb3J9fTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNsb3NldGFnPWZ1bmN0aW9uKCl7dmFyIGVsZW09dGhpcy5fdGFnU3RhY2sucG9wKCk7aWYodGhpcy5fZWxlbWVudENCKXRoaXMuX2VsZW1lbnRDQihlbGVtKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2FkZERvbUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbWVudCl7dmFyIHBhcmVudD10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07dmFyIHNpYmxpbmdzPXBhcmVudD9wYXJlbnQuY2hpbGRyZW46dGhpcy5kb207dmFyIHByZXZpb3VzU2libGluZz1zaWJsaW5nc1tzaWJsaW5ncy5sZW5ndGgtMV07ZWxlbWVudC5uZXh0PW51bGw7aWYodGhpcy5fb3B0aW9ucy53aXRoU3RhcnRJbmRpY2VzKXtlbGVtZW50LnN0YXJ0SW5kZXg9dGhpcy5fcGFyc2VyLnN0YXJ0SW5kZXh9aWYodGhpcy5fb3B0aW9ucy53aXRoRG9tTHZsMSl7ZWxlbWVudC5fX3Byb3RvX189ZWxlbWVudC50eXBlPT09XCJ0YWdcIj9FbGVtZW50UHJvdG90eXBlOk5vZGVQcm90b3R5cGV9aWYocHJldmlvdXNTaWJsaW5nKXtlbGVtZW50LnByZXY9cHJldmlvdXNTaWJsaW5nO3ByZXZpb3VzU2libGluZy5uZXh0PWVsZW1lbnR9ZWxzZXtlbGVtZW50LnByZXY9bnVsbH1zaWJsaW5ncy5wdXNoKGVsZW1lbnQpO2VsZW1lbnQucGFyZW50PXBhcmVudHx8bnVsbH07RG9tSGFuZGxlci5wcm90b3R5cGUub25vcGVudGFnPWZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7dmFyIGVsZW1lbnQ9e3R5cGU6bmFtZT09PVwic2NyaXB0XCI/RWxlbWVudFR5cGUuU2NyaXB0Om5hbWU9PT1cInN0eWxlXCI/RWxlbWVudFR5cGUuU3R5bGU6RWxlbWVudFR5cGUuVGFnLG5hbWU6bmFtZSxhdHRyaWJzOmF0dHJpYnMsY2hpbGRyZW46W119O3RoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KX07RG9tSGFuZGxlci5wcm90b3R5cGUub250ZXh0PWZ1bmN0aW9uKGRhdGEpe3ZhciBub3JtYWxpemU9dGhpcy5fb3B0aW9ucy5ub3JtYWxpemVXaGl0ZXNwYWNlfHx0aGlzLl9vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2U7dmFyIGxhc3RUYWc7aWYoIXRoaXMuX3RhZ1N0YWNrLmxlbmd0aCYmdGhpcy5kb20ubGVuZ3RoJiYobGFzdFRhZz10aGlzLmRvbVt0aGlzLmRvbS5sZW5ndGgtMV0pLnR5cGU9PT1FbGVtZW50VHlwZS5UZXh0KXtpZihub3JtYWxpemUpe2xhc3RUYWcuZGF0YT0obGFzdFRhZy5kYXRhK2RhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9ZWxzZXtsYXN0VGFnLmRhdGErPWRhdGF9fWVsc2V7aWYodGhpcy5fdGFnU3RhY2subGVuZ3RoJiYobGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV0pJiYobGFzdFRhZz1sYXN0VGFnLmNoaWxkcmVuW2xhc3RUYWcuY2hpbGRyZW4ubGVuZ3RoLTFdKSYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuVGV4dCl7aWYobm9ybWFsaXplKXtsYXN0VGFnLmRhdGE9KGxhc3RUYWcuZGF0YStkYXRhKS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsXCIgXCIpfWVsc2V7bGFzdFRhZy5kYXRhKz1kYXRhfX1lbHNle2lmKG5vcm1hbGl6ZSl7ZGF0YT1kYXRhLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9dGhpcy5fYWRkRG9tRWxlbWVudCh7ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuVGV4dH0pfX19O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudD1mdW5jdGlvbihkYXRhKXt2YXIgbGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07aWYobGFzdFRhZyYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudCl7bGFzdFRhZy5kYXRhKz1kYXRhO3JldHVybn12YXIgZWxlbWVudD17ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuQ29tbWVudH07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNkYXRhc3RhcnQ9ZnVuY3Rpb24oKXt2YXIgZWxlbWVudD17Y2hpbGRyZW46W3tkYXRhOlwiXCIsdHlwZTpFbGVtZW50VHlwZS5UZXh0fV0sdHlwZTpFbGVtZW50VHlwZS5DREFUQX07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnRlbmQ9RG9tSGFuZGxlci5wcm90b3R5cGUub25jZGF0YWVuZD1mdW5jdGlvbigpe3RoaXMuX3RhZ1N0YWNrLnBvcCgpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbihuYW1lLGRhdGEpe3RoaXMuX2FkZERvbUVsZW1lbnQoe25hbWU6bmFtZSxkYXRhOmRhdGEsdHlwZTpFbGVtZW50VHlwZS5EaXJlY3RpdmV9KX07bW9kdWxlLmV4cG9ydHM9RG9tSGFuZGxlcn0se1wiLi9saWIvZWxlbWVudFwiOjExLFwiLi9saWIvbm9kZVwiOjEyLGRvbWVsZW1lbnR0eXBlOjl9XSwxMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9cmVxdWlyZShcIi4vbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1tb2R1bGUuZXhwb3J0cz1PYmplY3QuY3JlYXRlKE5vZGVQcm90b3R5cGUpO3ZhciBkb21MdmwxPXt0YWdOYW1lOlwibmFtZVwifTtPYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7dmFyIHNob3J0aGFuZD1kb21MdmwxW2tleV07T2JqZWN0LmRlZmluZVByb3BlcnR5KEVsZW1lbnRQcm90b3R5cGUsa2V5LHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1tzaG9ydGhhbmRdfHxudWxsfSxzZXQ6ZnVuY3Rpb24odmFsKXt0aGlzW3Nob3J0aGFuZF09dmFsO3JldHVybiB2YWx9fSl9KX0se1wiLi9ub2RlXCI6MTJ9XSwxMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9bW9kdWxlLmV4cG9ydHM9e2dldCBmaXJzdENoaWxkKCl7dmFyIGNoaWxkcmVuPXRoaXMuY2hpbGRyZW47cmV0dXJuIGNoaWxkcmVuJiZjaGlsZHJlblswXXx8bnVsbH0sZ2V0IGxhc3RDaGlsZCgpe3ZhciBjaGlsZHJlbj10aGlzLmNoaWxkcmVuO3JldHVybiBjaGlsZHJlbiYmY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoLTFdfHxudWxsfSxnZXQgbm9kZVR5cGUoKXtyZXR1cm4gbm9kZVR5cGVzW3RoaXMudHlwZV18fG5vZGVUeXBlcy5lbGVtZW50fX07dmFyIGRvbUx2bDE9e3RhZ05hbWU6XCJuYW1lXCIsY2hpbGROb2RlczpcImNoaWxkcmVuXCIscGFyZW50Tm9kZTpcInBhcmVudFwiLHByZXZpb3VzU2libGluZzpcInByZXZcIixuZXh0U2libGluZzpcIm5leHRcIixub2RlVmFsdWU6XCJkYXRhXCJ9O3ZhciBub2RlVHlwZXM9e2VsZW1lbnQ6MSx0ZXh0OjMsY2RhdGE6NCxjb21tZW50Ojh9O09iamVjdC5rZXlzKGRvbUx2bDEpLmZvckVhY2goZnVuY3Rpb24oa2V5KXt2YXIgc2hvcnRoYW5kPWRvbUx2bDFba2V5XTtPYmplY3QuZGVmaW5lUHJvcGVydHkoTm9kZVByb3RvdHlwZSxrZXkse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzW3Nob3J0aGFuZF18fG51bGx9LHNldDpmdW5jdGlvbih2YWwpe3RoaXNbc2hvcnRoYW5kXT12YWw7cmV0dXJuIHZhbH19KX0pfSx7fV0sMTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBEb21VdGlscz1tb2R1bGUuZXhwb3J0cztbcmVxdWlyZShcIi4vbGliL3N0cmluZ2lmeVwiKSxyZXF1aXJlKFwiLi9saWIvdHJhdmVyc2FsXCIpLHJlcXVpcmUoXCIuL2xpYi9tYW5pcHVsYXRpb25cIikscmVxdWlyZShcIi4vbGliL3F1ZXJ5aW5nXCIpLHJlcXVpcmUoXCIuL2xpYi9sZWdhY3lcIikscmVxdWlyZShcIi4vbGliL2hlbHBlcnNcIildLmZvckVhY2goZnVuY3Rpb24oZXh0KXtPYmplY3Qua2V5cyhleHQpLmZvckVhY2goZnVuY3Rpb24oa2V5KXtEb21VdGlsc1trZXldPWV4dFtrZXldLmJpbmQoRG9tVXRpbHMpfSl9KX0se1wiLi9saWIvaGVscGVyc1wiOjE0LFwiLi9saWIvbGVnYWN5XCI6MTUsXCIuL2xpYi9tYW5pcHVsYXRpb25cIjoxNixcIi4vbGliL3F1ZXJ5aW5nXCI6MTcsXCIuL2xpYi9zdHJpbmdpZnlcIjoxOCxcIi4vbGliL3RyYXZlcnNhbFwiOjE5fV0sMTQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVtb3ZlU3Vic2V0cz1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxhbmNlc3RvcixyZXBsYWNlO3doaWxlKC0taWR4Pi0xKXtub2RlPWFuY2VzdG9yPW5vZGVzW2lkeF07bm9kZXNbaWR4XT1udWxsO3JlcGxhY2U9dHJ1ZTt3aGlsZShhbmNlc3Rvcil7aWYobm9kZXMuaW5kZXhPZihhbmNlc3Rvcik+LTEpe3JlcGxhY2U9ZmFsc2U7bm9kZXMuc3BsaWNlKGlkeCwxKTticmVha31hbmNlc3Rvcj1hbmNlc3Rvci5wYXJlbnR9aWYocmVwbGFjZSl7bm9kZXNbaWR4XT1ub2RlfX1yZXR1cm4gbm9kZXN9O3ZhciBQT1NJVElPTj17RElTQ09OTkVDVEVEOjEsUFJFQ0VESU5HOjIsRk9MTE9XSU5HOjQsQ09OVEFJTlM6OCxDT05UQUlORURfQlk6MTZ9O3ZhciBjb21wYXJlUG9zPWV4cG9ydHMuY29tcGFyZURvY3VtZW50UG9zaXRpb249ZnVuY3Rpb24obm9kZUEsbm9kZUIpe3ZhciBhUGFyZW50cz1bXTt2YXIgYlBhcmVudHM9W107dmFyIGN1cnJlbnQsc2hhcmVkUGFyZW50LHNpYmxpbmdzLGFTaWJsaW5nLGJTaWJsaW5nLGlkeDtpZihub2RlQT09PW5vZGVCKXtyZXR1cm4gMH1jdXJyZW50PW5vZGVBO3doaWxlKGN1cnJlbnQpe2FQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1jdXJyZW50PW5vZGVCO3doaWxlKGN1cnJlbnQpe2JQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1pZHg9MDt3aGlsZShhUGFyZW50c1tpZHhdPT09YlBhcmVudHNbaWR4XSl7aWR4Kyt9aWYoaWR4PT09MCl7cmV0dXJuIFBPU0lUSU9OLkRJU0NPTk5FQ1RFRH1zaGFyZWRQYXJlbnQ9YVBhcmVudHNbaWR4LTFdO3NpYmxpbmdzPXNoYXJlZFBhcmVudC5jaGlsZHJlbjthU2libGluZz1hUGFyZW50c1tpZHhdO2JTaWJsaW5nPWJQYXJlbnRzW2lkeF07aWYoc2libGluZ3MuaW5kZXhPZihhU2libGluZyk+c2libGluZ3MuaW5kZXhPZihiU2libGluZykpe2lmKHNoYXJlZFBhcmVudD09PW5vZGVCKXtyZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfFBPU0lUSU9OLkNPTlRBSU5FRF9CWX1yZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfWVsc2V7aWYoc2hhcmVkUGFyZW50PT09bm9kZUEpe3JldHVybiBQT1NJVElPTi5QUkVDRURJTkd8UE9TSVRJT04uQ09OVEFJTlN9cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElOR319O2V4cG9ydHMudW5pcXVlU29ydD1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxwb3NpdGlvbjtub2Rlcz1ub2Rlcy5zbGljZSgpO3doaWxlKC0taWR4Pi0xKXtub2RlPW5vZGVzW2lkeF07cG9zaXRpb249bm9kZXMuaW5kZXhPZihub2RlKTtpZihwb3NpdGlvbj4tMSYmcG9zaXRpb248aWR4KXtub2Rlcy5zcGxpY2UoaWR4LDEpfX1ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsYil7dmFyIHJlbGF0aXZlPWNvbXBhcmVQb3MoYSxiKTtpZihyZWxhdGl2ZSZQT1NJVElPTi5QUkVDRURJTkcpe3JldHVybi0xfWVsc2UgaWYocmVsYXRpdmUmUE9TSVRJT04uRk9MTE9XSU5HKXtyZXR1cm4gMX1yZXR1cm4gMH0pO3JldHVybiBub2Rlc319LHt9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKTt2YXIgaXNUYWc9ZXhwb3J0cy5pc1RhZz1FbGVtZW50VHlwZS5pc1RhZztleHBvcnRzLnRlc3RFbGVtZW50PWZ1bmN0aW9uKG9wdGlvbnMsZWxlbWVudCl7Zm9yKHZhciBrZXkgaW4gb3B0aW9ucyl7aWYoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSk7ZWxzZSBpZihrZXk9PT1cInRhZ19uYW1lXCIpe2lmKCFpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX25hbWUoZWxlbWVudC5uYW1lKSl7cmV0dXJuIGZhbHNlfX1lbHNlIGlmKGtleT09PVwidGFnX3R5cGVcIil7aWYoIW9wdGlvbnMudGFnX3R5cGUoZWxlbWVudC50eXBlKSlyZXR1cm4gZmFsc2V9ZWxzZSBpZihrZXk9PT1cInRhZ19jb250YWluc1wiKXtpZihpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX2NvbnRhaW5zKGVsZW1lbnQuZGF0YSkpe3JldHVybiBmYWxzZX19ZWxzZSBpZighZWxlbWVudC5hdHRyaWJzfHwhb3B0aW9uc1trZXldKGVsZW1lbnQuYXR0cmlic1trZXldKSl7cmV0dXJuIGZhbHNlfX1yZXR1cm4gdHJ1ZX07dmFyIENoZWNrcz17dGFnX25hbWU6ZnVuY3Rpb24obmFtZSl7aWYodHlwZW9mIG5hbWU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJm5hbWUoZWxlbS5uYW1lKX19ZWxzZSBpZihuYW1lPT09XCIqXCIpe3JldHVybiBpc1RhZ31lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJmVsZW0ubmFtZT09PW5hbWV9fX0sdGFnX3R5cGU6ZnVuY3Rpb24odHlwZSl7aWYodHlwZW9mIHR5cGU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gdHlwZShlbGVtLnR5cGUpfX1lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS50eXBlPT09dHlwZX19fSx0YWdfY29udGFpbnM6ZnVuY3Rpb24oZGF0YSl7aWYodHlwZW9mIGRhdGE9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4haXNUYWcoZWxlbSkmJmRhdGEoZWxlbS5kYXRhKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIWlzVGFnKGVsZW0pJiZlbGVtLmRhdGE9PT1kYXRhfX19fTtmdW5jdGlvbiBnZXRBdHRyaWJDaGVjayhhdHRyaWIsdmFsdWUpe2lmKHR5cGVvZiB2YWx1ZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLmF0dHJpYnMmJnZhbHVlKGVsZW0uYXR0cmlic1thdHRyaWJdKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0uYXR0cmlicyYmZWxlbS5hdHRyaWJzW2F0dHJpYl09PT12YWx1ZX19fWZ1bmN0aW9uIGNvbWJpbmVGdW5jcyhhLGIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gYShlbGVtKXx8YihlbGVtKX19ZXhwb3J0cy5nZXRFbGVtZW50cz1mdW5jdGlvbihvcHRpb25zLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7dmFyIGZ1bmNzPU9iamVjdC5rZXlzKG9wdGlvbnMpLm1hcChmdW5jdGlvbihrZXkpe3ZhciB2YWx1ZT1vcHRpb25zW2tleV07cmV0dXJuIGtleSBpbiBDaGVja3M/Q2hlY2tzW2tleV0odmFsdWUpOmdldEF0dHJpYkNoZWNrKGtleSx2YWx1ZSl9KTtyZXR1cm4gZnVuY3MubGVuZ3RoPT09MD9bXTp0aGlzLmZpbHRlcihmdW5jcy5yZWR1Y2UoY29tYmluZUZ1bmNzKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRCeUlkPWZ1bmN0aW9uKGlkLGVsZW1lbnQscmVjdXJzZSl7aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpZWxlbWVudD1bZWxlbWVudF07cmV0dXJuIHRoaXMuZmluZE9uZShnZXRBdHRyaWJDaGVjayhcImlkXCIsaWQpLGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlKX07ZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnTmFtZT1mdW5jdGlvbihuYW1lLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfbmFtZShuYW1lKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRzQnlUYWdUeXBlPWZ1bmN0aW9uKHR5cGUsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ190eXBlKHR5cGUpLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl9fSx7ZG9tZWxlbWVudHR5cGU6OX1dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtleHBvcnRzLnJlbW92ZUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbSl7aWYoZWxlbS5wcmV2KWVsZW0ucHJldi5uZXh0PWVsZW0ubmV4dDtpZihlbGVtLm5leHQpZWxlbS5uZXh0LnByZXY9ZWxlbS5wcmV2O2lmKGVsZW0ucGFyZW50KXt2YXIgY2hpbGRzPWVsZW0ucGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDEpfX07ZXhwb3J0cy5yZXBsYWNlRWxlbWVudD1mdW5jdGlvbihlbGVtLHJlcGxhY2VtZW50KXt2YXIgcHJldj1yZXBsYWNlbWVudC5wcmV2PWVsZW0ucHJldjtpZihwcmV2KXtwcmV2Lm5leHQ9cmVwbGFjZW1lbnR9dmFyIG5leHQ9cmVwbGFjZW1lbnQubmV4dD1lbGVtLm5leHQ7aWYobmV4dCl7bmV4dC5wcmV2PXJlcGxhY2VtZW50fXZhciBwYXJlbnQ9cmVwbGFjZW1lbnQucGFyZW50PWVsZW0ucGFyZW50O2lmKHBhcmVudCl7dmFyIGNoaWxkcz1wYXJlbnQuY2hpbGRyZW47Y2hpbGRzW2NoaWxkcy5sYXN0SW5kZXhPZihlbGVtKV09cmVwbGFjZW1lbnR9fTtleHBvcnRzLmFwcGVuZENoaWxkPWZ1bmN0aW9uKGVsZW0sY2hpbGQpe2NoaWxkLnBhcmVudD1lbGVtO2lmKGVsZW0uY2hpbGRyZW4ucHVzaChjaGlsZCkhPT0xKXt2YXIgc2libGluZz1lbGVtLmNoaWxkcmVuW2VsZW0uY2hpbGRyZW4ubGVuZ3RoLTJdO3NpYmxpbmcubmV4dD1jaGlsZDtjaGlsZC5wcmV2PXNpYmxpbmc7Y2hpbGQubmV4dD1udWxsfX07ZXhwb3J0cy5hcHBlbmQ9ZnVuY3Rpb24oZWxlbSxuZXh0KXt2YXIgcGFyZW50PWVsZW0ucGFyZW50LGN1cnJOZXh0PWVsZW0ubmV4dDtuZXh0Lm5leHQ9Y3Vyck5leHQ7bmV4dC5wcmV2PWVsZW07ZWxlbS5uZXh0PW5leHQ7bmV4dC5wYXJlbnQ9cGFyZW50O2lmKGN1cnJOZXh0KXtjdXJyTmV4dC5wcmV2PW5leHQ7aWYocGFyZW50KXt2YXIgY2hpbGRzPXBhcmVudC5jaGlsZHJlbjtjaGlsZHMuc3BsaWNlKGNoaWxkcy5sYXN0SW5kZXhPZihjdXJyTmV4dCksMCxuZXh0KX19ZWxzZSBpZihwYXJlbnQpe3BhcmVudC5jaGlsZHJlbi5wdXNoKG5leHQpfX07ZXhwb3J0cy5wcmVwZW5kPWZ1bmN0aW9uKGVsZW0scHJldil7dmFyIHBhcmVudD1lbGVtLnBhcmVudDtpZihwYXJlbnQpe3ZhciBjaGlsZHM9cGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDAscHJldil9aWYoZWxlbS5wcmV2KXtlbGVtLnByZXYubmV4dD1wcmV2fXByZXYucGFyZW50PXBhcmVudDtwcmV2LnByZXY9ZWxlbS5wcmV2O3ByZXYubmV4dD1lbGVtO2VsZW0ucHJldj1wcmV2fX0se31dLDE3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaXNUYWc9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLmlzVGFnO21vZHVsZS5leHBvcnRzPXtmaWx0ZXI6ZmlsdGVyLGZpbmQ6ZmluZCxmaW5kT25lQ2hpbGQ6ZmluZE9uZUNoaWxkLGZpbmRPbmU6ZmluZE9uZSxleGlzdHNPbmU6ZXhpc3RzT25lLGZpbmRBbGw6ZmluZEFsbH07ZnVuY3Rpb24gZmlsdGVyKHRlc3QsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtpZighQXJyYXkuaXNBcnJheShlbGVtZW50KSllbGVtZW50PVtlbGVtZW50XTtpZih0eXBlb2YgbGltaXQhPT1cIm51bWJlclwifHwhaXNGaW5pdGUobGltaXQpKXtsaW1pdD1JbmZpbml0eX1yZXR1cm4gZmluZCh0ZXN0LGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlLGxpbWl0KX1mdW5jdGlvbiBmaW5kKHRlc3QsZWxlbXMscmVjdXJzZSxsaW1pdCl7dmFyIHJlc3VsdD1bXSxjaGlsZHM7Zm9yKHZhciBpPTAsaj1lbGVtcy5sZW5ndGg7aTxqO2krKyl7aWYodGVzdChlbGVtc1tpXSkpe3Jlc3VsdC5wdXNoKGVsZW1zW2ldKTtpZigtLWxpbWl0PD0wKWJyZWFrfWNoaWxkcz1lbGVtc1tpXS5jaGlsZHJlbjtpZihyZWN1cnNlJiZjaGlsZHMmJmNoaWxkcy5sZW5ndGg+MCl7Y2hpbGRzPWZpbmQodGVzdCxjaGlsZHMscmVjdXJzZSxsaW1pdCk7cmVzdWx0PXJlc3VsdC5jb25jYXQoY2hpbGRzKTtsaW1pdC09Y2hpbGRzLmxlbmd0aDtpZihsaW1pdDw9MClicmVha319cmV0dXJuIHJlc3VsdH1mdW5jdGlvbiBmaW5kT25lQ2hpbGQodGVzdCxlbGVtcyl7Zm9yKHZhciBpPTAsbD1lbGVtcy5sZW5ndGg7aTxsO2krKyl7aWYodGVzdChlbGVtc1tpXSkpcmV0dXJuIGVsZW1zW2ldfXJldHVybiBudWxsfWZ1bmN0aW9uIGZpbmRPbmUodGVzdCxlbGVtcyl7dmFyIGVsZW09bnVsbDtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGwmJiFlbGVtO2krKyl7aWYoIWlzVGFnKGVsZW1zW2ldKSl7Y29udGludWV9ZWxzZSBpZih0ZXN0KGVsZW1zW2ldKSl7ZWxlbT1lbGVtc1tpXX1lbHNlIGlmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtlbGVtPWZpbmRPbmUodGVzdCxlbGVtc1tpXS5jaGlsZHJlbil9fXJldHVybiBlbGVtfWZ1bmN0aW9uIGV4aXN0c09uZSh0ZXN0LGVsZW1zKXtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGw7aSsrKXtpZihpc1RhZyhlbGVtc1tpXSkmJih0ZXN0KGVsZW1zW2ldKXx8ZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoPjAmJmV4aXN0c09uZSh0ZXN0LGVsZW1zW2ldLmNoaWxkcmVuKSkpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9ZnVuY3Rpb24gZmluZEFsbCh0ZXN0LGVsZW1zKXt2YXIgcmVzdWx0PVtdO2Zvcih2YXIgaT0wLGo9ZWxlbXMubGVuZ3RoO2k8ajtpKyspe2lmKCFpc1RhZyhlbGVtc1tpXSkpY29udGludWU7aWYodGVzdChlbGVtc1tpXSkpcmVzdWx0LnB1c2goZWxlbXNbaV0pO2lmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtyZXN1bHQ9cmVzdWx0LmNvbmNhdChmaW5kQWxsKHRlc3QsZWxlbXNbaV0uY2hpbGRyZW4pKX19cmV0dXJuIHJlc3VsdH19LHtkb21lbGVtZW50dHlwZTo5fV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIiksZ2V0T3V0ZXJIVE1MPXJlcXVpcmUoXCJkb20tc2VyaWFsaXplclwiKSxpc1RhZz1FbGVtZW50VHlwZS5pc1RhZzttb2R1bGUuZXhwb3J0cz17Z2V0SW5uZXJIVE1MOmdldElubmVySFRNTCxnZXRPdXRlckhUTUw6Z2V0T3V0ZXJIVE1MLGdldFRleHQ6Z2V0VGV4dH07ZnVuY3Rpb24gZ2V0SW5uZXJIVE1MKGVsZW0sb3B0cyl7cmV0dXJuIGVsZW0uY2hpbGRyZW4/ZWxlbS5jaGlsZHJlbi5tYXAoZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGdldE91dGVySFRNTChlbGVtLG9wdHMpfSkuam9pbihcIlwiKTpcIlwifWZ1bmN0aW9uIGdldFRleHQoZWxlbSl7aWYoQXJyYXkuaXNBcnJheShlbGVtKSlyZXR1cm4gZWxlbS5tYXAoZ2V0VGV4dCkuam9pbihcIlwiKTtpZihpc1RhZyhlbGVtKXx8ZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ0RBVEEpcmV0dXJuIGdldFRleHQoZWxlbS5jaGlsZHJlbik7aWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuVGV4dClyZXR1cm4gZWxlbS5kYXRhO3JldHVyblwiXCJ9fSx7XCJkb20tc2VyaWFsaXplclwiOjcsZG9tZWxlbWVudHR5cGU6OX1dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZ2V0Q2hpbGRyZW49ZXhwb3J0cy5nZXRDaGlsZHJlbj1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5jaGlsZHJlbn07dmFyIGdldFBhcmVudD1leHBvcnRzLmdldFBhcmVudD1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5wYXJlbnR9O2V4cG9ydHMuZ2V0U2libGluZ3M9ZnVuY3Rpb24oZWxlbSl7dmFyIHBhcmVudD1nZXRQYXJlbnQoZWxlbSk7cmV0dXJuIHBhcmVudD9nZXRDaGlsZHJlbihwYXJlbnQpOltlbGVtXX07ZXhwb3J0cy5nZXRBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihlbGVtLG5hbWUpe3JldHVybiBlbGVtLmF0dHJpYnMmJmVsZW0uYXR0cmlic1tuYW1lXX07ZXhwb3J0cy5oYXNBdHRyaWI9ZnVuY3Rpb24oZWxlbSxuYW1lKXtyZXR1cm4hIWVsZW0uYXR0cmlicyYmaGFzT3duUHJvcGVydHkuY2FsbChlbGVtLmF0dHJpYnMsbmFtZSl9O2V4cG9ydHMuZ2V0TmFtZT1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5uYW1lfX0se31dLDIwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZW5jb2RlPXJlcXVpcmUoXCIuL2xpYi9lbmNvZGUuanNcIiksZGVjb2RlPXJlcXVpcmUoXCIuL2xpYi9kZWNvZGUuanNcIik7ZXhwb3J0cy5kZWNvZGU9ZnVuY3Rpb24oZGF0YSxsZXZlbCl7cmV0dXJuKCFsZXZlbHx8bGV2ZWw8PTA/ZGVjb2RlLlhNTDpkZWNvZGUuSFRNTCkoZGF0YSl9O2V4cG9ydHMuZGVjb2RlU3RyaWN0PWZ1bmN0aW9uKGRhdGEsbGV2ZWwpe3JldHVybighbGV2ZWx8fGxldmVsPD0wP2RlY29kZS5YTUw6ZGVjb2RlLkhUTUxTdHJpY3QpKGRhdGEpfTtleHBvcnRzLmVuY29kZT1mdW5jdGlvbihkYXRhLGxldmVsKXtyZXR1cm4oIWxldmVsfHxsZXZlbDw9MD9lbmNvZGUuWE1MOmVuY29kZS5IVE1MKShkYXRhKX07ZXhwb3J0cy5lbmNvZGVYTUw9ZW5jb2RlLlhNTDtleHBvcnRzLmVuY29kZUhUTUw0PWV4cG9ydHMuZW5jb2RlSFRNTDU9ZXhwb3J0cy5lbmNvZGVIVE1MPWVuY29kZS5IVE1MO2V4cG9ydHMuZGVjb2RlWE1MPWV4cG9ydHMuZGVjb2RlWE1MU3RyaWN0PWRlY29kZS5YTUw7ZXhwb3J0cy5kZWNvZGVIVE1MND1leHBvcnRzLmRlY29kZUhUTUw1PWV4cG9ydHMuZGVjb2RlSFRNTD1kZWNvZGUuSFRNTDtleHBvcnRzLmRlY29kZUhUTUw0U3RyaWN0PWV4cG9ydHMuZGVjb2RlSFRNTDVTdHJpY3Q9ZXhwb3J0cy5kZWNvZGVIVE1MU3RyaWN0PWRlY29kZS5IVE1MU3RyaWN0O2V4cG9ydHMuZXNjYXBlPWVuY29kZS5lc2NhcGV9LHtcIi4vbGliL2RlY29kZS5qc1wiOjIxLFwiLi9saWIvZW5jb2RlLmpzXCI6MjN9XSwyMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGVudGl0eU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpLGxlZ2FjeU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9sZWdhY3kuanNvblwiKSx4bWxNYXA9cmVxdWlyZShcIi4uL21hcHMveG1sLmpzb25cIiksZGVjb2RlQ29kZVBvaW50PXJlcXVpcmUoXCIuL2RlY29kZV9jb2RlcG9pbnQuanNcIik7dmFyIGRlY29kZVhNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKHhtbE1hcCksZGVjb2RlSFRNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKGVudGl0eU1hcCk7ZnVuY3Rpb24gZ2V0U3RyaWN0RGVjb2RlcihtYXApe3ZhciBrZXlzPU9iamVjdC5rZXlzKG1hcCkuam9pbihcInxcIikscmVwbGFjZT1nZXRSZXBsYWNlcihtYXApO2tleXMrPVwifCNbeFhdW1xcXFxkYS1mQS1GXSt8I1xcXFxkK1wiO3ZhciByZT1uZXcgUmVnRXhwKFwiJig/OlwiK2tleXMrXCIpO1wiLFwiZ1wiKTtyZXR1cm4gZnVuY3Rpb24oc3RyKXtyZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZShyZSxyZXBsYWNlKX19dmFyIGRlY29kZUhUTUw9ZnVuY3Rpb24oKXt2YXIgbGVnYWN5PU9iamVjdC5rZXlzKGxlZ2FjeU1hcCkuc29ydChzb3J0ZXIpO3ZhciBrZXlzPU9iamVjdC5rZXlzKGVudGl0eU1hcCkuc29ydChzb3J0ZXIpO2Zvcih2YXIgaT0wLGo9MDtpPGtleXMubGVuZ3RoO2krKyl7aWYobGVnYWN5W2pdPT09a2V5c1tpXSl7a2V5c1tpXSs9XCI7P1wiO2orK31lbHNle2tleXNbaV0rPVwiO1wifX12YXIgcmU9bmV3IFJlZ0V4cChcIiYoPzpcIitrZXlzLmpvaW4oXCJ8XCIpK1wifCNbeFhdW1xcXFxkYS1mQS1GXSs7P3wjXFxcXGQrOz8pXCIsXCJnXCIpLHJlcGxhY2U9Z2V0UmVwbGFjZXIoZW50aXR5TWFwKTtmdW5jdGlvbiByZXBsYWNlcihzdHIpe2lmKHN0ci5zdWJzdHIoLTEpIT09XCI7XCIpc3RyKz1cIjtcIjtyZXR1cm4gcmVwbGFjZShzdHIpfXJldHVybiBmdW5jdGlvbihzdHIpe3JldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLHJlcGxhY2VyKX19KCk7ZnVuY3Rpb24gc29ydGVyKGEsYil7cmV0dXJuIGE8Yj8xOi0xfWZ1bmN0aW9uIGdldFJlcGxhY2VyKG1hcCl7cmV0dXJuIGZ1bmN0aW9uIHJlcGxhY2Uoc3RyKXtpZihzdHIuY2hhckF0KDEpPT09XCIjXCIpe2lmKHN0ci5jaGFyQXQoMik9PT1cIlhcInx8c3RyLmNoYXJBdCgyKT09PVwieFwiKXtyZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMyksMTYpKX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMiksMTApKX1yZXR1cm4gbWFwW3N0ci5zbGljZSgxLC0xKV07XG59fW1vZHVsZS5leHBvcnRzPXtYTUw6ZGVjb2RlWE1MU3RyaWN0LEhUTUw6ZGVjb2RlSFRNTCxIVE1MU3RyaWN0OmRlY29kZUhUTUxTdHJpY3R9fSx7XCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcIi4uL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcIi4uL21hcHMveG1sLmpzb25cIjoyNyxcIi4vZGVjb2RlX2NvZGVwb2ludC5qc1wiOjIyfV0sMjI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBkZWNvZGVNYXA9cmVxdWlyZShcIi4uL21hcHMvZGVjb2RlLmpzb25cIik7bW9kdWxlLmV4cG9ydHM9ZGVjb2RlQ29kZVBvaW50O2Z1bmN0aW9uIGRlY29kZUNvZGVQb2ludChjb2RlUG9pbnQpe2lmKGNvZGVQb2ludD49NTUyOTYmJmNvZGVQb2ludDw9NTczNDN8fGNvZGVQb2ludD4xMTE0MTExKXtyZXR1cm5cIu+/vVwifWlmKGNvZGVQb2ludCBpbiBkZWNvZGVNYXApe2NvZGVQb2ludD1kZWNvZGVNYXBbY29kZVBvaW50XX12YXIgb3V0cHV0PVwiXCI7aWYoY29kZVBvaW50PjY1NTM1KXtjb2RlUG9pbnQtPTY1NTM2O291dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQ+Pj4xMCYxMDIzfDU1Mjk2KTtjb2RlUG9pbnQ9NTYzMjB8Y29kZVBvaW50JjEwMjN9b3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7cmV0dXJuIG91dHB1dH19LHtcIi4uL21hcHMvZGVjb2RlLmpzb25cIjoyNH1dLDIzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaW52ZXJzZVhNTD1nZXRJbnZlcnNlT2JqKHJlcXVpcmUoXCIuLi9tYXBzL3htbC5qc29uXCIpKSx4bWxSZXBsYWNlcj1nZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7ZXhwb3J0cy5YTUw9Z2V0SW52ZXJzZShpbnZlcnNlWE1MLHhtbFJlcGxhY2VyKTt2YXIgaW52ZXJzZUhUTUw9Z2V0SW52ZXJzZU9iaihyZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpKSxodG1sUmVwbGFjZXI9Z2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VIVE1MKTtleHBvcnRzLkhUTUw9Z2V0SW52ZXJzZShpbnZlcnNlSFRNTCxodG1sUmVwbGFjZXIpO2Z1bmN0aW9uIGdldEludmVyc2VPYmoob2JqKXtyZXR1cm4gT2JqZWN0LmtleXMob2JqKS5zb3J0KCkucmVkdWNlKGZ1bmN0aW9uKGludmVyc2UsbmFtZSl7aW52ZXJzZVtvYmpbbmFtZV1dPVwiJlwiK25hbWUrXCI7XCI7cmV0dXJuIGludmVyc2V9LHt9KX1mdW5jdGlvbiBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZSl7dmFyIHNpbmdsZT1bXSxtdWx0aXBsZT1bXTtPYmplY3Qua2V5cyhpbnZlcnNlKS5mb3JFYWNoKGZ1bmN0aW9uKGspe2lmKGsubGVuZ3RoPT09MSl7c2luZ2xlLnB1c2goXCJcXFxcXCIrayl9ZWxzZXttdWx0aXBsZS5wdXNoKGspfX0pO211bHRpcGxlLnVuc2hpZnQoXCJbXCIrc2luZ2xlLmpvaW4oXCJcIikrXCJdXCIpO3JldHVybiBuZXcgUmVnRXhwKG11bHRpcGxlLmpvaW4oXCJ8XCIpLFwiZ1wiKX12YXIgcmVfbm9uQVNDSUk9L1teXFwwLVxceDdGXS9nLHJlX2FzdHJhbFN5bWJvbHM9L1tcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl0vZztmdW5jdGlvbiBzaW5nbGVDaGFyUmVwbGFjZXIoYyl7cmV0dXJuXCImI3hcIitjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkrXCI7XCJ9ZnVuY3Rpb24gYXN0cmFsUmVwbGFjZXIoYyl7dmFyIGhpZ2g9Yy5jaGFyQ29kZUF0KDApO3ZhciBsb3c9Yy5jaGFyQ29kZUF0KDEpO3ZhciBjb2RlUG9pbnQ9KGhpZ2gtNTUyOTYpKjEwMjQrbG93LTU2MzIwKzY1NTM2O3JldHVyblwiJiN4XCIrY29kZVBvaW50LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpK1wiO1wifWZ1bmN0aW9uIGdldEludmVyc2UoaW52ZXJzZSxyZSl7ZnVuY3Rpb24gZnVuYyhuYW1lKXtyZXR1cm4gaW52ZXJzZVtuYW1lXX1yZXR1cm4gZnVuY3Rpb24oZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZSxmdW5jKS5yZXBsYWNlKHJlX2FzdHJhbFN5bWJvbHMsYXN0cmFsUmVwbGFjZXIpLnJlcGxhY2UocmVfbm9uQVNDSUksc2luZ2xlQ2hhclJlcGxhY2VyKX19dmFyIHJlX3htbENoYXJzPWdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlWE1MKTtmdW5jdGlvbiBlc2NhcGVYTUwoZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZV94bWxDaGFycyxzaW5nbGVDaGFyUmVwbGFjZXIpLnJlcGxhY2UocmVfYXN0cmFsU3ltYm9scyxhc3RyYWxSZXBsYWNlcikucmVwbGFjZShyZV9ub25BU0NJSSxzaW5nbGVDaGFyUmVwbGFjZXIpfWV4cG9ydHMuZXNjYXBlPWVzY2FwZVhNTH0se1wiLi4vbWFwcy9lbnRpdGllcy5qc29uXCI6MjUsXCIuLi9tYXBzL3htbC5qc29uXCI6Mjd9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ezA6NjU1MzMsMTI4OjgzNjQsMTMwOjgyMTgsMTMxOjQwMiwxMzI6ODIyMiwxMzM6ODIzMCwxMzQ6ODIyNCwxMzU6ODIyNSwxMzY6NzEwLDEzNzo4MjQwLDEzODozNTIsMTM5OjgyNDksMTQwOjMzOCwxNDI6MzgxLDE0NTo4MjE2LDE0Njo4MjE3LDE0Nzo4MjIwLDE0ODo4MjIxLDE0OTo4MjI2LDE1MDo4MjExLDE1MTo4MjEyLDE1Mjo3MzIsMTUzOjg0ODIsMTU0OjM1MywxNTU6ODI1MCwxNTY6MzM5LDE1ODozODIsMTU5OjM3Nn19LHt9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e0FhY3V0ZTpcIsOBXCIsYWFjdXRlOlwiw6FcIixBYnJldmU6XCLEglwiLGFicmV2ZTpcIsSDXCIsYWM6XCLiiL5cIixhY2Q6XCLiiL9cIixhY0U6XCLiiL7Ms1wiLEFjaXJjOlwiw4JcIixhY2lyYzpcIsOiXCIsYWN1dGU6XCLCtFwiLEFjeTpcItCQXCIsYWN5Olwi0LBcIixBRWxpZzpcIsOGXCIsYWVsaWc6XCLDplwiLGFmOlwi4oGhXCIsQWZyOlwi8J2UhFwiLGFmcjpcIvCdlJ5cIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYWxlZnN5bTpcIuKEtVwiLGFsZXBoOlwi4oS1XCIsQWxwaGE6XCLOkVwiLGFscGhhOlwizrFcIixBbWFjcjpcIsSAXCIsYW1hY3I6XCLEgVwiLGFtYWxnOlwi4qi/XCIsYW1wOlwiJlwiLEFNUDpcIiZcIixhbmRhbmQ6XCLiqZVcIixBbmQ6XCLiqZNcIixhbmQ6XCLiiKdcIixhbmRkOlwi4qmcXCIsYW5kc2xvcGU6XCLiqZhcIixhbmR2Olwi4qmaXCIsYW5nOlwi4oigXCIsYW5nZTpcIuKmpFwiLGFuZ2xlOlwi4oigXCIsYW5nbXNkYWE6XCLipqhcIixhbmdtc2RhYjpcIuKmqVwiLGFuZ21zZGFjOlwi4qaqXCIsYW5nbXNkYWQ6XCLipqtcIixhbmdtc2RhZTpcIuKmrFwiLGFuZ21zZGFmOlwi4qatXCIsYW5nbXNkYWc6XCLipq5cIixhbmdtc2RhaDpcIuKmr1wiLGFuZ21zZDpcIuKIoVwiLGFuZ3J0Olwi4oifXCIsYW5ncnR2YjpcIuKKvlwiLGFuZ3J0dmJkOlwi4qadXCIsYW5nc3BoOlwi4oiiXCIsYW5nc3Q6XCLDhVwiLGFuZ3phcnI6XCLijbxcIixBb2dvbjpcIsSEXCIsYW9nb246XCLEhVwiLEFvcGY6XCLwnZS4XCIsYW9wZjpcIvCdlZJcIixhcGFjaXI6XCLiqa9cIixhcDpcIuKJiFwiLGFwRTpcIuKpsFwiLGFwZTpcIuKJilwiLGFwaWQ6XCLiiYtcIixhcG9zOlwiJ1wiLEFwcGx5RnVuY3Rpb246XCLigaFcIixhcHByb3g6XCLiiYhcIixhcHByb3hlcTpcIuKJilwiLEFyaW5nOlwiw4VcIixhcmluZzpcIsOlXCIsQXNjcjpcIvCdkpxcIixhc2NyOlwi8J2StlwiLEFzc2lnbjpcIuKJlFwiLGFzdDpcIipcIixhc3ltcDpcIuKJiFwiLGFzeW1wZXE6XCLiiY1cIixBdGlsZGU6XCLDg1wiLGF0aWxkZTpcIsOjXCIsQXVtbDpcIsOEXCIsYXVtbDpcIsOkXCIsYXdjb25pbnQ6XCLiiLNcIixhd2ludDpcIuKokVwiLGJhY2tjb25nOlwi4omMXCIsYmFja2Vwc2lsb246XCLPtlwiLGJhY2twcmltZTpcIuKAtVwiLGJhY2tzaW06XCLiiL1cIixiYWNrc2ltZXE6XCLii41cIixCYWNrc2xhc2g6XCLiiJZcIixCYXJ2Olwi4qunXCIsYmFydmVlOlwi4oq9XCIsYmFyd2VkOlwi4oyFXCIsQmFyd2VkOlwi4oyGXCIsYmFyd2VkZ2U6XCLijIVcIixiYnJrOlwi4o61XCIsYmJya3Ricms6XCLijrZcIixiY29uZzpcIuKJjFwiLEJjeTpcItCRXCIsYmN5Olwi0LFcIixiZHF1bzpcIuKAnlwiLGJlY2F1czpcIuKItVwiLGJlY2F1c2U6XCLiiLVcIixCZWNhdXNlOlwi4oi1XCIsYmVtcHR5djpcIuKmsFwiLGJlcHNpOlwiz7ZcIixiZXJub3U6XCLihKxcIixCZXJub3VsbGlzOlwi4oSsXCIsQmV0YTpcIs6SXCIsYmV0YTpcIs6yXCIsYmV0aDpcIuKEtlwiLGJldHdlZW46XCLiiaxcIixCZnI6XCLwnZSFXCIsYmZyOlwi8J2Un1wiLGJpZ2NhcDpcIuKLglwiLGJpZ2NpcmM6XCLil69cIixiaWdjdXA6XCLii4NcIixiaWdvZG90Olwi4qiAXCIsYmlnb3BsdXM6XCLiqIFcIixiaWdvdGltZXM6XCLiqIJcIixiaWdzcWN1cDpcIuKohlwiLGJpZ3N0YXI6XCLimIVcIixiaWd0cmlhbmdsZWRvd246XCLilr1cIixiaWd0cmlhbmdsZXVwOlwi4pazXCIsYmlndXBsdXM6XCLiqIRcIixiaWd2ZWU6XCLii4FcIixiaWd3ZWRnZTpcIuKLgFwiLGJrYXJvdzpcIuKkjVwiLGJsYWNrbG96ZW5nZTpcIuKnq1wiLGJsYWNrc3F1YXJlOlwi4paqXCIsYmxhY2t0cmlhbmdsZTpcIuKWtFwiLGJsYWNrdHJpYW5nbGVkb3duOlwi4pa+XCIsYmxhY2t0cmlhbmdsZWxlZnQ6XCLil4JcIixibGFja3RyaWFuZ2xlcmlnaHQ6XCLilrhcIixibGFuazpcIuKQo1wiLGJsazEyOlwi4paSXCIsYmxrMTQ6XCLilpFcIixibGszNDpcIuKWk1wiLGJsb2NrOlwi4paIXCIsYm5lOlwiPeKDpVwiLGJuZXF1aXY6XCLiiaHig6VcIixiTm90Olwi4qutXCIsYm5vdDpcIuKMkFwiLEJvcGY6XCLwnZS5XCIsYm9wZjpcIvCdlZNcIixib3Q6XCLiiqVcIixib3R0b206XCLiiqVcIixib3d0aWU6XCLii4hcIixib3hib3g6XCLip4lcIixib3hkbDpcIuKUkFwiLGJveGRMOlwi4pWVXCIsYm94RGw6XCLilZZcIixib3hETDpcIuKVl1wiLGJveGRyOlwi4pSMXCIsYm94ZFI6XCLilZJcIixib3hEcjpcIuKVk1wiLGJveERSOlwi4pWUXCIsYm94aDpcIuKUgFwiLGJveEg6XCLilZBcIixib3hoZDpcIuKUrFwiLGJveEhkOlwi4pWkXCIsYm94aEQ6XCLilaVcIixib3hIRDpcIuKVplwiLGJveGh1Olwi4pS0XCIsYm94SHU6XCLiladcIixib3hoVTpcIuKVqFwiLGJveEhVOlwi4pWpXCIsYm94bWludXM6XCLiip9cIixib3hwbHVzOlwi4oqeXCIsYm94dGltZXM6XCLiiqBcIixib3h1bDpcIuKUmFwiLGJveHVMOlwi4pWbXCIsYm94VWw6XCLilZxcIixib3hVTDpcIuKVnVwiLGJveHVyOlwi4pSUXCIsYm94dVI6XCLilZhcIixib3hVcjpcIuKVmVwiLGJveFVSOlwi4pWaXCIsYm94djpcIuKUglwiLGJveFY6XCLilZFcIixib3h2aDpcIuKUvFwiLGJveHZIOlwi4pWqXCIsYm94Vmg6XCLilatcIixib3hWSDpcIuKVrFwiLGJveHZsOlwi4pSkXCIsYm94dkw6XCLilaFcIixib3hWbDpcIuKVolwiLGJveFZMOlwi4pWjXCIsYm94dnI6XCLilJxcIixib3h2UjpcIuKVnlwiLGJveFZyOlwi4pWfXCIsYm94VlI6XCLilaBcIixicHJpbWU6XCLigLVcIixicmV2ZTpcIsuYXCIsQnJldmU6XCLLmFwiLGJydmJhcjpcIsKmXCIsYnNjcjpcIvCdkrdcIixCc2NyOlwi4oSsXCIsYnNlbWk6XCLigY9cIixic2ltOlwi4oi9XCIsYnNpbWU6XCLii41cIixic29sYjpcIuKnhVwiLGJzb2w6XCJcXFxcXCIsYnNvbGhzdWI6XCLin4hcIixidWxsOlwi4oCiXCIsYnVsbGV0Olwi4oCiXCIsYnVtcDpcIuKJjlwiLGJ1bXBFOlwi4qquXCIsYnVtcGU6XCLiiY9cIixCdW1wZXE6XCLiiY5cIixidW1wZXE6XCLiiY9cIixDYWN1dGU6XCLEhlwiLGNhY3V0ZTpcIsSHXCIsY2FwYW5kOlwi4qmEXCIsY2FwYnJjdXA6XCLiqYlcIixjYXBjYXA6XCLiqYtcIixjYXA6XCLiiKlcIixDYXA6XCLii5JcIixjYXBjdXA6XCLiqYdcIixjYXBkb3Q6XCLiqYBcIixDYXBpdGFsRGlmZmVyZW50aWFsRDpcIuKFhVwiLGNhcHM6XCLiiKnvuIBcIixjYXJldDpcIuKBgVwiLGNhcm9uOlwiy4dcIixDYXlsZXlzOlwi4oStXCIsY2NhcHM6XCLiqY1cIixDY2Fyb246XCLEjFwiLGNjYXJvbjpcIsSNXCIsQ2NlZGlsOlwiw4dcIixjY2VkaWw6XCLDp1wiLENjaXJjOlwixIhcIixjY2lyYzpcIsSJXCIsQ2NvbmludDpcIuKIsFwiLGNjdXBzOlwi4qmMXCIsY2N1cHNzbTpcIuKpkFwiLENkb3Q6XCLEilwiLGNkb3Q6XCLEi1wiLGNlZGlsOlwiwrhcIixDZWRpbGxhOlwiwrhcIixjZW1wdHl2Olwi4qayXCIsY2VudDpcIsKiXCIsY2VudGVyZG90OlwiwrdcIixDZW50ZXJEb3Q6XCLCt1wiLGNmcjpcIvCdlKBcIixDZnI6XCLihK1cIixDSGN5Olwi0KdcIixjaGN5Olwi0YdcIixjaGVjazpcIuKck1wiLGNoZWNrbWFyazpcIuKck1wiLENoaTpcIs6nXCIsY2hpOlwiz4dcIixjaXJjOlwiy4ZcIixjaXJjZXE6XCLiiZdcIixjaXJjbGVhcnJvd2xlZnQ6XCLihrpcIixjaXJjbGVhcnJvd3JpZ2h0Olwi4oa7XCIsY2lyY2xlZGFzdDpcIuKKm1wiLGNpcmNsZWRjaXJjOlwi4oqaXCIsY2lyY2xlZGRhc2g6XCLiip1cIixDaXJjbGVEb3Q6XCLiiplcIixjaXJjbGVkUjpcIsKuXCIsY2lyY2xlZFM6XCLik4hcIixDaXJjbGVNaW51czpcIuKKllwiLENpcmNsZVBsdXM6XCLiipVcIixDaXJjbGVUaW1lczpcIuKKl1wiLGNpcjpcIuKXi1wiLGNpckU6XCLip4NcIixjaXJlOlwi4omXXCIsY2lyZm5pbnQ6XCLiqJBcIixjaXJtaWQ6XCLiq69cIixjaXJzY2lyOlwi4qeCXCIsQ2xvY2t3aXNlQ29udG91ckludGVncmFsOlwi4oiyXCIsQ2xvc2VDdXJseURvdWJsZVF1b3RlOlwi4oCdXCIsQ2xvc2VDdXJseVF1b3RlOlwi4oCZXCIsY2x1YnM6XCLimaNcIixjbHVic3VpdDpcIuKZo1wiLGNvbG9uOlwiOlwiLENvbG9uOlwi4oi3XCIsQ29sb25lOlwi4qm0XCIsY29sb25lOlwi4omUXCIsY29sb25lcTpcIuKJlFwiLGNvbW1hOlwiLFwiLGNvbW1hdDpcIkBcIixjb21wOlwi4oiBXCIsY29tcGZuOlwi4oiYXCIsY29tcGxlbWVudDpcIuKIgVwiLGNvbXBsZXhlczpcIuKEglwiLGNvbmc6XCLiiYVcIixjb25nZG90Olwi4qmtXCIsQ29uZ3J1ZW50Olwi4omhXCIsY29uaW50Olwi4oiuXCIsQ29uaW50Olwi4oivXCIsQ29udG91ckludGVncmFsOlwi4oiuXCIsY29wZjpcIvCdlZRcIixDb3BmOlwi4oSCXCIsY29wcm9kOlwi4oiQXCIsQ29wcm9kdWN0Olwi4oiQXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY29weXNyOlwi4oSXXCIsQ291bnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbDpcIuKIs1wiLGNyYXJyOlwi4oa1XCIsY3Jvc3M6XCLinJdcIixDcm9zczpcIuKor1wiLENzY3I6XCLwnZKeXCIsY3NjcjpcIvCdkrhcIixjc3ViOlwi4quPXCIsY3N1YmU6XCLiq5FcIixjc3VwOlwi4quQXCIsY3N1cGU6XCLiq5JcIixjdGRvdDpcIuKLr1wiLGN1ZGFycmw6XCLipLhcIixjdWRhcnJyOlwi4qS1XCIsY3VlcHI6XCLii55cIixjdWVzYzpcIuKLn1wiLGN1bGFycjpcIuKGtlwiLGN1bGFycnA6XCLipL1cIixjdXBicmNhcDpcIuKpiFwiLGN1cGNhcDpcIuKphlwiLEN1cENhcDpcIuKJjVwiLGN1cDpcIuKIqlwiLEN1cDpcIuKLk1wiLGN1cGN1cDpcIuKpilwiLGN1cGRvdDpcIuKKjVwiLGN1cG9yOlwi4qmFXCIsY3VwczpcIuKIqu+4gFwiLGN1cmFycjpcIuKGt1wiLGN1cmFycm06XCLipLxcIixjdXJseWVxcHJlYzpcIuKLnlwiLGN1cmx5ZXFzdWNjOlwi4oufXCIsY3VybHl2ZWU6XCLii45cIixjdXJseXdlZGdlOlwi4ouPXCIsY3VycmVuOlwiwqRcIixjdXJ2ZWFycm93bGVmdDpcIuKGtlwiLGN1cnZlYXJyb3dyaWdodDpcIuKGt1wiLGN1dmVlOlwi4ouOXCIsY3V3ZWQ6XCLii49cIixjd2NvbmludDpcIuKIslwiLGN3aW50Olwi4oixXCIsY3lsY3R5Olwi4oytXCIsZGFnZ2VyOlwi4oCgXCIsRGFnZ2VyOlwi4oChXCIsZGFsZXRoOlwi4oS4XCIsZGFycjpcIuKGk1wiLERhcnI6XCLihqFcIixkQXJyOlwi4oeTXCIsZGFzaDpcIuKAkFwiLERhc2h2Olwi4qukXCIsZGFzaHY6XCLiiqNcIixkYmthcm93Olwi4qSPXCIsZGJsYWM6XCLLnVwiLERjYXJvbjpcIsSOXCIsZGNhcm9uOlwixI9cIixEY3k6XCLQlFwiLGRjeTpcItC0XCIsZGRhZ2dlcjpcIuKAoVwiLGRkYXJyOlwi4oeKXCIsREQ6XCLihYVcIixkZDpcIuKFhlwiLEREb3RyYWhkOlwi4qSRXCIsZGRvdHNlcTpcIuKpt1wiLGRlZzpcIsKwXCIsRGVsOlwi4oiHXCIsRGVsdGE6XCLOlFwiLGRlbHRhOlwizrRcIixkZW1wdHl2Olwi4qaxXCIsZGZpc2h0Olwi4qW/XCIsRGZyOlwi8J2Uh1wiLGRmcjpcIvCdlKFcIixkSGFyOlwi4qWlXCIsZGhhcmw6XCLih4NcIixkaGFycjpcIuKHglwiLERpYWNyaXRpY2FsQWN1dGU6XCLCtFwiLERpYWNyaXRpY2FsRG90Olwiy5lcIixEaWFjcml0aWNhbERvdWJsZUFjdXRlOlwiy51cIixEaWFjcml0aWNhbEdyYXZlOlwiYFwiLERpYWNyaXRpY2FsVGlsZGU6XCLLnFwiLGRpYW06XCLii4RcIixkaWFtb25kOlwi4ouEXCIsRGlhbW9uZDpcIuKLhFwiLGRpYW1vbmRzdWl0Olwi4pmmXCIsZGlhbXM6XCLimaZcIixkaWU6XCLCqFwiLERpZmZlcmVudGlhbEQ6XCLihYZcIixkaWdhbW1hOlwiz51cIixkaXNpbjpcIuKLslwiLGRpdjpcIsO3XCIsZGl2aWRlOlwiw7dcIixkaXZpZGVvbnRpbWVzOlwi4ouHXCIsZGl2b254Olwi4ouHXCIsREpjeTpcItCCXCIsZGpjeTpcItGSXCIsZGxjb3JuOlwi4oyeXCIsZGxjcm9wOlwi4oyNXCIsZG9sbGFyOlwiJFwiLERvcGY6XCLwnZS7XCIsZG9wZjpcIvCdlZVcIixEb3Q6XCLCqFwiLGRvdDpcIsuZXCIsRG90RG90Olwi4oOcXCIsZG90ZXE6XCLiiZBcIixkb3RlcWRvdDpcIuKJkVwiLERvdEVxdWFsOlwi4omQXCIsZG90bWludXM6XCLiiLhcIixkb3RwbHVzOlwi4oiUXCIsZG90c3F1YXJlOlwi4oqhXCIsZG91YmxlYmFyd2VkZ2U6XCLijIZcIixEb3VibGVDb250b3VySW50ZWdyYWw6XCLiiK9cIixEb3VibGVEb3Q6XCLCqFwiLERvdWJsZURvd25BcnJvdzpcIuKHk1wiLERvdWJsZUxlZnRBcnJvdzpcIuKHkFwiLERvdWJsZUxlZnRSaWdodEFycm93Olwi4oeUXCIsRG91YmxlTGVmdFRlZTpcIuKrpFwiLERvdWJsZUxvbmdMZWZ0QXJyb3c6XCLin7hcIixEb3VibGVMb25nTGVmdFJpZ2h0QXJyb3c6XCLin7pcIixEb3VibGVMb25nUmlnaHRBcnJvdzpcIuKfuVwiLERvdWJsZVJpZ2h0QXJyb3c6XCLih5JcIixEb3VibGVSaWdodFRlZTpcIuKKqFwiLERvdWJsZVVwQXJyb3c6XCLih5FcIixEb3VibGVVcERvd25BcnJvdzpcIuKHlVwiLERvdWJsZVZlcnRpY2FsQmFyOlwi4oilXCIsRG93bkFycm93QmFyOlwi4qSTXCIsZG93bmFycm93Olwi4oaTXCIsRG93bkFycm93Olwi4oaTXCIsRG93bmFycm93Olwi4oeTXCIsRG93bkFycm93VXBBcnJvdzpcIuKHtVwiLERvd25CcmV2ZTpcIsyRXCIsZG93bmRvd25hcnJvd3M6XCLih4pcIixkb3duaGFycG9vbmxlZnQ6XCLih4NcIixkb3duaGFycG9vbnJpZ2h0Olwi4oeCXCIsRG93bkxlZnRSaWdodFZlY3RvcjpcIuKlkFwiLERvd25MZWZ0VGVlVmVjdG9yOlwi4qWeXCIsRG93bkxlZnRWZWN0b3JCYXI6XCLipZZcIixEb3duTGVmdFZlY3RvcjpcIuKGvVwiLERvd25SaWdodFRlZVZlY3RvcjpcIuKln1wiLERvd25SaWdodFZlY3RvckJhcjpcIuKll1wiLERvd25SaWdodFZlY3RvcjpcIuKHgVwiLERvd25UZWVBcnJvdzpcIuKGp1wiLERvd25UZWU6XCLiiqRcIixkcmJrYXJvdzpcIuKkkFwiLGRyY29ybjpcIuKMn1wiLGRyY3JvcDpcIuKMjFwiLERzY3I6XCLwnZKfXCIsZHNjcjpcIvCdkrlcIixEU2N5Olwi0IVcIixkc2N5Olwi0ZVcIixkc29sOlwi4qe2XCIsRHN0cm9rOlwixJBcIixkc3Ryb2s6XCLEkVwiLGR0ZG90Olwi4ouxXCIsZHRyaTpcIuKWv1wiLGR0cmlmOlwi4pa+XCIsZHVhcnI6XCLih7VcIixkdWhhcjpcIuKlr1wiLGR3YW5nbGU6XCLipqZcIixEWmN5Olwi0I9cIixkemN5Olwi0Z9cIixkemlncmFycjpcIuKfv1wiLEVhY3V0ZTpcIsOJXCIsZWFjdXRlOlwiw6lcIixlYXN0ZXI6XCLiqa5cIixFY2Fyb246XCLEmlwiLGVjYXJvbjpcIsSbXCIsRWNpcmM6XCLDilwiLGVjaXJjOlwiw6pcIixlY2lyOlwi4omWXCIsZWNvbG9uOlwi4omVXCIsRWN5Olwi0K1cIixlY3k6XCLRjVwiLGVERG90Olwi4qm3XCIsRWRvdDpcIsSWXCIsZWRvdDpcIsSXXCIsZURvdDpcIuKJkVwiLGVlOlwi4oWHXCIsZWZEb3Q6XCLiiZJcIixFZnI6XCLwnZSIXCIsZWZyOlwi8J2UolwiLGVnOlwi4qqaXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLGVnczpcIuKqllwiLGVnc2RvdDpcIuKqmFwiLGVsOlwi4qqZXCIsRWxlbWVudDpcIuKIiFwiLGVsaW50ZXJzOlwi4o+nXCIsZWxsOlwi4oSTXCIsZWxzOlwi4qqVXCIsZWxzZG90Olwi4qqXXCIsRW1hY3I6XCLEklwiLGVtYWNyOlwixJNcIixlbXB0eTpcIuKIhVwiLGVtcHR5c2V0Olwi4oiFXCIsRW1wdHlTbWFsbFNxdWFyZTpcIuKXu1wiLGVtcHR5djpcIuKIhVwiLEVtcHR5VmVyeVNtYWxsU3F1YXJlOlwi4parXCIsZW1zcDEzOlwi4oCEXCIsZW1zcDE0Olwi4oCFXCIsZW1zcDpcIuKAg1wiLEVORzpcIsWKXCIsZW5nOlwixYtcIixlbnNwOlwi4oCCXCIsRW9nb246XCLEmFwiLGVvZ29uOlwixJlcIixFb3BmOlwi8J2UvFwiLGVvcGY6XCLwnZWWXCIsZXBhcjpcIuKLlVwiLGVwYXJzbDpcIuKno1wiLGVwbHVzOlwi4qmxXCIsZXBzaTpcIs61XCIsRXBzaWxvbjpcIs6VXCIsZXBzaWxvbjpcIs61XCIsZXBzaXY6XCLPtVwiLGVxY2lyYzpcIuKJllwiLGVxY29sb246XCLiiZVcIixlcXNpbTpcIuKJglwiLGVxc2xhbnRndHI6XCLiqpZcIixlcXNsYW50bGVzczpcIuKqlVwiLEVxdWFsOlwi4qm1XCIsZXF1YWxzOlwiPVwiLEVxdWFsVGlsZGU6XCLiiYJcIixlcXVlc3Q6XCLiiZ9cIixFcXVpbGlicml1bTpcIuKHjFwiLGVxdWl2Olwi4omhXCIsZXF1aXZERDpcIuKpuFwiLGVxdnBhcnNsOlwi4qelXCIsZXJhcnI6XCLipbFcIixlckRvdDpcIuKJk1wiLGVzY3I6XCLihK9cIixFc2NyOlwi4oSwXCIsZXNkb3Q6XCLiiZBcIixFc2ltOlwi4qmzXCIsZXNpbTpcIuKJglwiLEV0YTpcIs6XXCIsZXRhOlwizrdcIixFVEg6XCLDkFwiLGV0aDpcIsOwXCIsRXVtbDpcIsOLXCIsZXVtbDpcIsOrXCIsZXVybzpcIuKCrFwiLGV4Y2w6XCIhXCIsZXhpc3Q6XCLiiINcIixFeGlzdHM6XCLiiINcIixleHBlY3RhdGlvbjpcIuKEsFwiLGV4cG9uZW50aWFsZTpcIuKFh1wiLEV4cG9uZW50aWFsRTpcIuKFh1wiLGZhbGxpbmdkb3RzZXE6XCLiiZJcIixGY3k6XCLQpFwiLGZjeTpcItGEXCIsZmVtYWxlOlwi4pmAXCIsZmZpbGlnOlwi76yDXCIsZmZsaWc6XCLvrIBcIixmZmxsaWc6XCLvrIRcIixGZnI6XCLwnZSJXCIsZmZyOlwi8J2Uo1wiLGZpbGlnOlwi76yBXCIsRmlsbGVkU21hbGxTcXVhcmU6XCLil7xcIixGaWxsZWRWZXJ5U21hbGxTcXVhcmU6XCLilqpcIixmamxpZzpcImZqXCIsZmxhdDpcIuKZrVwiLGZsbGlnOlwi76yCXCIsZmx0bnM6XCLilrFcIixmbm9mOlwixpJcIixGb3BmOlwi8J2UvVwiLGZvcGY6XCLwnZWXXCIsZm9yYWxsOlwi4oiAXCIsRm9yQWxsOlwi4oiAXCIsZm9yazpcIuKLlFwiLGZvcmt2Olwi4quZXCIsRm91cmllcnRyZjpcIuKEsVwiLGZwYXJ0aW50Olwi4qiNXCIsZnJhYzEyOlwiwr1cIixmcmFjMTM6XCLihZNcIixmcmFjMTQ6XCLCvFwiLGZyYWMxNTpcIuKFlVwiLGZyYWMxNjpcIuKFmVwiLGZyYWMxODpcIuKFm1wiLGZyYWMyMzpcIuKFlFwiLGZyYWMyNTpcIuKFllwiLGZyYWMzNDpcIsK+XCIsZnJhYzM1Olwi4oWXXCIsZnJhYzM4Olwi4oWcXCIsZnJhYzQ1Olwi4oWYXCIsZnJhYzU2Olwi4oWaXCIsZnJhYzU4Olwi4oWdXCIsZnJhYzc4Olwi4oWeXCIsZnJhc2w6XCLigYRcIixmcm93bjpcIuKMolwiLGZzY3I6XCLwnZK7XCIsRnNjcjpcIuKEsVwiLGdhY3V0ZTpcIse1XCIsR2FtbWE6XCLOk1wiLGdhbW1hOlwizrNcIixHYW1tYWQ6XCLPnFwiLGdhbW1hZDpcIs+dXCIsZ2FwOlwi4qqGXCIsR2JyZXZlOlwixJ5cIixnYnJldmU6XCLEn1wiLEdjZWRpbDpcIsSiXCIsR2NpcmM6XCLEnFwiLGdjaXJjOlwixJ1cIixHY3k6XCLQk1wiLGdjeTpcItCzXCIsR2RvdDpcIsSgXCIsZ2RvdDpcIsShXCIsZ2U6XCLiiaVcIixnRTpcIuKJp1wiLGdFbDpcIuKqjFwiLGdlbDpcIuKLm1wiLGdlcTpcIuKJpVwiLGdlcXE6XCLiiadcIixnZXFzbGFudDpcIuKpvlwiLGdlc2NjOlwi4qqpXCIsZ2VzOlwi4qm+XCIsZ2VzZG90Olwi4qqAXCIsZ2VzZG90bzpcIuKqglwiLGdlc2RvdG9sOlwi4qqEXCIsZ2VzbDpcIuKLm++4gFwiLGdlc2xlczpcIuKqlFwiLEdmcjpcIvCdlIpcIixnZnI6XCLwnZSkXCIsZ2c6XCLiiatcIixHZzpcIuKLmVwiLGdnZzpcIuKLmVwiLGdpbWVsOlwi4oS3XCIsR0pjeTpcItCDXCIsZ2pjeTpcItGTXCIsZ2xhOlwi4qqlXCIsZ2w6XCLiibdcIixnbEU6XCLiqpJcIixnbGo6XCLiqqRcIixnbmFwOlwi4qqKXCIsZ25hcHByb3g6XCLiqopcIixnbmU6XCLiqohcIixnbkU6XCLiialcIixnbmVxOlwi4qqIXCIsZ25lcXE6XCLiialcIixnbnNpbTpcIuKLp1wiLEdvcGY6XCLwnZS+XCIsZ29wZjpcIvCdlZhcIixncmF2ZTpcImBcIixHcmVhdGVyRXF1YWw6XCLiiaVcIixHcmVhdGVyRXF1YWxMZXNzOlwi4oubXCIsR3JlYXRlckZ1bGxFcXVhbDpcIuKJp1wiLEdyZWF0ZXJHcmVhdGVyOlwi4qqiXCIsR3JlYXRlckxlc3M6XCLiibdcIixHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvlwiLEdyZWF0ZXJUaWxkZTpcIuKJs1wiLEdzY3I6XCLwnZKiXCIsZ3NjcjpcIuKEilwiLGdzaW06XCLiibNcIixnc2ltZTpcIuKqjlwiLGdzaW1sOlwi4qqQXCIsZ3RjYzpcIuKqp1wiLGd0Y2lyOlwi4qm6XCIsZ3Q6XCI+XCIsR1Q6XCI+XCIsR3Q6XCLiiatcIixndGRvdDpcIuKLl1wiLGd0bFBhcjpcIuKmlVwiLGd0cXVlc3Q6XCLiqbxcIixndHJhcHByb3g6XCLiqoZcIixndHJhcnI6XCLipbhcIixndHJkb3Q6XCLii5dcIixndHJlcWxlc3M6XCLii5tcIixndHJlcXFsZXNzOlwi4qqMXCIsZ3RybGVzczpcIuKJt1wiLGd0cnNpbTpcIuKJs1wiLGd2ZXJ0bmVxcTpcIuKJqe+4gFwiLGd2bkU6XCLiianvuIBcIixIYWNlazpcIsuHXCIsaGFpcnNwOlwi4oCKXCIsaGFsZjpcIsK9XCIsaGFtaWx0Olwi4oSLXCIsSEFSRGN5Olwi0KpcIixoYXJkY3k6XCLRilwiLGhhcnJjaXI6XCLipYhcIixoYXJyOlwi4oaUXCIsaEFycjpcIuKHlFwiLGhhcnJ3Olwi4oatXCIsSGF0OlwiXlwiLGhiYXI6XCLihI9cIixIY2lyYzpcIsSkXCIsaGNpcmM6XCLEpVwiLGhlYXJ0czpcIuKZpVwiLGhlYXJ0c3VpdDpcIuKZpVwiLGhlbGxpcDpcIuKAplwiLGhlcmNvbjpcIuKKuVwiLGhmcjpcIvCdlKVcIixIZnI6XCLihIxcIixIaWxiZXJ0U3BhY2U6XCLihItcIixoa3NlYXJvdzpcIuKkpVwiLGhrc3dhcm93Olwi4qSmXCIsaG9hcnI6XCLih79cIixob210aHQ6XCLiiLtcIixob29rbGVmdGFycm93Olwi4oapXCIsaG9va3JpZ2h0YXJyb3c6XCLihqpcIixob3BmOlwi8J2VmVwiLEhvcGY6XCLihI1cIixob3JiYXI6XCLigJVcIixIb3Jpem9udGFsTGluZTpcIuKUgFwiLGhzY3I6XCLwnZK9XCIsSHNjcjpcIuKEi1wiLGhzbGFzaDpcIuKEj1wiLEhzdHJvazpcIsSmXCIsaHN0cm9rOlwixKdcIixIdW1wRG93bkh1bXA6XCLiiY5cIixIdW1wRXF1YWw6XCLiiY9cIixoeWJ1bGw6XCLigYNcIixoeXBoZW46XCLigJBcIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsaWM6XCLigaNcIixJY2lyYzpcIsOOXCIsaWNpcmM6XCLDrlwiLEljeTpcItCYXCIsaWN5Olwi0LhcIixJZG90OlwixLBcIixJRWN5Olwi0JVcIixpZWN5Olwi0LVcIixpZXhjbDpcIsKhXCIsaWZmOlwi4oeUXCIsaWZyOlwi8J2UplwiLElmcjpcIuKEkVwiLElncmF2ZTpcIsOMXCIsaWdyYXZlOlwiw6xcIixpaTpcIuKFiFwiLGlpaWludDpcIuKojFwiLGlpaW50Olwi4oitXCIsaWluZmluOlwi4qecXCIsaWlvdGE6XCLihKlcIixJSmxpZzpcIsSyXCIsaWpsaWc6XCLEs1wiLEltYWNyOlwixKpcIixpbWFjcjpcIsSrXCIsaW1hZ2U6XCLihJFcIixJbWFnaW5hcnlJOlwi4oWIXCIsaW1hZ2xpbmU6XCLihJBcIixpbWFncGFydDpcIuKEkVwiLGltYXRoOlwixLFcIixJbTpcIuKEkVwiLGltb2Y6XCLiirdcIixpbXBlZDpcIsa1XCIsSW1wbGllczpcIuKHklwiLGluY2FyZTpcIuKEhVwiLGluOlwi4oiIXCIsaW5maW46XCLiiJ5cIixpbmZpbnRpZTpcIuKnnVwiLGlub2RvdDpcIsSxXCIsaW50Y2FsOlwi4oq6XCIsaW50Olwi4oirXCIsSW50Olwi4oisXCIsaW50ZWdlcnM6XCLihKRcIixJbnRlZ3JhbDpcIuKIq1wiLGludGVyY2FsOlwi4oq6XCIsSW50ZXJzZWN0aW9uOlwi4ouCXCIsaW50bGFyaGs6XCLiqJdcIixpbnRwcm9kOlwi4qi8XCIsSW52aXNpYmxlQ29tbWE6XCLigaNcIixJbnZpc2libGVUaW1lczpcIuKBolwiLElPY3k6XCLQgVwiLGlvY3k6XCLRkVwiLElvZ29uOlwixK5cIixpb2dvbjpcIsSvXCIsSW9wZjpcIvCdlYBcIixpb3BmOlwi8J2VmlwiLElvdGE6XCLOmVwiLGlvdGE6XCLOuVwiLGlwcm9kOlwi4qi8XCIsaXF1ZXN0Olwiwr9cIixpc2NyOlwi8J2SvlwiLElzY3I6XCLihJBcIixpc2luOlwi4oiIXCIsaXNpbmRvdDpcIuKLtVwiLGlzaW5FOlwi4ou5XCIsaXNpbnM6XCLii7RcIixpc2luc3Y6XCLii7NcIixpc2ludjpcIuKIiFwiLGl0Olwi4oGiXCIsSXRpbGRlOlwixKhcIixpdGlsZGU6XCLEqVwiLEl1a2N5Olwi0IZcIixpdWtjeTpcItGWXCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsSmNpcmM6XCLEtFwiLGpjaXJjOlwixLVcIixKY3k6XCLQmVwiLGpjeTpcItC5XCIsSmZyOlwi8J2UjVwiLGpmcjpcIvCdlKdcIixqbWF0aDpcIsi3XCIsSm9wZjpcIvCdlYFcIixqb3BmOlwi8J2Vm1wiLEpzY3I6XCLwnZKlXCIsanNjcjpcIvCdkr9cIixKc2VyY3k6XCLQiFwiLGpzZXJjeTpcItGYXCIsSnVrY3k6XCLQhFwiLGp1a2N5Olwi0ZRcIixLYXBwYTpcIs6aXCIsa2FwcGE6XCLOulwiLGthcHBhdjpcIs+wXCIsS2NlZGlsOlwixLZcIixrY2VkaWw6XCLEt1wiLEtjeTpcItCaXCIsa2N5Olwi0LpcIixLZnI6XCLwnZSOXCIsa2ZyOlwi8J2UqFwiLGtncmVlbjpcIsS4XCIsS0hjeTpcItClXCIsa2hjeTpcItGFXCIsS0pjeTpcItCMXCIsa2pjeTpcItGcXCIsS29wZjpcIvCdlYJcIixrb3BmOlwi8J2VnFwiLEtzY3I6XCLwnZKmXCIsa3NjcjpcIvCdk4BcIixsQWFycjpcIuKHmlwiLExhY3V0ZTpcIsS5XCIsbGFjdXRlOlwixLpcIixsYWVtcHR5djpcIuKmtFwiLGxhZ3JhbjpcIuKEklwiLExhbWJkYTpcIs6bXCIsbGFtYmRhOlwizrtcIixsYW5nOlwi4p+oXCIsTGFuZzpcIuKfqlwiLGxhbmdkOlwi4qaRXCIsbGFuZ2xlOlwi4p+oXCIsbGFwOlwi4qqFXCIsTGFwbGFjZXRyZjpcIuKEklwiLGxhcXVvOlwiwqtcIixsYXJyYjpcIuKHpFwiLGxhcnJiZnM6XCLipJ9cIixsYXJyOlwi4oaQXCIsTGFycjpcIuKGnlwiLGxBcnI6XCLih5BcIixsYXJyZnM6XCLipJ1cIixsYXJyaGs6XCLihqlcIixsYXJybHA6XCLihqtcIixsYXJycGw6XCLipLlcIixsYXJyc2ltOlwi4qWzXCIsbGFycnRsOlwi4oaiXCIsbGF0YWlsOlwi4qSZXCIsbEF0YWlsOlwi4qSbXCIsbGF0Olwi4qqrXCIsbGF0ZTpcIuKqrVwiLGxhdGVzOlwi4qqt77iAXCIsbGJhcnI6XCLipIxcIixsQmFycjpcIuKkjlwiLGxiYnJrOlwi4p2yXCIsbGJyYWNlOlwie1wiLGxicmFjazpcIltcIixsYnJrZTpcIuKmi1wiLGxicmtzbGQ6XCLipo9cIixsYnJrc2x1Olwi4qaNXCIsTGNhcm9uOlwixL1cIixsY2Fyb246XCLEvlwiLExjZWRpbDpcIsS7XCIsbGNlZGlsOlwixLxcIixsY2VpbDpcIuKMiFwiLGxjdWI6XCJ7XCIsTGN5Olwi0JtcIixsY3k6XCLQu1wiLGxkY2E6XCLipLZcIixsZHF1bzpcIuKAnFwiLGxkcXVvcjpcIuKAnlwiLGxkcmRoYXI6XCLipadcIixsZHJ1c2hhcjpcIuKli1wiLGxkc2g6XCLihrJcIixsZTpcIuKJpFwiLGxFOlwi4ommXCIsTGVmdEFuZ2xlQnJhY2tldDpcIuKfqFwiLExlZnRBcnJvd0JhcjpcIuKHpFwiLGxlZnRhcnJvdzpcIuKGkFwiLExlZnRBcnJvdzpcIuKGkFwiLExlZnRhcnJvdzpcIuKHkFwiLExlZnRBcnJvd1JpZ2h0QXJyb3c6XCLih4ZcIixsZWZ0YXJyb3d0YWlsOlwi4oaiXCIsTGVmdENlaWxpbmc6XCLijIhcIixMZWZ0RG91YmxlQnJhY2tldDpcIuKfplwiLExlZnREb3duVGVlVmVjdG9yOlwi4qWhXCIsTGVmdERvd25WZWN0b3JCYXI6XCLipZlcIixMZWZ0RG93blZlY3RvcjpcIuKHg1wiLExlZnRGbG9vcjpcIuKMilwiLGxlZnRoYXJwb29uZG93bjpcIuKGvVwiLGxlZnRoYXJwb29udXA6XCLihrxcIixsZWZ0bGVmdGFycm93czpcIuKHh1wiLGxlZnRyaWdodGFycm93Olwi4oaUXCIsTGVmdFJpZ2h0QXJyb3c6XCLihpRcIixMZWZ0cmlnaHRhcnJvdzpcIuKHlFwiLGxlZnRyaWdodGFycm93czpcIuKHhlwiLGxlZnRyaWdodGhhcnBvb25zOlwi4oeLXCIsbGVmdHJpZ2h0c3F1aWdhcnJvdzpcIuKGrVwiLExlZnRSaWdodFZlY3RvcjpcIuKljlwiLExlZnRUZWVBcnJvdzpcIuKGpFwiLExlZnRUZWU6XCLiiqNcIixMZWZ0VGVlVmVjdG9yOlwi4qWaXCIsbGVmdHRocmVldGltZXM6XCLii4tcIixMZWZ0VHJpYW5nbGVCYXI6XCLip49cIixMZWZ0VHJpYW5nbGU6XCLiirJcIixMZWZ0VHJpYW5nbGVFcXVhbDpcIuKKtFwiLExlZnRVcERvd25WZWN0b3I6XCLipZFcIixMZWZ0VXBUZWVWZWN0b3I6XCLipaBcIixMZWZ0VXBWZWN0b3JCYXI6XCLipZhcIixMZWZ0VXBWZWN0b3I6XCLihr9cIixMZWZ0VmVjdG9yQmFyOlwi4qWSXCIsTGVmdFZlY3RvcjpcIuKGvFwiLGxFZzpcIuKqi1wiLGxlZzpcIuKLmlwiLGxlcTpcIuKJpFwiLGxlcXE6XCLiiaZcIixsZXFzbGFudDpcIuKpvVwiLGxlc2NjOlwi4qqoXCIsbGVzOlwi4qm9XCIsbGVzZG90Olwi4qm/XCIsbGVzZG90bzpcIuKqgVwiLGxlc2RvdG9yOlwi4qqDXCIsbGVzZzpcIuKLmu+4gFwiLGxlc2dlczpcIuKqk1wiLGxlc3NhcHByb3g6XCLiqoVcIixsZXNzZG90Olwi4ouWXCIsbGVzc2VxZ3RyOlwi4ouaXCIsbGVzc2VxcWd0cjpcIuKqi1wiLExlc3NFcXVhbEdyZWF0ZXI6XCLii5pcIixMZXNzRnVsbEVxdWFsOlwi4ommXCIsTGVzc0dyZWF0ZXI6XCLiibZcIixsZXNzZ3RyOlwi4om2XCIsTGVzc0xlc3M6XCLiqqFcIixsZXNzc2ltOlwi4omyXCIsTGVzc1NsYW50RXF1YWw6XCLiqb1cIixMZXNzVGlsZGU6XCLiibJcIixsZmlzaHQ6XCLipbxcIixsZmxvb3I6XCLijIpcIixMZnI6XCLwnZSPXCIsbGZyOlwi8J2UqVwiLGxnOlwi4om2XCIsbGdFOlwi4qqRXCIsbEhhcjpcIuKlolwiLGxoYXJkOlwi4oa9XCIsbGhhcnU6XCLihrxcIixsaGFydWw6XCLipapcIixsaGJsazpcIuKWhFwiLExKY3k6XCLQiVwiLGxqY3k6XCLRmVwiLGxsYXJyOlwi4oeHXCIsbGw6XCLiiapcIixMbDpcIuKLmFwiLGxsY29ybmVyOlwi4oyeXCIsTGxlZnRhcnJvdzpcIuKHmlwiLGxsaGFyZDpcIuKlq1wiLGxsdHJpOlwi4pe6XCIsTG1pZG90OlwixL9cIixsbWlkb3Q6XCLFgFwiLGxtb3VzdGFjaGU6XCLijrBcIixsbW91c3Q6XCLijrBcIixsbmFwOlwi4qqJXCIsbG5hcHByb3g6XCLiqolcIixsbmU6XCLiqodcIixsbkU6XCLiiahcIixsbmVxOlwi4qqHXCIsbG5lcXE6XCLiiahcIixsbnNpbTpcIuKLplwiLGxvYW5nOlwi4p+sXCIsbG9hcnI6XCLih71cIixsb2JyazpcIuKfplwiLGxvbmdsZWZ0YXJyb3c6XCLin7VcIixMb25nTGVmdEFycm93Olwi4p+1XCIsTG9uZ2xlZnRhcnJvdzpcIuKfuFwiLGxvbmdsZWZ0cmlnaHRhcnJvdzpcIuKft1wiLExvbmdMZWZ0UmlnaHRBcnJvdzpcIuKft1wiLExvbmdsZWZ0cmlnaHRhcnJvdzpcIuKfulwiLGxvbmdtYXBzdG86XCLin7xcIixsb25ncmlnaHRhcnJvdzpcIuKftlwiLExvbmdSaWdodEFycm93Olwi4p+2XCIsTG9uZ3JpZ2h0YXJyb3c6XCLin7lcIixsb29wYXJyb3dsZWZ0Olwi4oarXCIsbG9vcGFycm93cmlnaHQ6XCLihqxcIixsb3BhcjpcIuKmhVwiLExvcGY6XCLwnZWDXCIsbG9wZjpcIvCdlZ1cIixsb3BsdXM6XCLiqK1cIixsb3RpbWVzOlwi4qi0XCIsbG93YXN0Olwi4oiXXCIsbG93YmFyOlwiX1wiLExvd2VyTGVmdEFycm93Olwi4oaZXCIsTG93ZXJSaWdodEFycm93Olwi4oaYXCIsbG96Olwi4peKXCIsbG96ZW5nZTpcIuKXilwiLGxvemY6XCLip6tcIixscGFyOlwiKFwiLGxwYXJsdDpcIuKmk1wiLGxyYXJyOlwi4oeGXCIsbHJjb3JuZXI6XCLijJ9cIixscmhhcjpcIuKHi1wiLGxyaGFyZDpcIuKlrVwiLGxybTpcIuKAjlwiLGxydHJpOlwi4oq/XCIsbHNhcXVvOlwi4oC5XCIsbHNjcjpcIvCdk4FcIixMc2NyOlwi4oSSXCIsbHNoOlwi4oawXCIsTHNoOlwi4oawXCIsbHNpbTpcIuKJslwiLGxzaW1lOlwi4qqNXCIsbHNpbWc6XCLiqo9cIixsc3FiOlwiW1wiLGxzcXVvOlwi4oCYXCIsbHNxdW9yOlwi4oCaXCIsTHN0cm9rOlwixYFcIixsc3Ryb2s6XCLFglwiLGx0Y2M6XCLiqqZcIixsdGNpcjpcIuKpuVwiLGx0OlwiPFwiLExUOlwiPFwiLEx0Olwi4omqXCIsbHRkb3Q6XCLii5ZcIixsdGhyZWU6XCLii4tcIixsdGltZXM6XCLii4lcIixsdGxhcnI6XCLipbZcIixsdHF1ZXN0Olwi4qm7XCIsbHRyaTpcIuKXg1wiLGx0cmllOlwi4oq0XCIsbHRyaWY6XCLil4JcIixsdHJQYXI6XCLippZcIixsdXJkc2hhcjpcIuKlilwiLGx1cnVoYXI6XCLipaZcIixsdmVydG5lcXE6XCLiiajvuIBcIixsdm5FOlwi4omo77iAXCIsbWFjcjpcIsKvXCIsbWFsZTpcIuKZglwiLG1hbHQ6XCLinKBcIixtYWx0ZXNlOlwi4pygXCIsTWFwOlwi4qSFXCIsbWFwOlwi4oamXCIsbWFwc3RvOlwi4oamXCIsbWFwc3RvZG93bjpcIuKGp1wiLG1hcHN0b2xlZnQ6XCLihqRcIixtYXBzdG91cDpcIuKGpVwiLG1hcmtlcjpcIuKWrlwiLG1jb21tYTpcIuKoqVwiLE1jeTpcItCcXCIsbWN5Olwi0LxcIixtZGFzaDpcIuKAlFwiLG1ERG90Olwi4oi6XCIsbWVhc3VyZWRhbmdsZTpcIuKIoVwiLE1lZGl1bVNwYWNlOlwi4oGfXCIsTWVsbGludHJmOlwi4oSzXCIsTWZyOlwi8J2UkFwiLG1mcjpcIvCdlKpcIixtaG86XCLihKdcIixtaWNybzpcIsK1XCIsbWlkYXN0OlwiKlwiLG1pZGNpcjpcIuKrsFwiLG1pZDpcIuKIo1wiLG1pZGRvdDpcIsK3XCIsbWludXNiOlwi4oqfXCIsbWludXM6XCLiiJJcIixtaW51c2Q6XCLiiLhcIixtaW51c2R1Olwi4qiqXCIsTWludXNQbHVzOlwi4oiTXCIsbWxjcDpcIuKrm1wiLG1sZHI6XCLigKZcIixtbnBsdXM6XCLiiJNcIixtb2RlbHM6XCLiiqdcIixNb3BmOlwi8J2VhFwiLG1vcGY6XCLwnZWeXCIsbXA6XCLiiJNcIixtc2NyOlwi8J2TglwiLE1zY3I6XCLihLNcIixtc3Rwb3M6XCLiiL5cIixNdTpcIs6cXCIsbXU6XCLOvFwiLG11bHRpbWFwOlwi4oq4XCIsbXVtYXA6XCLiirhcIixuYWJsYTpcIuKIh1wiLE5hY3V0ZTpcIsWDXCIsbmFjdXRlOlwixYRcIixuYW5nOlwi4oig4oOSXCIsbmFwOlwi4omJXCIsbmFwRTpcIuKpsMy4XCIsbmFwaWQ6XCLiiYvMuFwiLG5hcG9zOlwixYlcIixuYXBwcm94Olwi4omJXCIsbmF0dXJhbDpcIuKZrlwiLG5hdHVyYWxzOlwi4oSVXCIsbmF0dXI6XCLima5cIixuYnNwOlwiwqBcIixuYnVtcDpcIuKJjsy4XCIsbmJ1bXBlOlwi4omPzLhcIixuY2FwOlwi4qmDXCIsTmNhcm9uOlwixYdcIixuY2Fyb246XCLFiFwiLE5jZWRpbDpcIsWFXCIsbmNlZGlsOlwixYZcIixuY29uZzpcIuKJh1wiLG5jb25nZG90Olwi4qmtzLhcIixuY3VwOlwi4qmCXCIsTmN5Olwi0J1cIixuY3k6XCLQvVwiLG5kYXNoOlwi4oCTXCIsbmVhcmhrOlwi4qSkXCIsbmVhcnI6XCLihpdcIixuZUFycjpcIuKHl1wiLG5lYXJyb3c6XCLihpdcIixuZTpcIuKJoFwiLG5lZG90Olwi4omQzLhcIixOZWdhdGl2ZU1lZGl1bVNwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGlja1NwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGluU3BhY2U6XCLigItcIixOZWdhdGl2ZVZlcnlUaGluU3BhY2U6XCLigItcIixuZXF1aXY6XCLiiaJcIixuZXNlYXI6XCLipKhcIixuZXNpbTpcIuKJgsy4XCIsTmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiiatcIixOZXN0ZWRMZXNzTGVzczpcIuKJqlwiLE5ld0xpbmU6XCJcXG5cIixuZXhpc3Q6XCLiiIRcIixuZXhpc3RzOlwi4oiEXCIsTmZyOlwi8J2UkVwiLG5mcjpcIvCdlKtcIixuZ0U6XCLiiafMuFwiLG5nZTpcIuKJsVwiLG5nZXE6XCLiibFcIixuZ2VxcTpcIuKJp8y4XCIsbmdlcXNsYW50Olwi4qm+zLhcIixuZ2VzOlwi4qm+zLhcIixuR2c6XCLii5nMuFwiLG5nc2ltOlwi4om1XCIsbkd0Olwi4omr4oOSXCIsbmd0Olwi4omvXCIsbmd0cjpcIuKJr1wiLG5HdHY6XCLiiavMuFwiLG5oYXJyOlwi4oauXCIsbmhBcnI6XCLih45cIixuaHBhcjpcIuKrslwiLG5pOlwi4oiLXCIsbmlzOlwi4ou8XCIsbmlzZDpcIuKLulwiLG5pdjpcIuKIi1wiLE5KY3k6XCLQilwiLG5qY3k6XCLRmlwiLG5sYXJyOlwi4oaaXCIsbmxBcnI6XCLih41cIixubGRyOlwi4oClXCIsbmxFOlwi4ommzLhcIixubGU6XCLiibBcIixubGVmdGFycm93Olwi4oaaXCIsbkxlZnRhcnJvdzpcIuKHjVwiLG5sZWZ0cmlnaHRhcnJvdzpcIuKGrlwiLG5MZWZ0cmlnaHRhcnJvdzpcIuKHjlwiLG5sZXE6XCLiibBcIixubGVxcTpcIuKJpsy4XCIsbmxlcXNsYW50Olwi4qm9zLhcIixubGVzOlwi4qm9zLhcIixubGVzczpcIuKJrlwiLG5MbDpcIuKLmMy4XCIsbmxzaW06XCLiibRcIixuTHQ6XCLiiarig5JcIixubHQ6XCLiia5cIixubHRyaTpcIuKLqlwiLG5sdHJpZTpcIuKLrFwiLG5MdHY6XCLiiarMuFwiLG5taWQ6XCLiiKRcIixOb0JyZWFrOlwi4oGgXCIsTm9uQnJlYWtpbmdTcGFjZTpcIsKgXCIsbm9wZjpcIvCdlZ9cIixOb3BmOlwi4oSVXCIsTm90Olwi4qusXCIsbm90OlwiwqxcIixOb3RDb25ncnVlbnQ6XCLiiaJcIixOb3RDdXBDYXA6XCLiia1cIixOb3REb3VibGVWZXJ0aWNhbEJhcjpcIuKIplwiLE5vdEVsZW1lbnQ6XCLiiIlcIixOb3RFcXVhbDpcIuKJoFwiLE5vdEVxdWFsVGlsZGU6XCLiiYLMuFwiLE5vdEV4aXN0czpcIuKIhFwiLE5vdEdyZWF0ZXI6XCLiia9cIixOb3RHcmVhdGVyRXF1YWw6XCLiibFcIixOb3RHcmVhdGVyRnVsbEVxdWFsOlwi4omnzLhcIixOb3RHcmVhdGVyR3JlYXRlcjpcIuKJq8y4XCIsTm90R3JlYXRlckxlc3M6XCLiiblcIixOb3RHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvsy4XCIsTm90R3JlYXRlclRpbGRlOlwi4om1XCIsTm90SHVtcERvd25IdW1wOlwi4omOzLhcIixOb3RIdW1wRXF1YWw6XCLiiY/MuFwiLG5vdGluOlwi4oiJXCIsbm90aW5kb3Q6XCLii7XMuFwiLG5vdGluRTpcIuKLucy4XCIsbm90aW52YTpcIuKIiVwiLG5vdGludmI6XCLii7dcIixub3RpbnZjOlwi4ou2XCIsTm90TGVmdFRyaWFuZ2xlQmFyOlwi4qePzLhcIixOb3RMZWZ0VHJpYW5nbGU6XCLii6pcIixOb3RMZWZ0VHJpYW5nbGVFcXVhbDpcIuKLrFwiLE5vdExlc3M6XCLiia5cIixOb3RMZXNzRXF1YWw6XCLiibBcIixOb3RMZXNzR3JlYXRlcjpcIuKJuFwiLE5vdExlc3NMZXNzOlwi4omqzLhcIixOb3RMZXNzU2xhbnRFcXVhbDpcIuKpvcy4XCIsTm90TGVzc1RpbGRlOlwi4om0XCIsTm90TmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiqqLMuFwiLE5vdE5lc3RlZExlc3NMZXNzOlwi4qqhzLhcIixub3RuaTpcIuKIjFwiLG5vdG5pdmE6XCLiiIxcIixub3RuaXZiOlwi4ou+XCIsbm90bml2YzpcIuKLvVwiLE5vdFByZWNlZGVzOlwi4oqAXCIsTm90UHJlY2VkZXNFcXVhbDpcIuKqr8y4XCIsTm90UHJlY2VkZXNTbGFudEVxdWFsOlwi4ougXCIsTm90UmV2ZXJzZUVsZW1lbnQ6XCLiiIxcIixOb3RSaWdodFRyaWFuZ2xlQmFyOlwi4qeQzLhcIixOb3RSaWdodFRyaWFuZ2xlOlwi4ourXCIsTm90UmlnaHRUcmlhbmdsZUVxdWFsOlwi4outXCIsTm90U3F1YXJlU3Vic2V0Olwi4oqPzLhcIixOb3RTcXVhcmVTdWJzZXRFcXVhbDpcIuKLolwiLE5vdFNxdWFyZVN1cGVyc2V0Olwi4oqQzLhcIixOb3RTcXVhcmVTdXBlcnNldEVxdWFsOlwi4oujXCIsTm90U3Vic2V0Olwi4oqC4oOSXCIsTm90U3Vic2V0RXF1YWw6XCLiiohcIixOb3RTdWNjZWVkczpcIuKKgVwiLE5vdFN1Y2NlZWRzRXF1YWw6XCLiqrDMuFwiLE5vdFN1Y2NlZWRzU2xhbnRFcXVhbDpcIuKLoVwiLE5vdFN1Y2NlZWRzVGlsZGU6XCLiib/MuFwiLE5vdFN1cGVyc2V0Olwi4oqD4oOSXCIsTm90U3VwZXJzZXRFcXVhbDpcIuKKiVwiLE5vdFRpbGRlOlwi4omBXCIsTm90VGlsZGVFcXVhbDpcIuKJhFwiLE5vdFRpbGRlRnVsbEVxdWFsOlwi4omHXCIsTm90VGlsZGVUaWxkZTpcIuKJiVwiLE5vdFZlcnRpY2FsQmFyOlwi4oikXCIsbnBhcmFsbGVsOlwi4oimXCIsbnBhcjpcIuKIplwiLG5wYXJzbDpcIuKrveKDpVwiLG5wYXJ0Olwi4oiCzLhcIixucG9saW50Olwi4qiUXCIsbnByOlwi4oqAXCIsbnByY3VlOlwi4ougXCIsbnByZWM6XCLiioBcIixucHJlY2VxOlwi4qqvzLhcIixucHJlOlwi4qqvzLhcIixucmFycmM6XCLipLPMuFwiLG5yYXJyOlwi4oabXCIsbnJBcnI6XCLih49cIixucmFycnc6XCLihp3MuFwiLG5yaWdodGFycm93Olwi4oabXCIsblJpZ2h0YXJyb3c6XCLih49cIixucnRyaTpcIuKLq1wiLG5ydHJpZTpcIuKLrVwiLG5zYzpcIuKKgVwiLG5zY2N1ZTpcIuKLoVwiLG5zY2U6XCLiqrDMuFwiLE5zY3I6XCLwnZKpXCIsbnNjcjpcIvCdk4NcIixuc2hvcnRtaWQ6XCLiiKRcIixuc2hvcnRwYXJhbGxlbDpcIuKIplwiLG5zaW06XCLiiYFcIixuc2ltZTpcIuKJhFwiLG5zaW1lcTpcIuKJhFwiLG5zbWlkOlwi4oikXCIsbnNwYXI6XCLiiKZcIixuc3FzdWJlOlwi4ouiXCIsbnNxc3VwZTpcIuKLo1wiLG5zdWI6XCLiioRcIixuc3ViRTpcIuKrhcy4XCIsbnN1YmU6XCLiiohcIixuc3Vic2V0Olwi4oqC4oOSXCIsbnN1YnNldGVxOlwi4oqIXCIsbnN1YnNldGVxcTpcIuKrhcy4XCIsbnN1Y2M6XCLiioFcIixuc3VjY2VxOlwi4qqwzLhcIixuc3VwOlwi4oqFXCIsbnN1cEU6XCLiq4bMuFwiLG5zdXBlOlwi4oqJXCIsbnN1cHNldDpcIuKKg+KDklwiLG5zdXBzZXRlcTpcIuKKiVwiLG5zdXBzZXRlcXE6XCLiq4bMuFwiLG50Z2w6XCLiiblcIixOdGlsZGU6XCLDkVwiLG50aWxkZTpcIsOxXCIsbnRsZzpcIuKJuFwiLG50cmlhbmdsZWxlZnQ6XCLii6pcIixudHJpYW5nbGVsZWZ0ZXE6XCLii6xcIixudHJpYW5nbGVyaWdodDpcIuKLq1wiLG50cmlhbmdsZXJpZ2h0ZXE6XCLii61cIixOdTpcIs6dXCIsbnU6XCLOvVwiLG51bTpcIiNcIixudW1lcm86XCLihJZcIixudW1zcDpcIuKAh1wiLG52YXA6XCLiiY3ig5JcIixudmRhc2g6XCLiiqxcIixudkRhc2g6XCLiiq1cIixuVmRhc2g6XCLiiq5cIixuVkRhc2g6XCLiiq9cIixudmdlOlwi4oml4oOSXCIsbnZndDpcIj7ig5JcIixudkhhcnI6XCLipIRcIixudmluZmluOlwi4qeeXCIsbnZsQXJyOlwi4qSCXCIsbnZsZTpcIuKJpOKDklwiLG52bHQ6XCI84oOSXCIsbnZsdHJpZTpcIuKKtOKDklwiLG52ckFycjpcIuKkg1wiLG52cnRyaWU6XCLiirXig5JcIixudnNpbTpcIuKIvOKDklwiLG53YXJoazpcIuKko1wiLG53YXJyOlwi4oaWXCIsbndBcnI6XCLih5ZcIixud2Fycm93Olwi4oaWXCIsbnduZWFyOlwi4qSnXCIsT2FjdXRlOlwiw5NcIixvYWN1dGU6XCLDs1wiLG9hc3Q6XCLiiptcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLG9jaXI6XCLiippcIixPY3k6XCLQnlwiLG9jeTpcItC+XCIsb2Rhc2g6XCLiip1cIixPZGJsYWM6XCLFkFwiLG9kYmxhYzpcIsWRXCIsb2RpdjpcIuKouFwiLG9kb3Q6XCLiiplcIixvZHNvbGQ6XCLiprxcIixPRWxpZzpcIsWSXCIsb2VsaWc6XCLFk1wiLG9mY2lyOlwi4qa/XCIsT2ZyOlwi8J2UklwiLG9mcjpcIvCdlKxcIixvZ29uOlwiy5tcIixPZ3JhdmU6XCLDklwiLG9ncmF2ZTpcIsOyXCIsb2d0Olwi4qeBXCIsb2hiYXI6XCLiprVcIixvaG06XCLOqVwiLG9pbnQ6XCLiiK5cIixvbGFycjpcIuKGulwiLG9sY2lyOlwi4qa+XCIsb2xjcm9zczpcIuKmu1wiLG9saW5lOlwi4oC+XCIsb2x0Olwi4qeAXCIsT21hY3I6XCLFjFwiLG9tYWNyOlwixY1cIixPbWVnYTpcIs6pXCIsb21lZ2E6XCLPiVwiLE9taWNyb246XCLOn1wiLG9taWNyb246XCLOv1wiLG9taWQ6XCLiprZcIixvbWludXM6XCLiipZcIixPb3BmOlwi8J2VhlwiLG9vcGY6XCLwnZWgXCIsb3BhcjpcIuKmt1wiLE9wZW5DdXJseURvdWJsZVF1b3RlOlwi4oCcXCIsT3BlbkN1cmx5UXVvdGU6XCLigJhcIixvcGVycDpcIuKmuVwiLG9wbHVzOlwi4oqVXCIsb3JhcnI6XCLihrtcIixPcjpcIuKplFwiLG9yOlwi4oioXCIsb3JkOlwi4qmdXCIsb3JkZXI6XCLihLRcIixvcmRlcm9mOlwi4oS0XCIsb3JkZjpcIsKqXCIsb3JkbTpcIsK6XCIsb3JpZ29mOlwi4oq2XCIsb3JvcjpcIuKpllwiLG9yc2xvcGU6XCLiqZdcIixvcnY6XCLiqZtcIixvUzpcIuKTiFwiLE9zY3I6XCLwnZKqXCIsb3NjcjpcIuKEtFwiLE9zbGFzaDpcIsOYXCIsb3NsYXNoOlwiw7hcIixvc29sOlwi4oqYXCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLG90aW1lc2FzOlwi4qi2XCIsT3RpbWVzOlwi4qi3XCIsb3RpbWVzOlwi4oqXXCIsT3VtbDpcIsOWXCIsb3VtbDpcIsO2XCIsb3ZiYXI6XCLijL1cIixPdmVyQmFyOlwi4oC+XCIsT3ZlckJyYWNlOlwi4o+eXCIsT3ZlckJyYWNrZXQ6XCLijrRcIixPdmVyUGFyZW50aGVzaXM6XCLij5xcIixwYXJhOlwiwrZcIixwYXJhbGxlbDpcIuKIpVwiLHBhcjpcIuKIpVwiLHBhcnNpbTpcIuKrs1wiLHBhcnNsOlwi4qu9XCIscGFydDpcIuKIglwiLFBhcnRpYWxEOlwi4oiCXCIsUGN5Olwi0J9cIixwY3k6XCLQv1wiLHBlcmNudDpcIiVcIixwZXJpb2Q6XCIuXCIscGVybWlsOlwi4oCwXCIscGVycDpcIuKKpVwiLHBlcnRlbms6XCLigLFcIixQZnI6XCLwnZSTXCIscGZyOlwi8J2UrVwiLFBoaTpcIs6mXCIscGhpOlwiz4ZcIixwaGl2Olwiz5VcIixwaG1tYXQ6XCLihLNcIixwaG9uZTpcIuKYjlwiLFBpOlwizqBcIixwaTpcIs+AXCIscGl0Y2hmb3JrOlwi4ouUXCIscGl2Olwiz5ZcIixwbGFuY2s6XCLihI9cIixwbGFuY2toOlwi4oSOXCIscGxhbmt2Olwi4oSPXCIscGx1c2FjaXI6XCLiqKNcIixwbHVzYjpcIuKKnlwiLHBsdXNjaXI6XCLiqKJcIixwbHVzOlwiK1wiLHBsdXNkbzpcIuKIlFwiLHBsdXNkdTpcIuKopVwiLHBsdXNlOlwi4qmyXCIsUGx1c01pbnVzOlwiwrFcIixwbHVzbW46XCLCsVwiLHBsdXNzaW06XCLiqKZcIixwbHVzdHdvOlwi4qinXCIscG06XCLCsVwiLFBvaW5jYXJlcGxhbmU6XCLihIxcIixwb2ludGludDpcIuKolVwiLHBvcGY6XCLwnZWhXCIsUG9wZjpcIuKEmVwiLHBvdW5kOlwiwqNcIixwcmFwOlwi4qq3XCIsUHI6XCLiqrtcIixwcjpcIuKJulwiLHByY3VlOlwi4om8XCIscHJlY2FwcHJveDpcIuKqt1wiLHByZWM6XCLiibpcIixwcmVjY3VybHllcTpcIuKJvFwiLFByZWNlZGVzOlwi4om6XCIsUHJlY2VkZXNFcXVhbDpcIuKqr1wiLFByZWNlZGVzU2xhbnRFcXVhbDpcIuKJvFwiLFByZWNlZGVzVGlsZGU6XCLiib5cIixwcmVjZXE6XCLiqq9cIixwcmVjbmFwcHJveDpcIuKquVwiLHByZWNuZXFxOlwi4qq1XCIscHJlY25zaW06XCLii6hcIixwcmU6XCLiqq9cIixwckU6XCLiqrNcIixwcmVjc2ltOlwi4om+XCIscHJpbWU6XCLigLJcIixQcmltZTpcIuKAs1wiLHByaW1lczpcIuKEmVwiLHBybmFwOlwi4qq5XCIscHJuRTpcIuKqtVwiLHBybnNpbTpcIuKLqFwiLHByb2Q6XCLiiI9cIixQcm9kdWN0Olwi4oiPXCIscHJvZmFsYXI6XCLijK5cIixwcm9mbGluZTpcIuKMklwiLHByb2ZzdXJmOlwi4oyTXCIscHJvcDpcIuKInVwiLFByb3BvcnRpb25hbDpcIuKInVwiLFByb3BvcnRpb246XCLiiLdcIixwcm9wdG86XCLiiJ1cIixwcnNpbTpcIuKJvlwiLHBydXJlbDpcIuKKsFwiLFBzY3I6XCLwnZKrXCIscHNjcjpcIvCdk4VcIixQc2k6XCLOqFwiLHBzaTpcIs+IXCIscHVuY3NwOlwi4oCIXCIsUWZyOlwi8J2UlFwiLHFmcjpcIvCdlK5cIixxaW50Olwi4qiMXCIscW9wZjpcIvCdlaJcIixRb3BmOlwi4oSaXCIscXByaW1lOlwi4oGXXCIsUXNjcjpcIvCdkqxcIixxc2NyOlwi8J2ThlwiLHF1YXRlcm5pb25zOlwi4oSNXCIscXVhdGludDpcIuKollwiLHF1ZXN0OlwiP1wiLHF1ZXN0ZXE6XCLiiZ9cIixxdW90OidcIicsUVVPVDonXCInLHJBYXJyOlwi4oebXCIscmFjZTpcIuKIvcyxXCIsUmFjdXRlOlwixZRcIixyYWN1dGU6XCLFlVwiLHJhZGljOlwi4oiaXCIscmFlbXB0eXY6XCLiprNcIixyYW5nOlwi4p+pXCIsUmFuZzpcIuKfq1wiLHJhbmdkOlwi4qaSXCIscmFuZ2U6XCLipqVcIixyYW5nbGU6XCLin6lcIixyYXF1bzpcIsK7XCIscmFycmFwOlwi4qW1XCIscmFycmI6XCLih6VcIixyYXJyYmZzOlwi4qSgXCIscmFycmM6XCLipLNcIixyYXJyOlwi4oaSXCIsUmFycjpcIuKGoFwiLHJBcnI6XCLih5JcIixyYXJyZnM6XCLipJ5cIixyYXJyaGs6XCLihqpcIixyYXJybHA6XCLihqxcIixyYXJycGw6XCLipYVcIixyYXJyc2ltOlwi4qW0XCIsUmFycnRsOlwi4qSWXCIscmFycnRsOlwi4oajXCIscmFycnc6XCLihp1cIixyYXRhaWw6XCLipJpcIixyQXRhaWw6XCLipJxcIixyYXRpbzpcIuKItlwiLHJhdGlvbmFsczpcIuKEmlwiLHJiYXJyOlwi4qSNXCIsckJhcnI6XCLipI9cIixSQmFycjpcIuKkkFwiLHJiYnJrOlwi4p2zXCIscmJyYWNlOlwifVwiLHJicmFjazpcIl1cIixyYnJrZTpcIuKmjFwiLHJicmtzbGQ6XCLipo5cIixyYnJrc2x1Olwi4qaQXCIsUmNhcm9uOlwixZhcIixyY2Fyb246XCLFmVwiLFJjZWRpbDpcIsWWXCIscmNlZGlsOlwixZdcIixyY2VpbDpcIuKMiVwiLHJjdWI6XCJ9XCIsUmN5Olwi0KBcIixyY3k6XCLRgFwiLHJkY2E6XCLipLdcIixyZGxkaGFyOlwi4qWpXCIscmRxdW86XCLigJ1cIixyZHF1b3I6XCLigJ1cIixyZHNoOlwi4oazXCIscmVhbDpcIuKEnFwiLHJlYWxpbmU6XCLihJtcIixyZWFscGFydDpcIuKEnFwiLHJlYWxzOlwi4oSdXCIsUmU6XCLihJxcIixyZWN0Olwi4patXCIscmVnOlwiwq5cIixSRUc6XCLCrlwiLFJldmVyc2VFbGVtZW50Olwi4oiLXCIsUmV2ZXJzZUVxdWlsaWJyaXVtOlwi4oeLXCIsUmV2ZXJzZVVwRXF1aWxpYnJpdW06XCLipa9cIixyZmlzaHQ6XCLipb1cIixyZmxvb3I6XCLijItcIixyZnI6XCLwnZSvXCIsUmZyOlwi4oScXCIsckhhcjpcIuKlpFwiLHJoYXJkOlwi4oeBXCIscmhhcnU6XCLih4BcIixyaGFydWw6XCLipaxcIixSaG86XCLOoVwiLHJobzpcIs+BXCIscmhvdjpcIs+xXCIsUmlnaHRBbmdsZUJyYWNrZXQ6XCLin6lcIixSaWdodEFycm93QmFyOlwi4oelXCIscmlnaHRhcnJvdzpcIuKGklwiLFJpZ2h0QXJyb3c6XCLihpJcIixSaWdodGFycm93Olwi4oeSXCIsUmlnaHRBcnJvd0xlZnRBcnJvdzpcIuKHhFwiLHJpZ2h0YXJyb3d0YWlsOlwi4oajXCIsUmlnaHRDZWlsaW5nOlwi4oyJXCIsUmlnaHREb3VibGVCcmFja2V0Olwi4p+nXCIsUmlnaHREb3duVGVlVmVjdG9yOlwi4qWdXCIsUmlnaHREb3duVmVjdG9yQmFyOlwi4qWVXCIsUmlnaHREb3duVmVjdG9yOlwi4oeCXCIsUmlnaHRGbG9vcjpcIuKMi1wiLHJpZ2h0aGFycG9vbmRvd246XCLih4FcIixyaWdodGhhcnBvb251cDpcIuKHgFwiLHJpZ2h0bGVmdGFycm93czpcIuKHhFwiLHJpZ2h0bGVmdGhhcnBvb25zOlwi4oeMXCIscmlnaHRyaWdodGFycm93czpcIuKHiVwiLHJpZ2h0c3F1aWdhcnJvdzpcIuKGnVwiLFJpZ2h0VGVlQXJyb3c6XCLihqZcIixSaWdodFRlZTpcIuKKolwiLFJpZ2h0VGVlVmVjdG9yOlwi4qWbXCIscmlnaHR0aHJlZXRpbWVzOlwi4ouMXCIsUmlnaHRUcmlhbmdsZUJhcjpcIuKnkFwiLFJpZ2h0VHJpYW5nbGU6XCLiirNcIixSaWdodFRyaWFuZ2xlRXF1YWw6XCLiirVcIixSaWdodFVwRG93blZlY3RvcjpcIuKlj1wiLFJpZ2h0VXBUZWVWZWN0b3I6XCLipZxcIixSaWdodFVwVmVjdG9yQmFyOlwi4qWUXCIsUmlnaHRVcFZlY3RvcjpcIuKGvlwiLFJpZ2h0VmVjdG9yQmFyOlwi4qWTXCIsUmlnaHRWZWN0b3I6XCLih4BcIixyaW5nOlwiy5pcIixyaXNpbmdkb3RzZXE6XCLiiZNcIixybGFycjpcIuKHhFwiLHJsaGFyOlwi4oeMXCIscmxtOlwi4oCPXCIscm1vdXN0YWNoZTpcIuKOsVwiLHJtb3VzdDpcIuKOsVwiLHJubWlkOlwi4quuXCIscm9hbmc6XCLin61cIixyb2FycjpcIuKHvlwiLHJvYnJrOlwi4p+nXCIscm9wYXI6XCLipoZcIixyb3BmOlwi8J2Vo1wiLFJvcGY6XCLihJ1cIixyb3BsdXM6XCLiqK5cIixyb3RpbWVzOlwi4qi1XCIsUm91bmRJbXBsaWVzOlwi4qWwXCIscnBhcjpcIilcIixycGFyZ3Q6XCLippRcIixycHBvbGludDpcIuKoklwiLHJyYXJyOlwi4oeJXCIsUnJpZ2h0YXJyb3c6XCLih5tcIixyc2FxdW86XCLigLpcIixyc2NyOlwi8J2Th1wiLFJzY3I6XCLihJtcIixyc2g6XCLihrFcIixSc2g6XCLihrFcIixyc3FiOlwiXVwiLHJzcXVvOlwi4oCZXCIscnNxdW9yOlwi4oCZXCIscnRocmVlOlwi4ouMXCIscnRpbWVzOlwi4ouKXCIscnRyaTpcIuKWuVwiLHJ0cmllOlwi4oq1XCIscnRyaWY6XCLilrhcIixydHJpbHRyaTpcIuKnjlwiLFJ1bGVEZWxheWVkOlwi4qe0XCIscnVsdWhhcjpcIuKlqFwiLHJ4Olwi4oSeXCIsU2FjdXRlOlwixZpcIixzYWN1dGU6XCLFm1wiLHNicXVvOlwi4oCaXCIsc2NhcDpcIuKquFwiLFNjYXJvbjpcIsWgXCIsc2Nhcm9uOlwixaFcIixTYzpcIuKqvFwiLHNjOlwi4om7XCIsc2NjdWU6XCLiib1cIixzY2U6XCLiqrBcIixzY0U6XCLiqrRcIixTY2VkaWw6XCLFnlwiLHNjZWRpbDpcIsWfXCIsU2NpcmM6XCLFnFwiLHNjaXJjOlwixZ1cIixzY25hcDpcIuKqulwiLHNjbkU6XCLiqrZcIixzY25zaW06XCLii6lcIixzY3BvbGludDpcIuKok1wiLHNjc2ltOlwi4om/XCIsU2N5Olwi0KFcIixzY3k6XCLRgVwiLHNkb3RiOlwi4oqhXCIsc2RvdDpcIuKLhVwiLHNkb3RlOlwi4qmmXCIsc2VhcmhrOlwi4qSlXCIsc2VhcnI6XCLihphcIixzZUFycjpcIuKHmFwiLHNlYXJyb3c6XCLihphcIixzZWN0OlwiwqdcIixzZW1pOlwiO1wiLHNlc3dhcjpcIuKkqVwiLHNldG1pbnVzOlwi4oiWXCIsc2V0bW46XCLiiJZcIixzZXh0Olwi4py2XCIsU2ZyOlwi8J2UllwiLHNmcjpcIvCdlLBcIixzZnJvd246XCLijKJcIixzaGFycDpcIuKZr1wiLFNIQ0hjeTpcItCpXCIsc2hjaGN5Olwi0YlcIixTSGN5Olwi0KhcIixzaGN5Olwi0YhcIixTaG9ydERvd25BcnJvdzpcIuKGk1wiLFNob3J0TGVmdEFycm93Olwi4oaQXCIsc2hvcnRtaWQ6XCLiiKNcIixzaG9ydHBhcmFsbGVsOlwi4oilXCIsU2hvcnRSaWdodEFycm93Olwi4oaSXCIsU2hvcnRVcEFycm93Olwi4oaRXCIsc2h5Olwiwq1cIixTaWdtYTpcIs6jXCIsc2lnbWE6XCLPg1wiLHNpZ21hZjpcIs+CXCIsc2lnbWF2Olwiz4JcIixzaW06XCLiiLxcIixzaW1kb3Q6XCLiqapcIixzaW1lOlwi4omDXCIsc2ltZXE6XCLiiYNcIixzaW1nOlwi4qqeXCIsc2ltZ0U6XCLiqqBcIixzaW1sOlwi4qqdXCIsc2ltbEU6XCLiqp9cIixzaW1uZTpcIuKJhlwiLHNpbXBsdXM6XCLiqKRcIixzaW1yYXJyOlwi4qWyXCIsc2xhcnI6XCLihpBcIixTbWFsbENpcmNsZTpcIuKImFwiLHNtYWxsc2V0bWludXM6XCLiiJZcIixzbWFzaHA6XCLiqLNcIixzbWVwYXJzbDpcIuKnpFwiLHNtaWQ6XCLiiKNcIixzbWlsZTpcIuKMo1wiLHNtdDpcIuKqqlwiLHNtdGU6XCLiqqxcIixzbXRlczpcIuKqrO+4gFwiLFNPRlRjeTpcItCsXCIsc29mdGN5Olwi0YxcIixzb2xiYXI6XCLijL9cIixzb2xiOlwi4qeEXCIsc29sOlwiL1wiLFNvcGY6XCLwnZWKXCIsc29wZjpcIvCdlaRcIixzcGFkZXM6XCLimaBcIixzcGFkZXN1aXQ6XCLimaBcIixzcGFyOlwi4oilXCIsc3FjYXA6XCLiipNcIixzcWNhcHM6XCLiipPvuIBcIixzcWN1cDpcIuKKlFwiLHNxY3VwczpcIuKKlO+4gFwiLFNxcnQ6XCLiiJpcIixzcXN1YjpcIuKKj1wiLHNxc3ViZTpcIuKKkVwiLHNxc3Vic2V0Olwi4oqPXCIsc3FzdWJzZXRlcTpcIuKKkVwiLHNxc3VwOlwi4oqQXCIsc3FzdXBlOlwi4oqSXCIsc3FzdXBzZXQ6XCLiipBcIixzcXN1cHNldGVxOlwi4oqSXCIsc3F1YXJlOlwi4pahXCIsU3F1YXJlOlwi4pahXCIsU3F1YXJlSW50ZXJzZWN0aW9uOlwi4oqTXCIsU3F1YXJlU3Vic2V0Olwi4oqPXCIsU3F1YXJlU3Vic2V0RXF1YWw6XCLiipFcIixTcXVhcmVTdXBlcnNldDpcIuKKkFwiLFNxdWFyZVN1cGVyc2V0RXF1YWw6XCLiipJcIixTcXVhcmVVbmlvbjpcIuKKlFwiLHNxdWFyZjpcIuKWqlwiLHNxdTpcIuKWoVwiLHNxdWY6XCLilqpcIixzcmFycjpcIuKGklwiLFNzY3I6XCLwnZKuXCIsc3NjcjpcIvCdk4hcIixzc2V0bW46XCLiiJZcIixzc21pbGU6XCLijKNcIixzc3RhcmY6XCLii4ZcIixTdGFyOlwi4ouGXCIsc3RhcjpcIuKYhlwiLHN0YXJmOlwi4piFXCIsc3RyYWlnaHRlcHNpbG9uOlwiz7VcIixzdHJhaWdodHBoaTpcIs+VXCIsc3RybnM6XCLCr1wiLHN1YjpcIuKKglwiLFN1YjpcIuKLkFwiLHN1YmRvdDpcIuKqvVwiLHN1YkU6XCLiq4VcIixzdWJlOlwi4oqGXCIsc3ViZWRvdDpcIuKrg1wiLHN1Ym11bHQ6XCLiq4FcIixzdWJuRTpcIuKri1wiLHN1Ym5lOlwi4oqKXCIsc3VicGx1czpcIuKqv1wiLHN1YnJhcnI6XCLipblcIixzdWJzZXQ6XCLiioJcIixTdWJzZXQ6XCLii5BcIixzdWJzZXRlcTpcIuKKhlwiLHN1YnNldGVxcTpcIuKrhVwiLFN1YnNldEVxdWFsOlwi4oqGXCIsc3Vic2V0bmVxOlwi4oqKXCIsc3Vic2V0bmVxcTpcIuKri1wiLHN1YnNpbTpcIuKrh1wiLHN1YnN1YjpcIuKrlVwiLHN1YnN1cDpcIuKrk1wiLHN1Y2NhcHByb3g6XCLiqrhcIixzdWNjOlwi4om7XCIsc3VjY2N1cmx5ZXE6XCLiib1cIixTdWNjZWVkczpcIuKJu1wiLFN1Y2NlZWRzRXF1YWw6XCLiqrBcIixTdWNjZWVkc1NsYW50RXF1YWw6XCLiib1cIixTdWNjZWVkc1RpbGRlOlwi4om/XCIsc3VjY2VxOlwi4qqwXCIsc3VjY25hcHByb3g6XCLiqrpcIixzdWNjbmVxcTpcIuKqtlwiLHN1Y2Nuc2ltOlwi4oupXCIsc3VjY3NpbTpcIuKJv1wiLFN1Y2hUaGF0Olwi4oiLXCIsc3VtOlwi4oiRXCIsU3VtOlwi4oiRXCIsc3VuZzpcIuKZqlwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN1cDpcIuKKg1wiLFN1cDpcIuKLkVwiLHN1cGRvdDpcIuKqvlwiLHN1cGRzdWI6XCLiq5hcIixzdXBFOlwi4quGXCIsc3VwZTpcIuKKh1wiLHN1cGVkb3Q6XCLiq4RcIixTdXBlcnNldDpcIuKKg1wiLFN1cGVyc2V0RXF1YWw6XCLiiodcIixzdXBoc29sOlwi4p+JXCIsc3VwaHN1YjpcIuKrl1wiLHN1cGxhcnI6XCLipbtcIixzdXBtdWx0Olwi4quCXCIsc3VwbkU6XCLiq4xcIixzdXBuZTpcIuKKi1wiLHN1cHBsdXM6XCLiq4BcIixzdXBzZXQ6XCLiioNcIixTdXBzZXQ6XCLii5FcIixzdXBzZXRlcTpcIuKKh1wiLHN1cHNldGVxcTpcIuKrhlwiLHN1cHNldG5lcTpcIuKKi1wiLHN1cHNldG5lcXE6XCLiq4xcIixzdXBzaW06XCLiq4hcIixzdXBzdWI6XCLiq5RcIixzdXBzdXA6XCLiq5ZcIixzd2FyaGs6XCLipKZcIixzd2FycjpcIuKGmVwiLHN3QXJyOlwi4oeZXCIsc3dhcnJvdzpcIuKGmVwiLHN3bndhcjpcIuKkqlwiLHN6bGlnOlwiw59cIixUYWI6XCJcXHRcIix0YXJnZXQ6XCLijJZcIixUYXU6XCLOpFwiLHRhdTpcIs+EXCIsdGJyazpcIuKOtFwiLFRjYXJvbjpcIsWkXCIsdGNhcm9uOlwixaVcIixUY2VkaWw6XCLFolwiLHRjZWRpbDpcIsWjXCIsVGN5Olwi0KJcIix0Y3k6XCLRglwiLHRkb3Q6XCLig5tcIix0ZWxyZWM6XCLijJVcIixUZnI6XCLwnZSXXCIsdGZyOlwi8J2UsVwiLHRoZXJlNDpcIuKItFwiLHRoZXJlZm9yZTpcIuKItFwiLFRoZXJlZm9yZTpcIuKItFwiLFRoZXRhOlwizphcIix0aGV0YTpcIs64XCIsdGhldGFzeW06XCLPkVwiLHRoZXRhdjpcIs+RXCIsdGhpY2thcHByb3g6XCLiiYhcIix0aGlja3NpbTpcIuKIvFwiLFRoaWNrU3BhY2U6XCLigZ/igIpcIixUaGluU3BhY2U6XCLigIlcIix0aGluc3A6XCLigIlcIix0aGthcDpcIuKJiFwiLHRoa3NpbTpcIuKIvFwiLFRIT1JOOlwiw55cIix0aG9ybjpcIsO+XCIsdGlsZGU6XCLLnFwiLFRpbGRlOlwi4oi8XCIsVGlsZGVFcXVhbDpcIuKJg1wiLFRpbGRlRnVsbEVxdWFsOlwi4omFXCIsVGlsZGVUaWxkZTpcIuKJiFwiLHRpbWVzYmFyOlwi4qixXCIsdGltZXNiOlwi4oqgXCIsdGltZXM6XCLDl1wiLHRpbWVzZDpcIuKosFwiLHRpbnQ6XCLiiK1cIix0b2VhOlwi4qSoXCIsdG9wYm90Olwi4oy2XCIsdG9wY2lyOlwi4quxXCIsdG9wOlwi4oqkXCIsVG9wZjpcIvCdlYtcIix0b3BmOlwi8J2VpVwiLHRvcGZvcms6XCLiq5pcIix0b3NhOlwi4qSpXCIsdHByaW1lOlwi4oC0XCIsdHJhZGU6XCLihKJcIixUUkFERTpcIuKEolwiLHRyaWFuZ2xlOlwi4pa1XCIsdHJpYW5nbGVkb3duOlwi4pa/XCIsdHJpYW5nbGVsZWZ0Olwi4peDXCIsdHJpYW5nbGVsZWZ0ZXE6XCLiirRcIix0cmlhbmdsZXE6XCLiiZxcIix0cmlhbmdsZXJpZ2h0Olwi4pa5XCIsdHJpYW5nbGVyaWdodGVxOlwi4oq1XCIsdHJpZG90Olwi4pesXCIsdHJpZTpcIuKJnFwiLHRyaW1pbnVzOlwi4qi6XCIsVHJpcGxlRG90Olwi4oObXCIsdHJpcGx1czpcIuKouVwiLHRyaXNiOlwi4qeNXCIsdHJpdGltZTpcIuKou1wiLHRycGV6aXVtOlwi4o+iXCIsVHNjcjpcIvCdkq9cIix0c2NyOlwi8J2TiVwiLFRTY3k6XCLQplwiLHRzY3k6XCLRhlwiLFRTSGN5Olwi0ItcIix0c2hjeTpcItGbXCIsVHN0cm9rOlwixaZcIix0c3Ryb2s6XCLFp1wiLHR3aXh0Olwi4omsXCIsdHdvaGVhZGxlZnRhcnJvdzpcIuKGnlwiLHR3b2hlYWRyaWdodGFycm93Olwi4oagXCIsVWFjdXRlOlwiw5pcIix1YWN1dGU6XCLDulwiLHVhcnI6XCLihpFcIixVYXJyOlwi4oafXCIsdUFycjpcIuKHkVwiLFVhcnJvY2lyOlwi4qWJXCIsVWJyY3k6XCLQjlwiLHVicmN5Olwi0Z5cIixVYnJldmU6XCLFrFwiLHVicmV2ZTpcIsWtXCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVY3k6XCLQo1wiLHVjeTpcItGDXCIsdWRhcnI6XCLih4VcIixVZGJsYWM6XCLFsFwiLHVkYmxhYzpcIsWxXCIsdWRoYXI6XCLipa5cIix1ZmlzaHQ6XCLipb5cIixVZnI6XCLwnZSYXCIsdWZyOlwi8J2UslwiLFVncmF2ZTpcIsOZXCIsdWdyYXZlOlwiw7lcIix1SGFyOlwi4qWjXCIsdWhhcmw6XCLihr9cIix1aGFycjpcIuKGvlwiLHVoYmxrOlwi4paAXCIsdWxjb3JuOlwi4oycXCIsdWxjb3JuZXI6XCLijJxcIix1bGNyb3A6XCLijI9cIix1bHRyaTpcIuKXuFwiLFVtYWNyOlwixapcIix1bWFjcjpcIsWrXCIsdW1sOlwiwqhcIixVbmRlckJhcjpcIl9cIixVbmRlckJyYWNlOlwi4o+fXCIsVW5kZXJCcmFja2V0Olwi4o61XCIsVW5kZXJQYXJlbnRoZXNpczpcIuKPnVwiLFVuaW9uOlwi4ouDXCIsVW5pb25QbHVzOlwi4oqOXCIsVW9nb246XCLFslwiLHVvZ29uOlwixbNcIixVb3BmOlwi8J2VjFwiLHVvcGY6XCLwnZWmXCIsVXBBcnJvd0JhcjpcIuKkklwiLHVwYXJyb3c6XCLihpFcIixVcEFycm93Olwi4oaRXCIsVXBhcnJvdzpcIuKHkVwiLFVwQXJyb3dEb3duQXJyb3c6XCLih4VcIix1cGRvd25hcnJvdzpcIuKGlVwiLFVwRG93bkFycm93Olwi4oaVXCIsVXBkb3duYXJyb3c6XCLih5VcIixVcEVxdWlsaWJyaXVtOlwi4qWuXCIsdXBoYXJwb29ubGVmdDpcIuKGv1wiLHVwaGFycG9vbnJpZ2h0Olwi4oa+XCIsdXBsdXM6XCLiio5cIixVcHBlckxlZnRBcnJvdzpcIuKGllwiLFVwcGVyUmlnaHRBcnJvdzpcIuKGl1wiLHVwc2k6XCLPhVwiLFVwc2k6XCLPklwiLHVwc2loOlwiz5JcIixVcHNpbG9uOlwizqVcIix1cHNpbG9uOlwiz4VcIixVcFRlZUFycm93Olwi4oalXCIsVXBUZWU6XCLiiqVcIix1cHVwYXJyb3dzOlwi4oeIXCIsdXJjb3JuOlwi4oydXCIsdXJjb3JuZXI6XCLijJ1cIix1cmNyb3A6XCLijI5cIixVcmluZzpcIsWuXCIsdXJpbmc6XCLFr1wiLHVydHJpOlwi4pe5XCIsVXNjcjpcIvCdkrBcIix1c2NyOlwi8J2TilwiLHV0ZG90Olwi4ouwXCIsVXRpbGRlOlwixahcIix1dGlsZGU6XCLFqVwiLHV0cmk6XCLilrVcIix1dHJpZjpcIuKWtFwiLHV1YXJyOlwi4oeIXCIsVXVtbDpcIsOcXCIsdXVtbDpcIsO8XCIsdXdhbmdsZTpcIuKmp1wiLHZhbmdydDpcIuKmnFwiLHZhcmVwc2lsb246XCLPtVwiLHZhcmthcHBhOlwiz7BcIix2YXJub3RoaW5nOlwi4oiFXCIsdmFycGhpOlwiz5VcIix2YXJwaTpcIs+WXCIsdmFycHJvcHRvOlwi4oidXCIsdmFycjpcIuKGlVwiLHZBcnI6XCLih5VcIix2YXJyaG86XCLPsVwiLHZhcnNpZ21hOlwiz4JcIix2YXJzdWJzZXRuZXE6XCLiiorvuIBcIix2YXJzdWJzZXRuZXFxOlwi4quL77iAXCIsdmFyc3Vwc2V0bmVxOlwi4oqL77iAXCIsdmFyc3Vwc2V0bmVxcTpcIuKrjO+4gFwiLHZhcnRoZXRhOlwiz5FcIix2YXJ0cmlhbmdsZWxlZnQ6XCLiirJcIix2YXJ0cmlhbmdsZXJpZ2h0Olwi4oqzXCIsdkJhcjpcIuKrqFwiLFZiYXI6XCLiq6tcIix2QmFydjpcIuKrqVwiLFZjeTpcItCSXCIsdmN5Olwi0LJcIix2ZGFzaDpcIuKKolwiLHZEYXNoOlwi4oqoXCIsVmRhc2g6XCLiiqlcIixWRGFzaDpcIuKKq1wiLFZkYXNobDpcIuKrplwiLHZlZWJhcjpcIuKKu1wiLHZlZTpcIuKIqFwiLFZlZTpcIuKLgVwiLHZlZWVxOlwi4omaXCIsdmVsbGlwOlwi4ouuXCIsdmVyYmFyOlwifFwiLFZlcmJhcjpcIuKAllwiLHZlcnQ6XCJ8XCIsVmVydDpcIuKAllwiLFZlcnRpY2FsQmFyOlwi4oijXCIsVmVydGljYWxMaW5lOlwifFwiLFZlcnRpY2FsU2VwYXJhdG9yOlwi4p2YXCIsVmVydGljYWxUaWxkZTpcIuKJgFwiLFZlcnlUaGluU3BhY2U6XCLigIpcIixWZnI6XCLwnZSZXCIsdmZyOlwi8J2Us1wiLHZsdHJpOlwi4oqyXCIsdm5zdWI6XCLiioLig5JcIix2bnN1cDpcIuKKg+KDklwiLFZvcGY6XCLwnZWNXCIsdm9wZjpcIvCdladcIix2cHJvcDpcIuKInVwiLHZydHJpOlwi4oqzXCIsVnNjcjpcIvCdkrFcIix2c2NyOlwi8J2Ti1wiLHZzdWJuRTpcIuKri++4gFwiLHZzdWJuZTpcIuKKiu+4gFwiLHZzdXBuRTpcIuKrjO+4gFwiLHZzdXBuZTpcIuKKi++4gFwiLFZ2ZGFzaDpcIuKKqlwiLHZ6aWd6YWc6XCLipppcIixXY2lyYzpcIsW0XCIsd2NpcmM6XCLFtVwiLHdlZGJhcjpcIuKpn1wiLHdlZGdlOlwi4oinXCIsV2VkZ2U6XCLii4BcIix3ZWRnZXE6XCLiiZlcIix3ZWllcnA6XCLihJhcIixXZnI6XCLwnZSaXCIsd2ZyOlwi8J2UtFwiLFdvcGY6XCLwnZWOXCIsd29wZjpcIvCdlahcIix3cDpcIuKEmFwiLHdyOlwi4omAXCIsd3JlYXRoOlwi4omAXCIsV3NjcjpcIvCdkrJcIix3c2NyOlwi8J2TjFwiLHhjYXA6XCLii4JcIix4Y2lyYzpcIuKXr1wiLHhjdXA6XCLii4NcIix4ZHRyaTpcIuKWvVwiLFhmcjpcIvCdlJtcIix4ZnI6XCLwnZS1XCIseGhhcnI6XCLin7dcIix4aEFycjpcIuKfulwiLFhpOlwizp5cIix4aTpcIs6+XCIseGxhcnI6XCLin7VcIix4bEFycjpcIuKfuFwiLHhtYXA6XCLin7xcIix4bmlzOlwi4ou7XCIseG9kb3Q6XCLiqIBcIixYb3BmOlwi8J2Vj1wiLHhvcGY6XCLwnZWpXCIseG9wbHVzOlwi4qiBXCIseG90aW1lOlwi4qiCXCIseHJhcnI6XCLin7ZcIix4ckFycjpcIuKfuVwiLFhzY3I6XCLwnZKzXCIseHNjcjpcIvCdk41cIix4c3FjdXA6XCLiqIZcIix4dXBsdXM6XCLiqIRcIix4dXRyaTpcIuKWs1wiLHh2ZWU6XCLii4FcIix4d2VkZ2U6XCLii4BcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIsWUFjeTpcItCvXCIseWFjeTpcItGPXCIsWWNpcmM6XCLFtlwiLHljaXJjOlwixbdcIixZY3k6XCLQq1wiLHljeTpcItGLXCIseWVuOlwiwqVcIixZZnI6XCLwnZScXCIseWZyOlwi8J2UtlwiLFlJY3k6XCLQh1wiLHlpY3k6XCLRl1wiLFlvcGY6XCLwnZWQXCIseW9wZjpcIvCdlapcIixZc2NyOlwi8J2StFwiLHlzY3I6XCLwnZOOXCIsWVVjeTpcItCuXCIseXVjeTpcItGOXCIseXVtbDpcIsO/XCIsWXVtbDpcIsW4XCIsWmFjdXRlOlwixblcIix6YWN1dGU6XCLFulwiLFpjYXJvbjpcIsW9XCIsemNhcm9uOlwixb5cIixaY3k6XCLQl1wiLHpjeTpcItC3XCIsWmRvdDpcIsW7XCIsemRvdDpcIsW8XCIsemVldHJmOlwi4oSoXCIsWmVyb1dpZHRoU3BhY2U6XCLigItcIixaZXRhOlwizpZcIix6ZXRhOlwizrZcIix6ZnI6XCLwnZS3XCIsWmZyOlwi4oSoXCIsWkhjeTpcItCWXCIsemhjeTpcItC2XCIsemlncmFycjpcIuKHnVwiLHpvcGY6XCLwnZWrXCIsWm9wZjpcIuKEpFwiLFpzY3I6XCLwnZK1XCIsenNjcjpcIvCdk49cIix6d2o6XCLigI1cIix6d25qOlwi4oCMXCJ9fSx7fV0sMjY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtBYWN1dGU6XCLDgVwiLGFhY3V0ZTpcIsOhXCIsQWNpcmM6XCLDglwiLGFjaXJjOlwiw6JcIixhY3V0ZTpcIsK0XCIsQUVsaWc6XCLDhlwiLGFlbGlnOlwiw6ZcIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYW1wOlwiJlwiLEFNUDpcIiZcIixBcmluZzpcIsOFXCIsYXJpbmc6XCLDpVwiLEF0aWxkZTpcIsODXCIsYXRpbGRlOlwiw6NcIixBdW1sOlwiw4RcIixhdW1sOlwiw6RcIixicnZiYXI6XCLCplwiLENjZWRpbDpcIsOHXCIsY2NlZGlsOlwiw6dcIixjZWRpbDpcIsK4XCIsY2VudDpcIsKiXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY3VycmVuOlwiwqRcIixkZWc6XCLCsFwiLGRpdmlkZTpcIsO3XCIsRWFjdXRlOlwiw4lcIixlYWN1dGU6XCLDqVwiLEVjaXJjOlwiw4pcIixlY2lyYzpcIsOqXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLEVUSDpcIsOQXCIsZXRoOlwiw7BcIixFdW1sOlwiw4tcIixldW1sOlwiw6tcIixmcmFjMTI6XCLCvVwiLGZyYWMxNDpcIsK8XCIsZnJhYzM0Olwiwr5cIixndDpcIj5cIixHVDpcIj5cIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsSWNpcmM6XCLDjlwiLGljaXJjOlwiw65cIixpZXhjbDpcIsKhXCIsSWdyYXZlOlwiw4xcIixpZ3JhdmU6XCLDrFwiLGlxdWVzdDpcIsK/XCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsbGFxdW86XCLCq1wiLGx0OlwiPFwiLExUOlwiPFwiLG1hY3I6XCLCr1wiLG1pY3JvOlwiwrVcIixtaWRkb3Q6XCLCt1wiLG5ic3A6XCLCoFwiLG5vdDpcIsKsXCIsTnRpbGRlOlwiw5FcIixudGlsZGU6XCLDsVwiLE9hY3V0ZTpcIsOTXCIsb2FjdXRlOlwiw7NcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLE9ncmF2ZTpcIsOSXCIsb2dyYXZlOlwiw7JcIixvcmRmOlwiwqpcIixvcmRtOlwiwrpcIixPc2xhc2g6XCLDmFwiLG9zbGFzaDpcIsO4XCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLE91bWw6XCLDllwiLG91bWw6XCLDtlwiLHBhcmE6XCLCtlwiLHBsdXNtbjpcIsKxXCIscG91bmQ6XCLCo1wiLHF1b3Q6J1wiJyxRVU9UOidcIicscmFxdW86XCLCu1wiLHJlZzpcIsKuXCIsUkVHOlwiwq5cIixzZWN0OlwiwqdcIixzaHk6XCLCrVwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN6bGlnOlwiw59cIixUSE9STjpcIsOeXCIsdGhvcm46XCLDvlwiLHRpbWVzOlwiw5dcIixVYWN1dGU6XCLDmlwiLHVhY3V0ZTpcIsO6XCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVZ3JhdmU6XCLDmVwiLHVncmF2ZTpcIsO5XCIsdW1sOlwiwqhcIixVdW1sOlwiw5xcIix1dW1sOlwiw7xcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIseWVuOlwiwqVcIix5dW1sOlwiw79cIn19LHt9XSwyNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e2FtcDpcIiZcIixhcG9zOlwiJ1wiLGd0OlwiPlwiLGx0OlwiPFwiLHF1b3Q6J1wiJ319LHt9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCl7dGhpcy5fZXZlbnRzPXRoaXMuX2V2ZW50c3x8e307dGhpcy5fbWF4TGlzdGVuZXJzPXRoaXMuX21heExpc3RlbmVyc3x8dW5kZWZpbmVkfW1vZHVsZS5leHBvcnRzPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHM9dW5kZWZpbmVkO0V2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycz11bmRlZmluZWQ7RXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM9MTA7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnM9ZnVuY3Rpb24obil7aWYoIWlzTnVtYmVyKG4pfHxuPDB8fGlzTmFOKG4pKXRocm93IFR5cGVFcnJvcihcIm4gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlclwiKTt0aGlzLl9tYXhMaXN0ZW5lcnM9bjtyZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0PWZ1bmN0aW9uKHR5cGUpe3ZhciBlcixoYW5kbGVyLGxlbixhcmdzLGksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpdGhpcy5fZXZlbnRzPXt9O2lmKHR5cGU9PT1cImVycm9yXCIpe2lmKCF0aGlzLl9ldmVudHMuZXJyb3J8fGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikmJiF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKXtlcj1hcmd1bWVudHNbMV07aWYoZXIgaW5zdGFuY2VvZiBFcnJvcil7dGhyb3cgZXJ9ZWxzZXt2YXIgZXJyPW5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcrZXIrXCIpXCIpO2Vyci5jb250ZXh0PWVyO3Rocm93IGVycn19fWhhbmRsZXI9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzVW5kZWZpbmVkKGhhbmRsZXIpKXJldHVybiBmYWxzZTtpZihpc0Z1bmN0aW9uKGhhbmRsZXIpKXtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmhhbmRsZXIuY2FsbCh0aGlzKTticmVhaztjYXNlIDI6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdKTticmVhaztjYXNlIDM6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdLGFyZ3VtZW50c1syXSk7YnJlYWs7ZGVmYXVsdDphcmdzPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtoYW5kbGVyLmFwcGx5KHRoaXMsYXJncyl9fWVsc2UgaWYoaXNPYmplY3QoaGFuZGxlcikpe2FyZ3M9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO2xpc3RlbmVycz1oYW5kbGVyLnNsaWNlKCk7bGVuPWxpc3RlbmVycy5sZW5ndGg7Zm9yKGk9MDtpPGxlbjtpKyspbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsYXJncyl9cmV0dXJuIHRydWV9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7dmFyIG07aWYoIWlzRnVuY3Rpb24obGlzdGVuZXIpKXRocm93IFR5cGVFcnJvcihcImxpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvblwiKTtpZighdGhpcy5fZXZlbnRzKXRoaXMuX2V2ZW50cz17fTtpZih0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpdGhpcy5lbWl0KFwibmV3TGlzdGVuZXJcIix0eXBlLGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpP2xpc3RlbmVyLmxpc3RlbmVyOmxpc3RlbmVyKTtpZighdGhpcy5fZXZlbnRzW3R5cGVdKXRoaXMuX2V2ZW50c1t0eXBlXT1saXN0ZW5lcjtlbHNlIGlmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO2Vsc2UgdGhpcy5fZXZlbnRzW3R5cGVdPVt0aGlzLl9ldmVudHNbdHlwZV0sbGlzdGVuZXJdO2lmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkmJiF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKXtpZighaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSl7bT10aGlzLl9tYXhMaXN0ZW5lcnN9ZWxzZXttPUV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzfWlmKG0mJm0+MCYmdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aD5tKXt0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkPXRydWU7Y29uc29sZS5lcnJvcihcIihub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IFwiK1wibGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiBcIitcIlVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LlwiLHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO2lmKHR5cGVvZiBjb25zb2xlLnRyYWNlPT09XCJmdW5jdGlvblwiKXtjb25zb2xlLnRyYWNlKCl9fX1yZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbj1FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO0V2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZT1mdW5jdGlvbih0eXBlLGxpc3RlbmVyKXtpZighaXNGdW5jdGlvbihsaXN0ZW5lcikpdGhyb3cgVHlwZUVycm9yKFwibGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO3ZhciBmaXJlZD1mYWxzZTtmdW5jdGlvbiBnKCl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGcpO2lmKCFmaXJlZCl7ZmlyZWQ9dHJ1ZTtsaXN0ZW5lci5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fWcubGlzdGVuZXI9bGlzdGVuZXI7dGhpcy5vbih0eXBlLGcpO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyPWZ1bmN0aW9uKHR5cGUsbGlzdGVuZXIpe3ZhciBsaXN0LHBvc2l0aW9uLGxlbmd0aCxpO2lmKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSl0aHJvdyBUeXBlRXJyb3IoXCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb25cIik7aWYoIXRoaXMuX2V2ZW50c3x8IXRoaXMuX2V2ZW50c1t0eXBlXSlyZXR1cm4gdGhpcztsaXN0PXRoaXMuX2V2ZW50c1t0eXBlXTtsZW5ndGg9bGlzdC5sZW5ndGg7cG9zaXRpb249LTE7aWYobGlzdD09PWxpc3RlbmVyfHxpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpJiZsaXN0Lmxpc3RlbmVyPT09bGlzdGVuZXIpe2RlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9ZWxzZSBpZihpc09iamVjdChsaXN0KSl7Zm9yKGk9bGVuZ3RoO2ktLSA+MDspe2lmKGxpc3RbaV09PT1saXN0ZW5lcnx8bGlzdFtpXS5saXN0ZW5lciYmbGlzdFtpXS5saXN0ZW5lcj09PWxpc3RlbmVyKXtwb3NpdGlvbj1pO2JyZWFrfX1pZihwb3NpdGlvbjwwKXJldHVybiB0aGlzO2lmKGxpc3QubGVuZ3RoPT09MSl7bGlzdC5sZW5ndGg9MDtkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdfWVsc2V7bGlzdC5zcGxpY2UocG9zaXRpb24sMSk7XG59aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzPWZ1bmN0aW9uKHR5cGUpe3ZhciBrZXksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpcmV0dXJuIHRoaXM7aWYoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcil7aWYoYXJndW1lbnRzLmxlbmd0aD09PTApdGhpcy5fZXZlbnRzPXt9O2Vsc2UgaWYodGhpcy5fZXZlbnRzW3R5cGVdKWRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07cmV0dXJuIHRoaXN9aWYoYXJndW1lbnRzLmxlbmd0aD09PTApe2ZvcihrZXkgaW4gdGhpcy5fZXZlbnRzKXtpZihrZXk9PT1cInJlbW92ZUxpc3RlbmVyXCIpY29udGludWU7dGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KX10aGlzLnJlbW92ZUFsbExpc3RlbmVycyhcInJlbW92ZUxpc3RlbmVyXCIpO3RoaXMuX2V2ZW50cz17fTtyZXR1cm4gdGhpc31saXN0ZW5lcnM9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzRnVuY3Rpb24obGlzdGVuZXJzKSl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVycyl9ZWxzZSBpZihsaXN0ZW5lcnMpe3doaWxlKGxpc3RlbmVycy5sZW5ndGgpdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoLTFdKX1kZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycz1mdW5jdGlvbih0eXBlKXt2YXIgcmV0O2lmKCF0aGlzLl9ldmVudHN8fCF0aGlzLl9ldmVudHNbdHlwZV0pcmV0PVtdO2Vsc2UgaWYoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKXJldD1bdGhpcy5fZXZlbnRzW3R5cGVdXTtlbHNlIHJldD10aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtyZXR1cm4gcmV0fTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQ9ZnVuY3Rpb24odHlwZSl7aWYodGhpcy5fZXZlbnRzKXt2YXIgZXZsaXN0ZW5lcj10aGlzLl9ldmVudHNbdHlwZV07aWYoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlyZXR1cm4gMTtlbHNlIGlmKGV2bGlzdGVuZXIpcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RofXJldHVybiAwfTtFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudD1mdW5jdGlvbihlbWl0dGVyLHR5cGUpe3JldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSl9O2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1mdW5jdGlvbiBpc051bWJlcihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJudW1iZXJcIn1mdW5jdGlvbiBpc09iamVjdChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJvYmplY3RcIiYmYXJnIT09bnVsbH1mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpe3JldHVybiBhcmc9PT12b2lkIDB9fSx7fV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPUNvbGxlY3RpbmdIYW5kbGVyO2Z1bmN0aW9uIENvbGxlY3RpbmdIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e307dGhpcy5ldmVudHM9W119dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbigpe3RoaXMuZXZlbnRzLnB1c2goW25hbWVdKTtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSl7dGhpcy5ldmVudHMucHVzaChbbmFtZSxhXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0yKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhLGIpe3RoaXMuZXZlbnRzLnB1c2goW25hbWUsYSxiXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUub25yZXNldD1mdW5jdGlvbigpe3RoaXMuZXZlbnRzPVtdO2lmKHRoaXMuX2Nicy5vbnJlc2V0KXRoaXMuX2Nicy5vbnJlc2V0KCl9O0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZS5yZXN0YXJ0PWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9ucmVzZXQpdGhpcy5fY2JzLm9ucmVzZXQoKTtmb3IodmFyIGk9MCxsZW49dGhpcy5ldmVudHMubGVuZ3RoO2k8bGVuO2krKyl7aWYodGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSl7dmFyIG51bT10aGlzLmV2ZW50c1tpXS5sZW5ndGg7aWYobnVtPT09MSl7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSgpfWVsc2UgaWYobnVtPT09Mil7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSh0aGlzLmV2ZW50c1tpXVsxXSl9ZWxzZXt0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdLHRoaXMuZXZlbnRzW2ldWzJdKX19fX19LHtcIi4vXCI6MzZ9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGluZGV4PXJlcXVpcmUoXCIuL2luZGV4LmpzXCIpLERvbUhhbmRsZXI9aW5kZXguRG9tSGFuZGxlcixEb21VdGlscz1pbmRleC5Eb21VdGlscztmdW5jdGlvbiBGZWVkSGFuZGxlcihjYWxsYmFjayxvcHRpb25zKXt0aGlzLmluaXQoY2FsbGJhY2ssb3B0aW9ucyl9cmVxdWlyZShcImluaGVyaXRzXCIpKEZlZWRIYW5kbGVyLERvbUhhbmRsZXIpO0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5pbml0PURvbUhhbmRsZXI7ZnVuY3Rpb24gZ2V0RWxlbWVudHMod2hhdCx3aGVyZSl7cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsd2hlcmUsdHJ1ZSl9ZnVuY3Rpb24gZ2V0T25lRWxlbWVudCh3aGF0LHdoZXJlKXtyZXR1cm4gRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSx0cnVlLDEpWzBdfWZ1bmN0aW9uIGZldGNoKHdoYXQsd2hlcmUscmVjdXJzZSl7cmV0dXJuIERvbVV0aWxzLmdldFRleHQoRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSxyZWN1cnNlLDEpKS50cmltKCl9ZnVuY3Rpb24gYWRkQ29uZGl0aW9uYWxseShvYmoscHJvcCx3aGF0LHdoZXJlLHJlY3Vyc2Upe3ZhciB0bXA9ZmV0Y2god2hhdCx3aGVyZSxyZWN1cnNlKTtpZih0bXApb2JqW3Byb3BdPXRtcH12YXIgaXNWYWxpZEZlZWQ9ZnVuY3Rpb24odmFsdWUpe3JldHVybiB2YWx1ZT09PVwicnNzXCJ8fHZhbHVlPT09XCJmZWVkXCJ8fHZhbHVlPT09XCJyZGY6UkRGXCJ9O0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe3ZhciBmZWVkPXt9LGZlZWRSb290PWdldE9uZUVsZW1lbnQoaXNWYWxpZEZlZWQsdGhpcy5kb20pLHRtcCxjaGlsZHM7aWYoZmVlZFJvb3Qpe2lmKGZlZWRSb290Lm5hbWU9PT1cImZlZWRcIil7Y2hpbGRzPWZlZWRSb290LmNoaWxkcmVuO2ZlZWQudHlwZT1cImF0b21cIjthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJpZFwiLFwiaWRcIixjaGlsZHMpO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcInRpdGxlXCIsXCJ0aXRsZVwiLGNoaWxkcyk7aWYoKHRtcD1nZXRPbmVFbGVtZW50KFwibGlua1wiLGNoaWxkcykpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZmVlZC5saW5rPXRtcDthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwic3VidGl0bGVcIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcInVwZGF0ZWRcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwiZW1haWxcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcImVudHJ5XCIsY2hpbGRzKS5tYXAoZnVuY3Rpb24oaXRlbSl7dmFyIGVudHJ5PXt9LHRtcDtpdGVtPWl0ZW0uY2hpbGRyZW47YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImlkXCIsXCJpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTtpZigodG1wPWdldE9uZUVsZW1lbnQoXCJsaW5rXCIsaXRlbSkpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZW50cnkubGluaz10bXA7aWYodG1wPWZldGNoKFwic3VtbWFyeVwiLGl0ZW0pfHxmZXRjaChcImNvbnRlbnRcIixpdGVtKSllbnRyeS5kZXNjcmlwdGlvbj10bXA7aWYodG1wPWZldGNoKFwidXBkYXRlZFwiLGl0ZW0pKWVudHJ5LnB1YkRhdGU9bmV3IERhdGUodG1wKTtyZXR1cm4gZW50cnl9KX1lbHNle2NoaWxkcz1nZXRPbmVFbGVtZW50KFwiY2hhbm5lbFwiLGZlZWRSb290LmNoaWxkcmVuKS5jaGlsZHJlbjtmZWVkLnR5cGU9ZmVlZFJvb3QubmFtZS5zdWJzdHIoMCwzKTtmZWVkLmlkPVwiXCI7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwidGl0bGVcIixcInRpdGxlXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJsaW5rXCIsXCJsaW5rXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcImxhc3RCdWlsZERhdGVcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwibWFuYWdpbmdFZGl0b3JcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcIml0ZW1cIixmZWVkUm9vdC5jaGlsZHJlbikubWFwKGZ1bmN0aW9uKGl0ZW0pe3ZhciBlbnRyeT17fSx0bXA7aXRlbT1pdGVtLmNoaWxkcmVuO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJpZFwiLFwiZ3VpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwibGlua1wiLFwibGlua1wiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixpdGVtKTtpZih0bXA9ZmV0Y2goXCJwdWJEYXRlXCIsaXRlbSkpZW50cnkucHViRGF0ZT1uZXcgRGF0ZSh0bXApO3JldHVybiBlbnRyeX0pfX10aGlzLmRvbT1mZWVkO0RvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjay5jYWxsKHRoaXMsZmVlZFJvb3Q/bnVsbDpFcnJvcihcImNvdWxkbid0IGZpbmQgcm9vdCBvZiBmZWVkXCIpKX07bW9kdWxlLmV4cG9ydHM9RmVlZEhhbmRsZXJ9LHtcIi4vaW5kZXguanNcIjozNixpbmhlcml0czozOH1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgVG9rZW5pemVyPXJlcXVpcmUoXCIuL1Rva2VuaXplci5qc1wiKTt2YXIgZm9ybVRhZ3M9e2lucHV0OnRydWUsb3B0aW9uOnRydWUsb3B0Z3JvdXA6dHJ1ZSxzZWxlY3Q6dHJ1ZSxidXR0b246dHJ1ZSxkYXRhbGlzdDp0cnVlLHRleHRhcmVhOnRydWV9O3ZhciBvcGVuSW1wbGllc0Nsb3NlPXt0cjp7dHI6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LHRoOnt0aDp0cnVlfSx0ZDp7dGhlYWQ6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LGJvZHk6e2hlYWQ6dHJ1ZSxsaW5rOnRydWUsc2NyaXB0OnRydWV9LGxpOntsaTp0cnVlfSxwOntwOnRydWV9LGgxOntwOnRydWV9LGgyOntwOnRydWV9LGgzOntwOnRydWV9LGg0OntwOnRydWV9LGg1OntwOnRydWV9LGg2OntwOnRydWV9LHNlbGVjdDpmb3JtVGFncyxpbnB1dDpmb3JtVGFncyxvdXRwdXQ6Zm9ybVRhZ3MsYnV0dG9uOmZvcm1UYWdzLGRhdGFsaXN0OmZvcm1UYWdzLHRleHRhcmVhOmZvcm1UYWdzLG9wdGlvbjp7b3B0aW9uOnRydWV9LG9wdGdyb3VwOntvcHRncm91cDp0cnVlfX07dmFyIHZvaWRFbGVtZW50cz17X19wcm90b19fOm51bGwsYXJlYTp0cnVlLGJhc2U6dHJ1ZSxiYXNlZm9udDp0cnVlLGJyOnRydWUsY29sOnRydWUsY29tbWFuZDp0cnVlLGVtYmVkOnRydWUsZnJhbWU6dHJ1ZSxocjp0cnVlLGltZzp0cnVlLGlucHV0OnRydWUsaXNpbmRleDp0cnVlLGtleWdlbjp0cnVlLGxpbms6dHJ1ZSxtZXRhOnRydWUscGFyYW06dHJ1ZSxzb3VyY2U6dHJ1ZSx0cmFjazp0cnVlLHdicjp0cnVlLHBhdGg6dHJ1ZSxjaXJjbGU6dHJ1ZSxlbGxpcHNlOnRydWUsbGluZTp0cnVlLHJlY3Q6dHJ1ZSx1c2U6dHJ1ZSxzdG9wOnRydWUscG9seWxpbmU6dHJ1ZSxwb2x5Z29uOnRydWV9O3ZhciByZV9uYW1lRW5kPS9cXHN8XFwvLztmdW5jdGlvbiBQYXJzZXIoY2JzLG9wdGlvbnMpe3RoaXMuX29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5fY2JzPWNic3x8e307dGhpcy5fdGFnbmFtZT1cIlwiO3RoaXMuX2F0dHJpYm5hbWU9XCJcIjt0aGlzLl9hdHRyaWJ2YWx1ZT1cIlwiO3RoaXMuX2F0dHJpYnM9bnVsbDt0aGlzLl9zdGFjaz1bXTt0aGlzLnN0YXJ0SW5kZXg9MDt0aGlzLmVuZEluZGV4PW51bGw7dGhpcy5fbG93ZXJDYXNlVGFnTmFtZXM9XCJsb3dlckNhc2VUYWdzXCJpbiB0aGlzLl9vcHRpb25zPyEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VUYWdzOiF0aGlzLl9vcHRpb25zLnhtbE1vZGU7dGhpcy5fbG93ZXJDYXNlQXR0cmlidXRlTmFtZXM9XCJsb3dlckNhc2VBdHRyaWJ1dGVOYW1lc1wiaW4gdGhpcy5fb3B0aW9ucz8hIXRoaXMuX29wdGlvbnMubG93ZXJDYXNlQXR0cmlidXRlTmFtZXM6IXRoaXMuX29wdGlvbnMueG1sTW9kZTtpZih0aGlzLl9vcHRpb25zLlRva2VuaXplcil7VG9rZW5pemVyPXRoaXMuX29wdGlvbnMuVG9rZW5pemVyfXRoaXMuX3Rva2VuaXplcj1uZXcgVG9rZW5pemVyKHRoaXMuX29wdGlvbnMsdGhpcyk7aWYodGhpcy5fY2JzLm9ucGFyc2VyaW5pdCl0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShQYXJzZXIscmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXIpO1BhcnNlci5wcm90b3R5cGUuX3VwZGF0ZVBvc2l0aW9uPWZ1bmN0aW9uKGluaXRpYWxPZmZzZXQpe2lmKHRoaXMuZW5kSW5kZXg9PT1udWxsKXtpZih0aGlzLl90b2tlbml6ZXIuX3NlY3Rpb25TdGFydDw9aW5pdGlhbE9mZnNldCl7dGhpcy5zdGFydEluZGV4PTB9ZWxzZXt0aGlzLnN0YXJ0SW5kZXg9dGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQtaW5pdGlhbE9mZnNldH19ZWxzZSB0aGlzLnN0YXJ0SW5kZXg9dGhpcy5lbmRJbmRleCsxO3RoaXMuZW5kSW5kZXg9dGhpcy5fdG9rZW5pemVyLmdldEFic29sdXRlSW5kZXgoKX07UGFyc2VyLnByb3RvdHlwZS5vbnRleHQ9ZnVuY3Rpb24oZGF0YSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7dGhpcy5lbmRJbmRleC0tO2lmKHRoaXMuX2Nicy5vbnRleHQpdGhpcy5fY2JzLm9udGV4dChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS5vbm9wZW50YWduYW1lPWZ1bmN0aW9uKG5hbWUpe2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX10aGlzLl90YWduYW1lPW5hbWU7aWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSYmbmFtZSBpbiBvcGVuSW1wbGllc0Nsb3NlKXtmb3IodmFyIGVsOyhlbD10aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV0paW4gb3BlbkltcGxpZXNDbG9zZVtuYW1lXTt0aGlzLm9uY2xvc2V0YWcoZWwpKTt9aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlfHwhKG5hbWUgaW4gdm9pZEVsZW1lbnRzKSl7dGhpcy5fc3RhY2sucHVzaChuYW1lKX1pZih0aGlzLl9jYnMub25vcGVudGFnbmFtZSl0aGlzLl9jYnMub25vcGVudGFnbmFtZShuYW1lKTtpZih0aGlzLl9jYnMub25vcGVudGFnKXRoaXMuX2F0dHJpYnM9e319O1BhcnNlci5wcm90b3R5cGUub25vcGVudGFnZW5kPWZ1bmN0aW9uKCl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fYXR0cmlicyl7aWYodGhpcy5fY2JzLm9ub3BlbnRhZyl0aGlzLl9jYnMub25vcGVudGFnKHRoaXMuX3RhZ25hbWUsdGhpcy5fYXR0cmlicyk7dGhpcy5fYXR0cmlicz1udWxsfWlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJnRoaXMuX2Nicy5vbmNsb3NldGFnJiZ0aGlzLl90YWduYW1lIGluIHZvaWRFbGVtZW50cyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fdGFnbmFtZSl9dGhpcy5fdGFnbmFtZT1cIlwifTtQYXJzZXIucHJvdG90eXBlLm9uY2xvc2V0YWc9ZnVuY3Rpb24obmFtZSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfWlmKHRoaXMuX3N0YWNrLmxlbmd0aCYmKCEobmFtZSBpbiB2b2lkRWxlbWVudHMpfHx0aGlzLl9vcHRpb25zLnhtbE1vZGUpKXt2YXIgcG9zPXRoaXMuX3N0YWNrLmxhc3RJbmRleE9mKG5hbWUpO2lmKHBvcyE9PS0xKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7cG9zPXRoaXMuX3N0YWNrLmxlbmd0aC1wb3M7d2hpbGUocG9zLS0pdGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2sucG9wKCkpfWVsc2UgdGhpcy5fc3RhY2subGVuZ3RoPXBvc31lbHNlIGlmKG5hbWU9PT1cInBcIiYmIXRoaXMuX29wdGlvbnMueG1sTW9kZSl7dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfX1lbHNlIGlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJihuYW1lPT09XCJiclwifHxuYW1lPT09XCJwXCIpKXt0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7dGhpcy5fY2xvc2VDdXJyZW50VGFnKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uc2VsZmNsb3Npbmd0YWc9ZnVuY3Rpb24oKXtpZih0aGlzLl9vcHRpb25zLnhtbE1vZGV8fHRoaXMuX29wdGlvbnMucmVjb2duaXplU2VsZkNsb3Npbmcpe3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfWVsc2V7dGhpcy5vbm9wZW50YWdlbmQoKX19O1BhcnNlci5wcm90b3R5cGUuX2Nsb3NlQ3VycmVudFRhZz1mdW5jdGlvbigpe3ZhciBuYW1lPXRoaXMuX3RhZ25hbWU7dGhpcy5vbm9wZW50YWdlbmQoKTtpZih0aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV09PT1uYW1lKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcobmFtZSl9dGhpcy5fc3RhY2sucG9wKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmlibmFtZT1mdW5jdGlvbihuYW1lKXtpZih0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9dGhpcy5fYXR0cmlibmFtZT1uYW1lfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZGF0YT1mdW5jdGlvbih2YWx1ZSl7dGhpcy5fYXR0cmlidmFsdWUrPXZhbHVlfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZW5kPWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9uYXR0cmlidXRlKXRoaXMuX2Nicy5vbmF0dHJpYnV0ZSh0aGlzLl9hdHRyaWJuYW1lLHRoaXMuX2F0dHJpYnZhbHVlKTtpZih0aGlzLl9hdHRyaWJzJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX2F0dHJpYnMsdGhpcy5fYXR0cmlibmFtZSkpe3RoaXMuX2F0dHJpYnNbdGhpcy5fYXR0cmlibmFtZV09dGhpcy5fYXR0cmlidmFsdWV9dGhpcy5fYXR0cmlibmFtZT1cIlwiO3RoaXMuX2F0dHJpYnZhbHVlPVwiXCJ9O1BhcnNlci5wcm90b3R5cGUuX2dldEluc3RydWN0aW9uTmFtZT1mdW5jdGlvbih2YWx1ZSl7dmFyIGlkeD12YWx1ZS5zZWFyY2gocmVfbmFtZUVuZCksbmFtZT1pZHg8MD92YWx1ZTp2YWx1ZS5zdWJzdHIoMCxpZHgpO2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX1yZXR1cm4gbmFtZX07UGFyc2VyLnByb3RvdHlwZS5vbmRlY2xhcmF0aW9uPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24pe3ZhciBuYW1lPXRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiIVwiK25hbWUsXCIhXCIrdmFsdWUpfX07UGFyc2VyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbih2YWx1ZSl7aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXt2YXIgbmFtZT10aGlzLl9nZXRJbnN0cnVjdGlvbk5hbWUodmFsdWUpO3RoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbihcIj9cIituYW1lLFwiP1wiK3ZhbHVlKX19O1BhcnNlci5wcm90b3R5cGUub25jb21tZW50PWZ1bmN0aW9uKHZhbHVlKXt0aGlzLl91cGRhdGVQb3NpdGlvbig0KTtpZih0aGlzLl9jYnMub25jb21tZW50KXRoaXMuX2Nicy5vbmNvbW1lbnQodmFsdWUpO2lmKHRoaXMuX2Nicy5vbmNvbW1lbnRlbmQpdGhpcy5fY2JzLm9uY29tbWVudGVuZCgpfTtQYXJzZXIucHJvdG90eXBlLm9uY2RhdGE9ZnVuY3Rpb24odmFsdWUpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO2lmKHRoaXMuX29wdGlvbnMueG1sTW9kZXx8dGhpcy5fb3B0aW9ucy5yZWNvZ25pemVDREFUQSl7aWYodGhpcy5fY2JzLm9uY2RhdGFzdGFydCl0aGlzLl9jYnMub25jZGF0YXN0YXJ0KCk7aWYodGhpcy5fY2JzLm9udGV4dCl0aGlzLl9jYnMub250ZXh0KHZhbHVlKTtpZih0aGlzLl9jYnMub25jZGF0YWVuZCl0aGlzLl9jYnMub25jZGF0YWVuZCgpfWVsc2V7dGhpcy5vbmNvbW1lbnQoXCJbQ0RBVEFbXCIrdmFsdWUrXCJdXVwiKX19O1BhcnNlci5wcm90b3R5cGUub25lcnJvcj1mdW5jdGlvbihlcnIpe2lmKHRoaXMuX2Nicy5vbmVycm9yKXRoaXMuX2Nicy5vbmVycm9yKGVycil9O1BhcnNlci5wcm90b3R5cGUub25lbmQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7Zm9yKHZhciBpPXRoaXMuX3N0YWNrLmxlbmd0aDtpPjA7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2tbLS1pXSkpO31pZih0aGlzLl9jYnMub25lbmQpdGhpcy5fY2JzLm9uZW5kKCl9O1BhcnNlci5wcm90b3R5cGUucmVzZXQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25yZXNldCl0aGlzLl9jYnMub25yZXNldCgpO3RoaXMuX3Rva2VuaXplci5yZXNldCgpO3RoaXMuX3RhZ25hbWU9XCJcIjt0aGlzLl9hdHRyaWJuYW1lPVwiXCI7dGhpcy5fYXR0cmlicz1udWxsO3RoaXMuX3N0YWNrPVtdO2lmKHRoaXMuX2Nicy5vbnBhcnNlcmluaXQpdGhpcy5fY2JzLm9ucGFyc2VyaW5pdCh0aGlzKX07UGFyc2VyLnByb3RvdHlwZS5wYXJzZUNvbXBsZXRlPWZ1bmN0aW9uKGRhdGEpe3RoaXMucmVzZXQoKTt0aGlzLmVuZChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihjaHVuayl7dGhpcy5fdG9rZW5pemVyLndyaXRlKGNodW5rKX07UGFyc2VyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe3RoaXMuX3Rva2VuaXplci5lbmQoY2h1bmspfTtQYXJzZXIucHJvdG90eXBlLnBhdXNlPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnBhdXNlKCl9O1BhcnNlci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnJlc3VtZSgpfTtQYXJzZXIucHJvdG90eXBlLnBhcnNlQ2h1bms9UGFyc2VyLnByb3RvdHlwZS53cml0ZTtQYXJzZXIucHJvdG90eXBlLmRvbmU9UGFyc2VyLnByb3RvdHlwZS5lbmQ7bW9kdWxlLmV4cG9ydHM9UGFyc2VyfSx7XCIuL1Rva2VuaXplci5qc1wiOjM0LGV2ZW50czoyOCxpbmhlcml0czozOH1dLDMyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Qcm94eUhhbmRsZXI7ZnVuY3Rpb24gUHJveHlIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e319dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO1Byb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEpe2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09Mil7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEsYil7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KX0se1wiLi9cIjozNn1dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiKTtmdW5jdGlvbiBTdHJlYW0ob3B0aW9ucyl7UGFyc2VyLmNhbGwodGhpcyxuZXcgQ2JzKHRoaXMpLG9wdGlvbnMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShTdHJlYW0sUGFyc2VyKTtTdHJlYW0ucHJvdG90eXBlLnJlYWRhYmxlPXRydWU7ZnVuY3Rpb24gQ2JzKHNjb3BlKXt0aGlzLnNjb3BlPXNjb3BlfXZhciBFVkVOVFM9cmVxdWlyZShcIi4uL1wiKS5FVkVOVFM7T2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKEVWRU5UU1tuYW1lXT09PTApe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKCl7dGhpcy5zY29wZS5lbWl0KG5hbWUpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTEpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEpe3RoaXMuc2NvcGUuZW1pdChuYW1lLGEpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTIpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEsYil7dGhpcy5zY29wZS5lbWl0KG5hbWUsYSxiKX19ZWxzZXt0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMhXCIpfX0pfSx7XCIuLi9cIjozNixcIi4vV3JpdGFibGVTdHJlYW0uanNcIjozNSxpbmhlcml0czozOH1dLDM0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Ub2tlbml6ZXI7dmFyIGRlY29kZUNvZGVQb2ludD1yZXF1aXJlKFwiZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcIiksZW50aXR5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIiksbGVnYWN5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2xlZ2FjeS5qc29uXCIpLHhtbE1hcD1yZXF1aXJlKFwiZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSxpPTAsVEVYVD1pKyssQkVGT1JFX1RBR19OQU1FPWkrKyxJTl9UQUdfTkFNRT1pKyssSU5fU0VMRl9DTE9TSU5HX1RBRz1pKyssQkVGT1JFX0NMT1NJTkdfVEFHX05BTUU9aSsrLElOX0NMT1NJTkdfVEFHX05BTUU9aSsrLEFGVEVSX0NMT1NJTkdfVEFHX05BTUU9aSsrLEJFRk9SRV9BVFRSSUJVVEVfTkFNRT1pKyssSU5fQVRUUklCVVRFX05BTUU9aSsrLEFGVEVSX0FUVFJJQlVURV9OQU1FPWkrKyxCRUZPUkVfQVRUUklCVVRFX1ZBTFVFPWkrKyxJTl9BVFRSSUJVVEVfVkFMVUVfRFE9aSsrLElOX0FUVFJJQlVURV9WQUxVRV9TUT1pKyssSU5fQVRUUklCVVRFX1ZBTFVFX05RPWkrKyxCRUZPUkVfREVDTEFSQVRJT049aSsrLElOX0RFQ0xBUkFUSU9OPWkrKyxJTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OPWkrKyxCRUZPUkVfQ09NTUVOVD1pKyssSU5fQ09NTUVOVD1pKyssQUZURVJfQ09NTUVOVF8xPWkrKyxBRlRFUl9DT01NRU5UXzI9aSsrLEJFRk9SRV9DREFUQV8xPWkrKyxCRUZPUkVfQ0RBVEFfMj1pKyssQkVGT1JFX0NEQVRBXzM9aSsrLEJFRk9SRV9DREFUQV80PWkrKyxCRUZPUkVfQ0RBVEFfNT1pKyssQkVGT1JFX0NEQVRBXzY9aSsrLElOX0NEQVRBPWkrKyxBRlRFUl9DREFUQV8xPWkrKyxBRlRFUl9DREFUQV8yPWkrKyxCRUZPUkVfU1BFQ0lBTD1pKyssQkVGT1JFX1NQRUNJQUxfRU5EPWkrKyxCRUZPUkVfU0NSSVBUXzE9aSsrLEJFRk9SRV9TQ1JJUFRfMj1pKyssQkVGT1JFX1NDUklQVF8zPWkrKyxCRUZPUkVfU0NSSVBUXzQ9aSsrLEJFRk9SRV9TQ1JJUFRfNT1pKyssQUZURVJfU0NSSVBUXzE9aSsrLEFGVEVSX1NDUklQVF8yPWkrKyxBRlRFUl9TQ1JJUFRfMz1pKyssQUZURVJfU0NSSVBUXzQ9aSsrLEFGVEVSX1NDUklQVF81PWkrKyxCRUZPUkVfU1RZTEVfMT1pKyssQkVGT1JFX1NUWUxFXzI9aSsrLEJFRk9SRV9TVFlMRV8zPWkrKyxCRUZPUkVfU1RZTEVfND1pKyssQUZURVJfU1RZTEVfMT1pKyssQUZURVJfU1RZTEVfMj1pKyssQUZURVJfU1RZTEVfMz1pKyssQUZURVJfU1RZTEVfND1pKyssQkVGT1JFX0VOVElUWT1pKyssQkVGT1JFX05VTUVSSUNfRU5USVRZPWkrKyxJTl9OQU1FRF9FTlRJVFk9aSsrLElOX05VTUVSSUNfRU5USVRZPWkrKyxJTl9IRVhfRU5USVRZPWkrKyxqPTAsU1BFQ0lBTF9OT05FPWorKyxTUEVDSUFMX1NDUklQVD1qKyssU1BFQ0lBTF9TVFlMRT1qKys7ZnVuY3Rpb24gd2hpdGVzcGFjZShjKXtyZXR1cm4gYz09PVwiIFwifHxjPT09XCJcXG5cInx8Yz09PVwiXFx0XCJ8fGM9PT1cIlxcZlwifHxjPT09XCJcXHJcIn1mdW5jdGlvbiBjaGFyYWN0ZXJTdGF0ZShjaGFyLFNVQ0NFU1Mpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09Y2hhcil0aGlzLl9zdGF0ZT1TVUNDRVNTfX1mdW5jdGlvbiBpZkVsc2VTdGF0ZSh1cHBlcixTVUNDRVNTLEZBSUxVUkUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO2lmKHVwcGVyPT09bG93ZXIpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXIpe3RoaXMuX3N0YXRlPVNVQ0NFU1N9ZWxzZXt0aGlzLl9zdGF0ZT1GQUlMVVJFO3RoaXMuX2luZGV4LS19fX1lbHNle3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9U1VDQ0VTU31lbHNle3RoaXMuX3N0YXRlPUZBSUxVUkU7dGhpcy5faW5kZXgtLX19fX1mdW5jdGlvbiBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKHVwcGVyLE5FWFRfU1RBVEUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9TkVYVF9TVEFURX1lbHNle3RoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19fX1mdW5jdGlvbiBUb2tlbml6ZXIob3B0aW9ucyxjYnMpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5fc2VjdGlvblN0YXJ0PTA7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQ9MDt0aGlzLl9iYXNlU3RhdGU9VEVYVDt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfTk9ORTt0aGlzLl9jYnM9Y2JzO3RoaXMuX3J1bm5pbmc9dHJ1ZTt0aGlzLl9lbmRlZD1mYWxzZTt0aGlzLl94bWxNb2RlPSEhKG9wdGlvbnMmJm9wdGlvbnMueG1sTW9kZSk7dGhpcy5fZGVjb2RlRW50aXRpZXM9ISEob3B0aW9ucyYmb3B0aW9ucy5kZWNvZGVFbnRpdGllcyl9VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVUZXh0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjxcIil7aWYodGhpcy5faW5kZXg+dGhpcy5fc2VjdGlvblN0YXJ0KXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSl9dGhpcy5fc3RhdGU9QkVGT1JFX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZ0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9OT05FJiZjPT09XCImXCIpe2lmKHRoaXMuX2luZGV4PnRoaXMuX3NlY3Rpb25TdGFydCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9nZXRTZWN0aW9uKCkpfXRoaXMuX2Jhc2VTdGF0ZT1URVhUO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9QkVGT1JFX0NMT1NJTkdfVEFHX05BTUV9ZWxzZSBpZihjPT09XCI8XCIpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9ZWxzZSBpZihjPT09XCI+XCJ8fHRoaXMuX3NwZWNpYWwhPT1TUEVDSUFMX05PTkV8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZihjPT09XCIhXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9ERUNMQVJBVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIj9cIil7dGhpcy5fc3RhdGU9SU5fUFJPQ0VTU0lOR19JTlNUUlVDVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNle3RoaXMuX3N0YXRlPSF0aGlzLl94bWxNb2RlJiYoYz09PVwic1wifHxjPT09XCJTXCIpP0JFRk9SRV9TUEVDSUFMOklOX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5UYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9lbWl0VG9rZW4oXCJvbm9wZW50YWduYW1lXCIpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWU9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKSk7ZWxzZSBpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZih0aGlzLl9zcGVjaWFsIT09U1BFQ0lBTF9OT05FKXtpZihjPT09XCJzXCJ8fGM9PT1cIlNcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NQRUNJQUxfRU5EfWVsc2V7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9pbmRleC0tfX1lbHNle3RoaXMuX3N0YXRlPUlOX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX2VtaXRUb2tlbihcIm9uY2xvc2V0YWdcIik7dGhpcy5fc3RhdGU9QUZURVJfQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25vcGVudGFnZW5kKCk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9SU5fU0VMRl9DTE9TSU5HX1RBR31lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluU2VsZkNsb3NpbmdUYWc9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25zZWxmY2xvc2luZ3RhZygpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCJ8fGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9jYnMub25hdHRyaWJuYW1lKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc2VjdGlvblN0YXJ0PS0xO3RoaXMuX3N0YXRlPUFGVEVSX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfVkFMVUV9ZWxzZSBpZihjPT09XCIvXCJ8fGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihjKXtpZihjPT09J1wiJyl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX0RRO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYz09PVwiJ1wiKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfVkFMVUVfU1E7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX05RO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleDt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzPWZ1bmN0aW9uKGMpe2lmKGM9PT0nXCInKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FfWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJmM9PT1cIiZcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Jhc2VTdGF0ZT10aGlzLl9zdGF0ZTt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3Rlcz1mdW5jdGlvbihjKXtpZihjPT09XCInXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUV9ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXM9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKXx8Yz09PVwiPlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbj1mdW5jdGlvbihjKXt0aGlzLl9zdGF0ZT1jPT09XCJbXCI/QkVGT1JFX0NEQVRBXzE6Yz09PVwiLVwiP0JFRk9SRV9DT01NRU5UOklOX0RFQ0xBUkFUSU9OfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluRGVjbGFyYXRpb249ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25kZWNsYXJhdGlvbih0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ29tbWVudD1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUlOX0NPTU1FTlQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9ERUNMQVJBVElPTn19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Db21tZW50PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi1cIil0aGlzLl9zdGF0ZT1BRlRFUl9DT01NRU5UXzF9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50MT1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUFGVEVSX0NPTU1FTlRfMn1lbHNle3RoaXMuX3N0YXRlPUlOX0NPTU1FTlR9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDI9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25jb21tZW50KHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4LTIpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYyE9PVwiLVwiKXt0aGlzLl9zdGF0ZT1JTl9DT01NRU5UfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTE9aWZFbHNlU3RhdGUoXCJDXCIsQkVGT1JFX0NEQVRBXzIsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEyPWlmRWxzZVN0YXRlKFwiRFwiLEJFRk9SRV9DREFUQV8zLElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMz1pZkVsc2VTdGF0ZShcIkFcIixCRUZPUkVfQ0RBVEFfNCxJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTQ9aWZFbHNlU3RhdGUoXCJUXCIsQkVGT1JFX0NEQVRBXzUsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE1PWlmRWxzZVN0YXRlKFwiQVwiLEJFRk9SRV9DREFUQV82LElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhNj1mdW5jdGlvbihjKXtpZihjPT09XCJbXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2V7dGhpcy5fc3RhdGU9SU5fREVDTEFSQVRJT047dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DZGF0YT1mdW5jdGlvbihjKXtpZihjPT09XCJdXCIpdGhpcy5fc3RhdGU9QUZURVJfQ0RBVEFfMX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMT1jaGFyYWN0ZXJTdGF0ZShcIl1cIixBRlRFUl9DREFUQV8yKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ2RhdGEyPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uY2RhdGEodGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgtMikpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjIT09XCJdXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsPWZ1bmN0aW9uKGMpe2lmKGM9PT1cImNcInx8Yz09PVwiQ1wiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfU0NSSVBUXzF9ZWxzZSBpZihjPT09XCJ0XCJ8fGM9PT1cIlRcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NUWUxFXzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsRW5kPWZ1bmN0aW9uKGMpe2lmKHRoaXMuX3NwZWNpYWw9PT1TUEVDSUFMX1NDUklQVCYmKGM9PT1cImNcInx8Yz09PVwiQ1wiKSl7dGhpcy5fc3RhdGU9QUZURVJfU0NSSVBUXzF9ZWxzZSBpZih0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9TVFlMRSYmKGM9PT1cInRcInx8Yz09PVwiVFwiKSl7dGhpcy5fc3RhdGU9QUZURVJfU1RZTEVfMX1lbHNlIHRoaXMuX3N0YXRlPVRFWFR9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0MT1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUlwiLEJFRk9SRV9TQ1JJUFRfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQyPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJJXCIsQkVGT1JFX1NDUklQVF8zKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIlBcIixCRUZPUkVfU0NSSVBUXzQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0ND1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiVFwiLEJFRk9SRV9TQ1JJUFRfNSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfU0NSSVBUfXRoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQxPWlmRWxzZVN0YXRlKFwiUlwiLEFGVEVSX1NDUklQVF8yLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQyPWlmRWxzZVN0YXRlKFwiSVwiLEFGVEVSX1NDUklQVF8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQzPWlmRWxzZVN0YXRlKFwiUFwiLEFGVEVSX1NDUklQVF80LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ0PWlmRWxzZVN0YXRlKFwiVFwiLEFGVEVSX1NDUklQVF81LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNjt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTE9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIllcIixCRUZPUkVfU1RZTEVfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTI9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkxcIixCRUZPUkVfU1RZTEVfMyk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkVcIixCRUZPUkVfU1RZTEVfNCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9TVFlMRX10aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUxPWlmRWxzZVN0YXRlKFwiWVwiLEFGVEVSX1NUWUxFXzIsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMj1pZkVsc2VTdGF0ZShcIkxcIixBRlRFUl9TVFlMRV8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTM9aWZFbHNlU3RhdGUoXCJFXCIsQUZURVJfU1RZTEVfNCxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGU0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNTt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVFbnRpdHk9aWZFbHNlU3RhdGUoXCIjXCIsQkVGT1JFX05VTUVSSUNfRU5USVRZLElOX05BTUVEX0VOVElUWSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5PWlmRWxzZVN0YXRlKFwiWFwiLElOX0hFWF9FTlRJVFksSU5fTlVNRVJJQ19FTlRJVFkpO1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3Q9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQrMTx0aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCsxLHRoaXMuX2luZGV4KSxtYXA9dGhpcy5feG1sTW9kZT94bWxNYXA6ZW50aXR5TWFwO2lmKG1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChtYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fX07VG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VMZWdhY3lFbnRpdHk9ZnVuY3Rpb24oKXt2YXIgc3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0KzEsbGltaXQ9dGhpcy5faW5kZXgtc3RhcnQ7aWYobGltaXQ+NilsaW1pdD02O3doaWxlKGxpbWl0Pj0yKXt2YXIgZW50aXR5PXRoaXMuX2J1ZmZlci5zdWJzdHIoc3RhcnQsbGltaXQpO2lmKGxlZ2FjeU1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChsZWdhY3lNYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0Kz1saW1pdCsxO3JldHVybn1lbHNle2xpbWl0LS19fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk5hbWVkRW50aXR5PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjtcIil7dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpO2lmKHRoaXMuX3NlY3Rpb25TdGFydCsxPHRoaXMuX2luZGV4JiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9ZWxzZSBpZigoYzxcImFcInx8Yz5cInpcIikmJihjPFwiQVwifHxjPlwiWlwiKSYmKGM8XCIwXCJ8fGM+XCI5XCIpKXtpZih0aGlzLl94bWxNb2RlKTtlbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydCsxPT09dGhpcy5faW5kZXgpO2Vsc2UgaWYodGhpcy5fYmFzZVN0YXRlIT09VEVYVCl7aWYoYyE9PVwiPVwiKXt0aGlzLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0KCl9fWVsc2V7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2RlY29kZU51bWVyaWNFbnRpdHk9ZnVuY3Rpb24ob2Zmc2V0LGJhc2Upe3ZhciBzZWN0aW9uU3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0K29mZnNldDtpZihzZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHNlY3Rpb25TdGFydCx0aGlzLl9pbmRleCk7dmFyIHBhcnNlZD1wYXJzZUludChlbnRpdHksYmFzZSk7dGhpcy5fZW1pdFBhcnRpYWwoZGVjb2RlQ29kZVBvaW50KHBhcnNlZCkpO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNle3RoaXMuX3NlY3Rpb25TdGFydC0tfXRoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk51bWVyaWNFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsMTApO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoYzxcIjBcInx8Yz5cIjlcIil7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMiwxMCl9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5IZXhFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoKGM8XCJhXCJ8fGM+XCJmXCIpJiYoYzxcIkFcInx8Yz5cIkZcIikmJihjPFwiMFwifHxjPlwiOVwiKSl7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywxNil9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2NsZWFudXA9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8MCl7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4fWVsc2UgaWYodGhpcy5fcnVubmluZyl7aWYodGhpcy5fc3RhdGU9PT1URVhUKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCkpfXRoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5faW5kZXg7dGhpcy5faW5kZXg9MH1lbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydD09PXRoaXMuX2luZGV4KXt0aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4O3RoaXMuX2luZGV4PTB9ZWxzZXt0aGlzLl9idWZmZXI9dGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO3RoaXMuX2luZGV4LT10aGlzLl9zZWN0aW9uU3RhcnQ7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9zZWN0aW9uU3RhcnR9dGhpcy5fc2VjdGlvblN0YXJ0PTB9fTtUb2tlbml6ZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rKXtpZih0aGlzLl9lbmRlZCl0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi53cml0ZSgpIGFmdGVyIGRvbmUhXCIpKTt0aGlzLl9idWZmZXIrPWNodW5rO3RoaXMuX3BhcnNlKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlPWZ1bmN0aW9uKCl7d2hpbGUodGhpcy5faW5kZXg8dGhpcy5fYnVmZmVyLmxlbmd0aCYmdGhpcy5fcnVubmluZyl7dmFyIGM9dGhpcy5fYnVmZmVyLmNoYXJBdCh0aGlzLl9pbmRleCk7aWYodGhpcy5fc3RhdGU9PT1URVhUKXt0aGlzLl9zdGF0ZVRleHQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9UQUdfTkFNRSl7dGhpcy5fc3RhdGVCZWZvcmVUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9UQUdfTkFNRSl7dGhpcy5fc3RhdGVJblRhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DTE9TSU5HX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUJlZm9yZUNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fU0VMRl9DTE9TSU5HX1RBRyl7dGhpcy5fc3RhdGVJblNlbGZDbG9zaW5nVGFnKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9BVFRSSUJVVEVfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9WQUxVRV9EUSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfVkFMVUVfU1Epe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX1ZBTFVFX05RKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVOb1F1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0RFQ0xBUkFUSU9OKXt0aGlzLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9ERUNMQVJBVElPTil7dGhpcy5fc3RhdGVJbkRlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXt0aGlzLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ09NTUVOVCl7dGhpcy5fc3RhdGVCZWZvcmVDb21tZW50KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DT01NRU5UKXt0aGlzLl9zdGF0ZUluQ29tbWVudChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xKXt0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fc3RhdGVBZnRlckNvbW1lbnQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfMSl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV8yKXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzMpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGEzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfNCl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV81KXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzYpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGE2KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DREFUQSl7dGhpcy5fc3RhdGVJbkNkYXRhKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8xKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGExKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8yKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGEyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTCl7dGhpcy5fc3RhdGVCZWZvcmVTcGVjaWFsKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTF9FTkQpe3RoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF8xKXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfMil7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF80KXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfNSl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQ1KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfMSl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF8yKXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfNCl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF81KXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzEpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfMil7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV8zKXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzQpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8xKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8yKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8zKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV80KXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZUVudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX05VTUVSSUNfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZU51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05BTUVEX0VOVElUWSl7dGhpcy5fc3RhdGVJbk5hbWVkRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OVU1FUklDX0VOVElUWSl7dGhpcy5fc3RhdGVJbk51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkpe3RoaXMuX3N0YXRlSW5IZXhFbnRpdHkoYyl9ZWxzZXt0aGlzLl9jYnMub25lcnJvcihFcnJvcihcInVua25vd24gX3N0YXRlXCIpLHRoaXMuX3N0YXRlKX10aGlzLl9pbmRleCsrfXRoaXMuX2NsZWFudXAoKX07VG9rZW5pemVyLnByb3RvdHlwZS5wYXVzZT1mdW5jdGlvbigpe3RoaXMuX3J1bm5pbmc9ZmFsc2V9O1Rva2VuaXplci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fcnVubmluZz10cnVlO2lmKHRoaXMuX2luZGV4PHRoaXMuX2J1ZmZlci5sZW5ndGgpe3RoaXMuX3BhcnNlKCl9aWYodGhpcy5fZW5kZWQpe3RoaXMuX2ZpbmlzaCgpfX07VG9rZW5pemVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe2lmKHRoaXMuX2VuZGVkKXRoaXMuX2Nicy5vbmVycm9yKEVycm9yKFwiLmVuZCgpIGFmdGVyIGRvbmUhXCIpKTtpZihjaHVuayl0aGlzLndyaXRlKGNodW5rKTt0aGlzLl9lbmRlZD10cnVlO2lmKHRoaXMuX3J1bm5pbmcpdGhpcy5fZmluaXNoKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2ZpbmlzaD1mdW5jdGlvbigpe2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9dGhpcy5fY2JzLm9uZW5kKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2hhbmRsZVRyYWlsaW5nRGF0YT1mdW5jdGlvbigpe3ZhciBkYXRhPXRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTtpZih0aGlzLl9zdGF0ZT09PUlOX0NEQVRBfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzF8fHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMil7dGhpcy5fY2JzLm9uY2RhdGEoZGF0YSl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NPTU1FTlR8fHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fY2JzLm9uY29tbWVudChkYXRhKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTkFNRURfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05VTUVSSUNfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLDEwKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfX1lbHNlIGlmKHRoaXMuX3N0YXRlIT09SU5fVEFHX05BTUUmJnRoaXMuX3N0YXRlIT09QkVGT1JFX0FUVFJJQlVURV9OQU1FJiZ0aGlzLl9zdGF0ZSE9PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUmJnRoaXMuX3N0YXRlIT09QUZURVJfQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX1ZBTFVFX1NRJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9WQUxVRV9EUSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfVkFMVUVfTlEmJnRoaXMuX3N0YXRlIT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7XG50aGlzLl9jYnMub250ZXh0KGRhdGEpfX07VG9rZW5pemVyLnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe1Rva2VuaXplci5jYWxsKHRoaXMse3htbE1vZGU6dGhpcy5feG1sTW9kZSxkZWNvZGVFbnRpdGllczp0aGlzLl9kZWNvZGVFbnRpdGllc30sdGhpcy5fY2JzKX07VG9rZW5pemVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZUluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2J1ZmZlck9mZnNldCt0aGlzLl9pbmRleH07VG9rZW5pemVyLnByb3RvdHlwZS5fZ2V0U2VjdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCx0aGlzLl9pbmRleCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRUb2tlbj1mdW5jdGlvbihuYW1lKXt0aGlzLl9jYnNbbmFtZV0odGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9LTF9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRQYXJ0aWFsPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9iYXNlU3RhdGUhPT1URVhUKXt0aGlzLl9jYnMub25hdHRyaWJkYXRhKHZhbHVlKX1lbHNle3RoaXMuX2Nicy5vbnRleHQodmFsdWUpfX19LHtcImVudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzXCI6MjIsXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcImVudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcImVudGl0aWVzL21hcHMveG1sLmpzb25cIjoyN31dLDM1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9QYXJzZXIuanNcIiksV3JpdGFibGVTdHJlYW09cmVxdWlyZShcInN0cmVhbVwiKS5Xcml0YWJsZXx8cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbVwiKS5Xcml0YWJsZSxTdHJpbmdEZWNvZGVyPXJlcXVpcmUoXCJzdHJpbmdfZGVjb2RlclwiKS5TdHJpbmdEZWNvZGVyLEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjtmdW5jdGlvbiBTdHJlYW0oY2JzLG9wdGlvbnMpe3ZhciBwYXJzZXI9dGhpcy5fcGFyc2VyPW5ldyBQYXJzZXIoY2JzLG9wdGlvbnMpO3ZhciBkZWNvZGVyPXRoaXMuX2RlY29kZXI9bmV3IFN0cmluZ0RlY29kZXI7V3JpdGFibGVTdHJlYW0uY2FsbCh0aGlzLHtkZWNvZGVTdHJpbmdzOmZhbHNlfSk7dGhpcy5vbmNlKFwiZmluaXNoXCIsZnVuY3Rpb24oKXtwYXJzZXIuZW5kKGRlY29kZXIuZW5kKCkpfSl9cmVxdWlyZShcImluaGVyaXRzXCIpKFN0cmVhbSxXcml0YWJsZVN0cmVhbSk7V3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7aWYoY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIpY2h1bms9dGhpcy5fZGVjb2Rlci53cml0ZShjaHVuayk7dGhpcy5fcGFyc2VyLndyaXRlKGNodW5rKTtjYigpfX0se1wiLi9QYXJzZXIuanNcIjozMSxidWZmZXI6NSxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbVwiOjMsc3RyZWFtOjU1LHN0cmluZ19kZWNvZGVyOjU2fV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBQYXJzZXI9cmVxdWlyZShcIi4vUGFyc2VyLmpzXCIpLERvbUhhbmRsZXI9cmVxdWlyZShcImRvbWhhbmRsZXJcIik7ZnVuY3Rpb24gZGVmaW5lUHJvcChuYW1lLHZhbHVlKXtkZWxldGUgbW9kdWxlLmV4cG9ydHNbbmFtZV07bW9kdWxlLmV4cG9ydHNbbmFtZV09dmFsdWU7cmV0dXJuIHZhbHVlfW1vZHVsZS5leHBvcnRzPXtQYXJzZXI6UGFyc2VyLFRva2VuaXplcjpyZXF1aXJlKFwiLi9Ub2tlbml6ZXIuanNcIiksRWxlbWVudFR5cGU6cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLERvbUhhbmRsZXI6RG9tSGFuZGxlcixnZXQgRmVlZEhhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkZlZWRIYW5kbGVyXCIscmVxdWlyZShcIi4vRmVlZEhhbmRsZXIuanNcIikpfSxnZXQgU3RyZWFtKCl7cmV0dXJuIGRlZmluZVByb3AoXCJTdHJlYW1cIixyZXF1aXJlKFwiLi9TdHJlYW0uanNcIikpfSxnZXQgV3JpdGFibGVTdHJlYW0oKXtyZXR1cm4gZGVmaW5lUHJvcChcIldyaXRhYmxlU3RyZWFtXCIscmVxdWlyZShcIi4vV3JpdGFibGVTdHJlYW0uanNcIikpfSxnZXQgUHJveHlIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJQcm94eUhhbmRsZXJcIixyZXF1aXJlKFwiLi9Qcm94eUhhbmRsZXIuanNcIikpfSxnZXQgRG9tVXRpbHMoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkRvbVV0aWxzXCIscmVxdWlyZShcImRvbXV0aWxzXCIpKX0sZ2V0IENvbGxlY3RpbmdIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJDb2xsZWN0aW5nSGFuZGxlclwiLHJlcXVpcmUoXCIuL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCIpKX0sRGVmYXVsdEhhbmRsZXI6RG9tSGFuZGxlcixnZXQgUnNzSGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiUnNzSGFuZGxlclwiLHRoaXMuRmVlZEhhbmRsZXIpfSxwYXJzZURPTTpmdW5jdGlvbihkYXRhLG9wdGlvbnMpe3ZhciBoYW5kbGVyPW5ldyBEb21IYW5kbGVyKG9wdGlvbnMpO25ldyBQYXJzZXIoaGFuZGxlcixvcHRpb25zKS5lbmQoZGF0YSk7cmV0dXJuIGhhbmRsZXIuZG9tfSxwYXJzZUZlZWQ6ZnVuY3Rpb24oZmVlZCxvcHRpb25zKXt2YXIgaGFuZGxlcj1uZXcgbW9kdWxlLmV4cG9ydHMuRmVlZEhhbmRsZXIob3B0aW9ucyk7bmV3IFBhcnNlcihoYW5kbGVyLG9wdGlvbnMpLmVuZChmZWVkKTtyZXR1cm4gaGFuZGxlci5kb219LGNyZWF0ZURvbVN0cmVhbTpmdW5jdGlvbihjYixvcHRpb25zLGVsZW1lbnRDYil7dmFyIGhhbmRsZXI9bmV3IERvbUhhbmRsZXIoY2Isb3B0aW9ucyxlbGVtZW50Q2IpO3JldHVybiBuZXcgUGFyc2VyKGhhbmRsZXIsb3B0aW9ucyl9LEVWRU5UUzp7YXR0cmlidXRlOjIsY2RhdGFzdGFydDowLGNkYXRhZW5kOjAsdGV4dDoxLHByb2Nlc3NpbmdpbnN0cnVjdGlvbjoyLGNvbW1lbnQ6MSxjb21tZW50ZW5kOjAsY2xvc2V0YWc6MSxvcGVudGFnOjIsb3BlbnRhZ25hbWU6MSxlcnJvcjoxLGVuZDowfX19LHtcIi4vQ29sbGVjdGluZ0hhbmRsZXIuanNcIjoyOSxcIi4vRmVlZEhhbmRsZXIuanNcIjozMCxcIi4vUGFyc2VyLmpzXCI6MzEsXCIuL1Byb3h5SGFuZGxlci5qc1wiOjMyLFwiLi9TdHJlYW0uanNcIjozMyxcIi4vVG9rZW5pemVyLmpzXCI6MzQsXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCI6MzUsZG9tZWxlbWVudHR5cGU6OSxkb21oYW5kbGVyOjEwLGRvbXV0aWxzOjEzfV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVhZD1mdW5jdGlvbihidWZmZXIsb2Zmc2V0LGlzTEUsbUxlbixuQnl0ZXMpe3ZhciBlLG07dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBuQml0cz0tNzt2YXIgaT1pc0xFP25CeXRlcy0xOjA7dmFyIGQ9aXNMRT8tMToxO3ZhciBzPWJ1ZmZlcltvZmZzZXQraV07aSs9ZDtlPXMmKDE8PC1uQml0cyktMTtzPj49LW5CaXRzO25CaXRzKz1lTGVuO2Zvcig7bkJpdHM+MDtlPWUqMjU2K2J1ZmZlcltvZmZzZXQraV0saSs9ZCxuQml0cy09OCl7fW09ZSYoMTw8LW5CaXRzKS0xO2U+Pj0tbkJpdHM7bkJpdHMrPW1MZW47Zm9yKDtuQml0cz4wO209bSoyNTYrYnVmZmVyW29mZnNldCtpXSxpKz1kLG5CaXRzLT04KXt9aWYoZT09PTApe2U9MS1lQmlhc31lbHNlIGlmKGU9PT1lTWF4KXtyZXR1cm4gbT9OYU46KHM/LTE6MSkqSW5maW5pdHl9ZWxzZXttPW0rTWF0aC5wb3coMixtTGVuKTtlPWUtZUJpYXN9cmV0dXJuKHM/LTE6MSkqbSpNYXRoLnBvdygyLGUtbUxlbil9O2V4cG9ydHMud3JpdGU9ZnVuY3Rpb24oYnVmZmVyLHZhbHVlLG9mZnNldCxpc0xFLG1MZW4sbkJ5dGVzKXt2YXIgZSxtLGM7dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBydD1tTGVuPT09MjM/TWF0aC5wb3coMiwtMjQpLU1hdGgucG93KDIsLTc3KTowO3ZhciBpPWlzTEU/MDpuQnl0ZXMtMTt2YXIgZD1pc0xFPzE6LTE7dmFyIHM9dmFsdWU8MHx8dmFsdWU9PT0wJiYxL3ZhbHVlPDA/MTowO3ZhbHVlPU1hdGguYWJzKHZhbHVlKTtpZihpc05hTih2YWx1ZSl8fHZhbHVlPT09SW5maW5pdHkpe209aXNOYU4odmFsdWUpPzE6MDtlPWVNYXh9ZWxzZXtlPU1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpL01hdGguTE4yKTtpZih2YWx1ZSooYz1NYXRoLnBvdygyLC1lKSk8MSl7ZS0tO2MqPTJ9aWYoZStlQmlhcz49MSl7dmFsdWUrPXJ0L2N9ZWxzZXt2YWx1ZSs9cnQqTWF0aC5wb3coMiwxLWVCaWFzKX1pZih2YWx1ZSpjPj0yKXtlKys7Yy89Mn1pZihlK2VCaWFzPj1lTWF4KXttPTA7ZT1lTWF4fWVsc2UgaWYoZStlQmlhcz49MSl7bT0odmFsdWUqYy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9ZStlQmlhc31lbHNle209dmFsdWUqTWF0aC5wb3coMixlQmlhcy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9MH19Zm9yKDttTGVuPj04O2J1ZmZlcltvZmZzZXQraV09bSYyNTUsaSs9ZCxtLz0yNTYsbUxlbi09OCl7fWU9ZTw8bUxlbnxtO2VMZW4rPW1MZW47Zm9yKDtlTGVuPjA7YnVmZmVyW29mZnNldCtpXT1lJjI1NSxpKz1kLGUvPTI1NixlTGVuLT04KXt9YnVmZmVyW29mZnNldCtpLWRdfD1zKjEyOH19LHt9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7aWYodHlwZW9mIE9iamVjdC5jcmVhdGU9PT1cImZ1bmN0aW9uXCIpe21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uIGluaGVyaXRzKGN0b3Isc3VwZXJDdG9yKXtjdG9yLnN1cGVyXz1zdXBlckN0b3I7Y3Rvci5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6Y3RvcixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9fSl9fWVsc2V7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24gaW5oZXJpdHMoY3RvcixzdXBlckN0b3Ipe2N0b3Iuc3VwZXJfPXN1cGVyQ3Rvcjt2YXIgVGVtcEN0b3I9ZnVuY3Rpb24oKXt9O1RlbXBDdG9yLnByb3RvdHlwZT1zdXBlckN0b3IucHJvdG90eXBlO2N0b3IucHJvdG90eXBlPW5ldyBUZW1wQ3RvcjtjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1jdG9yfX19LHt9XSwzOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24ob2JqKXtyZXR1cm4gb2JqIT1udWxsJiYoaXNCdWZmZXIob2JqKXx8aXNTbG93QnVmZmVyKG9iail8fCEhb2JqLl9pc0J1ZmZlcil9O2Z1bmN0aW9uIGlzQnVmZmVyKG9iail7cmV0dXJuISFvYmouY29uc3RydWN0b3ImJnR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXI9PT1cImZ1bmN0aW9uXCImJm9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopfWZ1bmN0aW9uIGlzU2xvd0J1ZmZlcihvYmope3JldHVybiB0eXBlb2Ygb2JqLnJlYWRGbG9hdExFPT09XCJmdW5jdGlvblwiJiZ0eXBlb2Ygb2JqLnNsaWNlPT09XCJmdW5jdGlvblwiJiZpc0J1ZmZlcihvYmouc2xpY2UoMCwwKSl9fSx7fV0sNDA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciB0b1N0cmluZz17fS50b1N0cmluZzttb2R1bGUuZXhwb3J0cz1BcnJheS5pc0FycmF5fHxmdW5jdGlvbihhcnIpe3JldHVybiB0b1N0cmluZy5jYWxsKGFycik9PVwiW29iamVjdCBBcnJheV1cIn19LHt9XSw0MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe1widXNlIHN0cmljdFwiO2lmKCFwcm9jZXNzLnZlcnNpb258fHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKFwidjAuXCIpPT09MHx8cHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoXCJ2MS5cIik9PT0wJiZwcm9jZXNzLnZlcnNpb24uaW5kZXhPZihcInYxLjguXCIpIT09MCl7bW9kdWxlLmV4cG9ydHM9bmV4dFRpY2t9ZWxzZXttb2R1bGUuZXhwb3J0cz1wcm9jZXNzLm5leHRUaWNrfWZ1bmN0aW9uIG5leHRUaWNrKGZuLGFyZzEsYXJnMixhcmczKXtpZih0eXBlb2YgZm4hPT1cImZ1bmN0aW9uXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKX12YXIgbGVuPWFyZ3VtZW50cy5sZW5ndGg7dmFyIGFyZ3MsaTtzd2l0Y2gobGVuKXtjYXNlIDA6Y2FzZSAxOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtjYXNlIDI6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCl7Zm4uY2FsbChudWxsLGFyZzEpfSk7Y2FzZSAzOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpe2ZuLmNhbGwobnVsbCxhcmcxLGFyZzIpfSk7Y2FzZSA0OnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCl7Zm4uY2FsbChudWxsLGFyZzEsYXJnMixhcmczKX0pO2RlZmF1bHQ6YXJncz1uZXcgQXJyYXkobGVuLTEpO2k9MDt3aGlsZShpPGFyZ3MubGVuZ3RoKXthcmdzW2krK109YXJndW1lbnRzW2ldfXJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpe2ZuLmFwcGx5KG51bGwsYXJncyl9KX19fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtfcHJvY2Vzczo0Mn1dLDQyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgcHJvY2Vzcz1tb2R1bGUuZXhwb3J0cz17fTt2YXIgY2FjaGVkU2V0VGltZW91dDt2YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O2Z1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9KGZ1bmN0aW9uKCl7dHJ5e2lmKHR5cGVvZiBzZXRUaW1lb3V0PT09XCJmdW5jdGlvblwiKXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXR9ZWxzZXtjYWNoZWRTZXRUaW1lb3V0PWRlZmF1bHRTZXRUaW1vdXR9fWNhdGNoKGUpe2NhY2hlZFNldFRpbWVvdXQ9ZGVmYXVsdFNldFRpbW91dH10cnl7aWYodHlwZW9mIGNsZWFyVGltZW91dD09PVwiZnVuY3Rpb25cIil7Y2FjaGVkQ2xlYXJUaW1lb3V0PWNsZWFyVGltZW91dH1lbHNle2NhY2hlZENsZWFyVGltZW91dD1kZWZhdWx0Q2xlYXJUaW1lb3V0fX1jYXRjaChlKXtjYWNoZWRDbGVhclRpbWVvdXQ9ZGVmYXVsdENsZWFyVGltZW91dH19KSgpO2Z1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKXtpZihjYWNoZWRTZXRUaW1lb3V0PT09c2V0VGltZW91dCl7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfWlmKChjYWNoZWRTZXRUaW1lb3V0PT09ZGVmYXVsdFNldFRpbW91dHx8IWNhY2hlZFNldFRpbWVvdXQpJiZzZXRUaW1lb3V0KXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXQ7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfXRyeXtyZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sMCl9Y2F0Y2goZSl7dHJ5e3JldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCxmdW4sMCl9Y2F0Y2goZSl7cmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLGZ1biwwKX19fWZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpe2lmKGNhY2hlZENsZWFyVGltZW91dD09PWNsZWFyVGltZW91dCl7cmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpfWlmKChjYWNoZWRDbGVhclRpbWVvdXQ9PT1kZWZhdWx0Q2xlYXJUaW1lb3V0fHwhY2FjaGVkQ2xlYXJUaW1lb3V0KSYmY2xlYXJUaW1lb3V0KXtjYWNoZWRDbGVhclRpbWVvdXQ9Y2xlYXJUaW1lb3V0O3JldHVybiBjbGVhclRpbWVvdXQobWFya2VyKX10cnl7cmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpfWNhdGNoKGUpe3RyeXtyZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCxtYXJrZXIpfWNhdGNoKGUpe3JldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLG1hcmtlcil9fX12YXIgcXVldWU9W107dmFyIGRyYWluaW5nPWZhbHNlO3ZhciBjdXJyZW50UXVldWU7dmFyIHF1ZXVlSW5kZXg9LTE7ZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCl7aWYoIWRyYWluaW5nfHwhY3VycmVudFF1ZXVlKXtyZXR1cm59ZHJhaW5pbmc9ZmFsc2U7aWYoY3VycmVudFF1ZXVlLmxlbmd0aCl7cXVldWU9Y3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSl9ZWxzZXtxdWV1ZUluZGV4PS0xfWlmKHF1ZXVlLmxlbmd0aCl7ZHJhaW5RdWV1ZSgpfX1mdW5jdGlvbiBkcmFpblF1ZXVlKCl7aWYoZHJhaW5pbmcpe3JldHVybn12YXIgdGltZW91dD1ydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7ZHJhaW5pbmc9dHJ1ZTt2YXIgbGVuPXF1ZXVlLmxlbmd0aDt3aGlsZShsZW4pe2N1cnJlbnRRdWV1ZT1xdWV1ZTtxdWV1ZT1bXTt3aGlsZSgrK3F1ZXVlSW5kZXg8bGVuKXtpZihjdXJyZW50UXVldWUpe2N1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKX19cXVldWVJbmRleD0tMTtsZW49cXVldWUubGVuZ3RofWN1cnJlbnRRdWV1ZT1udWxsO2RyYWluaW5nPWZhbHNlO3J1bkNsZWFyVGltZW91dCh0aW1lb3V0KX1wcm9jZXNzLm5leHRUaWNrPWZ1bmN0aW9uKGZ1bil7dmFyIGFyZ3M9bmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgtMSk7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IodmFyIGk9MTtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXthcmdzW2ktMV09YXJndW1lbnRzW2ldfX1xdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1bixhcmdzKSk7aWYocXVldWUubGVuZ3RoPT09MSYmIWRyYWluaW5nKXtydW5UaW1lb3V0KGRyYWluUXVldWUpfX07ZnVuY3Rpb24gSXRlbShmdW4sYXJyYXkpe3RoaXMuZnVuPWZ1bjt0aGlzLmFycmF5PWFycmF5fUl0ZW0ucHJvdG90eXBlLnJ1bj1mdW5jdGlvbigpe3RoaXMuZnVuLmFwcGx5KG51bGwsdGhpcy5hcnJheSl9O3Byb2Nlc3MudGl0bGU9XCJicm93c2VyXCI7cHJvY2Vzcy5icm93c2VyPXRydWU7cHJvY2Vzcy5lbnY9e307cHJvY2Vzcy5hcmd2PVtdO3Byb2Nlc3MudmVyc2lvbj1cIlwiO3Byb2Nlc3MudmVyc2lvbnM9e307ZnVuY3Rpb24gbm9vcCgpe31wcm9jZXNzLm9uPW5vb3A7cHJvY2Vzcy5hZGRMaXN0ZW5lcj1ub29wO3Byb2Nlc3Mub25jZT1ub29wO3Byb2Nlc3Mub2ZmPW5vb3A7cHJvY2Vzcy5yZW1vdmVMaXN0ZW5lcj1ub29wO3Byb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzPW5vb3A7cHJvY2Vzcy5lbWl0PW5vb3A7cHJvY2Vzcy5iaW5kaW5nPWZ1bmN0aW9uKG5hbWUpe3Rocm93IG5ldyBFcnJvcihcInByb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLmN3ZD1mdW5jdGlvbigpe3JldHVyblwiL1wifTtwcm9jZXNzLmNoZGlyPWZ1bmN0aW9uKGRpcil7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLnVtYXNrPWZ1bmN0aW9uKCl7cmV0dXJuIDB9fSx7fV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NH1dLDQ0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgb2JqZWN0S2V5cz1PYmplY3Qua2V5c3x8ZnVuY3Rpb24ob2JqKXt2YXIga2V5cz1bXTtmb3IodmFyIGtleSBpbiBvYmope2tleXMucHVzaChrZXkpfXJldHVybiBrZXlzfTttb2R1bGUuZXhwb3J0cz1EdXBsZXg7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt2YXIgUmVhZGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV9yZWFkYWJsZVwiKTt2YXIgV3JpdGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV93cml0YWJsZVwiKTt1dGlsLmluaGVyaXRzKER1cGxleCxSZWFkYWJsZSk7dmFyIGtleXM9b2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO2Zvcih2YXIgdj0wO3Y8a2V5cy5sZW5ndGg7disrKXt2YXIgbWV0aG9kPWtleXNbdl07aWYoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSlEdXBsZXgucHJvdG90eXBlW21ldGhvZF09V3JpdGFibGUucHJvdG90eXBlW21ldGhvZF19ZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBEdXBsZXgob3B0aW9ucyk7UmVhZGFibGUuY2FsbCh0aGlzLG9wdGlvbnMpO1dyaXRhYmxlLmNhbGwodGhpcyxvcHRpb25zKTtpZihvcHRpb25zJiZvcHRpb25zLnJlYWRhYmxlPT09ZmFsc2UpdGhpcy5yZWFkYWJsZT1mYWxzZTtpZihvcHRpb25zJiZvcHRpb25zLndyaXRhYmxlPT09ZmFsc2UpdGhpcy53cml0YWJsZT1mYWxzZTt0aGlzLmFsbG93SGFsZk9wZW49dHJ1ZTtpZihvcHRpb25zJiZvcHRpb25zLmFsbG93SGFsZk9wZW49PT1mYWxzZSl0aGlzLmFsbG93SGFsZk9wZW49ZmFsc2U7dGhpcy5vbmNlKFwiZW5kXCIsb25lbmQpfWZ1bmN0aW9uIG9uZW5kKCl7aWYodGhpcy5hbGxvd0hhbGZPcGVufHx0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKXJldHVybjtwcm9jZXNzTmV4dFRpY2sob25FbmROVCx0aGlzKX1mdW5jdGlvbiBvbkVuZE5UKHNlbGYpe3NlbGYuZW5kKCl9ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX19LHtcIi4vX3N0cmVhbV9yZWFkYWJsZVwiOjQ2LFwiLi9fc3RyZWFtX3dyaXRhYmxlXCI6NDgsXCJjb3JlLXV0aWwtaXNcIjo2LGluaGVyaXRzOjM4LFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MX1dLDQ1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1QYXNzVGhyb3VnaDt2YXIgVHJhbnNmb3JtPXJlcXVpcmUoXCIuL19zdHJlYW1fdHJhbnNmb3JtXCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCxUcmFuc2Zvcm0pO2Z1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlyZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1RyYW5zZm9ybS5jYWxsKHRoaXMsb3B0aW9ucyl9UGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm09ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe2NiKG51bGwsY2h1bmspfX0se1wiLi9fc3RyZWFtX3RyYW5zZm9ybVwiOjQ3LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9UmVhZGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGlzQXJyYXk9cmVxdWlyZShcImlzYXJyYXlcIik7UmVhZGFibGUuUmVhZGFibGVTdGF0ZT1SZWFkYWJsZVN0YXRlO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgRUVsaXN0ZW5lckNvdW50PWZ1bmN0aW9uKGVtaXR0ZXIsdHlwZSl7cmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aH07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3ZhciBkZWJ1Z1V0aWw9cmVxdWlyZShcInV0aWxcIik7dmFyIGRlYnVnPXZvaWQgMDtpZihkZWJ1Z1V0aWwmJmRlYnVnVXRpbC5kZWJ1Z2xvZyl7ZGVidWc9ZGVidWdVdGlsLmRlYnVnbG9nKFwic3RyZWFtXCIpfWVsc2V7ZGVidWc9ZnVuY3Rpb24oKXt9fXZhciBCdWZmZXJMaXN0PXJlcXVpcmUoXCIuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdFwiKTt2YXIgU3RyaW5nRGVjb2Rlcjt1dGlsLmluaGVyaXRzKFJlYWRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKGVtaXR0ZXIsZXZlbnQsZm4pe2lmKHR5cGVvZiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcj09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LGZuKX1lbHNle2lmKCFlbWl0dGVyLl9ldmVudHN8fCFlbWl0dGVyLl9ldmVudHNbZXZlbnRdKWVtaXR0ZXIub24oZXZlbnQsZm4pO2Vsc2UgaWYoaXNBcnJheShlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSllbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XT1bZm4sZW1pdHRlci5fZXZlbnRzW2V2ZW50XV19fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLHN0cmVhbSl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7b3B0aW9ucz1vcHRpb25zfHx7fTt0aGlzLm9iamVjdE1vZGU9ISFvcHRpb25zLm9iamVjdE1vZGU7aWYoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KXRoaXMub2JqZWN0TW9kZT10aGlzLm9iamVjdE1vZGV8fCEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7dmFyIGh3bT1vcHRpb25zLmhpZ2hXYXRlck1hcms7dmFyIGRlZmF1bHRId209dGhpcy5vYmplY3RNb2RlPzE2OjE2KjEwMjQ7dGhpcy5oaWdoV2F0ZXJNYXJrPWh3bXx8aHdtPT09MD9od206ZGVmYXVsdEh3bTt0aGlzLmhpZ2hXYXRlck1hcms9fn50aGlzLmhpZ2hXYXRlck1hcms7dGhpcy5idWZmZXI9bmV3IEJ1ZmZlckxpc3Q7dGhpcy5sZW5ndGg9MDt0aGlzLnBpcGVzPW51bGw7dGhpcy5waXBlc0NvdW50PTA7dGhpcy5mbG93aW5nPW51bGw7dGhpcy5lbmRlZD1mYWxzZTt0aGlzLmVuZEVtaXR0ZWQ9ZmFsc2U7dGhpcy5yZWFkaW5nPWZhbHNlO3RoaXMuc3luYz10cnVlO3RoaXMubmVlZFJlYWRhYmxlPWZhbHNlO3RoaXMuZW1pdHRlZFJlYWRhYmxlPWZhbHNlO3RoaXMucmVhZGFibGVMaXN0ZW5pbmc9ZmFsc2U7dGhpcy5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7dGhpcy5kZWZhdWx0RW5jb2Rpbmc9b3B0aW9ucy5kZWZhdWx0RW5jb2Rpbmd8fFwidXRmOFwiO3RoaXMucmFuT3V0PWZhbHNlO3RoaXMuYXdhaXREcmFpbj0wO3RoaXMucmVhZGluZ01vcmU9ZmFsc2U7dGhpcy5kZWNvZGVyPW51bGw7dGhpcy5lbmNvZGluZz1udWxsO2lmKG9wdGlvbnMuZW5jb2Rpbmcpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTt0aGlzLmVuY29kaW5nPW9wdGlvbnMuZW5jb2Rpbmd9fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucyl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7aWYoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKXJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7dGhpcy5fcmVhZGFibGVTdGF0ZT1uZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLHRoaXMpO3RoaXMucmVhZGFibGU9dHJ1ZTtpZihvcHRpb25zJiZ0eXBlb2Ygb3B0aW9ucy5yZWFkPT09XCJmdW5jdGlvblwiKXRoaXMuX3JlYWQ9b3B0aW9ucy5yZWFkO1N0cmVhbS5jYWxsKHRoaXMpfVJlYWRhYmxlLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZighc3RhdGUub2JqZWN0TW9kZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5jb2Rpbmd8fHN0YXRlLmRlZmF1bHRFbmNvZGluZztpZihlbmNvZGluZyE9PXN0YXRlLmVuY29kaW5nKXtjaHVuaz1idWZmZXJTaGltLmZyb20oY2h1bmssZW5jb2RpbmcpO2VuY29kaW5nPVwiXCJ9fXJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsc3RhdGUsY2h1bmssZW5jb2RpbmcsZmFsc2UpfTtSZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbihjaHVuayl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7cmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxcIlwiLHRydWUpfTtSZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPT09ZmFsc2V9O2Z1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLHN0YXRlLGNodW5rLGVuY29kaW5nLGFkZFRvRnJvbnQpe3ZhciBlcj1jaHVua0ludmFsaWQoc3RhdGUsY2h1bmspO2lmKGVyKXtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpfWVsc2UgaWYoY2h1bms9PT1udWxsKXtzdGF0ZS5yZWFkaW5nPWZhbHNlO29uRW9mQ2h1bmsoc3RyZWFtLHN0YXRlKX1lbHNlIGlmKHN0YXRlLm9iamVjdE1vZGV8fGNodW5rJiZjaHVuay5sZW5ndGg+MCl7aWYoc3RhdGUuZW5kZWQmJiFhZGRUb0Zyb250KXt2YXIgZT1uZXcgRXJyb3IoXCJzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRlwiKTtzdHJlYW0uZW1pdChcImVycm9yXCIsZSl9ZWxzZSBpZihzdGF0ZS5lbmRFbWl0dGVkJiZhZGRUb0Zyb250KXt2YXIgX2U9bmV3IEVycm9yKFwic3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnRcIik7c3RyZWFtLmVtaXQoXCJlcnJvclwiLF9lKX1lbHNle3ZhciBza2lwQWRkO2lmKHN0YXRlLmRlY29kZXImJiFhZGRUb0Zyb250JiYhZW5jb2Rpbmcpe2NodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO3NraXBBZGQ9IXN0YXRlLm9iamVjdE1vZGUmJmNodW5rLmxlbmd0aD09PTB9aWYoIWFkZFRvRnJvbnQpc3RhdGUucmVhZGluZz1mYWxzZTtpZighc2tpcEFkZCl7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoPT09MCYmIXN0YXRlLnN5bmMpe3N0cmVhbS5lbWl0KFwiZGF0YVwiLGNodW5rKTtzdHJlYW0ucmVhZCgwKX1lbHNle3N0YXRlLmxlbmd0aCs9c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aDtpZihhZGRUb0Zyb250KXN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtpZihzdGF0ZS5uZWVkUmVhZGFibGUpZW1pdFJlYWRhYmxlKHN0cmVhbSl9fW1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKX19ZWxzZSBpZighYWRkVG9Gcm9udCl7c3RhdGUucmVhZGluZz1mYWxzZX1yZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKX1mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpe3JldHVybiFzdGF0ZS5lbmRlZCYmKHN0YXRlLm5lZWRSZWFkYWJsZXx8c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcmt8fHN0YXRlLmxlbmd0aD09PTApfVJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZz1mdW5jdGlvbihlbmMpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihlbmMpO3RoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2Rpbmc9ZW5jO3JldHVybiB0aGlzfTt2YXIgTUFYX0hXTT04Mzg4NjA4O2Z1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pe2lmKG4+PU1BWF9IV00pe249TUFYX0hXTX1lbHNle24tLTtufD1uPj4+MTtufD1uPj4+MjtufD1uPj4+NDtufD1uPj4+ODtufD1uPj4+MTY7bisrfXJldHVybiBufWZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobixzdGF0ZSl7aWYobjw9MHx8c3RhdGUubGVuZ3RoPT09MCYmc3RhdGUuZW5kZWQpcmV0dXJuIDA7aWYoc3RhdGUub2JqZWN0TW9kZSlyZXR1cm4gMTtpZihuIT09bil7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoKXJldHVybiBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGh9aWYobj5zdGF0ZS5oaWdoV2F0ZXJNYXJrKXN0YXRlLmhpZ2hXYXRlck1hcms9Y29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7aWYobjw9c3RhdGUubGVuZ3RoKXJldHVybiBuO2lmKCFzdGF0ZS5lbmRlZCl7c3RhdGUubmVlZFJlYWRhYmxlPXRydWU7cmV0dXJuIDB9cmV0dXJuIHN0YXRlLmxlbmd0aH1SZWFkYWJsZS5wcm90b3R5cGUucmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcInJlYWRcIixuKTtuPXBhcnNlSW50KG4sMTApO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBuT3JpZz1uO2lmKG4hPT0wKXN0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZihuPT09MCYmc3RhdGUubmVlZFJlYWRhYmxlJiYoc3RhdGUubGVuZ3RoPj1zdGF0ZS5oaWdoV2F0ZXJNYXJrfHxzdGF0ZS5lbmRlZCkpe2RlYnVnKFwicmVhZDogZW1pdFJlYWRhYmxlXCIsc3RhdGUubGVuZ3RoLHN0YXRlLmVuZGVkKTtpZihzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtyZXR1cm4gbnVsbH1uPWhvd011Y2hUb1JlYWQobixzdGF0ZSk7aWYobj09PTAmJnN0YXRlLmVuZGVkKXtpZihzdGF0ZS5sZW5ndGg9PT0wKWVuZFJlYWRhYmxlKHRoaXMpO3JldHVybiBudWxsfXZhciBkb1JlYWQ9c3RhdGUubmVlZFJlYWRhYmxlO2RlYnVnKFwibmVlZCByZWFkYWJsZVwiLGRvUmVhZCk7aWYoc3RhdGUubGVuZ3RoPT09MHx8c3RhdGUubGVuZ3RoLW48c3RhdGUuaGlnaFdhdGVyTWFyayl7ZG9SZWFkPXRydWU7ZGVidWcoXCJsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFya1wiLGRvUmVhZCl9aWYoc3RhdGUuZW5kZWR8fHN0YXRlLnJlYWRpbmcpe2RvUmVhZD1mYWxzZTtkZWJ1ZyhcInJlYWRpbmcgb3IgZW5kZWRcIixkb1JlYWQpfWVsc2UgaWYoZG9SZWFkKXtkZWJ1ZyhcImRvIHJlYWRcIik7c3RhdGUucmVhZGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZihzdGF0ZS5sZW5ndGg9PT0wKXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3RoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7c3RhdGUuc3luYz1mYWxzZTtpZighc3RhdGUucmVhZGluZyluPWhvd011Y2hUb1JlYWQobk9yaWcsc3RhdGUpfXZhciByZXQ7aWYobj4wKXJldD1mcm9tTGlzdChuLHN0YXRlKTtlbHNlIHJldD1udWxsO2lmKHJldD09PW51bGwpe3N0YXRlLm5lZWRSZWFkYWJsZT10cnVlO249MH1lbHNle3N0YXRlLmxlbmd0aC09bn1pZihzdGF0ZS5sZW5ndGg9PT0wKXtpZighc3RhdGUuZW5kZWQpc3RhdGUubmVlZFJlYWRhYmxlPXRydWU7aWYobk9yaWchPT1uJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKX1pZihyZXQhPT1udWxsKXRoaXMuZW1pdChcImRhdGFcIixyZXQpO3JldHVybiByZXR9O2Z1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSxjaHVuayl7dmFyIGVyPW51bGw7aWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09bnVsbCYmY2h1bmshPT11bmRlZmluZWQmJiFzdGF0ZS5vYmplY3RNb2RlKXtlcj1uZXcgVHlwZUVycm9yKFwiSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVua1wiKX1yZXR1cm4gZXJ9ZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sc3RhdGUpe2lmKHN0YXRlLmVuZGVkKXJldHVybjtpZihzdGF0ZS5kZWNvZGVyKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXtzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7c3RhdGUubGVuZ3RoKz1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RofX1zdGF0ZS5lbmRlZD10cnVlO2VtaXRSZWFkYWJsZShzdHJlYW0pfWZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7c3RhdGUubmVlZFJlYWRhYmxlPWZhbHNlO2lmKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpe2RlYnVnKFwiZW1pdFJlYWRhYmxlXCIsc3RhdGUuZmxvd2luZyk7c3RhdGUuZW1pdHRlZFJlYWRhYmxlPXRydWU7aWYoc3RhdGUuc3luYylwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXyxzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pfX1mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSl7ZGVidWcoXCJlbWl0IHJlYWRhYmxlXCIpO3N0cmVhbS5lbWl0KFwicmVhZGFibGVcIik7ZmxvdyhzdHJlYW0pfWZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVhZGluZ01vcmUpe3N0YXRlLnJlYWRpbmdNb3JlPXRydWU7cHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLHN0cmVhbSxzdGF0ZSl9fWZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSxzdGF0ZSl7dmFyIGxlbj1zdGF0ZS5sZW5ndGg7d2hpbGUoIXN0YXRlLnJlYWRpbmcmJiFzdGF0ZS5mbG93aW5nJiYhc3RhdGUuZW5kZWQmJnN0YXRlLmxlbmd0aDxzdGF0ZS5oaWdoV2F0ZXJNYXJrKXtkZWJ1ZyhcIm1heWJlUmVhZE1vcmUgcmVhZCAwXCIpO3N0cmVhbS5yZWFkKDApO2lmKGxlbj09PXN0YXRlLmxlbmd0aClicmVhaztlbHNlIGxlbj1zdGF0ZS5sZW5ndGh9c3RhdGUucmVhZGluZ01vcmU9ZmFsc2V9UmVhZGFibGUucHJvdG90eXBlLl9yZWFkPWZ1bmN0aW9uKG4pe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07UmVhZGFibGUucHJvdG90eXBlLnBpcGU9ZnVuY3Rpb24oZGVzdCxwaXBlT3B0cyl7dmFyIHNyYz10aGlzO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3N3aXRjaChzdGF0ZS5waXBlc0NvdW50KXtjYXNlIDA6c3RhdGUucGlwZXM9ZGVzdDticmVhaztjYXNlIDE6c3RhdGUucGlwZXM9W3N0YXRlLnBpcGVzLGRlc3RdO2JyZWFrO2RlZmF1bHQ6c3RhdGUucGlwZXMucHVzaChkZXN0KTticmVha31zdGF0ZS5waXBlc0NvdW50Kz0xO2RlYnVnKFwicGlwZSBjb3VudD0lZCBvcHRzPSVqXCIsc3RhdGUucGlwZXNDb3VudCxwaXBlT3B0cyk7dmFyIGRvRW5kPSghcGlwZU9wdHN8fHBpcGVPcHRzLmVuZCE9PWZhbHNlKSYmZGVzdCE9PXByb2Nlc3Muc3Rkb3V0JiZkZXN0IT09cHJvY2Vzcy5zdGRlcnI7dmFyIGVuZEZuPWRvRW5kP29uZW5kOmNsZWFudXA7aWYoc3RhdGUuZW5kRW1pdHRlZClwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoXCJlbmRcIixlbmRGbik7ZGVzdC5vbihcInVucGlwZVwiLG9udW5waXBlKTtmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSl7ZGVidWcoXCJvbnVucGlwZVwiKTtpZihyZWFkYWJsZT09PXNyYyl7Y2xlYW51cCgpfX1mdW5jdGlvbiBvbmVuZCgpe2RlYnVnKFwib25lbmRcIik7ZGVzdC5lbmQoKX12YXIgb25kcmFpbj1waXBlT25EcmFpbihzcmMpO2Rlc3Qub24oXCJkcmFpblwiLG9uZHJhaW4pO3ZhciBjbGVhbmVkVXA9ZmFsc2U7ZnVuY3Rpb24gY2xlYW51cCgpe2RlYnVnKFwiY2xlYW51cFwiKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixvbmNsb3NlKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJ1bnBpcGVcIixvbnVucGlwZSk7c3JjLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsb25lbmQpO3NyYy5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLGNsZWFudXApO3NyYy5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2NsZWFuZWRVcD10cnVlO2lmKHN0YXRlLmF3YWl0RHJhaW4mJighZGVzdC5fd3JpdGFibGVTdGF0ZXx8ZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKW9uZHJhaW4oKX12YXIgaW5jcmVhc2VkQXdhaXREcmFpbj1mYWxzZTtzcmMub24oXCJkYXRhXCIsb25kYXRhKTtmdW5jdGlvbiBvbmRhdGEoY2h1bmspe2RlYnVnKFwib25kYXRhXCIpO2luY3JlYXNlZEF3YWl0RHJhaW49ZmFsc2U7dmFyIHJldD1kZXN0LndyaXRlKGNodW5rKTtpZihmYWxzZT09PXJldCYmIWluY3JlYXNlZEF3YWl0RHJhaW4pe2lmKChzdGF0ZS5waXBlc0NvdW50PT09MSYmc3RhdGUucGlwZXM9PT1kZXN0fHxzdGF0ZS5waXBlc0NvdW50PjEmJmluZGV4T2Yoc3RhdGUucGlwZXMsZGVzdCkhPT0tMSkmJiFjbGVhbmVkVXApe2RlYnVnKFwiZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlXCIsc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO3NyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7aW5jcmVhc2VkQXdhaXREcmFpbj10cnVlfXNyYy5wYXVzZSgpfX1mdW5jdGlvbiBvbmVycm9yKGVyKXtkZWJ1ZyhcIm9uZXJyb3JcIixlcik7dW5waXBlKCk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7aWYoRUVsaXN0ZW5lckNvdW50KGRlc3QsXCJlcnJvclwiKT09PTApZGVzdC5lbWl0KFwiZXJyb3JcIixlcil9cHJlcGVuZExpc3RlbmVyKGRlc3QsXCJlcnJvclwiLG9uZXJyb3IpO2Z1bmN0aW9uIG9uY2xvc2UoKXtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO3VucGlwZSgpfWRlc3Qub25jZShcImNsb3NlXCIsb25jbG9zZSk7ZnVuY3Rpb24gb25maW5pc2goKXtkZWJ1ZyhcIm9uZmluaXNoXCIpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3VucGlwZSgpfWRlc3Qub25jZShcImZpbmlzaFwiLG9uZmluaXNoKTtmdW5jdGlvbiB1bnBpcGUoKXtkZWJ1ZyhcInVucGlwZVwiKTtzcmMudW5waXBlKGRlc3QpfWRlc3QuZW1pdChcInBpcGVcIixzcmMpO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInBpcGUgcmVzdW1lXCIpO3NyYy5yZXN1bWUoKX1yZXR1cm4gZGVzdH07ZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgc3RhdGU9c3JjLl9yZWFkYWJsZVN0YXRlO2RlYnVnKFwicGlwZU9uRHJhaW5cIixzdGF0ZS5hd2FpdERyYWluKTtpZihzdGF0ZS5hd2FpdERyYWluKXN0YXRlLmF3YWl0RHJhaW4tLTtpZihzdGF0ZS5hd2FpdERyYWluPT09MCYmRUVsaXN0ZW5lckNvdW50KHNyYyxcImRhdGFcIikpe3N0YXRlLmZsb3dpbmc9dHJ1ZTtmbG93KHNyYyl9fX1SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlPWZ1bmN0aW9uKGRlc3Qpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0wKXJldHVybiB0aGlzO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0xKXtpZihkZXN0JiZkZXN0IT09c3RhdGUucGlwZXMpcmV0dXJuIHRoaXM7aWYoIWRlc3QpZGVzdD1zdGF0ZS5waXBlcztzdGF0ZS5waXBlcz1udWxsO3N0YXRlLnBpcGVzQ291bnQ9MDtzdGF0ZS5mbG93aW5nPWZhbHNlO2lmKGRlc3QpZGVzdC5lbWl0KFwidW5waXBlXCIsdGhpcyk7cmV0dXJuIHRoaXN9aWYoIWRlc3Qpe3ZhciBkZXN0cz1zdGF0ZS5waXBlczt2YXIgbGVuPXN0YXRlLnBpcGVzQ291bnQ7c3RhdGUucGlwZXM9bnVsbDtzdGF0ZS5waXBlc0NvdW50PTA7c3RhdGUuZmxvd2luZz1mYWxzZTtmb3IodmFyIF9pPTA7X2k8bGVuO19pKyspe2Rlc3RzW19pXS5lbWl0KFwidW5waXBlXCIsdGhpcyl9cmV0dXJuIHRoaXN9dmFyIGk9aW5kZXhPZihzdGF0ZS5waXBlcyxkZXN0KTtpZihpPT09LTEpcmV0dXJuIHRoaXM7c3RhdGUucGlwZXMuc3BsaWNlKGksMSk7c3RhdGUucGlwZXNDb3VudC09MTtpZihzdGF0ZS5waXBlc0NvdW50PT09MSlzdGF0ZS5waXBlcz1zdGF0ZS5waXBlc1swXTtkZXN0LmVtaXQoXCJ1bnBpcGVcIix0aGlzKTtyZXR1cm4gdGhpc307UmVhZGFibGUucHJvdG90eXBlLm9uPWZ1bmN0aW9uKGV2LGZuKXt2YXIgcmVzPVN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLGV2LGZuKTtpZihldj09PVwiZGF0YVwiKXtpZih0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmchPT1mYWxzZSl0aGlzLnJlc3VtZSgpfWVsc2UgaWYoZXY9PT1cInJlYWRhYmxlXCIpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5lbmRFbWl0dGVkJiYhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpe3N0YXRlLnJlYWRhYmxlTGlzdGVuaW5nPXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3N0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZighc3RhdGUucmVhZGluZyl7cHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssdGhpcyl9ZWxzZSBpZihzdGF0ZS5sZW5ndGgpe2VtaXRSZWFkYWJsZSh0aGlzLHN0YXRlKX19fXJldHVybiByZXN9O1JlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lcj1SZWFkYWJsZS5wcm90b3R5cGUub247ZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKXtkZWJ1ZyhcInJlYWRhYmxlIG5leHR0aWNrIHJlYWQgMFwiKTtzZWxmLnJlYWQoMCl9UmVhZGFibGUucHJvdG90eXBlLnJlc3VtZT1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInJlc3VtZVwiKTtzdGF0ZS5mbG93aW5nPXRydWU7cmVzdW1lKHRoaXMsc3RhdGUpfXJldHVybiB0aGlzfTtmdW5jdGlvbiByZXN1bWUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVzdW1lU2NoZWR1bGVkKXtzdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9dHJ1ZTtwcm9jZXNzTmV4dFRpY2socmVzdW1lXyxzdHJlYW0sc3RhdGUpfX1mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnJlYWRpbmcpe2RlYnVnKFwicmVzdW1lIHJlYWQgMFwiKTtzdHJlYW0ucmVhZCgwKX1zdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7c3RhdGUuYXdhaXREcmFpbj0wO3N0cmVhbS5lbWl0KFwicmVzdW1lXCIpO2Zsb3coc3RyZWFtKTtpZihzdGF0ZS5mbG93aW5nJiYhc3RhdGUucmVhZGluZylzdHJlYW0ucmVhZCgwKX1SZWFkYWJsZS5wcm90b3R5cGUucGF1c2U9ZnVuY3Rpb24oKXtkZWJ1ZyhcImNhbGwgcGF1c2UgZmxvd2luZz0lalwiLHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7aWYoZmFsc2UhPT10aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpe2RlYnVnKFwicGF1c2VcIik7dGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPWZhbHNlO3RoaXMuZW1pdChcInBhdXNlXCIpfXJldHVybiB0aGlzfTtmdW5jdGlvbiBmbG93KHN0cmVhbSl7dmFyIHN0YXRlPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtkZWJ1ZyhcImZsb3dcIixzdGF0ZS5mbG93aW5nKTt3aGlsZShzdGF0ZS5mbG93aW5nJiZzdHJlYW0ucmVhZCgpIT09bnVsbCl7fX1SZWFkYWJsZS5wcm90b3R5cGUud3JhcD1mdW5jdGlvbihzdHJlYW0pe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBwYXVzZWQ9ZmFsc2U7dmFyIHNlbGY9dGhpcztzdHJlYW0ub24oXCJlbmRcIixmdW5jdGlvbigpe2RlYnVnKFwid3JhcHBlZCBlbmRcIik7aWYoc3RhdGUuZGVjb2RlciYmIXN0YXRlLmVuZGVkKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXNlbGYucHVzaChjaHVuayl9c2VsZi5wdXNoKG51bGwpfSk7c3RyZWFtLm9uKFwiZGF0YVwiLGZ1bmN0aW9uKGNodW5rKXtkZWJ1ZyhcIndyYXBwZWQgZGF0YVwiKTtpZihzdGF0ZS5kZWNvZGVyKWNodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO2lmKHN0YXRlLm9iamVjdE1vZGUmJihjaHVuaz09PW51bGx8fGNodW5rPT09dW5kZWZpbmVkKSlyZXR1cm47ZWxzZSBpZighc3RhdGUub2JqZWN0TW9kZSYmKCFjaHVua3x8IWNodW5rLmxlbmd0aCkpcmV0dXJuO3ZhciByZXQ9c2VsZi5wdXNoKGNodW5rKTtpZighcmV0KXtwYXVzZWQ9dHJ1ZTtzdHJlYW0ucGF1c2UoKX19KTtmb3IodmFyIGkgaW4gc3RyZWFtKXtpZih0aGlzW2ldPT09dW5kZWZpbmVkJiZ0eXBlb2Ygc3RyZWFtW2ldPT09XCJmdW5jdGlvblwiKXt0aGlzW2ldPWZ1bmN0aW9uKG1ldGhvZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSxhcmd1bWVudHMpfX0oaSl9fXZhciBldmVudHM9W1wiZXJyb3JcIixcImNsb3NlXCIsXCJkZXN0cm95XCIsXCJwYXVzZVwiLFwicmVzdW1lXCJdO2ZvckVhY2goZXZlbnRzLGZ1bmN0aW9uKGV2KXtzdHJlYW0ub24oZXYsc2VsZi5lbWl0LmJpbmQoc2VsZixldikpfSk7c2VsZi5fcmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcIndyYXBwZWQgX3JlYWRcIixuKTtpZihwYXVzZWQpe3BhdXNlZD1mYWxzZTtzdHJlYW0ucmVzdW1lKCl9fTtyZXR1cm4gc2VsZn07UmVhZGFibGUuX2Zyb21MaXN0PWZyb21MaXN0O2Z1bmN0aW9uIGZyb21MaXN0KG4sc3RhdGUpe2lmKHN0YXRlLmxlbmd0aD09PTApcmV0dXJuIG51bGw7dmFyIHJldDtpZihzdGF0ZS5vYmplY3RNb2RlKXJldD1zdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmKCFufHxuPj1zdGF0ZS5sZW5ndGgpe2lmKHN0YXRlLmRlY29kZXIpcmV0PXN0YXRlLmJ1ZmZlci5qb2luKFwiXCIpO2Vsc2UgaWYoc3RhdGUuYnVmZmVyLmxlbmd0aD09PTEpcmV0PXN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQ9c3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO3N0YXRlLmJ1ZmZlci5jbGVhcigpfWVsc2V7cmV0PWZyb21MaXN0UGFydGlhbChuLHN0YXRlLmJ1ZmZlcixzdGF0ZS5kZWNvZGVyKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGZyb21MaXN0UGFydGlhbChuLGxpc3QsaGFzU3RyaW5ncyl7dmFyIHJldDtpZihuPGxpc3QuaGVhZC5kYXRhLmxlbmd0aCl7cmV0PWxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsbik7bGlzdC5oZWFkLmRhdGE9bGlzdC5oZWFkLmRhdGEuc2xpY2Uobil9ZWxzZSBpZihuPT09bGlzdC5oZWFkLmRhdGEubGVuZ3RoKXtyZXQ9bGlzdC5zaGlmdCgpfWVsc2V7cmV0PWhhc1N0cmluZ3M/Y29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KTpjb3B5RnJvbUJ1ZmZlcihuLGxpc3QpfXJldHVybiByZXR9ZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KXt2YXIgcD1saXN0LmhlYWQ7dmFyIGM9MTt2YXIgcmV0PXAuZGF0YTtuLT1yZXQubGVuZ3RoO3doaWxlKHA9cC5uZXh0KXt2YXIgc3RyPXAuZGF0YTt2YXIgbmI9bj5zdHIubGVuZ3RoP3N0ci5sZW5ndGg6bjtpZihuYj09PXN0ci5sZW5ndGgpcmV0Kz1zdHI7ZWxzZSByZXQrPXN0ci5zbGljZSgwLG4pO24tPW5iO2lmKG49PT0wKXtpZihuYj09PXN0ci5sZW5ndGgpeysrYztpZihwLm5leHQpbGlzdC5oZWFkPXAubmV4dDtlbHNlIGxpc3QuaGVhZD1saXN0LnRhaWw9bnVsbH1lbHNle2xpc3QuaGVhZD1wO3AuZGF0YT1zdHIuc2xpY2UobmIpfWJyZWFrfSsrY31saXN0Lmxlbmd0aC09YztyZXR1cm4gcmV0fWZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyKG4sbGlzdCl7dmFyIHJldD1idWZmZXJTaGltLmFsbG9jVW5zYWZlKG4pO3ZhciBwPWxpc3QuaGVhZDt2YXIgYz0xO3AuZGF0YS5jb3B5KHJldCk7bi09cC5kYXRhLmxlbmd0aDt3aGlsZShwPXAubmV4dCl7dmFyIGJ1Zj1wLmRhdGE7dmFyIG5iPW4+YnVmLmxlbmd0aD9idWYubGVuZ3RoOm47YnVmLmNvcHkocmV0LHJldC5sZW5ndGgtbiwwLG5iKTtuLT1uYjtpZihuPT09MCl7aWYobmI9PT1idWYubGVuZ3RoKXsrK2M7aWYocC5uZXh0KWxpc3QuaGVhZD1wLm5leHQ7ZWxzZSBsaXN0LmhlYWQ9bGlzdC50YWlsPW51bGx9ZWxzZXtsaXN0LmhlYWQ9cDtwLmRhdGE9YnVmLnNsaWNlKG5iKX1icmVha30rK2N9bGlzdC5sZW5ndGgtPWM7cmV0dXJuIHJldH1mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7aWYoc3RhdGUubGVuZ3RoPjApdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO2lmKCFzdGF0ZS5lbmRFbWl0dGVkKXtzdGF0ZS5lbmRlZD10cnVlO3Byb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULHN0YXRlLHN0cmVhbSl9fWZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsc3RyZWFtKXtpZighc3RhdGUuZW5kRW1pdHRlZCYmc3RhdGUubGVuZ3RoPT09MCl7c3RhdGUuZW5kRW1pdHRlZD10cnVlO3N0cmVhbS5yZWFkYWJsZT1mYWxzZTtzdHJlYW0uZW1pdChcImVuZFwiKX19ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX1mdW5jdGlvbiBpbmRleE9mKHhzLHgpe2Zvcih2YXIgaT0wLGw9eHMubGVuZ3RoO2k8bDtpKyspe2lmKHhzW2ldPT09eClyZXR1cm4gaX1yZXR1cm4tMX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3RcIjo0OSxfcHJvY2Vzczo0MixidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjQsXCJjb3JlLXV0aWwtaXNcIjo2LGV2ZW50czoyOCxpbmhlcml0czozOCxpc2FycmF5OjQwLFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MSxcInN0cmluZ19kZWNvZGVyL1wiOjU2LHV0aWw6M31dLDQ3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1UcmFuc2Zvcm07dmFyIER1cGxleD1yZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3V0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLER1cGxleCk7ZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKXt0aGlzLmFmdGVyVHJhbnNmb3JtPWZ1bmN0aW9uKGVyLGRhdGEpe3JldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl9O3RoaXMubmVlZFRyYW5zZm9ybT1mYWxzZTt0aGlzLnRyYW5zZm9ybWluZz1mYWxzZTt0aGlzLndyaXRlY2I9bnVsbDt0aGlzLndyaXRlY2h1bms9bnVsbDt0aGlzLndyaXRlZW5jb2Rpbmc9bnVsbH1mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl7dmFyIHRzPXN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7dHMudHJhbnNmb3JtaW5nPWZhbHNlO3ZhciBjYj10cy53cml0ZWNiO2lmKCFjYilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLG5ldyBFcnJvcihcIm5vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzXCIpKTt0cy53cml0ZWNodW5rPW51bGw7dHMud3JpdGVjYj1udWxsO2lmKGRhdGEhPT1udWxsJiZkYXRhIT09dW5kZWZpbmVkKXN0cmVhbS5wdXNoKGRhdGEpO2NiKGVyKTt2YXIgcnM9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO3JzLnJlYWRpbmc9ZmFsc2U7aWYocnMubmVlZFJlYWRhYmxlfHxycy5sZW5ndGg8cnMuaGlnaFdhdGVyTWFyayl7c3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspfX1mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucyl7aWYoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlyZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtEdXBsZXguY2FsbCh0aGlzLG9wdGlvbnMpO3RoaXMuX3RyYW5zZm9ybVN0YXRlPW5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTt2YXIgc3RyZWFtPXRoaXM7dGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTt0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmM9ZmFsc2U7aWYob3B0aW9ucyl7aWYodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtPT09XCJmdW5jdGlvblwiKXRoaXMuX3RyYW5zZm9ybT1vcHRpb25zLnRyYW5zZm9ybTtpZih0eXBlb2Ygb3B0aW9ucy5mbHVzaD09PVwiZnVuY3Rpb25cIil0aGlzLl9mbHVzaD1vcHRpb25zLmZsdXNofXRoaXMub25jZShcInByZWZpbmlzaFwiLGZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuX2ZsdXNoPT09XCJmdW5jdGlvblwiKXRoaXMuX2ZsdXNoKGZ1bmN0aW9uKGVyKXtkb25lKHN0cmVhbSxlcil9KTtlbHNlIGRvbmUoc3RyZWFtKX0pfVRyYW5zZm9ybS5wcm90b3R5cGUucHVzaD1mdW5jdGlvbihjaHVuayxlbmNvZGluZyl7dGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybT1mYWxzZTtyZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcyxjaHVuayxlbmNvZGluZyl9O1RyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dGhyb3cgbmV3IEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpfTtUcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO3RzLndyaXRlY2I9Y2I7dHMud3JpdGVjaHVuaz1jaHVuazt0cy53cml0ZWVuY29kaW5nPWVuY29kaW5nO2lmKCF0cy50cmFuc2Zvcm1pbmcpe3ZhciBycz10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHRzLm5lZWRUcmFuc2Zvcm18fHJzLm5lZWRSZWFkYWJsZXx8cnMubGVuZ3RoPHJzLmhpZ2hXYXRlck1hcmspdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKX19O1RyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQ9ZnVuY3Rpb24obil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO2lmKHRzLndyaXRlY2h1bmshPT1udWxsJiZ0cy53cml0ZWNiJiYhdHMudHJhbnNmb3JtaW5nKXt0cy50cmFuc2Zvcm1pbmc9dHJ1ZTt0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuayx0cy53cml0ZWVuY29kaW5nLHRzLmFmdGVyVHJhbnNmb3JtKX1lbHNle3RzLm5lZWRUcmFuc2Zvcm09dHJ1ZX19O2Z1bmN0aW9uIGRvbmUoc3RyZWFtLGVyKXtpZihlcilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKTt2YXIgd3M9c3RyZWFtLl93cml0YWJsZVN0YXRlO3ZhciB0cz1zdHJlYW0uX3RyYW5zZm9ybVN0YXRlO2lmKHdzLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoXCJDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDBcIik7aWYodHMudHJhbnNmb3JtaW5nKXRocm93IG5ldyBFcnJvcihcIkNhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmdcIik7cmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpfX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9V3JpdGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGFzeW5jV3JpdGU9IXByb2Nlc3MuYnJvd3NlciYmW1widjAuMTBcIixcInYwLjkuXCJdLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsNSkpPi0xP3NldEltbWVkaWF0ZTpwcm9jZXNzTmV4dFRpY2s7V3JpdGFibGUuV3JpdGFibGVTdGF0ZT1Xcml0YWJsZVN0YXRlO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dmFyIGludGVybmFsVXRpbD17ZGVwcmVjYXRlOnJlcXVpcmUoXCJ1dGlsLWRlcHJlY2F0ZVwiKX07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt1dGlsLmluaGVyaXRzKFdyaXRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gbm9wKCl7fWZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLGVuY29kaW5nLGNiKXt0aGlzLmNodW5rPWNodW5rO3RoaXMuZW5jb2Rpbmc9ZW5jb2Rpbmc7dGhpcy5jYWxsYmFjaz1jYjt0aGlzLm5leHQ9bnVsbH12YXIgRHVwbGV4O2Z1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucyxzdHJlYW0pe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5vYmplY3RNb2RlPSEhb3B0aW9ucy5vYmplY3RNb2RlO2lmKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCl0aGlzLm9iamVjdE1vZGU9dGhpcy5vYmplY3RNb2RlfHwhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO3ZhciBod209b3B0aW9ucy5oaWdoV2F0ZXJNYXJrO3ZhciBkZWZhdWx0SHdtPXRoaXMub2JqZWN0TW9kZT8xNjoxNioxMDI0O3RoaXMuaGlnaFdhdGVyTWFyaz1od218fGh3bT09PTA/aHdtOmRlZmF1bHRId207dGhpcy5oaWdoV2F0ZXJNYXJrPX5+dGhpcy5oaWdoV2F0ZXJNYXJrO3RoaXMubmVlZERyYWluPWZhbHNlO3RoaXMuZW5kaW5nPWZhbHNlO3RoaXMuZW5kZWQ9ZmFsc2U7dGhpcy5maW5pc2hlZD1mYWxzZTt2YXIgbm9EZWNvZGU9b3B0aW9ucy5kZWNvZGVTdHJpbmdzPT09ZmFsc2U7dGhpcy5kZWNvZGVTdHJpbmdzPSFub0RlY29kZTt0aGlzLmRlZmF1bHRFbmNvZGluZz1vcHRpb25zLmRlZmF1bHRFbmNvZGluZ3x8XCJ1dGY4XCI7dGhpcy5sZW5ndGg9MDt0aGlzLndyaXRpbmc9ZmFsc2U7dGhpcy5jb3JrZWQ9MDt0aGlzLnN5bmM9dHJ1ZTt0aGlzLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2U7dGhpcy5vbndyaXRlPWZ1bmN0aW9uKGVyKXtvbndyaXRlKHN0cmVhbSxlcil9O3RoaXMud3JpdGVjYj1udWxsO3RoaXMud3JpdGVsZW49MDt0aGlzLmJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMucGVuZGluZ2NiPTA7dGhpcy5wcmVmaW5pc2hlZD1mYWxzZTt0aGlzLmVycm9yRW1pdHRlZD1mYWxzZTt0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7dGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3QodGhpcyl9V3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyPWZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVHZXRCdWZmZXIoKXt2YXIgY3VycmVudD10aGlzLmJ1ZmZlcmVkUmVxdWVzdDt2YXIgb3V0PVtdO3doaWxlKGN1cnJlbnQpe291dC5wdXNoKGN1cnJlbnQpO2N1cnJlbnQ9Y3VycmVudC5uZXh0fXJldHVybiBvdXR9OyhmdW5jdGlvbigpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsXCJidWZmZXJcIix7Z2V0OmludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nZXRCdWZmZXIoKX0sXCJfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciBcIitcImluc3RlYWQuXCIpfSl9Y2F0Y2goXyl7fX0pKCk7dmFyIER1cGxleDtmdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtpZighKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkmJiEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTt0aGlzLl93cml0YWJsZVN0YXRlPW5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsdGhpcyk7dGhpcy53cml0YWJsZT10cnVlO2lmKG9wdGlvbnMpe2lmKHR5cGVvZiBvcHRpb25zLndyaXRlPT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRlPW9wdGlvbnMud3JpdGU7aWYodHlwZW9mIG9wdGlvbnMud3JpdGV2PT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRldj1vcHRpb25zLndyaXRldn1TdHJlYW0uY2FsbCh0aGlzKX1Xcml0YWJsZS5wcm90b3R5cGUucGlwZT1mdW5jdGlvbigpe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwiQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZVwiKSl9O2Z1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLGNiKXt2YXIgZXI9bmV3IEVycm9yKFwid3JpdGUgYWZ0ZXIgZW5kXCIpO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKX1mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSxzdGF0ZSxjaHVuayxjYil7dmFyIHZhbGlkPXRydWU7dmFyIGVyPWZhbHNlO2lmKGNodW5rPT09bnVsbCl7ZXI9bmV3IFR5cGVFcnJvcihcIk1heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtXCIpfWVsc2UgaWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09dW5kZWZpbmVkJiYhc3RhdGUub2JqZWN0TW9kZSl7ZXI9bmV3IFR5cGVFcnJvcihcIkludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmtcIil9aWYoZXIpe3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKTt2YWxpZD1mYWxzZX1yZXR1cm4gdmFsaWR9V3JpdGFibGUucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTt2YXIgcmV0PWZhbHNlO2lmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7ZWxzZSBpZighZW5jb2RpbmcpZW5jb2Rpbmc9c3RhdGUuZGVmYXVsdEVuY29kaW5nO2lmKHR5cGVvZiBjYiE9PVwiZnVuY3Rpb25cIiljYj1ub3A7aWYoc3RhdGUuZW5kZWQpd3JpdGVBZnRlckVuZCh0aGlzLGNiKTtlbHNlIGlmKHZhbGlkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxjYikpe1xuc3RhdGUucGVuZGluZ2NiKys7cmV0PXdyaXRlT3JCdWZmZXIodGhpcyxzdGF0ZSxjaHVuayxlbmNvZGluZyxjYil9cmV0dXJuIHJldH07V3JpdGFibGUucHJvdG90eXBlLmNvcms9ZnVuY3Rpb24oKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtzdGF0ZS5jb3JrZWQrK307V3JpdGFibGUucHJvdG90eXBlLnVuY29yaz1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkLS07aWYoIXN0YXRlLndyaXRpbmcmJiFzdGF0ZS5jb3JrZWQmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCljbGVhckJ1ZmZlcih0aGlzLHN0YXRlKX19O1dyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2Rpbmc9ZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiKWVuY29kaW5nPWVuY29kaW5nLnRvTG93ZXJDYXNlKCk7aWYoIShbXCJoZXhcIixcInV0ZjhcIixcInV0Zi04XCIsXCJhc2NpaVwiLFwiYmluYXJ5XCIsXCJiYXNlNjRcIixcInVjczJcIixcInVjcy0yXCIsXCJ1dGYxNmxlXCIsXCJ1dGYtMTZsZVwiLFwicmF3XCJdLmluZGV4T2YoKGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCkpPi0xKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpO3RoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nPWVuY29kaW5nO3JldHVybiB0aGlzfTtmdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSxjaHVuayxlbmNvZGluZyl7aWYoIXN0YXRlLm9iamVjdE1vZGUmJnN0YXRlLmRlY29kZVN0cmluZ3MhPT1mYWxzZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7Y2h1bms9YnVmZmVyU2hpbS5mcm9tKGNodW5rLGVuY29kaW5nKX1yZXR1cm4gY2h1bmt9ZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sc3RhdGUsY2h1bmssZW5jb2RpbmcsY2Ipe2NodW5rPWRlY29kZUNodW5rKHN0YXRlLGNodW5rLGVuY29kaW5nKTtpZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7dmFyIGxlbj1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RoO3N0YXRlLmxlbmd0aCs9bGVuO3ZhciByZXQ9c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcms7aWYoIXJldClzdGF0ZS5uZWVkRHJhaW49dHJ1ZTtpZihzdGF0ZS53cml0aW5nfHxzdGF0ZS5jb3JrZWQpe3ZhciBsYXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1uZXcgV3JpdGVSZXEoY2h1bmssZW5jb2RpbmcsY2IpO2lmKGxhc3Qpe2xhc3QubmV4dD1zdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0fWVsc2V7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3R9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQrPTF9ZWxzZXtkb1dyaXRlKHN0cmVhbSxzdGF0ZSxmYWxzZSxsZW4sY2h1bmssZW5jb2RpbmcsY2IpfXJldHVybiByZXR9ZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sc3RhdGUsd3JpdGV2LGxlbixjaHVuayxlbmNvZGluZyxjYil7c3RhdGUud3JpdGVsZW49bGVuO3N0YXRlLndyaXRlY2I9Y2I7c3RhdGUud3JpdGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZih3cml0ZXYpc3RyZWFtLl93cml0ZXYoY2h1bmssc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLGVuY29kaW5nLHN0YXRlLm9ud3JpdGUpO3N0YXRlLnN5bmM9ZmFsc2V9ZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSxzdGF0ZSxzeW5jLGVyLGNiKXstLXN0YXRlLnBlbmRpbmdjYjtpZihzeW5jKXByb2Nlc3NOZXh0VGljayhjYixlcik7ZWxzZSBjYihlcik7c3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZD10cnVlO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcil9ZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKXtzdGF0ZS53cml0aW5nPWZhbHNlO3N0YXRlLndyaXRlY2I9bnVsbDtzdGF0ZS5sZW5ndGgtPXN0YXRlLndyaXRlbGVuO3N0YXRlLndyaXRlbGVuPTB9ZnVuY3Rpb24gb253cml0ZShzdHJlYW0sZXIpe3ZhciBzdGF0ZT1zdHJlYW0uX3dyaXRhYmxlU3RhdGU7dmFyIHN5bmM9c3RhdGUuc3luYzt2YXIgY2I9c3RhdGUud3JpdGVjYjtvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO2lmKGVyKW9ud3JpdGVFcnJvcihzdHJlYW0sc3RhdGUsc3luYyxlcixjYik7ZWxzZXt2YXIgZmluaXNoZWQ9bmVlZEZpbmlzaChzdGF0ZSk7aWYoIWZpbmlzaGVkJiYhc3RhdGUuY29ya2VkJiYhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyYmc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KXtjbGVhckJ1ZmZlcihzdHJlYW0sc3RhdGUpfWlmKHN5bmMpe2FzeW5jV3JpdGUoYWZ0ZXJXcml0ZSxzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfWVsc2V7YWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfX19ZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2Ipe2lmKCFmaW5pc2hlZClvbndyaXRlRHJhaW4oc3RyZWFtLHN0YXRlKTtzdGF0ZS5wZW5kaW5nY2ItLTtjYigpO2ZpbmlzaE1heWJlKHN0cmVhbSxzdGF0ZSl9ZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSxzdGF0ZSl7aWYoc3RhdGUubGVuZ3RoPT09MCYmc3RhdGUubmVlZERyYWluKXtzdGF0ZS5uZWVkRHJhaW49ZmFsc2U7c3RyZWFtLmVtaXQoXCJkcmFpblwiKX19ZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLHN0YXRlKXtzdGF0ZS5idWZmZXJQcm9jZXNzaW5nPXRydWU7dmFyIGVudHJ5PXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtpZihzdHJlYW0uX3dyaXRldiYmZW50cnkmJmVudHJ5Lm5leHQpe3ZhciBsPXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O3ZhciBidWZmZXI9bmV3IEFycmF5KGwpO3ZhciBob2xkZXI9c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO2hvbGRlci5lbnRyeT1lbnRyeTt2YXIgY291bnQ9MDt3aGlsZShlbnRyeSl7YnVmZmVyW2NvdW50XT1lbnRyeTtlbnRyeT1lbnRyeS5uZXh0O2NvdW50Kz0xfWRvV3JpdGUoc3RyZWFtLHN0YXRlLHRydWUsc3RhdGUubGVuZ3RoLGJ1ZmZlcixcIlwiLGhvbGRlci5maW5pc2gpO3N0YXRlLnBlbmRpbmdjYisrO3N0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bnVsbDtpZihob2xkZXIubmV4dCl7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlPWhvbGRlci5uZXh0O2hvbGRlci5uZXh0PW51bGx9ZWxzZXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpfX1lbHNle3doaWxlKGVudHJ5KXt2YXIgY2h1bms9ZW50cnkuY2h1bms7dmFyIGVuY29kaW5nPWVudHJ5LmVuY29kaW5nO3ZhciBjYj1lbnRyeS5jYWxsYmFjazt2YXIgbGVuPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGg7ZG9Xcml0ZShzdHJlYW0sc3RhdGUsZmFsc2UsbGVuLGNodW5rLGVuY29kaW5nLGNiKTtlbnRyeT1lbnRyeS5uZXh0O2lmKHN0YXRlLndyaXRpbmcpe2JyZWFrfX1pZihlbnRyeT09PW51bGwpc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsfXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PWVudHJ5O3N0YXRlLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2V9V3JpdGFibGUucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7Y2IobmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07V3JpdGFibGUucHJvdG90eXBlLl93cml0ZXY9bnVsbDtXcml0YWJsZS5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtpZih0eXBlb2YgY2h1bms9PT1cImZ1bmN0aW9uXCIpe2NiPWNodW5rO2NodW5rPW51bGw7ZW5jb2Rpbmc9bnVsbH1lbHNlIGlmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihjaHVuayE9PW51bGwmJmNodW5rIT09dW5kZWZpbmVkKXRoaXMud3JpdGUoY2h1bmssZW5jb2RpbmcpO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkPTE7dGhpcy51bmNvcmsoKX1pZighc3RhdGUuZW5kaW5nJiYhc3RhdGUuZmluaXNoZWQpZW5kV3JpdGFibGUodGhpcyxzdGF0ZSxjYil9O2Z1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpe3JldHVybiBzdGF0ZS5lbmRpbmcmJnN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdD09PW51bGwmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLndyaXRpbmd9ZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnByZWZpbmlzaGVkKXtzdGF0ZS5wcmVmaW5pc2hlZD10cnVlO3N0cmVhbS5lbWl0KFwicHJlZmluaXNoXCIpfX1mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpe3ZhciBuZWVkPW5lZWRGaW5pc2goc3RhdGUpO2lmKG5lZWQpe2lmKHN0YXRlLnBlbmRpbmdjYj09PTApe3ByZWZpbmlzaChzdHJlYW0sc3RhdGUpO3N0YXRlLmZpbmlzaGVkPXRydWU7c3RyZWFtLmVtaXQoXCJmaW5pc2hcIil9ZWxzZXtwcmVmaW5pc2goc3RyZWFtLHN0YXRlKX19cmV0dXJuIG5lZWR9ZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLHN0YXRlLGNiKXtzdGF0ZS5lbmRpbmc9dHJ1ZTtmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpO2lmKGNiKXtpZihzdGF0ZS5maW5pc2hlZClwcm9jZXNzTmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoXCJmaW5pc2hcIixjYil9c3RhdGUuZW5kZWQ9dHJ1ZTtzdHJlYW0ud3JpdGFibGU9ZmFsc2V9ZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSl7dmFyIF90aGlzPXRoaXM7dGhpcy5uZXh0PW51bGw7dGhpcy5lbnRyeT1udWxsO3RoaXMuZmluaXNoPWZ1bmN0aW9uKGVycil7dmFyIGVudHJ5PV90aGlzLmVudHJ5O190aGlzLmVudHJ5PW51bGw7d2hpbGUoZW50cnkpe3ZhciBjYj1lbnRyeS5jYWxsYmFjaztzdGF0ZS5wZW5kaW5nY2ItLTtjYihlcnIpO2VudHJ5PWVudHJ5Lm5leHR9aWYoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dD1fdGhpc31lbHNle3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZT1fdGhpc319fX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7XCIuL19zdHJlYW1fZHVwbGV4XCI6NDQsX3Byb2Nlc3M6NDIsYnVmZmVyOjUsXCJidWZmZXItc2hpbXNcIjo0LFwiY29yZS11dGlsLWlzXCI6NixldmVudHM6MjgsaW5oZXJpdHM6MzgsXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiOjQxLFwidXRpbC1kZXByZWNhdGVcIjo1N31dLDQ5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBidWZmZXJTaGltPXJlcXVpcmUoXCJidWZmZXItc2hpbXNcIik7bW9kdWxlLmV4cG9ydHM9QnVmZmVyTGlzdDtmdW5jdGlvbiBCdWZmZXJMaXN0KCl7dGhpcy5oZWFkPW51bGw7dGhpcy50YWlsPW51bGw7dGhpcy5sZW5ndGg9MH1CdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKHYpe3ZhciBlbnRyeT17ZGF0YTp2LG5leHQ6bnVsbH07aWYodGhpcy5sZW5ndGg+MCl0aGlzLnRhaWwubmV4dD1lbnRyeTtlbHNlIHRoaXMuaGVhZD1lbnRyeTt0aGlzLnRhaWw9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbih2KXt2YXIgZW50cnk9e2RhdGE6dixuZXh0OnRoaXMuaGVhZH07aWYodGhpcy5sZW5ndGg9PT0wKXRoaXMudGFpbD1lbnRyeTt0aGlzLmhlYWQ9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXtpZih0aGlzLmxlbmd0aD09PTApcmV0dXJuO3ZhciByZXQ9dGhpcy5oZWFkLmRhdGE7aWYodGhpcy5sZW5ndGg9PT0xKXRoaXMuaGVhZD10aGlzLnRhaWw9bnVsbDtlbHNlIHRoaXMuaGVhZD10aGlzLmhlYWQubmV4dDstLXRoaXMubGVuZ3RoO3JldHVybiByZXR9O0J1ZmZlckxpc3QucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5oZWFkPXRoaXMudGFpbD1udWxsO3RoaXMubGVuZ3RoPTB9O0J1ZmZlckxpc3QucHJvdG90eXBlLmpvaW49ZnVuY3Rpb24ocyl7aWYodGhpcy5sZW5ndGg9PT0wKXJldHVyblwiXCI7dmFyIHA9dGhpcy5oZWFkO3ZhciByZXQ9XCJcIitwLmRhdGE7d2hpbGUocD1wLm5leHQpe3JldCs9cytwLmRhdGF9cmV0dXJuIHJldH07QnVmZmVyTGlzdC5wcm90b3R5cGUuY29uY2F0PWZ1bmN0aW9uKG4pe2lmKHRoaXMubGVuZ3RoPT09MClyZXR1cm4gYnVmZmVyU2hpbS5hbGxvYygwKTtpZih0aGlzLmxlbmd0aD09PTEpcmV0dXJuIHRoaXMuaGVhZC5kYXRhO3ZhciByZXQ9YnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuPj4+MCk7dmFyIHA9dGhpcy5oZWFkO3ZhciBpPTA7d2hpbGUocCl7cC5kYXRhLmNvcHkocmV0LGkpO2krPXAuZGF0YS5sZW5ndGg7cD1wLm5leHR9cmV0dXJuIHJldH19LHtidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjR9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIil9LHtcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NX1dLDUxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7dmFyIFN0cmVhbT1mdW5jdGlvbigpe3RyeXtyZXR1cm4gcmVxdWlyZShcInN0XCIrXCJyZWFtXCIpfWNhdGNoKF8pe319KCk7ZXhwb3J0cz1tb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiKTtleHBvcnRzLlN0cmVhbT1TdHJlYW18fGV4cG9ydHM7ZXhwb3J0cy5SZWFkYWJsZT1leHBvcnRzO2V4cG9ydHMuV3JpdGFibGU9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIik7ZXhwb3J0cy5EdXBsZXg9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIpO2V4cG9ydHMuVHJhbnNmb3JtPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKTtleHBvcnRzLlBhc3NUaHJvdWdoPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpO2lmKCFwcm9jZXNzLmJyb3dzZXImJnByb2Nlc3MuZW52LlJFQURBQkxFX1NUUkVBTT09PVwiZGlzYWJsZVwiJiZTdHJlYW0pe21vZHVsZS5leHBvcnRzPVN0cmVhbX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NCxcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NSxcIi4vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIjo0NixcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCI6NDcsXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDgsX3Byb2Nlc3M6NDJ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiOjQ3fV0sNTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDh9XSw1NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oc3RyaW5nKXtyZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1stXFxcXF4kKis/LigpfFtcXF17fV0vZyxcIlxcXFwkJlwiKX19LHt9XSw1NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO2luaGVyaXRzKFN0cmVhbSxFRSk7U3RyZWFtLlJlYWRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanNcIik7U3RyZWFtLldyaXRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIik7U3RyZWFtLkR1cGxleD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiKTtTdHJlYW0uVHJhbnNmb3JtPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCIpO1N0cmVhbS5QYXNzVGhyb3VnaD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzXCIpO1N0cmVhbS5TdHJlYW09U3RyZWFtO2Z1bmN0aW9uIFN0cmVhbSgpe0VFLmNhbGwodGhpcyl9U3RyZWFtLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKGRlc3Qsb3B0aW9ucyl7dmFyIHNvdXJjZT10aGlzO2Z1bmN0aW9uIG9uZGF0YShjaHVuayl7aWYoZGVzdC53cml0YWJsZSl7aWYoZmFsc2U9PT1kZXN0LndyaXRlKGNodW5rKSYmc291cmNlLnBhdXNlKXtzb3VyY2UucGF1c2UoKX19fXNvdXJjZS5vbihcImRhdGFcIixvbmRhdGEpO2Z1bmN0aW9uIG9uZHJhaW4oKXtpZihzb3VyY2UucmVhZGFibGUmJnNvdXJjZS5yZXN1bWUpe3NvdXJjZS5yZXN1bWUoKX19ZGVzdC5vbihcImRyYWluXCIsb25kcmFpbik7aWYoIWRlc3QuX2lzU3RkaW8mJighb3B0aW9uc3x8b3B0aW9ucy5lbmQhPT1mYWxzZSkpe3NvdXJjZS5vbihcImVuZFwiLG9uZW5kKTtzb3VyY2Uub24oXCJjbG9zZVwiLG9uY2xvc2UpfXZhciBkaWRPbkVuZD1mYWxzZTtmdW5jdGlvbiBvbmVuZCgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2Rlc3QuZW5kKCl9ZnVuY3Rpb24gb25jbG9zZSgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2lmKHR5cGVvZiBkZXN0LmRlc3Ryb3k9PT1cImZ1bmN0aW9uXCIpZGVzdC5kZXN0cm95KCl9ZnVuY3Rpb24gb25lcnJvcihlcil7Y2xlYW51cCgpO2lmKEVFLmxpc3RlbmVyQ291bnQodGhpcyxcImVycm9yXCIpPT09MCl7dGhyb3cgZXJ9fXNvdXJjZS5vbihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5vbihcImVycm9yXCIsb25lcnJvcik7ZnVuY3Rpb24gY2xlYW51cCgpe3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLG9uZW5kKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsY2xlYW51cCk7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKX1zb3VyY2Uub24oXCJlbmRcIixjbGVhbnVwKTtzb3VyY2Uub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3Qub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3QuZW1pdChcInBpcGVcIixzb3VyY2UpO3JldHVybiBkZXN0fX0se2V2ZW50czoyOCxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbS9kdXBsZXguanNcIjo0MyxcInJlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiOjUwLFwicmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzXCI6NTEsXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCI6NTIsXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIjo1M31dLDU2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBpc0J1ZmZlckVuY29kaW5nPUJ1ZmZlci5pc0VuY29kaW5nfHxmdW5jdGlvbihlbmNvZGluZyl7c3dpdGNoKGVuY29kaW5nJiZlbmNvZGluZy50b0xvd2VyQ2FzZSgpKXtjYXNlXCJoZXhcIjpjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpjYXNlXCJhc2NpaVwiOmNhc2VcImJpbmFyeVwiOmNhc2VcImJhc2U2NFwiOmNhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOmNhc2VcInJhd1wiOnJldHVybiB0cnVlO2RlZmF1bHQ6cmV0dXJuIGZhbHNlfX07ZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2Rpbmcpe2lmKGVuY29kaW5nJiYhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19dmFyIFN0cmluZ0RlY29kZXI9ZXhwb3J0cy5TdHJpbmdEZWNvZGVyPWZ1bmN0aW9uKGVuY29kaW5nKXt0aGlzLmVuY29kaW5nPShlbmNvZGluZ3x8XCJ1dGY4XCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sXCJcIik7YXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO3N3aXRjaCh0aGlzLmVuY29kaW5nKXtjYXNlXCJ1dGY4XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7YnJlYWs7Y2FzZVwidWNzMlwiOmNhc2VcInV0ZjE2bGVcIjp0aGlzLnN1cnJvZ2F0ZVNpemU9Mjt0aGlzLmRldGVjdEluY29tcGxldGVDaGFyPXV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7YnJlYWs7Y2FzZVwiYmFzZTY0XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7dGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcj1iYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjticmVhaztkZWZhdWx0OnRoaXMud3JpdGU9cGFzc1Rocm91Z2hXcml0ZTtyZXR1cm59dGhpcy5jaGFyQnVmZmVyPW5ldyBCdWZmZXIoNik7dGhpcy5jaGFyUmVjZWl2ZWQ9MDt0aGlzLmNoYXJMZW5ndGg9MH07U3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgY2hhclN0cj1cIlwiO3doaWxlKHRoaXMuY2hhckxlbmd0aCl7dmFyIGF2YWlsYWJsZT1idWZmZXIubGVuZ3RoPj10aGlzLmNoYXJMZW5ndGgtdGhpcy5jaGFyUmVjZWl2ZWQ/dGhpcy5jaGFyTGVuZ3RoLXRoaXMuY2hhclJlY2VpdmVkOmJ1ZmZlci5sZW5ndGg7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHRoaXMuY2hhclJlY2VpdmVkLDAsYXZhaWxhYmxlKTt0aGlzLmNoYXJSZWNlaXZlZCs9YXZhaWxhYmxlO2lmKHRoaXMuY2hhclJlY2VpdmVkPHRoaXMuY2hhckxlbmd0aCl7cmV0dXJuXCJcIn1idWZmZXI9YnVmZmVyLnNsaWNlKGF2YWlsYWJsZSxidWZmZXIubGVuZ3RoKTtjaGFyU3RyPXRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7dmFyIGNoYXJDb2RlPWNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aC0xKTtpZihjaGFyQ29kZT49NTUyOTYmJmNoYXJDb2RlPD01NjMxOSl7dGhpcy5jaGFyTGVuZ3RoKz10aGlzLnN1cnJvZ2F0ZVNpemU7Y2hhclN0cj1cIlwiO2NvbnRpbnVlfXRoaXMuY2hhclJlY2VpdmVkPXRoaXMuY2hhckxlbmd0aD0wO2lmKGJ1ZmZlci5sZW5ndGg9PT0wKXtyZXR1cm4gY2hhclN0cn1icmVha310aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7dmFyIGVuZD1idWZmZXIubGVuZ3RoO2lmKHRoaXMuY2hhckxlbmd0aCl7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLDAsYnVmZmVyLmxlbmd0aC10aGlzLmNoYXJSZWNlaXZlZCxlbmQpO2VuZC09dGhpcy5jaGFyUmVjZWl2ZWR9Y2hhclN0cis9YnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsMCxlbmQpO3ZhciBlbmQ9Y2hhclN0ci5sZW5ndGgtMTt2YXIgY2hhckNvZGU9Y2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7aWYoY2hhckNvZGU+PTU1Mjk2JiZjaGFyQ29kZTw9NTYzMTkpe3ZhciBzaXplPXRoaXMuc3Vycm9nYXRlU2l6ZTt0aGlzLmNoYXJMZW5ndGgrPXNpemU7dGhpcy5jaGFyUmVjZWl2ZWQrPXNpemU7dGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHNpemUsMCxzaXplKTtidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsMCwwLHNpemUpO3JldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLGVuZCl9cmV0dXJuIGNoYXJTdHJ9O1N0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyPWZ1bmN0aW9uKGJ1ZmZlcil7dmFyIGk9YnVmZmVyLmxlbmd0aD49Mz8zOmJ1ZmZlci5sZW5ndGg7Zm9yKDtpPjA7aS0tKXt2YXIgYz1idWZmZXJbYnVmZmVyLmxlbmd0aC1pXTtpZihpPT0xJiZjPj41PT02KXt0aGlzLmNoYXJMZW5ndGg9MjticmVha31pZihpPD0yJiZjPj40PT0xNCl7dGhpcy5jaGFyTGVuZ3RoPTM7YnJlYWt9aWYoaTw9MyYmYz4+Mz09MzApe3RoaXMuY2hhckxlbmd0aD00O2JyZWFrfX10aGlzLmNoYXJSZWNlaXZlZD1pfTtTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgcmVzPVwiXCI7aWYoYnVmZmVyJiZidWZmZXIubGVuZ3RoKXJlcz10aGlzLndyaXRlKGJ1ZmZlcik7aWYodGhpcy5jaGFyUmVjZWl2ZWQpe3ZhciBjcj10aGlzLmNoYXJSZWNlaXZlZDt2YXIgYnVmPXRoaXMuY2hhckJ1ZmZlcjt2YXIgZW5jPXRoaXMuZW5jb2Rpbmc7cmVzKz1idWYuc2xpY2UoMCxjcikudG9TdHJpbmcoZW5jKX1yZXR1cm4gcmVzfTtmdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcil7cmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKX1mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcil7dGhpcy5jaGFyUmVjZWl2ZWQ9YnVmZmVyLmxlbmd0aCUyO3RoaXMuY2hhckxlbmd0aD10aGlzLmNoYXJSZWNlaXZlZD8yOjB9ZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKXt0aGlzLmNoYXJSZWNlaXZlZD1idWZmZXIubGVuZ3RoJTM7dGhpcy5jaGFyTGVuZ3RoPXRoaXMuY2hhclJlY2VpdmVkPzM6MH19LHtidWZmZXI6NX1dLDU3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oZ2xvYmFsKXttb2R1bGUuZXhwb3J0cz1kZXByZWNhdGU7ZnVuY3Rpb24gZGVwcmVjYXRlKGZuLG1zZyl7aWYoY29uZmlnKFwibm9EZXByZWNhdGlvblwiKSl7cmV0dXJuIGZufXZhciB3YXJuZWQ9ZmFsc2U7ZnVuY3Rpb24gZGVwcmVjYXRlZCgpe2lmKCF3YXJuZWQpe2lmKGNvbmZpZyhcInRocm93RGVwcmVjYXRpb25cIikpe3Rocm93IG5ldyBFcnJvcihtc2cpfWVsc2UgaWYoY29uZmlnKFwidHJhY2VEZXByZWNhdGlvblwiKSl7Y29uc29sZS50cmFjZShtc2cpfWVsc2V7Y29uc29sZS53YXJuKG1zZyl9d2FybmVkPXRydWV9cmV0dXJuIGZuLmFwcGx5KHRoaXMsYXJndW1lbnRzKX1yZXR1cm4gZGVwcmVjYXRlZH1mdW5jdGlvbiBjb25maWcobmFtZSl7dHJ5e2lmKCFnbG9iYWwubG9jYWxTdG9yYWdlKXJldHVybiBmYWxzZX1jYXRjaChfKXtyZXR1cm4gZmFsc2V9dmFyIHZhbD1nbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO2lmKG51bGw9PXZhbClyZXR1cm4gZmFsc2U7cmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCk9PT1cInRydWVcIn19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHt9XSw1ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZXh0ZW5kO3ZhciBoYXNPd25Qcm9wZXJ0eT1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O2Z1bmN0aW9uIGV4dGVuZCgpe3ZhciB0YXJnZXQ9e307Zm9yKHZhciBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKyl7dmFyIHNvdXJjZT1hcmd1bWVudHNbaV07Zm9yKHZhciBrZXkgaW4gc291cmNlKXtpZihoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSxrZXkpKXt0YXJnZXRba2V5XT1zb3VyY2Vba2V5XX19fXJldHVybiB0YXJnZXR9fSx7fV19LHt9LFsxXSkoMSl9KTtcbiIsIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vbGliL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpO1xudmFyIFN3YWdnZXJDbGllbnQgPSByZXF1aXJlKCcuL2xpYi9jbGllbnQnKTtcbnZhciBkZXByZWNhdGlvbldyYXBwZXIgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIGhlbHBlcnMubG9nKCdUaGlzIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIm5ldyBTd2FnZ2VyQ2xpZW50XCIgaW5zdGVhZC4nKTtcblxuICByZXR1cm4gbmV3IFN3YWdnZXJDbGllbnQodXJsLCBvcHRpb25zKTtcbn07XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIUFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gIEFycmF5LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24ob2JqLCBzdGFydCkge1xuICAgIGZvciAodmFyIGkgPSAoc3RhcnQgfHwgMCksIGogPSB0aGlzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgaWYgKHRoaXNbaV0gPT09IG9iaikgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH07XG59XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIVN0cmluZy5wcm90b3R5cGUudHJpbSkge1xuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBub2RlIDEwLnggc3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7XG4gIFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbihzdWZmaXgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleE9mKHN1ZmZpeCwgdGhpcy5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKSAhPT0gLTE7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU3dhZ2dlckNsaWVudDtcblxuU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uID0gYXV0aC5BcGlLZXlBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBhdXRoLlBhc3N3b3JkQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuQ29va2llQXV0aG9yaXphdGlvbiA9IGF1dGguQ29va2llQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckFwaSA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckNsaWVudCA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi9saWIvc2NoZW1hLW1hcmt1cCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIGJ0b2EgPSByZXF1aXJlKCdidG9hJyk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxudmFyIENvb2tpZUphciA9IHJlcXVpcmUoJ2Nvb2tpZWphcicpLkNvb2tpZUphcjtcbnZhciBfID0ge1xuICBlYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaCcpLFxuICBpbmNsdWRlczogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzJyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKVxufTtcblxuLyoqXG4gKiBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgYXBwbGllcyB0aGUgY29ycmVjdCBhdXRob3JpemF0aW9uIHRvIGFuIG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZFxuICovXG52YXIgU3dhZ2dlckF1dGhvcml6YXRpb25zID0gbW9kdWxlLmV4cG9ydHMuU3dhZ2dlckF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24gKGF1dGh6KSB7XG4gIHRoaXMuYXV0aHogPSBhdXRoeiB8fCB7fTtcbn07XG5cbi8qKlxuICogQWRkIGF1dGhzIHRvIHRoZSBoYXNoXG4gKiBXaWxsIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmdcbiAqXG4gKi9cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIGF1dGgpIHtcbiAgaWYoXy5pc09iamVjdChuYW1lKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IHRydWU7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIGZhdm9yIHRoZSBvYmplY3QtbGV2ZWwgYXV0aG9yaXphdGlvbnMgb3ZlciBnbG9iYWxcbiAgdmFyIGF1dGh6ID0gb2JqLmNsaWVudEF1dGhvcml6YXRpb25zIHx8IHRoaXMuYXV0aHo7XG5cbiAgLy8gU2VjdXJpdGllcyBjb3VsZCBiZSBbIHt9IF1cbiAgXy5lYWNoKHNlY3VyaXRpZXMsIGZ1bmN0aW9uIChvYmosIGtleSkge1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIGFjY291bnQgZm9yIHNlY3VyaXRpZXMgYmVpbmcgWyBzdHIgXVxuICAgIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9XG5cbiAgICAvLyBGbGF0dGVuIGtleXMgaW4gdG8gb3VyIGFycmF5XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24gKHZhbCwga2V5KSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgXy5lYWNoKGF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgdmFyIG5ld1N0YXR1cyA9IGF1dGguYXBwbHkob2JqKTtcbiAgICAgIHN0YXR1cyA9IHN0YXR1cyAmJiAhIW5ld1N0YXR1czsgLy8gbG9naWNhbCBPUnMgcmVnYXJkaW5nIHN0YXR1c1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXR1cztcbn07XG5cbi8qKlxuICogQXBpS2V5QXV0aG9yaXphdGlvbiBhbGxvd3MgYSBxdWVyeSBwYXJhbSBvciBoZWFkZXIgdG8gYmUgaW5qZWN0ZWRcbiAqL1xudmFyIEFwaUtleUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCB0eXBlKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn07XG5cbkFwaUtleUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAodGhpcy50eXBlID09PSAncXVlcnknKSB7XG4gICAgLy8gc2VlIGlmIGFscmVhZHkgYXBwbGllZC4gIElmIHNvLCBkb24ndCBkbyBpdCBhZ2FpblxuXG4gICAgdmFyIHFwO1xuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIHFwID0gb2JqLnVybC5zdWJzdHJpbmcob2JqLnVybC5pbmRleE9mKCc/JykgKyAxKTtcbiAgICAgIHZhciBwYXJ0cyA9IHFwLnNwbGl0KCcmJyk7XG4gICAgICBpZihwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBrdiA9IHBhcnRzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYoa3YgJiYga3YubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKGt2WzBdID09PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcCBpdFxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnJicgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICc/JyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnaGVhZGVyJykge1xuICAgIGlmKHR5cGVvZiBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbnZhciBDb29raWVBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQ29va2llQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgdGhpcy5jb29raWUgPSBjb29raWU7XG59O1xuXG5Db29raWVBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgb2JqLmNvb2tpZUphciA9IG9iai5jb29raWVKYXIgfHwgbmV3IENvb2tpZUphcigpO1xuICBvYmouY29va2llSmFyLnNldENvb2tpZSh0aGlzLmNvb2tpZSk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBhc3N3b3JkIEF1dGhvcml6YXRpb24gaXMgYSBiYXNpYyBhdXRoIGltcGxlbWVudGF0aW9uXG4gKi9cbnZhciBQYXNzd29yZEF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgaGVscGVycy5sb2coJ1Bhc3N3b3JkQXV0aG9yaXphdGlvbjogdGhlIFxcJ25hbWVcXCcgYXJndW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgcGFzcyBvbmx5IHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICAgIHVzZXJuYW1lID0gYXJndW1lbnRzWzFdO1xuICAgIHBhc3N3b3JkID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHRoaXMudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkO1xufTtcblxuUGFzc3dvcmRBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYodHlwZW9mIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh0aGlzLnVzZXJuYW1lICsgJzonICsgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRnVuY3Rpb246IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uJyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKVxufTtcbnZhciBhdXRoID0gcmVxdWlyZSgnLi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi90eXBlcy9tb2RlbCcpO1xudmFyIE9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uJyk7XG52YXIgT3BlcmF0aW9uR3JvdXAgPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbkdyb3VwJyk7XG52YXIgUmVzb2x2ZXIgPSByZXF1aXJlKCcuL3Jlc29sdmVyJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vc3BlYy1jb252ZXJ0ZXInKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRDbGllbnRUYWdzID0gW1xuICAnYXBpcycsXG4gICdhdXRob3JpemF0aW9uU2NoZW1lJyxcbiAgJ2F1dGhvcml6YXRpb25zJyxcbiAgJ2Jhc2VQYXRoJyxcbiAgJ2J1aWxkJyxcbiAgJ2J1aWxkRnJvbTFfMVNwZWMnLFxuICAnYnVpbGRGcm9tMV8yU3BlYycsXG4gICdidWlsZEZyb21TcGVjJyxcbiAgJ2NsaWVudEF1dGhvcml6YXRpb25zJyxcbiAgJ2NvbnZlcnRJbmZvJyxcbiAgJ2RlYnVnJyxcbiAgJ2RlZmF1bHRFcnJvckNhbGxiYWNrJyxcbiAgJ2RlZmF1bHRTdWNjZXNzQ2FsbGJhY2snLFxuICAnZW5hYmxlQ29va2llcycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaG9zdCcsXG4gICdpZEZyb21PcCcsXG4gICdpbmZvJyxcbiAgJ2luaXRpYWxpemUnLFxuICAnaXNCdWlsdCcsXG4gICdpc1ZhbGlkJyxcbiAgJ21vZGVsUHJvcGVydHlNYWNybycsXG4gICdtb2RlbHMnLFxuICAnbW9kZWxzQXJyYXknLFxuICAnb3B0aW9ucycsXG4gICdwYXJhbWV0ZXJNYWNybycsXG4gICdwYXJzZVVyaScsXG4gICdwcm9ncmVzcycsXG4gICdyZXNvdXJjZUNvdW50JyxcbiAgJ3NhbXBsZU1vZGVscycsXG4gICdzZWxmUmVmbGVjdCcsXG4gICdzZXRDb25zb2xpZGF0ZWRNb2RlbHMnLFxuICAnc3BlYycsXG4gICdzdXBwb3J0ZWRTdWJtaXRNZXRob2RzJyxcbiAgJ3N3YWdnZXJSZXF1ZXN0SGVhZGVycycsXG4gICd0YWdGcm9tTGFiZWwnLFxuICAndGl0bGUnLFxuICAndXJsJyxcbiAgJ3VzZUpRdWVyeScsXG4gICdqcXVlcnlBamF4Q2FjaGUnXG5dO1xuLy8gV2UgaGF2ZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lcyB0byBhdm9pZCBjb2xsaXNpb25zIGZvciB0YWcgbmFtZXMgd2hpY2ggYXJlIHVzZWQgdG8gYWxsb3cgdGhlXG4vLyBmb2xsb3dpbmcgdXNhZ2U6ICdjbGllbnQuYXBpcy57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRBcGlUYWdzID0gW1xuICAnYXBpcycsXG4gICdhc0N1cmwnLFxuICAnZGVzY3JpcHRpb24nLFxuICAnZXh0ZXJuYWxEb2NzJyxcbiAgJ2hlbHAnLFxuICAnbGFiZWwnLFxuICAnbmFtZScsXG4gICdvcGVyYXRpb24nLFxuICAnb3BlcmF0aW9ucycsXG4gICdvcGVyYXRpb25zQXJyYXknLFxuICAncGF0aCcsXG4gICd0YWcnXG5dO1xudmFyIHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMgPSBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJywgJ3BhdGNoJywgJ3Bvc3QnLCAncHV0J107XG52YXIgU3dhZ2dlckNsaWVudCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLmF1dGhvcml6YXRpb25zID0gbnVsbDtcbiAgdGhpcy5hdXRob3JpemF0aW9uU2NoZW1lID0gbnVsbDtcbiAgdGhpcy5iYXNlUGF0aCA9IG51bGw7XG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gZmFsc2U7XG4gIHRoaXMuaW5mbyA9IG51bGw7XG4gIHRoaXMuaXNCdWlsdCA9IGZhbHNlO1xuICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcbiAgdGhpcy5tb2RlbHNBcnJheSA9IFtdO1xuICB0aGlzLnJlc291cmNlQ291bnQgPSAwO1xuICB0aGlzLnVybCA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gZmFsc2U7XG4gIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gZmFsc2U7XG4gIHRoaXMuc3dhZ2dlck9iamVjdCA9IHt9O1xuICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gdW5kZWZpbmVkO1xuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBuZXcgYXV0aC5Td2FnZ2VyQXV0aG9yaXphdGlvbnMoKTtcblxuICBpZiAodHlwZW9mIHVybCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsaXplKHVybCwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMubW9kZWxzID0ge307XG4gIHRoaXMuc2FtcGxlTW9kZWxzID0ge307XG5cbiAgaWYgKHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH0gZWxzZSBpZiAoXy5pc09iamVjdCh1cmwpKSB7XG4gICAgb3B0aW9ucyA9IHVybDtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnMudXJsO1xuICB9XG5cbiAgaWYodGhpcy51cmwgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cDonKSA9PT0gLTEgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cHM6JykgPT09IC0xKSB7XG4gICAgLy8gbm8gcHJvdG9jb2wsIHNvIHdlIGNhbiBvbmx5IHVzZSB3aW5kb3cgaWYgaXQgZXhpc3RzXG4gICAgaWYodHlwZW9mKHdpbmRvdykgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdyAmJiB3aW5kb3cubG9jYXRpb24pIHtcbiAgICAgIHRoaXMudXJsID0gd2luZG93LmxvY2F0aW9uLm9yaWdpbiArIHRoaXMudXJsO1xuICAgIH1cbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFkZChvcHRpb25zLmF1dGhvcml6YXRpb25zKTtcbiAgdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSBvcHRpb25zLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyB8fCAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04LCovKic7XG4gIHRoaXMuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayA9IG9wdGlvbnMuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRFcnJvckNhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0RXJyb3JDYWxsYmFjayB8fCBudWxsO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eU1hY3JvIHx8IG51bGw7XG4gIHRoaXMuY29ubmVjdGlvbkFnZW50ID0gb3B0aW9ucy5jb25uZWN0aW9uQWdlbnQgfHwgbnVsbDtcbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IG9wdGlvbnMucGFyYW1ldGVyTWFjcm8gfHwgbnVsbDtcbiAgdGhpcy51c2VQcm9taXNlID0gb3B0aW9ucy51c2VQcm9taXNlIHx8IG51bGw7XG5cbiAgLy8gb3BlcmF0aW9uIHJlcXVlc3QgdGltZW91dCBkZWZhdWx0XG4gIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dCB8fCBudWxsO1xuICAvLyBkZWZhdWx0IHRvIHJlcXVlc3QgdGltZW91dCB3aGVuIG5vdCBzcGVjaWZpZWRcbiAgdGhpcy5mZXRjaFNwZWNUaW1lb3V0ID0gdHlwZW9mIG9wdGlvbnMuZmV0Y2hTcGVjVGltZW91dCAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgb3B0aW9ucy5mZXRjaFNwZWNUaW1lb3V0IDogb3B0aW9ucy50aW1lb3V0IHx8IG51bGw7XG5cbiAgaWYodGhpcy51c2VQcm9taXNlKSB7XG4gICAgdGhpcy5kZWZlcnJlZENsaWVudCA9IFEuZGVmZXIoKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5zdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuICB9XG4gIGlmIChvcHRpb25zLnVzZUpRdWVyeSkge1xuICAgIHRoaXMudXNlSlF1ZXJ5ID0gb3B0aW9ucy51c2VKUXVlcnk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5qcXVlcnlBamF4Q2FjaGUpIHtcbiAgICB0aGlzLmpxdWVyeUFqYXhDYWNoZSA9IG9wdGlvbnMuanF1ZXJ5QWpheENhY2hlO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuZW5hYmxlQ29va2llcykge1xuICAgIHRoaXMuZW5hYmxlQ29va2llcyA9IG9wdGlvbnMuZW5hYmxlQ29va2llcztcbiAgfVxuXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gbWF5YmUgZG9uJ3QgbmVlZCB0aGlzP1xuICB0aGlzLm9wdGlvbnMudGltZW91dCA9IHRoaXMudGltZW91dDtcbiAgdGhpcy5vcHRpb25zLmZldGNoU3BlY1RpbWVvdXQgPSB0aGlzLmZldGNoU3BlY1RpbWVvdXQ7XG5cbiAgdGhpcy5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gb3B0aW9ucy5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzIHx8IFtdO1xuICB0aGlzLmZhaWx1cmUgPSBvcHRpb25zLmZhaWx1cmUgfHwgZnVuY3Rpb24gKGVycikgeyB0aHJvdyBlcnI7IH07XG4gIHRoaXMucHJvZ3Jlc3MgPSBvcHRpb25zLnByb2dyZXNzIHx8IGZ1bmN0aW9uICgpIHt9O1xuICB0aGlzLnNwZWMgPSBfLmNsb25lRGVlcChvcHRpb25zLnNwZWMpOyAvLyBDbG9uZSBzbyB3ZSBkbyBub3QgYWx0ZXIgdGhlIHByb3ZpZGVkIGRvY3VtZW50XG5cbiAgaWYgKG9wdGlvbnMuc2NoZW1lKSB7XG4gICAgdGhpcy5zY2hlbWUgPSBvcHRpb25zLnNjaGVtZTtcbiAgfVxuXG4gIGlmICh0aGlzLnVzZVByb21pc2UgfHwgdHlwZW9mIG9wdGlvbnMuc3VjY2VzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMucmVhZHkgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLmJ1aWxkKCk7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmJ1aWxkID0gZnVuY3Rpb24gKG1vY2spIHtcbiAgaWYgKHRoaXMuaXNCdWlsdCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmICh0aGlzLnNwZWMpIHtcbiAgICB0aGlzLnByb2dyZXNzKCdmZXRjaGluZyByZXNvdXJjZSBsaXN0OyBQbGVhc2Ugd2FpdC4nKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnByb2dyZXNzKCdmZXRjaGluZyByZXNvdXJjZSBsaXN0OiAnICsgdGhpcy51cmwgKyAnOyBQbGVhc2Ugd2FpdC4nKTtcbiAgfVxuXG4gIHZhciBvYmogPSB7XG4gICAgdXNlSlF1ZXJ5OiB0aGlzLnVzZUpRdWVyeSxcbiAgICBqcXVlcnlBamF4Q2FjaGU6IHRoaXMuanF1ZXJ5QWpheENhY2hlLFxuICAgIGNvbm5lY3Rpb25BZ2VudDogdGhpcy5jb25uZWN0aW9uQWdlbnQsXG4gICAgZW5hYmxlQ29va2llczogdGhpcy5lbmFibGVDb29raWVzLFxuICAgIHVybDogdGhpcy51cmwsXG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBhY2NlcHQ6IHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoc2VsZi51cmwuc3Vic3RyaW5nKDAsIDQpICE9PSAnaHR0cCcpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdQbGVhc2Ugc3BlY2lmeSB0aGUgcHJvdG9jb2wgZm9yICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UuZXJyT2JqICYmIChyZXNwb25zZS5lcnJPYmouY29kZSA9PT0gJ0VDT05OQUJPUlRFRCcgfHwgcmVzcG9uc2UuZXJyT2JqLm1lc3NhZ2UuaW5kZXhPZigndGltZW91dCcpICE9PSAtMSkpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdSZXF1ZXN0IHRpbWVkIG91dCBhZnRlciAnICsgc2VsZi5mZXRjaFNwZWNUaW1lb3V0ICsgJ21zJyk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIGZyb20gc2VydmVyLiAgSXQgbWF5IG5vdCBoYXZlIHRoZSBhcHByb3ByaWF0ZSBhY2Nlc3MtY29udHJvbC1vcmlnaW4gc2V0dGluZ3MuJyk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgc3dhZ2dlciBKU09OIGZyb20gJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKHJlc3BvbnNlLnN0YXR1cyArICcgOiAnICsgcmVzcG9uc2Uuc3RhdHVzVGV4dCArICcgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcCkge1xuXG4gICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3Aub2JqO1xuICAgICAgICBpZighcmVzcG9uc2VPYmopIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdmYWlsZWQgdG8gcGFyc2UgSlNPTi9ZQU1MIHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLnN3YWdnZXJWZXJzaW9uID0gcmVzcG9uc2VPYmouc3dhZ2dlclZlcnNpb247XG4gICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHJlc3BvbnNlT2JqO1xuXG4gICAgICAgIGlmIChyZXNwb25zZU9iai5zd2FnZ2VyICYmIHBhcnNlSW50KHJlc3BvbnNlT2JqLnN3YWdnZXIpID09PSAyKSB7XG4gICAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXI7XG5cbiAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHJlc3BvbnNlT2JqLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcblxuICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGNvbnZlcnRlciA9IG5ldyBTd2FnZ2VyU3BlY0NvbnZlcnRlcigpO1xuICAgICAgICAgIHNlbGYub2xkU3dhZ2dlck9iamVjdCA9IHNlbGYuc3dhZ2dlck9iamVjdDtcblxuICAgICAgICAgIGNvbnZlcnRlci5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24oc2VsZi51cmwpO1xuICAgICAgICAgIGNvbnZlcnRlci5jb252ZXJ0KHJlc3BvbnNlT2JqLCBzZWxmLmNsaWVudEF1dGhvcml6YXRpb25zLCBzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uKHNwZWMpIHtcbiAgICAgICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHNwZWM7XG4gICAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgICAgICAgICAgc2VsZi5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBvbmx5IHNldCB0aW1lb3V0IHdoZW4gc3BlY2lmaWVkXG4gIGlmICh0aGlzLmZldGNoU3BlY1RpbWVvdXQpIHtcbiAgICBvYmoudGltZW91dCA9IHRoaXMuZmV0Y2hTcGVjVGltZW91dDtcbiAgfVxuXG4gIGlmICh0aGlzLnNwZWMpIHtcbiAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSB0aGlzLnNwZWM7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHNlbGYuc3BlYywgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG4gICAgfSwgMTApO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqKTtcblxuICAgIGlmIChtb2NrKSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCB0aGlzLm9wdGlvbnMpO1xuICB9XG5cbiAgcmV0dXJuICh0aGlzLnVzZVByb21pc2UpID8gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlIDogdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmJ1aWxkRnJvbVNwZWMgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgaWYgKHRoaXMuaXNCdWlsdCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhpcy5hcGlzID0ge307XG4gIHRoaXMuYXBpc0FycmF5ID0gW107XG4gIHRoaXMuYmFzZVBhdGggPSByZXNwb25zZS5iYXNlUGF0aCB8fCAnJztcbiAgdGhpcy5jb25zdW1lcyA9IHJlc3BvbnNlLmNvbnN1bWVzO1xuICB0aGlzLmhvc3QgPSByZXNwb25zZS5ob3N0IHx8ICcnO1xuICB0aGlzLmluZm8gPSByZXNwb25zZS5pbmZvIHx8IHt9O1xuICB0aGlzLnByb2R1Y2VzID0gcmVzcG9uc2UucHJvZHVjZXM7XG4gIHRoaXMuc2NoZW1lcyA9IHJlc3BvbnNlLnNjaGVtZXMgfHwgW107XG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyA9IF8uY2xvbmVEZWVwKHJlc3BvbnNlLnNlY3VyaXR5RGVmaW5pdGlvbnMpO1xuICB0aGlzLnNlY3VyaXR5ID0gcmVzcG9uc2Uuc2VjdXJpdHk7XG4gIHRoaXMudGl0bGUgPSByZXNwb25zZS50aXRsZSB8fCAnJztcblxuICB2YXIga2V5LCBkZWZpbmVkVGFncyA9IHt9LCBrLCBsb2NhdGlvbiwgc2VsZiA9IHRoaXMsIGk7XG5cbiAgaWYgKHJlc3BvbnNlLmV4dGVybmFsRG9jcykge1xuICAgIHRoaXMuZXh0ZXJuYWxEb2NzID0gcmVzcG9uc2UuZXh0ZXJuYWxEb2NzO1xuICB9XG5cbiAgLy8gbGVnYWN5IHN1cHBvcnRcbiAgdGhpcy5hdXRoU2NoZW1lcyA9IHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucztcblxuICBpZih0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICBmb3Ioa2V5IGluIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgICAgdmFyIHNlY3VyaXR5RGVmaW5pdGlvbiA9IHRoaXMuc2VjdXJpdHlEZWZpbml0aW9uc1trZXldO1xuICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnZlbmRvckV4dGVuc2lvbnMgPSB7fTtcbiAgICAgIGZvcih2YXIgZXh0IGluIHNlY3VyaXR5RGVmaW5pdGlvbikge1xuICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGV4dCwgc2VjdXJpdHlEZWZpbml0aW9uKTtcbiAgICAgICAgaWYgKGV4dCA9PT0gJ3Njb3BlcycpIHtcbiAgICAgICAgICB2YXIgc2NvcGVzID0gc2VjdXJpdHlEZWZpbml0aW9uW2V4dF07XG4gICAgICAgICAgaWYodHlwZW9mIHNjb3BlcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHNjb3Blcy52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICAgICAgICBmb3IgKHZhciBzIGluIHNjb3Blcykge1xuICAgICAgICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKHMsIHNjb3Blcyk7XG4gICAgICAgICAgICAgIGlmKHMuaW5kZXhPZigneC0nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBzY29wZXNbc107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShyZXNwb25zZS50YWdzKSkge1xuICAgIGRlZmluZWRUYWdzID0ge307XG5cbiAgICBmb3IgKGsgPSAwOyBrIDwgcmVzcG9uc2UudGFncy5sZW5ndGg7IGsrKykge1xuICAgICAgdmFyIHQgPSBfLmNsb25lRGVlcChyZXNwb25zZS50YWdzW2tdKTtcbiAgICAgIGRlZmluZWRUYWdzW3QubmFtZV0gPSB0O1xuICAgICAgZm9yKGkgaW4gdCkge1xuICAgICAgICBpZihpID09PSAnZXh0ZXJuYWxEb2NzJyAmJiB0eXBlb2YgdFtpXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBmb3IodmFyIGogaW4gdFtpXSkge1xuICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhqLCB0W2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhpLCB0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuXG4gIGlmICh0eXBlb2YgdGhpcy51cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgbG9jYXRpb24gPSB0aGlzLnBhcnNlVXJpKHRoaXMudXJsKTtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgdGhpcy5zY2hlbWVzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLnNjaGVtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyB1c2UgdGhlIHdpbmRvdyBzY2hlbWVcbiAgICAgICAgdGhpcy5zY2hlbWUgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wucmVwbGFjZSgnOicsJycpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lIHx8ICdodHRwJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHZhciBzY2hlbWUgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wucmVwbGFjZSgnOicsJycpO1xuICAgICAgICBpZihzY2hlbWUgPT09ICdodHRwcycgJiYgdGhpcy5zY2hlbWVzLmluZGV4T2Yoc2NoZW1lKSA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBjYW4ndCBjYWxsIGh0dHAgZnJvbSBodHRwcyBzZXJ2ZWQgcGFnZSBpbiBhIGJyb3dzZXIhXG4gICAgICAgICAgaGVscGVycy5sb2coJ0Nhbm5vdCBjYWxsIGEgaHR0cCBzZXJ2ZXIgZnJvbSBodHRwcyBpbnNpZGUgYSBicm93c2VyIScpO1xuICAgICAgICAgIHRoaXMuc2NoZW1lID0gJ2h0dHAnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodGhpcy5zY2hlbWVzLmluZGV4T2Yoc2NoZW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICB0aGlzLnNjaGVtZSA9IHNjaGVtZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBpZih0aGlzLnNjaGVtZXMuaW5kZXhPZignaHR0cHMnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuc2NoZW1lID0gJ2h0dHBzJztcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnNjaGVtZSA9IHRoaXMuc2NoZW1lc1swXSB8fCBsb2NhdGlvbi5zY2hlbWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmhvc3QgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuaG9zdCA9PT0gJycpIHtcbiAgICAgIHRoaXMuaG9zdCA9IGxvY2F0aW9uLmhvc3Q7XG5cbiAgICAgIGlmIChsb2NhdGlvbi5wb3J0KSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IHRoaXMuaG9zdCArICc6JyArIGxvY2F0aW9uLnBvcnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2YgdGhpcy5zY2hlbWVzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLnNjaGVtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF07XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kZWZpbml0aW9ucyA9IHJlc3BvbnNlLmRlZmluaXRpb25zO1xuXG4gIGZvciAoa2V5IGluIHRoaXMuZGVmaW5pdGlvbnMpIHtcbiAgICB2YXIgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCB0aGlzLmRlZmluaXRpb25zW2tleV0sIHRoaXMubW9kZWxzLCB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIHRoaXMubW9kZWxzW2tleV0gPSBtb2RlbDtcbiAgICB9XG4gIH1cblxuICAvLyBnZXQgcGF0aHMsIGNyZWF0ZSBmdW5jdGlvbnMgZm9yIGVhY2ggb3BlcmF0aW9uSWRcbiAgXG4gIC8vIEJpbmQgaGVscCB0byAnY2xpZW50LmFwaXMnXG4gIHNlbGYuYXBpcy5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgc2VsZik7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLnBhdGhzLCBmdW5jdGlvbiAocGF0aE9iaiwgcGF0aCkge1xuICAgIC8vIE9ubHkgcHJvY2VzcyBhIHBhdGggaWYgaXQncyBhbiBvYmplY3RcbiAgICBpZiAoIV8uaXNQbGFpbk9iamVjdChwYXRoT2JqKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIF8uZm9yRWFjaChzdXBwb3J0ZWRPcGVyYXRpb25NZXRob2RzLCBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gcGF0aE9ialttZXRob2RdO1xuXG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBkb2VzIG5vdCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKCFfLmlzUGxhaW5PYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAvLyBPcGVyYXRpb24gZXhpc3RzIGJ1dCBpdCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdC4gIFNpbmNlIHRoaXMgaXMgaW52YWxpZCwgbG9nIGl0LlxuICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBtZXRob2QgKyAnXFwnIG9wZXJhdGlvbiBmb3IgXFwnJyArIHBhdGggKyAnXFwnIHBhdGggaXMgbm90IGFuIE9wZXJhdGlvbiBPYmplY3QnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YWdzID0gb3BlcmF0aW9uLnRhZ3M7XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHRhZ3MpIHx8ICFfLmlzQXJyYXkodGFncykgfHwgdGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGFncyA9IG9wZXJhdGlvbi50YWdzID0gWyAnZGVmYXVsdCcgXTtcbiAgICAgIH1cblxuICAgICAgdmFyIG9wZXJhdGlvbklkID0gc2VsZi5pZEZyb21PcChwYXRoLCBtZXRob2QsIG9wZXJhdGlvbik7XG5cbiAgICAgIHZhciBvcGVyYXRpb25PYmplY3QgPSBuZXcgT3BlcmF0aW9uKHNlbGYsXG4gICAgICAgIG9wZXJhdGlvbi5zY2hlbWUsXG4gICAgICAgIG9wZXJhdGlvbklkLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgc2VsZi5kZWZpbml0aW9ucyxcbiAgICAgICAgc2VsZi5tb2RlbHMsXG4gICAgICAgIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMpO1xuXG4gICAgICBvcGVyYXRpb25PYmplY3QudmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgZm9yKGkgaW4gb3BlcmF0aW9uKSB7XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgb3BlcmF0aW9uT2JqZWN0LCBvcGVyYXRpb25baV0pO1xuICAgICAgfVxuICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyA9IG9wZXJhdGlvbi5leHRlcm5hbERvY3M7XG4gICAgICBpZihvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzKSB7XG4gICAgICAgIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MgPSBfLmNsb25lRGVlcChvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzKTtcbiAgICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcy52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICAgIGZvcihpIGluIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpIHtcbiAgICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGksIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGJpbmQgc2VsZiBvcGVyYXRpb24ncyBleGVjdXRlIGNvbW1hbmQgdG8gdGhlIGFwaVxuICAgICAgXy5mb3JFYWNoKHRhZ3MsIGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgdmFyIGNsaWVudFByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQ2xpZW50VGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgYXBpUHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldO1xuXG4gICAgICAgIGlmIChjbGllbnRQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LicgK1xuICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFByb3BlcnR5ICsgJ1xcJyBvciBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcGlQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgb3BlcmF0aW9uSWQpID4gLTEpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBvcGVyYXRpb25JZCArICdcXCcgb3BlcmF0aW9uSWQgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLl8nICsgb3BlcmF0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLicgKyBvcGVyYXRpb25JZCArICdcXCcuJyk7XG5cbiAgICAgICAgICBvcGVyYXRpb25JZCA9ICdfJyArIG9wZXJhdGlvbklkO1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdC5uaWNrbmFtZSA9IG9wZXJhdGlvbklkOyAvLyBTbyAnY2xpZW50LmFwaXMuW3RhZ10ub3BlcmF0aW9uSWQuaGVscCgpIHdvcmtzIHByb3Blcmx5XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb25Hcm91cCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldID0gc2VsZi5hcGlzW2FwaVByb3BlcnR5XSA9IHt9O1xuXG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9ucyA9IHt9O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmxhYmVsID0gYXBpUHJvcGVydHk7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpcyA9IHt9O1xuXG4gICAgICAgICAgdmFyIHRhZ0RlZiA9IGRlZmluZWRUYWdzW3RhZ107XG5cbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQodGFnRGVmKSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24gPSB0YWdEZWYuZGVzY3JpcHRpb247XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MgPSB0YWdEZWYuZXh0ZXJuYWxEb2NzO1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAudmVuZG9yRXh0ZW5zaW9ucyA9IHRhZ0RlZi52ZW5kb3JFeHRlbnNpb25zO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlbGZbY2xpZW50UHJvcGVydHldLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgICAgc2VsZi5hcGlzQXJyYXkucHVzaChuZXcgT3BlcmF0aW9uR3JvdXAodGFnLCBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiwgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb25PYmplY3QpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wZXJhdGlvbklkID0gc2VsZi5tYWtlVW5pcXVlT3BlcmF0aW9uSWQob3BlcmF0aW9uSWQsIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV0pO1xuXG4gICAgICAgIC8vIEJpbmQgdGFnIGhlbHBcbiAgICAgICAgaWYgKCFfLmlzRnVuY3Rpb24ob3BlcmF0aW9uR3JvdXAuaGVscCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmluZCB0byB0aGUgYXBpcyBvYmplY3RcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0gPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmV4ZWN1dGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uaGVscCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5oZWxwID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5oZWxwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uYXNDdXJsID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmFzQ3VybCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuYXNDdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG5cbiAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbk9iamVjdDtcblxuICAgICAgICAvLyBsZWdhY3kgVUkgZmVhdHVyZVxuICAgICAgICB2YXIgYXBpID0gXy5maW5kKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgICAgcmV0dXJuIGFwaS50YWcgPT09IHRhZztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgIGFwaS5vcGVyYXRpb25zQXJyYXkucHVzaChvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gc29ydCB0aGUgYXBpc0FycmF5IGFjY29yZGluZyB0byB0aGUgdGFnc1xuICB2YXIgc29ydGVkQXBpcyA9IFtdO1xuICBfLmZvckVhY2goT2JqZWN0LmtleXMoZGVmaW5lZFRhZ3MpLCBmdW5jdGlvbiAodGFnKSB7XG4gICAgdmFyIHBvcztcbiAgICBmb3IocG9zIGluIHNlbGYuYXBpc0FycmF5KSB7XG4gICAgICB2YXIgX2FwaSA9IHNlbGYuYXBpc0FycmF5W3Bvc107XG4gICAgICBpZihfYXBpICYmIHRhZyA9PT0gX2FwaS5uYW1lKSB7XG4gICAgICAgIHNvcnRlZEFwaXMucHVzaChfYXBpKTtcbiAgICAgICAgc2VsZi5hcGlzQXJyYXlbcG9zXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gYWRkIGFueXRoaW5nIGxlZnRcbiAgXy5mb3JFYWNoKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgaWYoYXBpKSB7XG4gICAgICBzb3J0ZWRBcGlzLnB1c2goYXBpKTtcbiAgICB9XG4gIH0pO1xuICBzZWxmLmFwaXNBcnJheSA9IHNvcnRlZEFwaXM7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLmRlZmluaXRpb25zLCBmdW5jdGlvbiAoZGVmaW5pdGlvbk9iaiwgZGVmaW5pdGlvbikge1xuICAgIGRlZmluaXRpb25PYmouaWQgPSBkZWZpbml0aW9uLnRvTG93ZXJDYXNlKCk7XG4gICAgZGVmaW5pdGlvbk9iai5uYW1lID0gZGVmaW5pdGlvbjtcbiAgICBzZWxmLm1vZGVsc0FycmF5LnB1c2goZGVmaW5pdGlvbk9iaik7XG4gIH0pO1xuXG4gIHRoaXMuaXNCdWlsdCA9IHRydWU7XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlc29sdmUodGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9XG5cbiAgaWYgKHRoaXMuc3VjY2Vzcykge1xuICAgIHRoaXMuc3VjY2VzcygpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5tYWtlVW5pcXVlT3BlcmF0aW9uSWQgPSBmdW5jdGlvbihvcGVyYXRpb25JZCwgYXBpKSB7XG4gIHZhciBjb3VudCA9IDA7XG4gIHZhciBuYW1lID0gb3BlcmF0aW9uSWQ7XG5cbiAgLy8gbWFrZSB1bmlxdWUgYWNyb3NzIHRoaXMgb3BlcmF0aW9uIGdyb3VwXG4gIHdoaWxlKHRydWUpIHtcbiAgICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgaWYob3BlcmF0aW9uLm5pY2tuYW1lID09PSBuYW1lKSB7XG4gICAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmKCFtYXRjaGVkKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IG9wZXJhdGlvbklkICsgJ18nICsgY291bnQ7XG4gICAgY291bnQgKys7XG4gIH1cblxuICByZXR1cm4gb3BlcmF0aW9uSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5wYXJzZVVyaSA9IGZ1bmN0aW9uICh1cmkpIHtcbiAgdmFyIHVybFBhcnNlUkUgPSAvXigoKChbXjpcXC8jXFw/XSs6KT8oPzooXFwvXFwvKSgoPzooKFteOkBcXC8jXFw/XSspKD86XFw6KFteOkBcXC8jXFw/XSspKT8pQCk/KChbXjpcXC8jXFw/XFxdXFxbXSt8XFxbW15cXC9cXF1AIz9dK1xcXSkoPzpcXDooWzAtOV0rKSk/KSk/KT8pPygoXFwvPyg/OlteXFwvXFw/I10rXFwvKykqKShbXlxcPyNdKikpKT8oXFw/W14jXSspPykoIy4qKT8vO1xuICB2YXIgcGFydHMgPSB1cmxQYXJzZVJFLmV4ZWModXJpKTtcblxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogcGFydHNbNF0gPyBwYXJ0c1s0XS5yZXBsYWNlKCc6JywnJykgOiB1bmRlZmluZWQsXG4gICAgaG9zdDogcGFydHNbMTFdLFxuICAgIHBvcnQ6IHBhcnRzWzEyXSxcbiAgICBwYXRoOiBwYXJ0c1sxNV1cbiAgfTtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXRwdXQgPSAnJztcblxuICBpZiAodGhpcyBpbnN0YW5jZW9mIFN3YWdnZXJDbGllbnQpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpLCBuYW1lKSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGFwaSkpIHtcbiAgICAgICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIG5hbWUgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcyBpbnN0YW5jZW9mIE9wZXJhdGlvbkdyb3VwIHx8IF8uaXNQbGFpbk9iamVjdCh0aGlzKSkge1xuICAgIG91dHB1dCArPSAnb3BlcmF0aW9ucyBmb3IgdGhlIFxcJycgKyB0aGlzLmxhYmVsICsgJ1xcJyB0YWdcXG4nO1xuXG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24gKG9wZXJhdGlvbiwgbmFtZSkge1xuICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkb250UHJpbnQpIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIGhlbHBlcnMubG9nKG91dHB1dCk7XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS50YWdGcm9tTGFiZWwgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgcmV0dXJuIGxhYmVsO1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaWRGcm9tT3AgPSBmdW5jdGlvbiAocGF0aCwgaHR0cE1ldGhvZCwgb3ApIHtcbiAgaWYoIW9wIHx8ICFvcC5vcGVyYXRpb25JZCkge1xuICAgIG9wID0gb3AgfHwge307XG4gICAgb3Aub3BlcmF0aW9uSWQgPSBodHRwTWV0aG9kICsgJ18nICsgcGF0aDtcbiAgfVxuICB2YXIgb3BJZCA9IG9wLm9wZXJhdGlvbklkLnJlcGxhY2UoL1tcXHMhQCMkJV4mKigpXys9XFxbe1xcXX07Ojw+fC5cXC8/LFxcXFwnXCJcIi1dL2csICdfJykgfHwgKHBhdGguc3Vic3RyaW5nKDEpICsgJ18nICsgaHR0cE1ldGhvZCk7XG5cbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKChfKXsyLH0pL2csICdfJyk7XG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoL14oXykqL2csICcnKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKFtfXSkqJC9nLCAnJyk7XG5cbiAgcmV0dXJuIG9wSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRIb3N0ID0gZnVuY3Rpb24gKGhvc3QpIHtcbiAgdGhpcy5ob3N0ID0gaG9zdDtcblxuICBpZih0aGlzLmFwaXMpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbihhcGkpIHtcbiAgICAgIGlmKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG4gICAgICAgICAgb3BlcmF0aW9uLmhvc3QgPSBob3N0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0QmFzZVBhdGggPSBmdW5jdGlvbiAoYmFzZVBhdGgpIHtcbiAgdGhpcy5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uYmFzZVBhdGggPSBiYXNlUGF0aDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldFNjaGVtZXMgPSBmdW5jdGlvbiAoc2NoZW1lcykge1xuICB0aGlzLnNjaGVtZXMgPSBzY2hlbWVzO1xuXG4gIGlmKHNjaGVtZXMgJiYgc2NoZW1lcy5sZW5ndGggPiAwKSB7XG4gICAgaWYodGhpcy5hcGlzKSB7XG4gICAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIGlmIChhcGkub3BlcmF0aW9ucykge1xuICAgICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSA9IHNjaGVtZXNbMF07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGlmICh0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlamVjdChtZXNzYWdlKTtcbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmZhaWx1cmUpIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmZhaWx1cmUobWVzc2FnZSk7XG4gICAgfVxuICB9XG59O1xuIiwiKGZ1bmN0aW9uIChwcm9jZXNzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpXG59O1xuXG5tb2R1bGUuZXhwb3J0cy5fX2JpbmQgPSBmdW5jdGlvbiAoZm4sIG1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpe1xuICAgIHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG5cbnZhciBsb2cgPSBtb2R1bGUuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgLy8gT25seSBsb2cgaWYgYXZhaWxhYmxlIGFuZCB3ZSdyZSBub3QgdGVzdGluZ1xuICBpZiAoY29uc29sZSAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgY29uc29sZS5sb2coQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVswXSk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICBsb2cobWVzc2FnZSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5vcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59O1xuXG52YXIgcmVzb2x2ZVNjaGVtYSA9IG1vZHVsZS5leHBvcnRzLnJlc29sdmVTY2hlbWEgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLnNpbXBsZVJlZiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChuYW1lLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICByZXR1cm4gbmFtZS5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuYW1lO1xuICB9XG59O1xuXG4vKipcbiAqIGhlbHBlciB0byByZW1vdmUgZXh0ZW5zaW9ucyBhbmQgYWRkIHRoZW0gdG8gYW4gb2JqZWN0XG4gKlxuICogQHBhcmFtIGtleW5hbWVcbiAqIEBwYXJhbSBvYmpcbiAqL1xubW9kdWxlLmV4cG9ydHMuZXh0cmFjdEV4dGVuc2lvbnMgPSBmdW5jdGlvbiAoa2V5bmFtZSwgb2JqLCB2YWx1ZSkge1xuICBpZigha2V5bmFtZSB8fCAhb2JqKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBrZXluYW1lID09PSAnc3RyaW5nJyAmJiBrZXluYW1lLmluZGV4T2YoJ3gtJykgPT09IDApIHtcbiAgICBvYmoudmVuZG9yRXh0ZW5zaW9ucyA9IG9iai52ZW5kb3JFeHRlbnNpb25zIHx8IHt9O1xuICAgIGlmKHZhbHVlKSB7XG4gICAgICBvYmoudmVuZG9yRXh0ZW5zaW9uc1trZXluYW1lXSA9IHZhbHVlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9iai52ZW5kb3JFeHRlbnNpb25zW2tleW5hbWVdID0gb2JqW2tleW5hbWVdO1xuICAgIH1cbiAgfVxufTtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW14cFlpOW9aV3h3WlhKekxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpZDFjMlVnYzNSeWFXTjBKenRjYmx4dWRtRnlJRjhnUFNCN1hHNGdJR2x6VUd4aGFXNVBZbXBsWTNRNklISmxjWFZwY21Vb0oyeHZaR0Z6YUMxamIyMXdZWFF2YkdGdVp5OXBjMUJzWVdsdVQySnFaV04wSnlrc1hHNGdJR2x1WkdWNFQyWTZJSEpsY1hWcGNtVW9KMnh2WkdGemFDMWpiMjF3WVhRdllYSnlZWGt2YVc1a1pYaFBaaWNwWEc1OU8xeHVYRzV0YjJSMWJHVXVaWGh3YjNKMGN5NWZYMkpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9abTRzSUcxbEtTQjdYRzRnSUhKbGRIVnliaUJtZFc1amRHbHZiaWdwZTF4dUlDQWdJSEpsZEhWeWJpQm1iaTVoY0hCc2VTaHRaU3dnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVHRjYm4wN1hHNWNiblpoY2lCc2IyY2dQU0J0YjJSMWJHVXVaWGh3YjNKMGN5NXNiMmNnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnTHk4Z1QyNXNlU0JzYjJjZ2FXWWdZWFpoYVd4aFlteGxJR0Z1WkNCM1pTZHlaU0J1YjNRZ2RHVnpkR2x1WjF4dUlDQnBaaUFvWTI5dWMyOXNaU0FtSmlCd2NtOWpaWE56TG1WdWRpNU9UMFJGWDBWT1ZpQWhQVDBnSjNSbGMzUW5LU0I3WEc0Z0lDQWdZMjl1YzI5c1pTNXNiMmNvUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbk5zYVdObExtTmhiR3dvWVhKbmRXMWxiblJ6S1Zzd1hTazdYRzRnSUgxY2JuMDdYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpMbVpoYVd3Z1BTQm1kVzVqZEdsdmJpQW9iV1Z6YzJGblpTa2dlMXh1SUNCc2IyY29iV1Z6YzJGblpTazdYRzU5TzF4dVhHNXRiMlIxYkdVdVpYaHdiM0owY3k1dmNIUnBiMjVJZEcxc0lEMGdablZ1WTNScGIyNGdLR3hoWW1Wc0xDQjJZV3gxWlNrZ2UxeHVJQ0J5WlhSMWNtNGdKengwY2o0OGRHUWdZMnhoYzNNOVhDSnZjSFJwYjI1T1lXMWxYQ0krSnlBcklHeGhZbVZzSUNzZ0p6bzhMM1JrUGp4MFpENG5JQ3NnZG1Gc2RXVWdLeUFuUEM5MFpENDhMM1J5UGljN1hHNTlPMXh1WEc1MllYSWdjbVZ6YjJ4MlpWTmphR1Z0WVNBOUlHMXZaSFZzWlM1bGVIQnZjblJ6TG5KbGMyOXNkbVZUWTJobGJXRWdQU0JtZFc1amRHbHZiaUFvYzJOb1pXMWhLU0I3WEc0Z0lHbG1JQ2hmTG1selVHeGhhVzVQWW1wbFkzUW9jMk5vWlcxaExuTmphR1Z0WVNrcElIdGNiaUFnSUNCelkyaGxiV0VnUFNCeVpYTnZiSFpsVTJOb1pXMWhLSE5qYUdWdFlTNXpZMmhsYldFcE8xeHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlITmphR1Z0WVR0Y2JuMDdYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpMbk5wYlhCc1pWSmxaaUE5SUdaMWJtTjBhVzl1SUNodVlXMWxLU0I3WEc0Z0lHbG1JQ2gwZVhCbGIyWWdibUZ0WlNBOVBUMGdKM1Z1WkdWbWFXNWxaQ2NwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdiblZzYkR0Y2JpQWdmVnh1WEc0Z0lHbG1JQ2h1WVcxbExtbHVaR1Y0VDJZb0p5TXZaR1ZtYVc1cGRHbHZibk12SnlrZ1BUMDlJREFwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdibUZ0WlM1emRXSnpkSEpwYm1jb0p5TXZaR1ZtYVc1cGRHbHZibk12Snk1c1pXNW5kR2dwTzF4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1WVcxbE8xeHVJQ0I5WEc1OU8xeHVYRzR2S2lwY2JpQXFJR2hsYkhCbGNpQjBieUJ5WlcxdmRtVWdaWGgwWlc1emFXOXVjeUJoYm1RZ1lXUmtJSFJvWlcwZ2RHOGdZVzRnYjJKcVpXTjBYRzRnS2x4dUlDb2dRSEJoY21GdElHdGxlVzVoYldWY2JpQXFJRUJ3WVhKaGJTQnZZbXBjYmlBcUwxeHViVzlrZFd4bExtVjRjRzl5ZEhNdVpYaDBjbUZqZEVWNGRHVnVjMmx2Ym5NZ1BTQm1kVzVqZEdsdmJpQW9hMlY1Ym1GdFpTd2diMkpxTENCMllXeDFaU2tnZTF4dUlDQnBaaWdoYTJWNWJtRnRaU0I4ZkNBaGIySnFLU0I3WEc0Z0lDQWdjbVYwZFhKdU8xeHVJQ0I5WEc1Y2JpQWdhV1lnS0hSNWNHVnZaaUJyWlhsdVlXMWxJRDA5UFNBbmMzUnlhVzVuSnlBbUppQnJaWGx1WVcxbExtbHVaR1Y0VDJZb0ozZ3RKeWtnUFQwOUlEQXBJSHRjYmlBZ0lDQnZZbW91ZG1WdVpHOXlSWGgwWlc1emFXOXVjeUE5SUc5aWFpNTJaVzVrYjNKRmVIUmxibk5wYjI1eklIeDhJSHQ5TzF4dUlDQWdJR2xtS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0J2WW1vdWRtVnVaRzl5UlhoMFpXNXphVzl1YzF0clpYbHVZVzFsWFNBOUlIWmhiSFZsTzF4dUlDQWdJSDFjYmlBZ0lDQmxiSE5sSUh0Y2JpQWdJQ0FnSUc5aWFpNTJaVzVrYjNKRmVIUmxibk5wYjI1elcydGxlVzVoYldWZElEMGdiMkpxVzJ0bGVXNWhiV1ZkTzF4dUlDQWdJSDFjYmlBZ2ZWeHVmVHNpWFgwPSIsIihmdW5jdGlvbiAoQnVmZmVyKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciByZXF1ZXN0ID0gcmVxdWlyZSgnc3VwZXJhZ2VudCcpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGtleXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMnKVxufTtcblxuLypcbiAqIEpRdWVyeUh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgSlF1ZXJ5SHR0cENsaWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy50eXBlID0gJ0pRdWVyeUh0dHBDbGllbnQnO1xufTtcblxuLypcbiAqIFN1cGVyYWdlbnRIdHRwQ2xpZW50IGlzIGEgbGlnaHQtd2VpZ2h0LCBub2RlIG9yIGJyb3dzZXIgSFRUUCBjbGllbnRcbiAqL1xudmFyIFN1cGVyYWdlbnRIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnU3VwZXJhZ2VudEh0dHBDbGllbnQnO1xufTtcblxuLyoqXG4gKiBTd2FnZ2VySHR0cCBpcyBhIHdyYXBwZXIgZm9yIGV4ZWN1dGluZyByZXF1ZXN0c1xuICovXG52YXIgU3dhZ2dlckh0dHAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHt9O1xuXG5Td2FnZ2VySHR0cC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmosIG9wdHMpIHtcbiAgdmFyIGNsaWVudDtcblxuICBpZihvcHRzICYmIG9wdHMuY2xpZW50KSB7XG4gICAgY2xpZW50ID0gb3B0cy5jbGllbnQ7XG4gIH1cbiAgZWxzZSB7XG4gICAgY2xpZW50ID0gbmV3IFN1cGVyYWdlbnRIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG4gIGNsaWVudC5vcHRzID0gb3B0cyB8fCB7fTtcblxuICBpZiAob3B0cyAmJiBvcHRzLnJlcXVlc3RBZ2VudCkge1xuICAgIHJlcXVlc3QgPSBvcHRzLnJlcXVlc3RBZ2VudDtcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHZhciBoYXNKUXVlcnkgPSBmYWxzZTtcbiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZih0eXBlb2Ygd2luZG93LmpRdWVyeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGhhc0pRdWVyeSA9IHRydWU7XG4gICAgfVxuICB9XG4gIC8vIE9QVElPTlMgc3VwcG9ydFxuICBpZihvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCkgPT09ICdvcHRpb25zJyAmJiBjbGllbnQudHlwZSA9PT0gJ1N1cGVyYWdlbnRIdHRwQ2xpZW50Jykge1xuICAgIGxvZygnZm9yY2luZyBqUXVlcnkgYXMgT1BUSU9OUyBhcmUgbm90IHN1cHBvcnRlZCBieSBTdXBlckFnZW50Jyk7XG4gICAgb2JqLnVzZUpRdWVyeSA9IHRydWU7XG4gIH1cbiAgaWYodGhpcy5pc0ludGVybmV0RXhwbG9yZXIoKSAmJiAob2JqLnVzZUpRdWVyeSA9PT0gZmFsc2UgfHwgIWhhc0pRdWVyeSApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuICBpZiAoKG9iaiAmJiBvYmoudXNlSlF1ZXJ5ID09PSB0cnVlKSB8fCB0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIGhhc0pRdWVyeSkge1xuICAgIGNsaWVudCA9IG5ldyBKUXVlcnlIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG5cbiAgdmFyIHN1Y2Nlc3MgPSBvYmoub24ucmVzcG9uc2U7XG4gIHZhciBlcnJvciA9IG9iai5vbi5lcnJvcjtcblxuICB2YXIgcmVxdWVzdEludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IpIHtcbiAgICAgIGRhdGEgPSBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvci5hcHBseShkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH07XG5cbiAgdmFyIHJlc3BvbnNlSW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IpIHtcbiAgICAgIGRhdGEgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IuYXBwbHkoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZXNzKGRhdGEpO1xuICB9O1xuXG4gIHZhciBlcnJvckludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICBlcnJvcihkYXRhKTtcbiAgfTtcblxuICBvYmoub24uZXJyb3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgZXJyb3JJbnRlcmNlcHRvcihkYXRhKTtcbiAgfTtcblxuICBvYmoub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgcmVzcG9uc2VJbnRlcmNlcHRvcihkYXRhKTtcbiAgfTtcblxuICBpZiAoXy5pc09iamVjdChvYmopICYmIF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgLy8gc3BlY2lhbCBwcm9jZXNzaW5nIGZvciBmaWxlIHVwbG9hZHMgdmlhIGpxdWVyeVxuICAgIGlmIChvYmouYm9keS50eXBlICYmIG9iai5ib2R5LnR5cGUgPT09ICdmb3JtRGF0YScpe1xuICAgICAgaWYob3B0cy51c2VKUXVlcnkpIHtcbiAgICAgICAgb2JqLmNvbnRlbnRUeXBlID0gZmFsc2U7XG4gICAgICAgIG9iai5wcm9jZXNzRGF0YSA9IGZhbHNlO1xuICAgICAgICBkZWxldGUgb2JqLmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9iaiA9IHJlcXVlc3RJbnRlcmNlcHRvcihvYmopIHx8IG9iajtcbiAgaWYgKG9iai5iZWZvcmVTZW5kKSB7XG4gICAgb2JqLmJlZm9yZVNlbmQoZnVuY3Rpb24oX29iaikge1xuICAgICAgY2xpZW50LmV4ZWN1dGUoX29iaiB8fCBvYmopO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNsaWVudC5leGVjdXRlKG9iaik7XG4gIH1cblxuICByZXR1cm4gKG9iai5kZWZlcnJlZCkgPyBvYmouZGVmZXJyZWQucHJvbWlzZSA6IG9iajtcbn07XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5pc0ludGVybmV0RXhwbG9yZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkZXRlY3RlZElFID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci51c2VyQWdlbnQpIHtcbiAgICB2YXIgbmF2ID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKG5hdi5pbmRleE9mKCdtc2llJykgIT09IC0xKSB7XG4gICAgICB2YXIgdmVyc2lvbiA9IHBhcnNlSW50KG5hdi5zcGxpdCgnbXNpZScpWzFdKTtcblxuICAgICAgaWYgKHZlcnNpb24gPD0gOCkge1xuICAgICAgICBkZXRlY3RlZElFID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGV0ZWN0ZWRJRTtcbn07XG5cbkpRdWVyeUh0dHBDbGllbnQucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBqcSA9IHRoaXMualF1ZXJ5IHx8ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cualF1ZXJ5KTtcbiAgdmFyIGNiID0gb2JqLm9uO1xuICB2YXIgcmVxdWVzdCA9IG9iajtcblxuICBpZih0eXBlb2YganEgPT09ICd1bmRlZmluZWQnIHx8IGpxID09PSBmYWxzZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgY29uZmlndXJhdGlvbiEgSlF1ZXJ5IGlzIHJlcXVpcmVkIGJ1dCBub3QgYXZhaWxhYmxlJyk7XG4gIH1cblxuICBvYmoudHlwZSA9IG9iai5tZXRob2Q7XG4gIG9iai5jYWNoZSA9IG9iai5qcXVlcnlBamF4Q2FjaGU7XG4gIG9iai5kYXRhID0gb2JqLmJvZHk7XG4gIGRlbGV0ZSBvYmouanF1ZXJ5QWpheENhY2hlO1xuICBkZWxldGUgb2JqLnVzZUpRdWVyeTtcbiAgZGVsZXRlIG9iai5ib2R5O1xuXG4gIG9iai5jb21wbGV0ZSA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgIHZhciBoZWFkZXJzID0ge307XG4gICAgdmFyIGhlYWRlckFycmF5ID0gcmVzcG9uc2UuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkuc3BsaXQoJ1xcbicpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWFkZXJBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHRvU3BsaXQgPSBoZWFkZXJBcnJheVtpXS50cmltKCk7XG5cbiAgICAgIGlmICh0b1NwbGl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNlcGFyYXRvciA9IHRvU3BsaXQuaW5kZXhPZignOicpO1xuXG4gICAgICBpZiAoc2VwYXJhdG9yID09PSAtMSkge1xuICAgICAgICAvLyBOYW1lIGJ1dCBubyB2YWx1ZSBpbiB0aGUgaGVhZGVyXG4gICAgICAgIGhlYWRlcnNbdG9TcGxpdF0gPSBudWxsO1xuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmFtZSA9IHRvU3BsaXQuc3Vic3RyaW5nKDAsIHNlcGFyYXRvcikudHJpbSgpO1xuICAgICAgdmFyIHZhbHVlID0gdG9TcGxpdC5zdWJzdHJpbmcoc2VwYXJhdG9yICsgMSkudHJpbSgpO1xuXG4gICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIG91dCA9IHtcbiAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICBzdGF0dXNUZXh0OiByZXNwb25zZS5zdGF0dXNUZXh0LFxuICAgICAgZGF0YTogcmVzcG9uc2UucmVzcG9uc2VUZXh0LFxuICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgdmFyIHBvc3NpYmxlT2JqID0gIHJlc3BvbnNlLnJlc3BvbnNlSlNPTiB8fCBqc3lhbWwuc2FmZUxvYWQocmVzcG9uc2UucmVzcG9uc2VUZXh0KTtcbiAgICAgIG91dC5vYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnc3RyaW5nJykgPyB7fSA6IHBvc3NpYmxlT2JqO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAvLyBkbyBub3Qgc2V0IG91dC5vYmpcbiAgICAgIGhlbHBlcnMubG9nKCd1bmFibGUgdG8gcGFyc2UgSlNPTi9ZQU1MIGNvbnRlbnQnKTtcbiAgICB9XG5cbiAgICAvLyBJIGNhbiB0aHJvdywgb3IgcGFyc2UgbnVsbD9cbiAgICBvdXQub2JqID0gb3V0Lm9iaiB8fCBudWxsO1xuXG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA+PSAyMDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgMzAwKSB7XG4gICAgICBjYi5yZXNwb25zZShvdXQpO1xuICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAwIHx8IChyZXNwb25zZS5zdGF0dXMgPj0gNDAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDU5OSkpIHtcbiAgICAgIGNiLmVycm9yKG91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjYi5yZXNwb25zZShvdXQpO1xuICAgIH1cbiAgfTtcblxuICBqcS5zdXBwb3J0LmNvcnMgPSB0cnVlO1xuXG4gIHJldHVybiBqcS5hamF4KG9iaik7XG59O1xuXG5TdXBlcmFnZW50SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGNvbm5lY3Rpb25BZ2VudCA9IG9iai5jb25uZWN0aW9uQWdlbnQ7XG4gIHZhciBtZXRob2QgPSBvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gIHZhciB0aW1lb3V0ID0gb2JqLnRpbWVvdXQ7XG5cbiAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScpIHtcbiAgICBtZXRob2QgPSAnZGVsJztcbiAgfVxuICB2YXIgaGVhZGVycyA9IG9iai5oZWFkZXJzIHx8IHt9O1xuXG4gIGlmIChjb25uZWN0aW9uQWdlbnQpIHtcbiAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LmFnZW50KGNvbm5lY3Rpb25BZ2VudCk7XG4gIH1cblxuICB2YXIgciA9IHJlcXVlc3RbbWV0aG9kXShvYmoudXJsKTtcblxuICBpZiAodGltZW91dCkge1xuICAgIHIudGltZW91dCh0aW1lb3V0KTtcbiAgfVxuXG4gIGlmIChvYmouZW5hYmxlQ29va2llcykge1xuICAgIHIud2l0aENyZWRlbnRpYWxzKCk7XG4gIH1cblxuICB2YXIgYWNjZXB0ID0gb2JqLmhlYWRlcnMuQWNjZXB0O1xuXG4gIGlmKHRoaXMuYmluYXJ5UmVxdWVzdChhY2NlcHQpKSB7XG4gICAgci5vbigncmVxdWVzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmKHRoaXMueGhyKSB7XG4gICAgICAgIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmKG9iai5ib2R5KSB7XG4gICAgaWYoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIHZhciBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCAnJztcbiAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseShvYmouYm9keSkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpIHtcbiAgICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBrZXluYW1lLCB2YWx1ZSwgdjtcbiAgICAgICAgICBmb3IgKGtleW5hbWUgaW4gb2JqLmJvZHkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gb2JqLmJvZHlba2V5bmFtZV07XG4gICAgICAgICAgICBpZihBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICBmb3IodiBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHIuZmllbGQoa2V5bmFtZSwgdik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICByLmZpZWxkKGtleW5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICAgIC8vIG5vbiBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIG9iai5ib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHIuc2VuZChvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5hbWU7XG4gIGZvciAobmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgci5zZXQobmFtZSwgaGVhZGVyc1tuYW1lXSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYgKHJlcy5oZWFkZXJzICYmIHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkge1xuICAgICAgICBpZiAocmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+PSAwKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3BvbnNlLm9iaiA9IEpTT04ucGFyc2UocmVzcG9uc2Uuc3RhdHVzVGV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2IgPSBvYmoub24uZXJyb3I7XG4gICAgfSBlbHNlIGlmIChyZXMgJiYgb2JqLm9uICYmIG9iai5vbi5yZXNwb25zZSkge1xuICAgICAgdmFyIHBvc3NpYmxlT2JqO1xuXG4gICAgICAvLyBBbHJlYWR5IHBhcnNlZCBieSBieSBzdXBlcmFnZW50P1xuICAgICAgaWYgKHJlcy5ib2R5ICYmIF8ua2V5cyhyZXMuYm9keSkubGVuZ3RoID4gMCkge1xuICAgICAgICBwb3NzaWJsZU9iaiA9IHJlcy5ib2R5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgLy8gY2FuIHBhcnNlIGludG8gYSBzdHJpbmcuLi4gd2hpY2ggd2UgZG9uJ3QgbmVlZCBydW5uaW5nIGFyb3VuZCBpbiB0aGUgc3lzdGVtXG4gICAgICAgICAgcG9zc2libGVPYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnc3RyaW5nJykgPyBudWxsIDogcG9zc2libGVPYmo7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnY2Fubm90IHBhcnNlIEpTT04vWUFNTCBjb250ZW50Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgaWYodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBCdWZmZXIuaXNCdWZmZXIocG9zc2libGVPYmopKSB7XG4gICAgICAgIHJlc3BvbnNlLmRhdGEgPSBwb3NzaWJsZU9iajtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXNwb25zZS5vYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnb2JqZWN0JykgPyBwb3NzaWJsZU9iaiA6IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG4gICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gcmVzLnRleHQ7XG4gICAgICBjYiA9IG9iai5vbi5yZXNwb25zZTtcbiAgICB9XG4gICAgaWYgKHJlcy54aHIgJiYgcmVzLnhoci5yZXNwb25zZSkge1xuICAgICAgcmVzcG9uc2UuZGF0YSA9IHJlcy54aHIucmVzcG9uc2U7XG4gICAgfVxuICAgIGVsc2UgaWYoIXJlc3BvbnNlLmRhdGEpIHtcbiAgICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuICAgIH1cblxuICAgIGlmIChjYikge1xuICAgICAgY2IocmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5TdXBlcmFnZW50SHR0cENsaWVudC5wcm90b3R5cGUuIGJpbmFyeVJlcXVlc3QgPSBmdW5jdGlvbiAoYWNjZXB0KSB7XG4gIGlmKCFhY2NlcHQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuICgvXmltYWdlL2kpLnRlc3QoYWNjZXB0KVxuICAgIHx8ICgvXmFwcGxpY2F0aW9uXFwvcGRmLykudGVzdChhY2NlcHQpXG4gICAgfHwgKC9eYXBwbGljYXRpb25cXC9vY3RldC1zdHJlYW0vKS50ZXN0KGFjY2VwdCk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b2RIUndMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzUyWVhJZ2FHVnNjR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZhR1ZzY0dWeWN5Y3BPMXh1ZG1GeUlISmxjWFZsYzNRZ1BTQnlaWEYxYVhKbEtDZHpkWEJsY21GblpXNTBKeWs3WEc1MllYSWdhbk41WVcxc0lEMGdjbVZ4ZFdseVpTZ25hbk10ZVdGdGJDY3BPMXh1ZG1GeUlGOGdQU0I3WEc0Z0lHbHpUMkpxWldOME9pQnlaWEYxYVhKbEtDZHNiMlJoYzJndFkyOXRjR0YwTDJ4aGJtY3ZhWE5QWW1wbFkzUW5LU3hjYmlBZ2EyVjVjem9nY21WeGRXbHlaU2duYkc5a1lYTm9MV052YlhCaGRDOXZZbXBsWTNRdmEyVjVjeWNwWEc1OU8xeHVYRzR2S2x4dUlDb2dTbEYxWlhKNVNIUjBjRU5zYVdWdWRDQnBjeUJoSUd4cFoyaDBMWGRsYVdkb2RDd2dibTlrWlNCdmNpQmljbTkzYzJWeUlFaFVWRkFnWTJ4cFpXNTBYRzRnS2k5Y2JuWmhjaUJLVVhWbGNubElkSFJ3UTJ4cFpXNTBJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0IwYUdsekxuUjVjR1VnUFNBblNsRjFaWEo1U0hSMGNFTnNhV1Z1ZENjN1hHNTlPMXh1WEc0dktseHVJQ29nVTNWd1pYSmhaMlZ1ZEVoMGRIQkRiR2xsYm5RZ2FYTWdZU0JzYVdkb2RDMTNaV2xuYUhRc0lHNXZaR1VnYjNJZ1luSnZkM05sY2lCSVZGUlFJR05zYVdWdWRGeHVJQ292WEc1MllYSWdVM1Z3WlhKaFoyVnVkRWgwZEhCRGJHbGxiblFnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUhSb2FYTXVkSGx3WlNBOUlDZFRkWEJsY21GblpXNTBTSFIwY0VOc2FXVnVkQ2M3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRk4zWVdkblpYSklkSFJ3SUdseklHRWdkM0poY0hCbGNpQm1iM0lnWlhobFkzVjBhVzVuSUhKbGNYVmxjM1J6WEc0Z0tpOWNiblpoY2lCVGQyRm5aMlZ5U0hSMGNDQTlJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdablZ1WTNScGIyNGdLQ2tnZTMwN1hHNWNibE4zWVdkblpYSklkSFJ3TG5CeWIzUnZkSGx3WlM1bGVHVmpkWFJsSUQwZ1puVnVZM1JwYjI0Z0tHOWlhaXdnYjNCMGN5a2dlMXh1SUNCMllYSWdZMnhwWlc1ME8xeHVYRzRnSUdsbUtHOXdkSE1nSmlZZ2IzQjBjeTVqYkdsbGJuUXBJSHRjYmlBZ0lDQmpiR2xsYm5RZ1BTQnZjSFJ6TG1Oc2FXVnVkRHRjYmlBZ2ZWeHVJQ0JsYkhObElIdGNiaUFnSUNCamJHbGxiblFnUFNCdVpYY2dVM1Z3WlhKaFoyVnVkRWgwZEhCRGJHbGxiblFvYjNCMGN5azdYRzRnSUgxY2JpQWdZMnhwWlc1MExtOXdkSE1nUFNCdmNIUnpJSHg4SUh0OU8xeHVYRzRnSUdsbUlDaHZjSFJ6SUNZbUlHOXdkSE11Y21WeGRXVnpkRUZuWlc1MEtTQjdYRzRnSUNBZ2NtVnhkV1Z6ZENBOUlHOXdkSE11Y21WeGRXVnpkRUZuWlc1ME8xeHVJQ0I5WEc1Y2JpQWdMeThnYkdWbllXTjVJSE4xY0hCdmNuUmNiaUFnZG1GeUlHaGhjMHBSZFdWeWVTQTlJR1poYkhObE8xeHVJQ0JwWmloMGVYQmxiMllnZDJsdVpHOTNJQ0U5UFNBbmRXNWtaV1pwYm1Wa0p5a2dlMXh1SUNBZ0lHbG1LSFI1Y0dWdlppQjNhVzVrYjNjdWFsRjFaWEo1SUNFOVBTQW5kVzVrWldacGJtVmtKeWtnZTF4dUlDQWdJQ0FnYUdGelNsRjFaWEo1SUQwZ2RISjFaVHRjYmlBZ0lDQjlYRzRnSUgxY2JpQWdMeThnVDFCVVNVOU9VeUJ6ZFhCd2IzSjBYRzRnSUdsbUtHOWlhaTV0WlhSb2IyUXVkRzlNYjNkbGNrTmhjMlVvS1NBOVBUMGdKMjl3ZEdsdmJuTW5JQ1ltSUdOc2FXVnVkQzUwZVhCbElEMDlQU0FuVTNWd1pYSmhaMlZ1ZEVoMGRIQkRiR2xsYm5RbktTQjdYRzRnSUNBZ2JHOW5LQ2RtYjNKamFXNW5JR3BSZFdWeWVTQmhjeUJQVUZSSlQwNVRJR0Z5WlNCdWIzUWdjM1Z3Y0c5eWRHVmtJR0o1SUZOMWNHVnlRV2RsYm5RbktUdGNiaUFnSUNCdlltb3VkWE5sU2xGMVpYSjVJRDBnZEhKMVpUdGNiaUFnZlZ4dUlDQnBaaWgwYUdsekxtbHpTVzUwWlhKdVpYUkZlSEJzYjNKbGNpZ3BJQ1ltSUNodlltb3VkWE5sU2xGMVpYSjVJRDA5UFNCbVlXeHpaU0I4ZkNBaGFHRnpTbEYxWlhKNUlDa3BJSHRjYmlBZ0lDQjBhSEp2ZHlCdVpYY2dSWEp5YjNJb0oxVnVjM1Z3Y0c5eWRHVmtJR052Ym1acFozVnlZWFJwYjI0aElFcFJkV1Z5ZVNCcGN5QnlaWEYxYVhKbFpDQmlkWFFnYm05MElHRjJZV2xzWVdKc1pTY3BPMXh1SUNCOVhHNGdJR2xtSUNnb2IySnFJQ1ltSUc5aWFpNTFjMlZLVVhWbGNua2dQVDA5SUhSeWRXVXBJSHg4SUhSb2FYTXVhWE5KYm5SbGNtNWxkRVY0Y0d4dmNtVnlLQ2tnSmlZZ2FHRnpTbEYxWlhKNUtTQjdYRzRnSUNBZ1kyeHBaVzUwSUQwZ2JtVjNJRXBSZFdWeWVVaDBkSEJEYkdsbGJuUW9iM0IwY3lrN1hHNGdJSDFjYmx4dUlDQjJZWElnYzNWalkyVnpjeUE5SUc5aWFpNXZiaTV5WlhOd2IyNXpaVHRjYmlBZ2RtRnlJR1Z5Y205eUlEMGdiMkpxTG05dUxtVnljbTl5TzF4dVhHNGdJSFpoY2lCeVpYRjFaWE4wU1c1MFpYSmpaWEIwYjNJZ1BTQm1kVzVqZEdsdmJpaGtZWFJoS1NCN1hHNGdJQ0FnYVdZb2IzQjBjeUFtSmlCdmNIUnpMbkpsY1hWbGMzUkpiblJsY21ObGNIUnZjaWtnZTF4dUlDQWdJQ0FnWkdGMFlTQTlJRzl3ZEhNdWNtVnhkV1Z6ZEVsdWRHVnlZMlZ3ZEc5eUxtRndjR3g1S0dSaGRHRXBPMXh1SUNBZ0lIMWNiaUFnSUNCeVpYUjFjbTRnWkdGMFlUdGNiaUFnZlR0Y2JseHVJQ0IyWVhJZ2NtVnpjRzl1YzJWSmJuUmxjbU5sY0hSdmNpQTlJR1oxYm1OMGFXOXVLR1JoZEdFcElIdGNiaUFnSUNCcFppaHZjSFJ6SUNZbUlHOXdkSE11Y21WemNHOXVjMlZKYm5SbGNtTmxjSFJ2Y2lrZ2UxeHVJQ0FnSUNBZ1pHRjBZU0E5SUc5d2RITXVjbVZ6Y0c5dWMyVkpiblJsY21ObGNIUnZjaTVoY0hCc2VTaGtZWFJoS1R0Y2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlITjFZMk5sYzNNb1pHRjBZU2s3WEc0Z0lIMDdYRzVjYmlBZ2RtRnlJR1Z5Y205eVNXNTBaWEpqWlhCMGIzSWdQU0JtZFc1amRHbHZiaWhrWVhSaEtTQjdYRzRnSUNBZ2FXWW9iM0IwY3lBbUppQnZjSFJ6TG5KbGMzQnZibk5sU1c1MFpYSmpaWEIwYjNJcElIdGNiaUFnSUNBZ0lHUmhkR0VnUFNCdmNIUnpMbkpsYzNCdmJuTmxTVzUwWlhKalpYQjBiM0l1WVhCd2JIa29aR0YwWVNrN1hHNGdJQ0FnZlZ4dUlDQWdJR1Z5Y205eUtHUmhkR0VwTzF4dUlDQjlPMXh1WEc0Z0lHOWlhaTV2Ymk1bGNuSnZjaUE5SUdaMWJtTjBhVzl1S0dSaGRHRXBJSHRjYmlBZ0lDQmxjbkp2Y2tsdWRHVnlZMlZ3ZEc5eUtHUmhkR0VwTzF4dUlDQjlPMXh1WEc0Z0lHOWlhaTV2Ymk1eVpYTndiMjV6WlNBOUlHWjFibU4wYVc5dUtHUmhkR0VwSUh0Y2JpQWdJQ0J5WlhOd2IyNXpaVWx1ZEdWeVkyVndkRzl5S0dSaGRHRXBPMXh1SUNCOU8xeHVYRzRnSUdsbUlDaGZMbWx6VDJKcVpXTjBLRzlpYWlrZ0ppWWdYeTVwYzA5aWFtVmpkQ2h2WW1vdVltOWtlU2twSUh0Y2JpQWdJQ0F2THlCemNHVmphV0ZzSUhCeWIyTmxjM05wYm1jZ1ptOXlJR1pwYkdVZ2RYQnNiMkZrY3lCMmFXRWdhbkYxWlhKNVhHNGdJQ0FnYVdZZ0tHOWlhaTVpYjJSNUxuUjVjR1VnSmlZZ2IySnFMbUp2WkhrdWRIbHdaU0E5UFQwZ0oyWnZjbTFFWVhSaEp5bDdYRzRnSUNBZ0lDQnBaaWh2Y0hSekxuVnpaVXBSZFdWeWVTa2dlMXh1SUNBZ0lDQWdJQ0J2WW1vdVkyOXVkR1Z1ZEZSNWNHVWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lDQWdiMkpxTG5CeWIyTmxjM05FWVhSaElEMGdabUZzYzJVN1hHNGdJQ0FnSUNBZ0lHUmxiR1YwWlNCdlltb3VhR1ZoWkdWeWMxc25RMjl1ZEdWdWRDMVVlWEJsSjEwN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dUlDQjlYRzVjYmlBZ2IySnFJRDBnY21WeGRXVnpkRWx1ZEdWeVkyVndkRzl5S0c5aWFpa2dmSHdnYjJKcU8xeHVJQ0JwWmlBb2IySnFMbUpsWm05eVpWTmxibVFwSUh0Y2JpQWdJQ0J2WW1vdVltVm1iM0psVTJWdVpDaG1kVzVqZEdsdmJpaGZiMkpxS1NCN1hHNGdJQ0FnSUNCamJHbGxiblF1WlhobFkzVjBaU2hmYjJKcUlIeDhJRzlpYWlrN1hHNGdJQ0FnZlNrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ1kyeHBaVzUwTG1WNFpXTjFkR1VvYjJKcUtUdGNiaUFnZlZ4dVhHNGdJSEpsZEhWeWJpQW9iMkpxTG1SbFptVnljbVZrS1NBL0lHOWlhaTVrWldabGNuSmxaQzV3Y205dGFYTmxJRG9nYjJKcU8xeHVmVHRjYmx4dVUzZGhaMmRsY2toMGRIQXVjSEp2ZEc5MGVYQmxMbWx6U1c1MFpYSnVaWFJGZUhCc2IzSmxjaUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnZG1GeUlHUmxkR1ZqZEdWa1NVVWdQU0JtWVd4elpUdGNibHh1SUNCcFppQW9kSGx3Wlc5bUlHNWhkbWxuWVhSdmNpQWhQVDBnSjNWdVpHVm1hVzVsWkNjZ0ppWWdibUYyYVdkaGRHOXlMblZ6WlhKQloyVnVkQ2tnZTF4dUlDQWdJSFpoY2lCdVlYWWdQU0J1WVhacFoyRjBiM0l1ZFhObGNrRm5aVzUwTG5SdlRHOTNaWEpEWVhObEtDazdYRzVjYmlBZ0lDQnBaaUFvYm1GMkxtbHVaR1Y0VDJZb0oyMXphV1VuS1NBaFBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUhaaGNpQjJaWEp6YVc5dUlEMGdjR0Z5YzJWSmJuUW9ibUYyTG5Od2JHbDBLQ2R0YzJsbEp5bGJNVjBwTzF4dVhHNGdJQ0FnSUNCcFppQW9kbVZ5YzJsdmJpQThQU0E0S1NCN1hHNGdJQ0FnSUNBZ0lHUmxkR1ZqZEdWa1NVVWdQU0IwY25WbE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lISmxkSFZ5YmlCa1pYUmxZM1JsWkVsRk8xeHVmVHRjYmx4dVNsRjFaWEo1U0hSMGNFTnNhV1Z1ZEM1d2NtOTBiM1I1Y0dVdVpYaGxZM1YwWlNBOUlHWjFibU4wYVc5dUlDaHZZbW9wSUh0Y2JpQWdkbUZ5SUdweElEMGdkR2hwY3k1cVVYVmxjbmtnZkh3Z0tIUjVjR1Z2WmlCM2FXNWtiM2NnSVQwOUlDZDFibVJsWm1sdVpXUW5JQ1ltSUhkcGJtUnZkeTVxVVhWbGNua3BPMXh1SUNCMllYSWdZMklnUFNCdlltb3ViMjQ3WEc0Z0lIWmhjaUJ5WlhGMVpYTjBJRDBnYjJKcU8xeHVYRzRnSUdsbUtIUjVjR1Z2WmlCcWNTQTlQVDBnSjNWdVpHVm1hVzVsWkNjZ2ZId2dhbkVnUFQwOUlHWmhiSE5sS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUVWeWNtOXlLQ2RWYm5OMWNIQnZjblJsWkNCamIyNW1hV2QxY21GMGFXOXVJU0JLVVhWbGNua2dhWE1nY21WeGRXbHlaV1FnWW5WMElHNXZkQ0JoZG1GcGJHRmliR1VuS1R0Y2JpQWdmVnh1WEc0Z0lHOWlhaTUwZVhCbElEMGdiMkpxTG0xbGRHaHZaRHRjYmlBZ2IySnFMbU5oWTJobElEMGdiMkpxTG1weGRXVnllVUZxWVhoRFlXTm9aVHRjYmlBZ2IySnFMbVJoZEdFZ1BTQnZZbW91WW05a2VUdGNiaUFnWkdWc1pYUmxJRzlpYWk1cWNYVmxjbmxCYW1GNFEyRmphR1U3WEc0Z0lHUmxiR1YwWlNCdlltb3VkWE5sU2xGMVpYSjVPMXh1SUNCa1pXeGxkR1VnYjJKcUxtSnZaSGs3WEc1Y2JpQWdiMkpxTG1OdmJYQnNaWFJsSUQwZ1puVnVZM1JwYjI0Z0tISmxjM0J2Ym5ObEtTQjdYRzRnSUNBZ2RtRnlJR2hsWVdSbGNuTWdQU0I3ZlR0Y2JpQWdJQ0IyWVhJZ2FHVmhaR1Z5UVhKeVlYa2dQU0J5WlhOd2IyNXpaUzVuWlhSQmJHeFNaWE53YjI1elpVaGxZV1JsY25Nb0tTNXpjR3hwZENnblhGeHVKeWs3WEc1Y2JpQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUdobFlXUmxja0Z5Y21GNUxteGxibWQwYURzZ2FTc3JLU0I3WEc0Z0lDQWdJQ0IyWVhJZ2RHOVRjR3hwZENBOUlHaGxZV1JsY2tGeWNtRjVXMmxkTG5SeWFXMG9LVHRjYmx4dUlDQWdJQ0FnYVdZZ0tIUnZVM0JzYVhRdWJHVnVaM1JvSUQwOVBTQXdLU0I3WEc0Z0lDQWdJQ0FnSUdOdmJuUnBiblZsTzF4dUlDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNCMllYSWdjMlZ3WVhKaGRHOXlJRDBnZEc5VGNHeHBkQzVwYm1SbGVFOW1LQ2M2SnlrN1hHNWNiaUFnSUNBZ0lHbG1JQ2h6WlhCaGNtRjBiM0lnUFQwOUlDMHhLU0I3WEc0Z0lDQWdJQ0FnSUM4dklFNWhiV1VnWW5WMElHNXZJSFpoYkhWbElHbHVJSFJvWlNCb1pXRmtaWEpjYmlBZ0lDQWdJQ0FnYUdWaFpHVnljMXQwYjFOd2JHbDBYU0E5SUc1MWJHdzdYRzVjYmlBZ0lDQWdJQ0FnWTI5dWRHbHVkV1U3WEc0Z0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUhaaGNpQnVZVzFsSUQwZ2RHOVRjR3hwZEM1emRXSnpkSEpwYm1jb01Dd2djMlZ3WVhKaGRHOXlLUzUwY21sdEtDazdYRzRnSUNBZ0lDQjJZWElnZG1Gc2RXVWdQU0IwYjFOd2JHbDBMbk4xWW5OMGNtbHVaeWh6WlhCaGNtRjBiM0lnS3lBeEtTNTBjbWx0S0NrN1hHNWNiaUFnSUNBZ0lHaGxZV1JsY25OYmJtRnRaVjBnUFNCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjJZWElnYjNWMElEMGdlMXh1SUNBZ0lDQWdkWEpzT2lCeVpYRjFaWE4wTG5WeWJDeGNiaUFnSUNBZ0lHMWxkR2h2WkRvZ2NtVnhkV1Z6ZEM1dFpYUm9iMlFzWEc0Z0lDQWdJQ0J6ZEdGMGRYTTZJSEpsYzNCdmJuTmxMbk4wWVhSMWN5eGNiaUFnSUNBZ0lITjBZWFIxYzFSbGVIUTZJSEpsYzNCdmJuTmxMbk4wWVhSMWMxUmxlSFFzWEc0Z0lDQWdJQ0JrWVhSaE9pQnlaWE53YjI1elpTNXlaWE53YjI1elpWUmxlSFFzWEc0Z0lDQWdJQ0JvWldGa1pYSnpPaUJvWldGa1pYSnpYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIUnllU0I3WEc0Z0lDQWdJQ0IyWVhJZ2NHOXpjMmxpYkdWUFltb2dQU0FnY21WemNHOXVjMlV1Y21WemNHOXVjMlZLVTA5T0lIeDhJR3B6ZVdGdGJDNXpZV1psVEc5aFpDaHlaWE53YjI1elpTNXlaWE53YjI1elpWUmxlSFFwTzF4dUlDQWdJQ0FnYjNWMExtOWlhaUE5SUNoMGVYQmxiMllnY0c5emMybGliR1ZQWW1vZ1BUMDlJQ2R6ZEhKcGJtY25LU0EvSUh0OUlEb2djRzl6YzJsaWJHVlBZbW83WEc0Z0lDQWdmU0JqWVhSamFDQW9aWGdwSUh0Y2JpQWdJQ0FnSUM4dklHUnZJRzV2ZENCelpYUWdiM1YwTG05aWFseHVJQ0FnSUNBZ2FHVnNjR1Z5Y3k1c2IyY29KM1Z1WVdKc1pTQjBieUJ3WVhKelpTQktVMDlPTDFsQlRVd2dZMjl1ZEdWdWRDY3BPMXh1SUNBZ0lIMWNibHh1SUNBZ0lDOHZJRWtnWTJGdUlIUm9jbTkzTENCdmNpQndZWEp6WlNCdWRXeHNQMXh1SUNBZ0lHOTFkQzV2WW1vZ1BTQnZkWFF1YjJKcUlIeDhJRzUxYkd3N1hHNWNiaUFnSUNCcFppQW9jbVZ6Y0c5dWMyVXVjM1JoZEhWeklENDlJREl3TUNBbUppQnlaWE53YjI1elpTNXpkR0YwZFhNZ1BDQXpNREFwSUh0Y2JpQWdJQ0FnSUdOaUxuSmxjM0J2Ym5ObEtHOTFkQ2s3WEc0Z0lDQWdmU0JsYkhObElHbG1JQ2h5WlhOd2IyNXpaUzV6ZEdGMGRYTWdQVDA5SURBZ2ZId2dLSEpsYzNCdmJuTmxMbk4wWVhSMWN5QStQU0EwTURBZ0ppWWdjbVZ6Y0c5dWMyVXVjM1JoZEhWeklEd2dOVGs1S1NrZ2UxeHVJQ0FnSUNBZ1kySXVaWEp5YjNJb2IzVjBLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2NtVjBkWEp1SUdOaUxuSmxjM0J2Ym5ObEtHOTFkQ2s3WEc0Z0lDQWdmVnh1SUNCOU8xeHVYRzRnSUdweExuTjFjSEJ2Y25RdVkyOXljeUE5SUhSeWRXVTdYRzVjYmlBZ2NtVjBkWEp1SUdweExtRnFZWGdvYjJKcUtUdGNibjA3WEc1Y2JsTjFjR1Z5WVdkbGJuUklkSFJ3UTJ4cFpXNTBMbkJ5YjNSdmRIbHdaUzVsZUdWamRYUmxJRDBnWm5WdVkzUnBiMjRnS0c5aWFpa2dlMXh1SUNCMllYSWdZMjl1Ym1WamRHbHZia0ZuWlc1MElEMGdiMkpxTG1OdmJtNWxZM1JwYjI1QloyVnVkRHRjYmlBZ2RtRnlJRzFsZEdodlpDQTlJRzlpYWk1dFpYUm9iMlF1ZEc5TWIzZGxja05oYzJVb0tUdGNiaUFnZG1GeUlIUnBiV1Z2ZFhRZ1BTQnZZbW91ZEdsdFpXOTFkRHRjYmx4dUlDQnBaaUFvYldWMGFHOWtJRDA5UFNBblpHVnNaWFJsSnlrZ2UxeHVJQ0FnSUcxbGRHaHZaQ0E5SUNka1pXd25PMXh1SUNCOVhHNGdJSFpoY2lCb1pXRmtaWEp6SUQwZ2IySnFMbWhsWVdSbGNuTWdmSHdnZTMwN1hHNWNiaUFnYVdZZ0tHTnZibTVsWTNScGIyNUJaMlZ1ZENrZ2UxeHVJQ0FnSUNBZ2NtVnhkV1Z6ZENBOUlISmxjWFZsYzNRdVlXZGxiblFvWTI5dWJtVmpkR2x2YmtGblpXNTBLVHRjYmlBZ2ZWeHVYRzRnSUhaaGNpQnlJRDBnY21WeGRXVnpkRnR0WlhSb2IyUmRLRzlpYWk1MWNtd3BPMXh1WEc0Z0lHbG1JQ2gwYVcxbGIzVjBLU0I3WEc0Z0lDQWdjaTUwYVcxbGIzVjBLSFJwYldWdmRYUXBPMXh1SUNCOVhHNWNiaUFnYVdZZ0tHOWlhaTVsYm1GaWJHVkRiMjlyYVdWektTQjdYRzRnSUNBZ2NpNTNhWFJvUTNKbFpHVnVkR2xoYkhNb0tUdGNiaUFnZlZ4dVhHNGdJSFpoY2lCaFkyTmxjSFFnUFNCdlltb3VhR1ZoWkdWeWN5NUJZMk5sY0hRN1hHNWNiaUFnYVdZb2RHaHBjeTVpYVc1aGNubFNaWEYxWlhOMEtHRmpZMlZ3ZENrcElIdGNiaUFnSUNCeUxtOXVLQ2R5WlhGMVpYTjBKeXdnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ2FXWW9kR2hwY3k1NGFISXBJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NTRhSEl1Y21WemNHOXVjMlZVZVhCbElEMGdKMkpzYjJJbk8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0I5WEc1Y2JpQWdhV1lvYjJKcUxtSnZaSGtwSUh0Y2JpQWdJQ0JwWmloZkxtbHpUMkpxWldOMEtHOWlhaTVpYjJSNUtTa2dlMXh1SUNBZ0lDQWdkbUZ5SUdOdmJuUmxiblJVZVhCbElEMGdiMkpxTG1obFlXUmxjbk5iSjBOdmJuUmxiblF0Vkhsd1pTZGRJSHg4SUNjbk8xeHVJQ0FnSUNBZ2FXWWdLR052Ym5SbGJuUlVlWEJsTG1sdVpHVjRUMllvSjIxMWJIUnBjR0Z5ZEM5bWIzSnRMV1JoZEdFbktTQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQmtaV3hsZEdVZ2FHVmhaR1Z5YzFzblEyOXVkR1Z1ZEMxVWVYQmxKMTA3WEc0Z0lDQWdJQ0FnSUdsbUtIdDlMblJ2VTNSeWFXNW5MbUZ3Y0d4NUtHOWlhaTVpYjJSNUtTQTlQVDBnSjF0dlltcGxZM1FnUm05eWJVUmhkR0ZkSnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJSEl1YzJWdVpDaHZZbW91WW05a2VTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnZG1GeUlHdGxlVzVoYldVc0lIWmhiSFZsTENCMk8xeHVJQ0FnSUNBZ0lDQWdJR1p2Y2lBb2EyVjVibUZ0WlNCcGJpQnZZbW91WW05a2VTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RtRnNkV1VnUFNCdlltb3VZbTlrZVZ0clpYbHVZVzFsWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtS0VGeWNtRjVMbWx6UVhKeVlYa29kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lHWnZjaWgySUdsdUlIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NpNW1hV1ZzWkNoclpYbHVZVzFsTENCMktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUhJdVptbGxiR1FvYTJWNWJtRnRaU3dnZG1Gc2RXVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnWld4elpTQnBaaUFvWHk1cGMwOWlhbVZqZENodlltb3VZbTlrZVNrcElIdGNiaUFnSUNBZ0lDQWdMeThnYm05dUlHMTFiSFJwY0dGeWRDOW1iM0p0TFdSaGRHRmNiaUFnSUNBZ0lDQWdiMkpxTG1KdlpIa2dQU0JLVTA5T0xuTjBjbWx1WjJsbWVTaHZZbW91WW05a2VTazdYRzRnSUNBZ0lDQWdJSEl1YzJWdVpDaHZZbW91WW05a2VTazdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVJQ0FnSUdWc2MyVWdlMXh1SUNBZ0lDQWdjaTV6Wlc1a0tHOWlhaTVpYjJSNUtUdGNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQjJZWElnYm1GdFpUdGNiaUFnWm05eUlDaHVZVzFsSUdsdUlHaGxZV1JsY25NcElIdGNiaUFnSUNCeUxuTmxkQ2h1WVcxbExDQm9aV0ZrWlhKelcyNWhiV1ZkS1R0Y2JpQWdmVnh1WEc0Z0lHbG1LSFI1Y0dWdlppQnlMbUoxWm1abGNpQTlQVDBnSjJaMWJtTjBhVzl1SnlrZ2UxeHVJQ0FnSUhJdVluVm1abVZ5S0NrN0lDOHZJR1p2Y21ObElITjFjR1Z5WVdkbGJuUWdkRzhnY0c5d2RXeGhkR1VnY21WekxuUmxlSFFnZDJsMGFDQjBhR1VnY21GM0lISmxjM0J2Ym5ObElHUmhkR0ZjYmlBZ2ZWeHVYRzRnSUhJdVpXNWtLR1oxYm1OMGFXOXVJQ2hsY25Jc0lISmxjeWtnZTF4dUlDQWdJSEpsY3lBOUlISmxjeUI4ZkNCN1hHNGdJQ0FnSUNCemRHRjBkWE02SURBc1hHNGdJQ0FnSUNCb1pXRmtaWEp6T2lCN1pYSnliM0k2SUNkdWJ5QnlaWE53YjI1elpTQm1jbTl0SUhObGNuWmxjaWQ5WEc0Z0lDQWdmVHRjYmlBZ0lDQjJZWElnY21WemNHOXVjMlVnUFNCN1hHNGdJQ0FnSUNCMWNtdzZJRzlpYWk1MWNtd3NYRzRnSUNBZ0lDQnRaWFJvYjJRNklHOWlhaTV0WlhSb2IyUXNYRzRnSUNBZ0lDQm9aV0ZrWlhKek9pQnlaWE11YUdWaFpHVnljMXh1SUNBZ0lIMDdYRzRnSUNBZ2RtRnlJR05pTzF4dVhHNGdJQ0FnYVdZZ0tDRmxjbklnSmlZZ2NtVnpMbVZ5Y205eUtTQjdYRzRnSUNBZ0lDQmxjbklnUFNCeVpYTXVaWEp5YjNJN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tHVnljaUFtSmlCdlltb3ViMjRnSmlZZ2IySnFMbTl1TG1WeWNtOXlLU0I3WEc0Z0lDQWdJQ0J5WlhOd2IyNXpaUzVsY25KUFltb2dQU0JsY25JN1hHNGdJQ0FnSUNCeVpYTndiMjV6WlM1emRHRjBkWE1nUFNCeVpYTWdQeUJ5WlhNdWMzUmhkSFZ6SURvZ05UQXdPMXh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVXVjM1JoZEhWelZHVjRkQ0E5SUhKbGN5QS9JSEpsY3k1MFpYaDBJRG9nWlhKeUxtMWxjM05oWjJVN1hHNGdJQ0FnSUNCcFppQW9jbVZ6TG1obFlXUmxjbk1nSmlZZ2NtVnpMbWhsWVdSbGNuTmJKMk52Ym5SbGJuUXRkSGx3WlNkZEtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTXVhR1ZoWkdWeWMxc25ZMjl1ZEdWdWRDMTBlWEJsSjEwdWFXNWtaWGhQWmlnbllYQndiR2xqWVhScGIyNHZhbk52YmljcElENDlJREFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6Y0c5dWMyVXViMkpxSUQwZ1NsTlBUaTV3WVhKelpTaHlaWE53YjI1elpTNXpkR0YwZFhOVVpYaDBLVHRjYmlBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdZMkYwWTJnZ0tHVXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjM0J2Ym5ObExtOWlhaUE5SUc1MWJHdzdYRzRnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOVhHNGdJQ0FnSUNCallpQTlJRzlpYWk1dmJpNWxjbkp2Y2p0Y2JpQWdJQ0I5SUdWc2MyVWdhV1lnS0hKbGN5QW1KaUJ2WW1vdWIyNGdKaVlnYjJKcUxtOXVMbkpsYzNCdmJuTmxLU0I3WEc0Z0lDQWdJQ0IyWVhJZ2NHOXpjMmxpYkdWUFltbzdYRzVjYmlBZ0lDQWdJQzh2SUVGc2NtVmhaSGtnY0dGeWMyVmtJR0o1SUdKNUlITjFjR1Z5WVdkbGJuUS9YRzRnSUNBZ0lDQnBaaUFvY21WekxtSnZaSGtnSmlZZ1h5NXJaWGx6S0hKbGN5NWliMlI1S1M1c1pXNW5kR2dnUGlBd0tTQjdYRzRnSUNBZ0lDQWdJSEJ2YzNOcFlteGxUMkpxSUQwZ2NtVnpMbUp2WkhrN1hHNGdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUhCdmMzTnBZbXhsVDJKcUlEMGdhbk41WVcxc0xuTmhabVZNYjJGa0tISmxjeTUwWlhoMEtUdGNiaUFnSUNBZ0lDQWdJQ0F2THlCallXNGdjR0Z5YzJVZ2FXNTBieUJoSUhOMGNtbHVaeTR1TGlCM2FHbGphQ0IzWlNCa2IyNG5kQ0J1WldWa0lISjFibTVwYm1jZ1lYSnZkVzVrSUdsdUlIUm9aU0J6ZVhOMFpXMWNiaUFnSUNBZ0lDQWdJQ0J3YjNOemFXSnNaVTlpYWlBOUlDaDBlWEJsYjJZZ2NHOXpjMmxpYkdWUFltb2dQVDA5SUNkemRISnBibWNuS1NBL0lHNTFiR3dnT2lCd2IzTnphV0pzWlU5aWFqdGNiaUFnSUNBZ0lDQWdmU0JqWVhSamFDQW9aU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHaGxiSEJsY25NdWJHOW5LQ2RqWVc1dWIzUWdjR0Z5YzJVZ1NsTlBUaTlaUVUxTUlHTnZiblJsYm5RbktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0F2THlCdWRXeHNJRzFsWVc1eklIZGxJR05oYmlkMElIQmhjbk5sSUdsdWRHOGdiMkpxWldOMFhHNGdJQ0FnSUNCcFppaDBlWEJsYjJZZ1FuVm1abVZ5SUQwOVBTQW5ablZ1WTNScGIyNG5JQ1ltSUVKMVptWmxjaTVwYzBKMVptWmxjaWh3YjNOemFXSnNaVTlpYWlrcElIdGNiaUFnSUNBZ0lDQWdjbVZ6Y0c5dWMyVXVaR0YwWVNBOUlIQnZjM05wWW14bFQySnFPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lISmxjM0J2Ym5ObExtOWlhaUE5SUNoMGVYQmxiMllnY0c5emMybGliR1ZQWW1vZ1BUMDlJQ2R2WW1wbFkzUW5LU0EvSUhCdmMzTnBZbXhsVDJKcUlEb2diblZzYkR0Y2JpQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6SUQwZ2NtVnpMbk4wWVhSMWN6dGNiaUFnSUNBZ0lISmxjM0J2Ym5ObExuTjBZWFIxYzFSbGVIUWdQU0J5WlhNdWRHVjRkRHRjYmlBZ0lDQWdJR05pSUQwZ2IySnFMbTl1TG5KbGMzQnZibk5sTzF4dUlDQWdJSDFjYmlBZ0lDQnBaaUFvY21WekxuaG9jaUFtSmlCeVpYTXVlR2h5TG5KbGMzQnZibk5sS1NCN1hHNGdJQ0FnSUNCeVpYTndiMjV6WlM1a1lYUmhJRDBnY21WekxuaG9jaTV5WlhOd2IyNXpaVHRjYmlBZ0lDQjlYRzRnSUNBZ1pXeHpaU0JwWmlnaGNtVnpjRzl1YzJVdVpHRjBZU2tnZTF4dUlDQWdJQ0FnY21WemNHOXVjMlV1WkdGMFlTQTlJSEpsYzNCdmJuTmxMbk4wWVhSMWMxUmxlSFE3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdhV1lnS0dOaUtTQjdYRzRnSUNBZ0lDQmpZaWh5WlhOd2IyNXpaU2s3WEc0Z0lDQWdmVnh1SUNCOUtUdGNibjA3WEc1Y2JsTjFjR1Z5WVdkbGJuUklkSFJ3UTJ4cFpXNTBMbkJ5YjNSdmRIbHdaUzRnWW1sdVlYSjVVbVZ4ZFdWemRDQTlJR1oxYm1OMGFXOXVJQ2hoWTJObGNIUXBJSHRjYmlBZ2FXWW9JV0ZqWTJWd2RDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCbVlXeHpaVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdLQzllYVcxaFoyVXZhU2t1ZEdWemRDaGhZMk5sY0hRcFhHNGdJQ0FnZkh3Z0tDOWVZWEJ3YkdsallYUnBiMjVjWEM5d1pHWXZLUzUwWlhOMEtHRmpZMlZ3ZENsY2JpQWdJQ0I4ZkNBb0wxNWhjSEJzYVdOaGRHbHZibHhjTDI5amRHVjBMWE4wY21WaGJTOHBMblJsYzNRb1lXTmpaWEIwS1R0Y2JuMDdYRzRpWFgwPSIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKSxcbiAgaXNTdHJpbmc6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZycpXG59O1xuXG5cbi8qKlxuICogUmVzb2x2ZXMgYSBzcGVjJ3MgcmVtb3RlIHJlZmVyZW5jZXNcbiAqL1xudmFyIFJlc29sdmVyID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZmFpbGVkVXJscyA9IFtdO1xuICB0aGlzLnJlc29sdmVyQ2FjaGUgPSB7fTtcbiAgdGhpcy5wZW5kaW5nVXJscyA9IHt9O1xufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnByb2Nlc3NBbGxPZiA9IGZ1bmN0aW9uKHJvb3QsIG5hbWUsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpIHtcbiAgdmFyIGksIGxvY2F0aW9uLCBwcm9wZXJ0eTtcblxuICBkZWZpbml0aW9uWyd4LXJlc29sdmVkLWZyb20nXSA9IFsgJyMvZGVmaW5pdGlvbnMvJyArIG5hbWUgXTtcbiAgdmFyIGFsbE9mID0gZGVmaW5pdGlvbi5hbGxPZjtcbiAgLy8gdGhlIHJlZnMgZ28gZmlyc3RcbiAgYWxsT2Yuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgaWYoYS4kcmVmICYmIGIuJHJlZikgeyByZXR1cm4gMDsgfVxuICAgIGVsc2UgaWYoYS4kcmVmKSB7IHJldHVybiAtMTsgfVxuICAgIGVsc2UgeyByZXR1cm4gMTsgfVxuICB9KTtcbiAgZm9yIChpID0gMDsgaSA8IGFsbE9mLmxlbmd0aDsgaSsrKSB7XG4gICAgcHJvcGVydHkgPSBhbGxPZltpXTtcbiAgICBsb2NhdGlvbiA9ICcvZGVmaW5pdGlvbnMvJyArIG5hbWUgKyAnL2FsbE9mJztcbiAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAoc3BlYywgYXJnMSwgYXJnMiwgYXJnMykge1xuICB0aGlzLnNwZWMgPSBzcGVjO1xuICB2YXIgcm9vdCA9IGFyZzEsIGNhbGxiYWNrID0gYXJnMiwgc2NvcGUgPSBhcmczLCBvcHRzID0ge30sIGxvY2F0aW9uLCBpO1xuICBpZih0eXBlb2YgYXJnMSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJvb3QgPSBudWxsO1xuICAgIGNhbGxiYWNrID0gYXJnMTtcbiAgICBzY29wZSA9IGFyZzI7XG4gIH1cbiAgdmFyIF9yb290ID0gcm9vdCwgbW9kZWxOYW1lO1xuICB0aGlzLnNjb3BlID0gKHNjb3BlIHx8IHRoaXMpO1xuICB0aGlzLml0ZXJhdGlvbiA9IHRoaXMuaXRlcmF0aW9uIHx8IDA7XG5cbiAgaWYodGhpcy5zY29wZS5vcHRpb25zICYmIHRoaXMuc2NvcGUub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIG9wdHMucmVxdWVzdEludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmKHRoaXMuc2NvcGUub3B0aW9ucyAmJiB0aGlzLnNjb3BlLm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvcil7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgbmFtZSwgcGF0aCwgcHJvcGVydHksIHByb3BlcnR5TmFtZSwgcGFyYW1ldGVyLCBkb25lLCBjb3VudGVyO1xuICB2YXIgcHJvY2Vzc2VkQ2FsbHMgPSAwLCByZXNvbHZlZFJlZnMgPSB7fSwgdW5yZXNvbHZlZFJlZnMgPSB7fTtcbiAgdmFyIHJlc29sdXRpb25UYWJsZSA9IFtdOyAvLyBzdG9yZSBvYmplY3RzIGZvciBkZXJlZmVyZW5jaW5nXG5cbiAgc3BlYy5kZWZpbml0aW9ucyA9IHNwZWMuZGVmaW5pdGlvbnMgfHwge307XG4gIC8vIGRlZmluaXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIGRlZmluaXRpb24gPSBzcGVjLmRlZmluaXRpb25zW25hbWVdO1xuICAgIGlmKGRlZmluaXRpb24uJHJlZikge1xuICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGRlZmluaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGZvciAocHJvcGVydHlOYW1lIGluIGRlZmluaXRpb24ucHJvcGVydGllcykge1xuICAgICAgICBwcm9wZXJ0eSA9IGRlZmluaXRpb24ucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgICBpZiAoXy5pc0FycmF5KHByb3BlcnR5LmFsbE9mKSkge1xuICAgICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCAnL2RlZmluaXRpb25zJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGRlZmluaXRpb24uYWxsT2YpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gc2hhcmVkIHBhcmFtZXRlcnNcbiAgc3BlYy5wYXJhbWV0ZXJzID0gc3BlYy5wYXJhbWV0ZXJzIHx8IHt9O1xuICBmb3IobmFtZSBpbiBzcGVjLnBhcmFtZXRlcnMpIHtcbiAgICBwYXJhbWV0ZXIgPSBzcGVjLnBhcmFtZXRlcnNbbmFtZV07XG4gICAgaWYgKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknICYmIHBhcmFtZXRlci5zY2hlbWEpIHtcbiAgICAgIGlmKF8uaXNBcnJheShwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgdmFyIF9uYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICBkb25lID0gZmFsc2U7IGNvdW50ZXIgPSAwO1xuICAgICAgICB3aGlsZSghZG9uZSkge1xuICAgICAgICAgIGlmKHR5cGVvZiBzcGVjLmRlZmluaXRpb25zW19uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIF9uYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICBjb3VudGVyICsrO1xuICAgICAgICB9XG4gICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbX25hbWVdID0geyBhbGxPZjogcGFyYW1ldGVyLnNjaGVtYS5hbGxPZiB9O1xuICAgICAgICBkZWxldGUgcGFyYW1ldGVyLnNjaGVtYS5hbGxPZjtcbiAgICAgICAgcGFyYW1ldGVyLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIF9uYW1lO1xuICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBfbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tfbmFtZV0sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHBhcmFtZXRlci5zY2hlbWEsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbWV0ZXIuJHJlZikge1xuICAgICAgLy8gcGFyYW1ldGVyIHJlZmVyZW5jZVxuICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhcmFtZXRlciwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgcGFyYW1ldGVyLiRyZWYpO1xuICAgIH1cbiAgfVxuXG4gIC8vIG9wZXJhdGlvbnNcbiAgZm9yIChuYW1lIGluIHNwZWMucGF0aHMpIHtcbiAgICB2YXIgbWV0aG9kLCBvcGVyYXRpb24sIHJlc3BvbnNlQ29kZTtcbiAgICBwYXRoID0gc3BlYy5wYXRoc1tuYW1lXTtcblxuICAgIGlmKHR5cGVvZiBwYXRoID09PSAnb2JqZWN0Jykge1xuICAgICAgZm9yIChtZXRob2QgaW4gcGF0aCkge1xuICAgICAgICAvLyBvcGVyYXRpb24gcmVmZXJlbmNlXG4gICAgICAgIGlmIChtZXRob2QgPT09ICckcmVmJykge1xuICAgICAgICAgIC8vIGxvY2F0aW9uID0gcGF0aFttZXRob2RdO1xuICAgICAgICAgIGxvY2F0aW9uID0gJy9wYXRocycgKyBuYW1lO1xuICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXRoLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgb3BlcmF0aW9uID0gcGF0aFttZXRob2RdO1xuICAgICAgICAgIHZhciBzaGFyZWRQYXJhbWV0ZXJzID0gcGF0aC5wYXJhbWV0ZXJzIHx8IFtdO1xuICAgICAgICAgIHZhciBwYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgW107XG5cbiAgICAgICAgICBzaGFyZWRQYXJhbWV0ZXJzLmZvckVhY2goZnVuY3Rpb24ocGFyYW1ldGVyKSB7XG4gICAgICAgICAgICBwYXJhbWV0ZXJzLnVuc2hpZnQocGFyYW1ldGVyKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChtZXRob2QgIT09ICdwYXJhbWV0ZXJzJyAmJiBfLmlzT2JqZWN0KG9wZXJhdGlvbikpIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgcGFyYW1ldGVycztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGkgaW4gcGFyYW1ldGVycykge1xuICAgICAgICAgICAgcGFyYW1ldGVyID0gcGFyYW1ldGVyc1tpXTtcbiAgICAgICAgICAgIGxvY2F0aW9uID0gJy9wYXRocycgKyBuYW1lICsgJy8nICsgbWV0aG9kICsgJy9wYXJhbWV0ZXJzJztcblxuICAgICAgICAgICAgaWYgKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknICYmIHBhcmFtZXRlci5zY2hlbWEpIHtcbiAgICAgICAgICAgICAgaWYgKF8uaXNBcnJheShwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgICAgICAgICAgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgICAgICAgICBkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY291bnRlciA9IDA7XG4gICAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzcGVjLmRlZmluaXRpb25zW25hbWVdID0ge2FsbE9mOiBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mfTtcbiAgICAgICAgICAgICAgICBkZWxldGUgcGFyYW1ldGVyLnNjaGVtYS5hbGxPZjtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXIuc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgICAgICAgICAgLy8gcGFyYW1ldGVyIHJlZmVyZW5jZVxuICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGFyYW1ldGVyLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBwYXJhbWV0ZXIuJHJlZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChyZXNwb25zZUNvZGUgaW4gb3BlcmF0aW9uLnJlc3BvbnNlcykge1xuICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gb3BlcmF0aW9uLnJlc3BvbnNlc1tyZXNwb25zZUNvZGVdO1xuICAgICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3Jlc3BvbnNlcy8nICsgcmVzcG9uc2VDb2RlO1xuXG4gICAgICAgICAgICBpZiAoXy5pc09iamVjdChyZXNwb25zZSkpIHtcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLiRyZWYpIHtcbiAgICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2UsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3BvbnNlT2JqID0gcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgaWYgKF8uaXNBcnJheShyZXNwb25zZU9iai5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgICAgICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICAgICAgICAgICAgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICAgICAgZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgY291bnRlciA9IDA7XG4gICAgICAgICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzcGVjLmRlZmluaXRpb25zW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBzcGVjLmRlZmluaXRpb25zW25hbWVdID0ge2FsbE9mOiByZXNwb25zZU9iai5zY2hlbWEuYWxsT2Z9O1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZjtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZU9iai5zY2hlbWEudHlwZTtcbiAgICAgICAgICAgICAgICAgIHJlc3BvbnNlT2JqLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoJ2FycmF5JyA9PT0gcmVzcG9uc2VPYmouc2NoZW1hLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZU9iai5zY2hlbWEuaXRlbXMgJiYgcmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zLiRyZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVzcG9uc2UgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCByZXNwb25zZU9iai5zY2hlbWEuaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCByZXNwb25zZS5zY2hlbWEsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gY2xlYXIgdGhlbSBvdXQgdG8gYXZvaWQgbXVsdGlwbGUgcmVzb2x1dGlvbnNcbiAgICAgIHBhdGgucGFyYW1ldGVycyA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIHZhciBleHBlY3RlZENhbGxzID0gMCwgdG9SZXNvbHZlID0gW107XG4gIC8vIGlmIHRoZSByb290IGlzIHNhbWUgYXMgb2JqW2ldLnJvb3Qgd2UgY2FuIHJlc29sdmUgbG9jYWxseVxuICB2YXIgYWxsID0gcmVzb2x1dGlvblRhYmxlO1xuXG4gIHZhciBwYXJ0cztcbiAgZm9yKGkgPSAwOyBpIDwgYWxsLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGEgPSBhbGxbaV07XG4gICAgaWYocm9vdCA9PT0gYS5yb290KSB7XG4gICAgICBpZihhLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgLy8gcmVzb2x2ZSBhbnkgcGF0aCB3YWxraW5nXG4gICAgICAgIHZhciBqb2luZWQgPSAoKGEucm9vdCB8fCAnJykgKyAnLycgKyBhLmtleSkuc3BsaXQoJy8nKTtcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSBbXTtcbiAgICAgICAgdmFyIHVybCA9ICcnO1xuICAgICAgICB2YXIgaztcblxuICAgICAgICBpZihhLmtleS5pbmRleE9mKCcuLi8nKSA+PSAwKSB7XG4gICAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IGpvaW5lZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYoam9pbmVkW2pdID09PSAnLi4nKSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNsaWNlKDAsIG5vcm1hbGl6ZWQubGVuZ3RoLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQucHVzaChqb2luZWRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IoayA9IDA7IGsgPCBub3JtYWxpemVkLmxlbmd0aDsgayArKykge1xuICAgICAgICAgICAgaWYoayA+IDApIHtcbiAgICAgICAgICAgICAgdXJsICs9ICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVybCArPSBub3JtYWxpemVkW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSBub3cgaGF2ZSB0byByZW1vdGUgcmVzb2x2ZSB0aGlzIGJlY2F1c2UgdGhlIHBhdGggaGFzIGNoYW5nZWRcbiAgICAgICAgICBhLnJvb3QgPSB1cmw7XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcGFydHMgPSBhLmtleS5zcGxpdCgnIycpO1xuICAgICAgICAgIGlmKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgaWYocGFydHNbMF0uaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXJ0c1swXS5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgICAgICAgICAgICBhLnJvb3QgPSBwYXJ0c1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvY2F0aW9uID0gcGFydHNbMV0uc3BsaXQoJy8nKTtcbiAgICAgICAgICAgIHZhciByO1xuICAgICAgICAgICAgdmFyIHMgPSBzcGVjO1xuICAgICAgICAgICAgZm9yKGsgPSAwOyBrIDwgbG9jYXRpb24ubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgdmFyIHBhcnQgPSBsb2NhdGlvbltrXTtcbiAgICAgICAgICAgICAgaWYocGFydCAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICBzID0gc1twYXJ0XTtcbiAgICAgICAgICAgICAgICBpZih0eXBlb2YgcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgIHIgPSBzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHIgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZihyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIG11c3QgcmVzb2x2ZSB0aGlzIHRvb1xuICAgICAgICAgICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAoYS5yZXNvbHZlQXMgPT09ICdpbmxpbmUnKSB7XG4gICAgICAgICAgaWYoYS5rZXkgJiYgYS5rZXkuaW5kZXhPZignIycpID09PSAtMSAmJiBhLmtleS5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICAgICAgLy8gaGFuZGxlIHJlbGF0aXZlIHNjaGVtYVxuICAgICAgICAgICAgcGFydHMgPSBhLnJvb3Quc3BsaXQoJy8nKTtcbiAgICAgICAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgICAgbG9jYXRpb24gKz0gcGFydHNbaV0gKyAnLyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbiArPSBhLmtleTtcbiAgICAgICAgICAgIGEucm9vdCA9IGxvY2F0aW9uO1xuICAgICAgICAgICAgYS5sb2NhdGlvbiA9ICcnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgIH1cbiAgfVxuICBleHBlY3RlZENhbGxzID0gdG9SZXNvbHZlLmxlbmd0aDtcblxuICAvLyByZXNvbHZlIGFueXRoaW5nIHRoYXQgaXMgbG9jYWxcblxuICB2YXIgbG9jayA9IHt9O1xuICBmb3IodmFyIGlpID0gMDsgaWkgPCB0b1Jlc29sdmUubGVuZ3RoOyBpaSsrKSB7XG4gICAgKGZ1bmN0aW9uKGl0ZW0sIHNwZWMsIHNlbGYsIGxvY2ssIGlpKSB7XG4gICAgICBpZighaXRlbS5yb290IHx8IGl0ZW0ucm9vdCA9PT0gcm9vdCkge1xuICAgICAgICAvLyBsb2NhbCByZXNvbHZlXG4gICAgICAgIHNlbGYucmVzb2x2ZUl0ZW0oc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgaWYocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZihzZWxmLmZhaWxlZFVybHMuaW5kZXhPZihpdGVtLnJvb3QpID09PSAtMSkge1xuICAgICAgICB2YXIgb2JqID0ge1xuICAgICAgICAgIHVzZUpRdWVyeTogZmFsc2UsICAvLyBUT0RPXG4gICAgICAgICAgdXJsOiBpdGVtLnJvb3QsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBhY2NlcHQ6IHNlbGYuc2NvcGUuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb246IHtcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2ZhaWxlZCB1cmw6ICcgKyBvYmoudXJsKTtcbiAgICAgICAgICAgICAgc2VsZi5mYWlsZWRVcmxzLnB1c2gob2JqLnVybCk7XG4gICAgICAgICAgICAgIGlmIChsb2NrKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxvY2tbaXRlbS5yb290XTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB1bnJlc29sdmVkUmVmc1tpdGVtLmtleV0gPSB7XG4gICAgICAgICAgICAgICAgcm9vdDogaXRlbS5yb290LFxuICAgICAgICAgICAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgICAgICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgIHZhciBzd2FnZ2VyID0gcmVzcG9uc2Uub2JqO1xuICAgICAgICAgICAgICBpZiAobG9jaykge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBsb2NrW2l0ZW0ucm9vdF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHNlbGYucmVzb2x2ZXJDYWNoZSkge1xuICAgICAgICAgICAgICAgIHNlbGYucmVzb2x2ZXJDYWNoZVtpdGVtLnJvb3RdID0gc3dhZ2dlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzZWxmLnJlc29sdmVJdGVtKHN3YWdnZXIsIGl0ZW0ucm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBpdGVtKTtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcblxuICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIGFwcGx5IHRpbWVvdXQgb25seSB3aGVuIHNwZWNpZmllZFxuICAgICAgICBpZiAoc2NvcGUgJiYgc2NvcGUuZmV0Y2hTcGVjVGltZW91dCkge1xuICAgICAgICAgIG9iai50aW1lb3V0ID0gc2NvcGUuZmV0Y2hTcGVjVGltZW91dDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY29wZSAmJiBzY29wZS5jbGllbnRBdXRob3JpemF0aW9ucykge1xuICAgICAgICAgIHNjb3BlLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG4gICAgICAgIH1cblxuICAgICAgICAoZnVuY3Rpb24gd2FpdEZvclVubG9jaygpIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKGxvY2tbb2JqLnVybF0pIHtcbiAgICAgICAgICAgICAgd2FpdEZvclVubG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIHZhciBjYWNoZWQgPSBzZWxmLnJlc29sdmVyQ2FjaGVbb2JqLnVybF07XG4gICAgICAgICAgICAgIGlmIChfLmlzT2JqZWN0KGNhY2hlZCkpIHtcbiAgICAgICAgICAgICAgICBvYmoub24ucmVzcG9uc2Uoe29iajogY2FjaGVkfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9ja1tvYmoudXJsXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMCk7XG4gICAgICAgIH0pKCk7XG4gICAgICB9XG5cbiAgICAgIGVsc2Uge1xuICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuICAgICAgICB1bnJlc29sdmVkUmVmc1tpdGVtLmtleV0gPSB7XG4gICAgICAgICAgcm9vdDogaXRlbS5yb290LFxuICAgICAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgICAgIH07XG4gICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0odG9SZXNvbHZlW2lpXSwgc3BlYywgdGhpcywgbG9jaywgaWkpKTtcbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyh0b1Jlc29sdmUpLmxlbmd0aCA9PT0gMCkge1xuICAgIHRoaXMuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVJdGVtID0gZnVuY3Rpb24oc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBpdGVtKSB7XG4gIHZhciBwYXRoID0gaXRlbS5sb2NhdGlvbjtcbiAgdmFyIGxvY2F0aW9uID0gc3BlYywgcGFydHMgPSBwYXRoLnNwbGl0KCcvJyk7XG4gIGlmKHBhdGggIT09ICcnKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBwYXJ0cy5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIHNlZ21lbnQgPSBwYXJ0c1tqXTtcbiAgICAgIGlmIChzZWdtZW50LmluZGV4T2YoJ34xJykgIT09IC0xKSB7XG4gICAgICAgIHNlZ21lbnQgPSBwYXJ0c1tqXS5yZXBsYWNlKC9+MC9nLCAnficpLnJlcGxhY2UoL34xL2csICcvJyk7XG4gICAgICAgIGlmIChzZWdtZW50LmNoYXJBdCgwKSAhPT0gJy8nKSB7XG4gICAgICAgICAgc2VnbWVudCA9ICcvJyArIHNlZ21lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbG9jYXRpb24gPT09ICd1bmRlZmluZWQnIHx8IGxvY2F0aW9uID09PSBudWxsKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHNlZ21lbnQgPT09ICcnICYmIGogPT09IChwYXJ0cy5sZW5ndGggLSAxKSAmJiBwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGxvY2F0aW9uID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc2VnbWVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxvY2F0aW9uID0gbG9jYXRpb25bc2VnbWVudF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHZhciByZXNvbHZlZCA9IGl0ZW0ua2V5O1xuICBwYXJ0cyA9IGl0ZW0ua2V5LnNwbGl0KCcvJyk7XG4gIHZhciByZXNvbHZlZE5hbWUgPSBwYXJ0c1twYXJ0cy5sZW5ndGgtMV07XG5cbiAgaWYocmVzb2x2ZWROYW1lLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgcmVzb2x2ZWROYW1lID0gcmVzb2x2ZWROYW1lLnNwbGl0KCcjJylbMV07XG4gIH1cblxuICBpZiAobG9jYXRpb24gIT09IG51bGwgJiYgdHlwZW9mIGxvY2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJlc29sdmVkUmVmc1tyZXNvbHZlZF0gPSB7XG4gICAgICBuYW1lOiByZXNvbHZlZE5hbWUsXG4gICAgICBvYmo6IGxvY2F0aW9uLFxuICAgICAga2V5OiBpdGVtLmtleSxcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgdW5yZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgcm9vdDogaXRlbS5yb290LFxuICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICB9O1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2ssIGxvY2FsUmVzb2x2ZSkge1xuICAvLyB3YWxrIHJlc29sdXRpb24gdGFibGUgYW5kIHJlcGxhY2Ugd2l0aCByZXNvbHZlZCByZWZzXG4gIHZhciByZWYsIGFicztcbiAgZm9yIChyZWYgaW4gcmVzb2x1dGlvblRhYmxlKSB7XG4gICAgdmFyIGl0ZW0gPSByZXNvbHV0aW9uVGFibGVbcmVmXTtcblxuICAgIHZhciBrZXkgPSBpdGVtLmtleTtcbiAgICB2YXIgcmVzb2x2ZWRUbyA9IHJlc29sdmVkUmVmc1trZXldO1xuICAgIGlmIChyZXNvbHZlZFRvKSB7XG4gICAgICBzcGVjLmRlZmluaXRpb25zID0gc3BlYy5kZWZpbml0aW9ucyB8fCB7fTtcbiAgICAgIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgaWYgKGxvY2FsUmVzb2x2ZSAhPT0gdHJ1ZSkge1xuICAgICAgICAgIC8vIGRvbid0IHJldGFpbiByb290IGZvciBsb2NhbCBkZWZpbml0aW9uc1xuICAgICAgICAgIGZvciAoa2V5IGluIHJlc29sdmVkVG8ub2JqKSB7XG4gICAgICAgICAgICBhYnMgPSB0aGlzLnJldGFpblJvb3Qoa2V5LCByZXNvbHZlZFRvLm9ialtrZXldLCBpdGVtLnJvb3QpO1xuICAgICAgICAgICAgcmVzb2x2ZWRUby5vYmpba2V5XSA9IGFicztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tyZXNvbHZlZFRvLm5hbWVdID0gcmVzb2x2ZWRUby5vYmo7XG4gICAgICAgIGl0ZW0ub2JqLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgcmVzb2x2ZWRUby5uYW1lO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgdmFyIHRhcmdldE9iaiA9IGl0ZW0ub2JqO1xuICAgICAgICB0YXJnZXRPYmpbJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyBpdGVtLmtleSBdO1xuICAgICAgICBkZWxldGUgdGFyZ2V0T2JqLiRyZWY7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICBhYnMgPSByZXNvbHZlZFRvLm9ialtrZXldO1xuXG4gICAgICAgICAgaWYgKGxvY2FsUmVzb2x2ZSAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gZG9uJ3QgcmV0YWluIHJvb3QgZm9yIGxvY2FsIGRlZmluaXRpb25zXG4gICAgICAgICAgICBhYnMgPSB0aGlzLnJldGFpblJvb3Qoa2V5LCByZXNvbHZlZFRvLm9ialtrZXldLCBpdGVtLnJvb3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YXJnZXRPYmpba2V5XSA9IGFicztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgZXhpc3RpbmdVbnJlc29sdmVkID0gdGhpcy5jb3VudFVucmVzb2x2ZWRSZWZzKHNwZWMpO1xuXG4gIGlmKGV4aXN0aW5nVW5yZXNvbHZlZCA9PT0gMCB8fCB0aGlzLml0ZXJhdGlvbiA+IDUpIHtcbiAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLmRlZmluaXRpb25zKTtcbiAgICB0aGlzLnJlc29sdmVyQ2FjaGUgPSBudWxsO1xuICAgIGNhbGxiYWNrLmNhbGwodGhpcy5zY29wZSwgc3BlYywgdW5yZXNvbHZlZFJlZnMpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuaXRlcmF0aW9uICs9IDE7XG4gICAgdGhpcy5yZXNvbHZlKHNwZWMsIHJvb3QsIGNhbGxiYWNrLCB0aGlzLnNjb3BlKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmNvdW50VW5yZXNvbHZlZFJlZnMgPSBmdW5jdGlvbihzcGVjKSB7XG4gIHZhciBpO1xuICB2YXIgcmVmcyA9IHRoaXMuZ2V0UmVmcyhzcGVjKTtcbiAgdmFyIGtleXMgPSBbXTtcbiAgdmFyIHVucmVzb2x2ZWRLZXlzID0gW107XG4gIGZvcihpIGluIHJlZnMpIHtcbiAgICBpZihpLmluZGV4T2YoJyMnKSA9PT0gMCkge1xuICAgICAga2V5cy5wdXNoKGkuc3Vic3RyaW5nKDEpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB1bnJlc29sdmVkS2V5cy5wdXNoKGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHZlcmlmeSBwb3NzaWJsZSBrZXlzXG4gIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnQgPSBrZXlzW2ldO1xuICAgIHZhciBwYXJ0cyA9IHBhcnQuc3BsaXQoJy8nKTtcbiAgICB2YXIgb2JqID0gc3BlYztcblxuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcGFydHMubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciBrZXkgPSBwYXJ0c1trXTtcbiAgICAgIGlmKGtleSAhPT0gJycpIHtcbiAgICAgICAgb2JqID0gb2JqW2tleV07XG4gICAgICAgIGlmKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChwYXJ0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdW5yZXNvbHZlZEtleXMubGVuZ3RoO1xufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmdldFJlZnMgPSBmdW5jdGlvbihzcGVjLCBvYmopIHtcbiAgb2JqID0gb2JqIHx8IHNwZWM7XG4gIHZhciBvdXRwdXQgPSB7fTtcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKCFvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoa2V5ID09PSAnJHJlZicgJiYgdHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBvdXRwdXRbaXRlbV0gPSBudWxsO1xuICAgIH1cbiAgICBlbHNlIGlmKF8uaXNPYmplY3QoaXRlbSkpIHtcbiAgICAgIHZhciBvID0gdGhpcy5nZXRSZWZzKGl0ZW0pO1xuICAgICAgZm9yKHZhciBrIGluIG8pIHtcbiAgICAgICAgb3V0cHV0W2tdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmZ1bmN0aW9uIHNwbGl0VXJsKHVybCkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBwcm90byA9IC9bYS16XSs6XFwvXFwvL2kuZXhlYyh1cmwpO1xuICBpZiAocHJvdG8pIHtcbiAgICByZXN1bHQucHJvdG8gPSBwcm90b1swXS5zbGljZSgwLCAtMyk7XG4gICAgdXJsID0gdXJsLnNsaWNlKHJlc3VsdC5wcm90by5sZW5ndGggKyAxKTtcbiAgfVxuICBpZiAodXJsLnNsaWNlKDAsIDIpID09PSAnLy8nKSB7XG4gICAgcmVzdWx0LmRvbWFpbiA9IHVybC5zbGljZSgyKS5zcGxpdCgnLycpWzBdO1xuICAgIHVybCA9IHVybC5zbGljZSgyICsgcmVzdWx0LmRvbWFpbi5sZW5ndGgpO1xuICB9XG4gIHZhciBwID0gdXJsLnNwbGl0KCcjJyk7XG4gIGlmIChwWzBdLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRoID0gcFswXTtcbiAgfVxuICBpZiAocC5sZW5ndGggPiAxKSB7XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcC5zbGljZSgxKS5qb2luKCcjJyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gdW5zcGxpdFVybCh1cmwpIHtcbiAgdmFyIHJlc3VsdCA9IHVybC5wYXRoO1xuICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXN1bHQgPSAnJztcbiAgfVxuICBpZiAodXJsLmZyYWdtZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXN1bHQgKz0gJyMnICsgdXJsLmZyYWdtZW50O1xuICB9XG4gIGlmICh1cmwuZG9tYWluICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAocmVzdWx0LnNsaWNlKDAsIDEpID09PSAnLycpIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgxKTtcbiAgICB9XG4gICAgcmVzdWx0ID0gJy8vJyArIHVybC5kb21haW4gKyAnLycgKyByZXN1bHQ7XG4gICAgaWYgKHVybC5wcm90byAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgPSB1cmwucHJvdG8gKyAnOicgKyByZXN1bHQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGpvaW5VcmwoYmFzZSwgcmVsKSB7XG4gIHZhciByZWxzcCA9IHNwbGl0VXJsKHJlbCk7XG4gIGlmIChyZWxzcC5kb21haW4gIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiByZWw7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IHNwbGl0VXJsKGJhc2UpO1xuICBpZiAocmVsc3AucGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gY2hhbmdlIG9ubHkgZnJhZ21lbnQgcGFydFxuICAgIHJlc3VsdC5mcmFnbWVudCA9IHJlbHNwLmZyYWdtZW50O1xuICB9IGVsc2UgaWYgKHJlbHNwLnBhdGguc2xpY2UoMCwgMSkgPT09ICcvJykge1xuICAgIC8vIHJlbGF0aXZlIHRvIGRvbWFpblxuICAgIHJlc3VsdC5wYXRoID0gcmVsc3AucGF0aDtcbiAgICByZXN1bHQuZnJhZ21lbnQgPSByZWxzcC5mcmFnbWVudDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWxhdGl2ZSB0byBwYXRoXG4gICAgdmFyIHBhdGggPSByZXN1bHQucGF0aCA9PT0gdW5kZWZpbmVkID8gW10gOiByZXN1bHQucGF0aC5zcGxpdCgnLycpO1xuICAgIHZhciByZWxwYXRoID0gcmVsc3AucGF0aC5zcGxpdCgnLycpO1xuICAgIGlmIChwYXRoLmxlbmd0aCkge1xuICAgICAgcGF0aC5wb3AoKTtcbiAgICB9XG4gICAgd2hpbGUgKHJlbHBhdGhbMF0gPT09ICcuLicgfHwgcmVscGF0aFswXSA9PT0gJy4nKSB7XG4gICAgICBpZiAocmVscGF0aFswXSA9PT0gJy4uJykge1xuICAgICAgICBwYXRoLnBvcCgpO1xuICAgICAgfVxuICAgICAgcmVscGF0aC5zaGlmdCgpO1xuICAgIH1cbiAgICByZXN1bHQucGF0aCA9IHBhdGguY29uY2F0KHJlbHBhdGgpLmpvaW4oJy8nKTtcbiAgICByZXN1bHQuZnJhZ21lbnQgPSByZWxzcC5mcmFnbWVudDtcbiAgfVxuICByZXR1cm4gdW5zcGxpdFVybChyZXN1bHQpO1xufVxuXG5SZXNvbHZlci5wcm90b3R5cGUucmV0YWluUm9vdCA9IGZ1bmN0aW9uKG9yaWdLZXksIG9iaiwgcm9vdCkge1xuICAvLyB3YWxrIG9iamVjdCBhbmQgbG9vayBmb3IgcmVsYXRpdmUgJHJlZnNcbiAgaWYoXy5pc09iamVjdChvYmopKSB7XG4gICAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgICAgaWYgKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICBvYmpba2V5XSA9IGpvaW5Vcmwocm9vdCwgaXRlbSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICAgIHRoaXMucmV0YWluUm9vdChrZXksIGl0ZW0sIHJvb3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIGlmKF8uaXNTdHJpbmcob2JqKSAmJiBvcmlnS2V5ID09PSAnJHJlZicpIHtcbiAgICBvYmogPSBqb2luVXJsKHJvb3QsIG9iaik7XG4gIH1cbiAgcmV0dXJuIG9iajtcbn07XG5cbi8qKlxuICogaW1tZWRpYXRlbHkgaW4tbGluZXMgbG9jYWwgcmVmcywgcXVldWVzIHJlbW90ZSByZWZzXG4gKiBmb3IgaW5saW5lIHJlc29sdXRpb25cbiAqL1xuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVJbmxpbmUgPSBmdW5jdGlvbiAocm9vdCwgc3BlYywgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKSB7XG4gIHZhciBrZXkgPSBwcm9wZXJ0eS4kcmVmLCByZWYgPSBwcm9wZXJ0eS4kcmVmLCBpLCBwLCBwMiwgcnM7XG4gIHZhciByb290VHJpbW1lZCA9IGZhbHNlO1xuXG4gIHJvb3QgPSByb290IHx8ICcnOyAvLyBHdWFyZCBhZ2FpbnN0IC5zcGxpdC4gQGZlaGd1eSwgeW91J2xsIG5lZWQgdG8gY2hlY2sgaWYgdGhpcyBsb2dpYyBmaXRzXG4gIC8vIE1vcmUgaW1wb3JhbnRseSBpcyBob3cgZG8gd2UgZ3JhY2VmdWxseSBoYW5kbGUgcmVsYXRpdmUgdXJscywgd2hlbiBwcm92aWRlZCBqdXN0IGEgJ3NwZWMnLCBub3QgYSAndXJsJyA/XG5cbiAgaWYgKHJlZikge1xuICAgIGlmKHJlZi5pbmRleE9mKCcuLi8nKSA9PT0gMCkge1xuICAgICAgLy8gcmVzZXQgcm9vdFxuICAgICAgcCA9IHJlZi5zcGxpdCgnLi4vJyk7XG4gICAgICBwMiA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIHJlZiA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZihwW2ldID09PSAnJykge1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoLTEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJlZiArPSBwW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBwMi5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYoaSA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgcm9vdCArPSBwMltpXTtcbiAgICAgIH1cbiAgICAgIHJvb3RUcmltbWVkID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIHAgID0gcm9vdC5zcGxpdCgnLy8nKTtcbiAgICAgICAgcDIgPSBwWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgIHJvb3QgPSBwWzBdICsgJy8vJyArIHAyWzBdICsgcnNbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcnNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcnMgPSByZWYuc3BsaXQoJyMnKTtcbiAgICAgICAgaWYocnNbMF0gIT09ICcnKSB7XG4gICAgICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgcDIgPSBwMi5zbGljZSgwLCBwMi5sZW5ndGggLSAxKTtcbiAgICAgICAgICBpZighcm9vdFRyaW1tZWQpIHtcbiAgICAgICAgICAgIHJvb3QgPSAnJztcbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcDIubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgaWYoayA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgICAgICAgcm9vdCArPSBwMltrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcm9vdCArPSAnLycgKyByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocmVmLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcmVmLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignIycpID49IDApIHtcbiAgICAgICAgcm9vdCA9IHJlZi5zcGxpdCgnIycpWzBdO1xuICAgICAgICBsb2NhdGlvbiA9IHJlZi5zcGxpdCgnIycpWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJvb3QgPSByZWY7XG4gICAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgICB9XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJyMnKSA9PT0gMCkge1xuICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfSBlbHNlIGlmIChyZWYuaW5kZXhPZignLycpID09PSAwICYmIHJlZi5pbmRleE9mKCcjJykgPT09IC0xKSB7XG4gICAgICBsb2NhdGlvbiA9IHJlZjtcbiAgICAgIHZhciBtYXRjaGVzID0gcm9vdC5tYXRjaCgvXmh0dHBzP1xcOlxcL1xcLyhbXlxcLz8jXSspKD86W1xcLz8jXXwkKS9pKTtcbiAgICAgIGlmKG1hdGNoZXMpIHtcbiAgICAgICAgcm9vdCA9IG1hdGNoZXNbMF0gKyByZWYuc3Vic3RyaW5nKDEpO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHkuaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZVRvID0gZnVuY3Rpb24gKHJvb3QsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKSB7XG4gIHZhciBzcCwgaTtcbiAgdmFyIHJlZiA9IHByb3BlcnR5LiRyZWY7XG4gIHZhciBscm9vdCA9IHJvb3Q7XG4gIGlmICgodHlwZW9mIHJlZiAhPT0gJ3VuZGVmaW5lZCcpICYmIChyZWYgIT09IG51bGwpKSB7XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICB2YXIgcGFydHMgPSByZWYuc3BsaXQoJyMnKTtcblxuICAgICAgLy8gIy9kZWZpbml0aW9ucy9mb29cbiAgICAgIC8vIGZvby5qc29uIy9iYXJcbiAgICAgIGlmKHBhcnRzWzBdICYmIHJlZi5pbmRleE9mKCcvJykgPT09IDApIHtcblxuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiAocGFydHNbMF0uaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXJ0c1swXS5pbmRleE9mKCdodHRwczonKSA9PT0gMCkpIHtcbiAgICAgICAgbHJvb3QgPSBwYXJ0c1swXTtcbiAgICAgICAgcmVmID0gcGFydHNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHBhcnRzWzBdICYmIHBhcnRzWzBdLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gcmVsYXRpdmUgZmlsZVxuICAgICAgICBzcCA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgICAgbHJvb3QgPSAnJztcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc3AubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgbHJvb3QgKz0gc3BbaV0gKyAnLyc7XG4gICAgICAgIH1cbiAgICAgICAgbHJvb3QgKz0gcGFydHNbMF07XG4gICAgICB9XG4gICAgICBlbHNlIHtcblxuICAgICAgfVxuXG4gICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZWYuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCByZWYuaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICAgIGxyb290ID0gcmVmO1xuICAgICAgbG9jYXRpb24gPSAnJztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAvLyByZWxhdGl2ZSBmaWxlXG4gICAgICBzcCA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIGxyb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBzcC5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgbHJvb3QgKz0gc3BbaV0gKyAnLyc7XG4gICAgICB9XG4gICAgICBscm9vdCArPSByZWY7XG4gICAgICBsb2NhdGlvbiA9ICcnO1xuICAgIH1cbiAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7XG4gICAgICBvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdyZWYnLCByb290OiBscm9vdCwga2V5OiByZWYsIGxvY2F0aW9uOiBsb2NhdGlvblxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHByb3BlcnR5LnR5cGUgPT09ICdhcnJheScpIHtcbiAgICB2YXIgaXRlbXMgPSBwcm9wZXJ0eS5pdGVtcztcbiAgICB0aGlzLnJlc29sdmVUbyhyb290LCBpdGVtcywgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgaWYocHJvcGVydHkgJiYgKHByb3BlcnR5LnByb3BlcnRpZXMgfHwgcHJvcGVydHkuYWRkaXRpb25hbFByb3BlcnRpZXMpKSB7XG4gICAgICB2YXIgbmFtZSA9IHRoaXMudW5pcXVlTmFtZSgnaW5saW5lX21vZGVsJyk7XG4gICAgICBpZiAocHJvcGVydHkudGl0bGUpIHtcbiAgICAgICAgbmFtZSA9IHRoaXMudW5pcXVlTmFtZShwcm9wZXJ0eS50aXRsZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgcHJvcGVydHkudGl0bGU7XG4gICAgICB0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG4gICAgICBwcm9wZXJ0eS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICBkZWxldGUgcHJvcGVydHkudHlwZTtcbiAgICAgIGRlbGV0ZSBwcm9wZXJ0eS5wcm9wZXJ0aWVzO1xuICAgIH1cbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnVuaXF1ZU5hbWUgPSBmdW5jdGlvbihiYXNlKSB7XG4gIHZhciBuYW1lID0gYmFzZTtcbiAgdmFyIGNvdW50ID0gMDtcbiAgd2hpbGUodHJ1ZSkge1xuICAgIGlmKCFfLmlzT2JqZWN0KHRoaXMuc3BlYy5kZWZpbml0aW9uc1tuYW1lXSkpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gYmFzZSArICdfJyArIGNvdW50O1xuICAgIGNvdW50Kys7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlQWxsT2YgPSBmdW5jdGlvbihzcGVjLCBvYmosIGRlcHRoKSB7XG4gIGRlcHRoID0gZGVwdGggfHwgMDtcbiAgb2JqID0gb2JqIHx8IHNwZWM7XG4gIHZhciBuYW1lO1xuICBmb3IodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihpdGVtID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdTd2FnZ2VyIDIuMCBkb2VzIG5vdCBzdXBwb3J0IG51bGwgdHlwZXMgKCcgKyBvYmogKyAnKS4gIFNlZSBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci1zcGVjL2lzc3Vlcy8yMjkuJyk7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgdGhpcy5yZXNvbHZlQWxsT2Yoc3BlYywgaXRlbSwgZGVwdGggKyAxKTtcbiAgICB9XG4gICAgaWYoaXRlbSAmJiB0eXBlb2YgaXRlbS5hbGxPZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBhbGxPZiA9IGl0ZW0uYWxsT2Y7XG4gICAgICBpZihfLmlzQXJyYXkoYWxsT2YpKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSBfLmNsb25lRGVlcChpdGVtKTtcbiAgICAgICAgZGVsZXRlIG91dHB1dC5hbGxPZjtcblxuICAgICAgICBvdXRwdXRbJ3gtY29tcG9zZWQnXSA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbVsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgb3V0cHV0Wyd4LXJlc29sdmVkLWZyb20nXSA9IGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGFsbE9mLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGNvbXBvbmVudCA9IGFsbE9mW2ldO1xuICAgICAgICAgIHZhciBzb3VyY2UgPSAnc2VsZic7XG4gICAgICAgICAgaWYodHlwZW9mIGNvbXBvbmVudFsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBzb3VyY2UgPSBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddWzBdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvcih2YXIgcGFydCBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGlmKCFvdXRwdXQuaGFzT3duUHJvcGVydHkocGFydCkpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdID0gXy5jbG9uZURlZXAoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgaWYocGFydCA9PT0gJ3Byb3BlcnRpZXMnKSB7XG4gICAgICAgICAgICAgICAgZm9yKG5hbWUgaW4gb3V0cHV0W3BhcnRdKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbcGFydF1bbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gc291cmNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0gY29tcG9uZW50W3BhcnRdO1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydGllc1tuYW1lXSk7XG4gICAgICAgICAgICAgICAgICB2YXIgcmVzb2x2ZWRGcm9tID0gcHJvcGVydGllc1tuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ107XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc29sdmVkRnJvbSA9PT0gJ3VuZGVmaW5lZCcgfHwgcmVzb2x2ZWRGcm9tID09PSAnc2VsZicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRGcm9tID0gc291cmNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb3V0cHV0LnByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gcmVzb2x2ZWRGcm9tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKHBhcnQgPT09ICdyZXF1aXJlZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBtZXJnZSAmIGRlZHVwIHRoZSByZXF1aXJlZCBhcnJheVxuICAgICAgICAgICAgICAgIHZhciBhID0gb3V0cHV0LnJlcXVpcmVkLmNvbmNhdChjb21wb25lbnRbcGFydF0pO1xuICAgICAgICAgICAgICAgIGZvcih2YXIgayA9IDA7IGsgPCBhLmxlbmd0aDsgKytrKSB7XG4gICAgICAgICAgICAgICAgICBmb3IodmFyIGogPSBrICsgMTsgaiA8IGEubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgICAgICAgICAgaWYoYVtrXSA9PT0gYVtqXSkgeyBhLnNwbGljZShqLS0sIDEpOyB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG91dHB1dC5yZXF1aXJlZCA9IGE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAneC1yZXNvbHZlZC1mcm9tJykge1xuICAgICAgICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10ucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IG5lZWQgdG8gbWVyZ2UgdGhpcyBwcm9wZXJ0eVxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCd3aGF0IHRvIGRvIHdpdGggJyArIHBhcnQpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgb2JqW2tleV0gPSBvdXRwdXQ7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRW1wdHk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5JyksXG4gIG1hcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL21hcCcpLFxuICBpbmRleE9mOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2FycmF5L2luZGV4T2YnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGtleXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKVxufTtcblxudmFyIG9wdGlvbkh0bWwgPSBtb2R1bGUuZXhwb3J0cy5vcHRpb25IdG1sID0gZnVuY3Rpb24gIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxubW9kdWxlLmV4cG9ydHMudHlwZUZyb21Kc29uU2NoZW1hID0gZnVuY3Rpb24gKHR5cGUsIGZvcm1hdCkge1xuICB2YXIgc3RyO1xuXG4gIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIHR5cGVvZiBmb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciA9ICdkYXRlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHN0ciA9ICdzdHJpbmcnO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn07XG5cbnZhciBnZXRTdHJpbmdTaWduYXR1cmUgPSBtb2R1bGUuZXhwb3J0cy5nZXRTdHJpbmdTaWduYXR1cmUgPSBmdW5jdGlvbiAob2JqLCBiYXNlQ29tcG9uZW50KSB7XG4gIHZhciBzdHIgPSAnJztcblxuICBpZiAodHlwZW9mIG9iai4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSBIZWxwZXJzLnNpbXBsZVJlZihvYmouJHJlZik7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9iai50eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnb2JqZWN0JztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIGlmIChiYXNlQ29tcG9uZW50KSB7XG4gICAgICBzdHIgKz0gZ2V0U3RyaW5nU2lnbmF0dXJlKChvYmouaXRlbXMgfHwgb2JqLiRyZWYgfHwge30pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICdBcnJheVsnO1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgICBzdHIgKz0gJ10nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQzMicpIHtcbiAgICBzdHIgKz0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2ludDY0Jykge1xuICAgIHN0ciArPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiB0eXBlb2Ygb2JqLmZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnc3RyaW5nJyAmJiBvYmouZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgIHN0ciArPSAnZGF0ZS10aW1lJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgc3RyICs9ICdkYXRlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdzdHJpbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyICs9ICdmbG9hdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdudW1iZXInICYmIG9iai5mb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2Ygb2JqLmZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciArPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAob2JqLiRyZWYpIHtcbiAgICBzdHIgKz0gSGVscGVycy5zaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2Uge1xuICAgIHN0ciArPSBvYmoudHlwZTtcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG52YXIgc2NoZW1hVG9KU09OID0gbW9kdWxlLmV4cG9ydHMuc2NoZW1hVG9KU09OID0gZnVuY3Rpb24gKHNjaGVtYSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gZnVuY3Rpb24ocHJvcCl7XG4gICAgICByZXR1cm4gKHByb3AgfHwge30pLmRlZmF1bHQ7XG4gICAgfTtcbiAgfVxuXG4gIG1vZGVsc1RvSWdub3JlPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICB2YXIgZm9ybWF0ID0gc2NoZW1hLmZvcm1hdDtcbiAgdmFyIG1vZGVsO1xuICB2YXIgb3V0cHV0O1xuXG4gIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZXhhbXBsZSkpIHtcbiAgICBvdXRwdXQgPSBzY2hlbWEuZXhhbXBsZTtcbiAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykgJiYgXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgIG91dHB1dCA9IHNjaGVtYS5lbnVtWzBdO1xuICB9XG5cbiAgaWYgKF8uaXNVbmRlZmluZWQob3V0cHV0KSkge1xuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpXTtcblxuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSkpIHtcbiAgICAgICAgICBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSA9IG1vZGVsO1xuICAgICAgICAgIG91dHB1dCA9IHNjaGVtYVRvSlNPTihtb2RlbC5kZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICAgIGRlbGV0ZSBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobW9kZWwudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgb3V0cHV0ID0gW107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG91dHB1dCA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgICBvdXRwdXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0ID0gJ3N0cmluZyc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgIG91dHB1dCA9IDA7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgb3V0cHV0ID0gMC4wO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBvdXRwdXQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG91dHB1dCA9IHt9O1xuXG4gICAgICBfLmZvckVhY2goc2NoZW1hLnByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wZXJ0eSwgbmFtZSkge1xuICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhwcm9wZXJ0eSk7XG5cbiAgICAgICAgb3V0cHV0W25hbWVdID0gc2NoZW1hVG9KU09OKGNQcm9wZXJ0eSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgb3V0cHV0ID0gW107XG5cbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBfLmZvckVhY2goc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHNjaGVtYVRvSlNPTihpdGVtLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHNjaGVtYVRvSlNPTihzY2hlbWEuaXRlbXMsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goe30pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgSGVscGVycy5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHByb3BlcnR5IGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLnNjaGVtYVRvSFRNTCA9ZnVuY3Rpb24gKG5hbWUsIHNjaGVtYSwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdmFyIHN0cm9uZ09wZW4gPSAnPHNwYW4gY2xhc3M9XCJzdHJvbmdcIj4nO1xuICB2YXIgc3Ryb25nQ2xvc2UgPSAnPC9zcGFuPic7XG5cbiAgLy8gQWxsb3cgZm9yIGlnbm9yaW5nIHRoZSAnbmFtZScgYXJndW1lbnQuLi4uIHNoaWZ0aW5nIHRoZSByZXN0XG4gIGlmKF8uaXNPYmplY3QoYXJndW1lbnRzWzBdKSkge1xuICAgIG5hbWUgPSB2b2lkIDA7XG4gICAgc2NoZW1hID0gYXJndW1lbnRzWzBdO1xuICAgIG1vZGVscyA9IGFyZ3VtZW50c1sxXTtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBhcmd1bWVudHNbMl07XG4gIH1cblxuICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gIHNjaGVtYSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gIC8vIFJldHVybiBmb3IgZW1wdHkgb2JqZWN0XG4gIGlmKF8uaXNFbXB0eShzY2hlbWEpKSB7XG4gICAgcmV0dXJuIHN0cm9uZ09wZW4gKyAnRW1wdHknICsgc3Ryb25nQ2xvc2U7XG4gIH1cblxuICAvLyBEZXJlZmVyZW5jZSAkcmVmIGZyb20gJ21vZGVscydcbiAgaWYodHlwZW9mIHNjaGVtYS4kcmVmID09PSAnc3RyaW5nJykge1xuICAgIG5hbWUgPSBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgc2NoZW1hID0gbW9kZWxzW25hbWVdO1xuICAgIGlmKHR5cGVvZiBzY2hlbWEgPT09ICd1bmRlZmluZWQnKVxuICAgIHtcbiAgICAgIHJldHVybiBzdHJvbmdPcGVuICsgbmFtZSArICcgaXMgbm90IGRlZmluZWQhJyArIHN0cm9uZ0Nsb3NlO1xuICAgIH1cbiAgfVxuXG4gIGlmKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgIG5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCc7XG4gIH1cblxuICAvLyBJZiB3ZSBhcmUgYSBNb2RlbCBvYmplY3QuLi4gYWRqdXN0IGFjY29yZGluZ2x5XG4gIGlmKHNjaGVtYS5kZWZpbml0aW9uKSB7XG4gICAgc2NoZW1hID0gc2NoZW1hLmRlZmluaXRpb247XG4gIH1cblxuICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gZnVuY3Rpb24ocHJvcCl7XG4gICAgICByZXR1cm4gKHByb3AgfHwge30pLmRlZmF1bHQ7XG4gICAgfTtcbiAgfVxuXG4gIHZhciByZWZlcmVuY2VzID0ge307XG4gIHZhciBzZWVuTW9kZWxzID0gW107XG4gIHZhciBpbmxpbmVNb2RlbHMgPSAwO1xuXG5cblxuICAvLyBHZW5lcmF0ZSBjdXJyZW50IEhUTUxcbiAgdmFyIGh0bWwgPSBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcblxuICAvLyBHZW5lcmF0ZSByZWZlcmVuY2VzIEhUTUxcbiAgd2hpbGUgKF8ua2V5cyhyZWZlcmVuY2VzKS5sZW5ndGggPiAwKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIF8uZm9yRWFjaChyZWZlcmVuY2VzLCBmdW5jdGlvbiAoc2NoZW1hLCBuYW1lKSB7XG4gICAgICB2YXIgc2Vlbk1vZGVsID0gXy5pbmRleE9mKHNlZW5Nb2RlbHMsIG5hbWUpID4gLTE7XG5cbiAgICAgIGRlbGV0ZSByZWZlcmVuY2VzW25hbWVdO1xuXG4gICAgICBpZiAoIXNlZW5Nb2RlbCkge1xuICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG5cbiAgICAgICAgaHRtbCArPSAnPGJyIC8+JyArIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cblxuICByZXR1cm4gaHRtbDtcblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBuYW1lLCBza2lwUmVmKSB7XG4gICAgdmFyIG1vZGVsTmFtZSA9IG5hbWU7XG4gICAgdmFyIG1vZGVsO1xuXG4gICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpO1xuICAgICAgbW9kZWwgPSBtb2RlbHNbbW9kZWxOYW1lXTtcbiAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCAnSW5saW5lIE1vZGVsICcgKyAoKytpbmxpbmVNb2RlbHMpO1xuICAgICAgbW9kZWwgPSB7ZGVmaW5pdGlvbjogc2NoZW1hfTtcbiAgICB9XG5cbiAgICBpZiAoc2tpcFJlZiAhPT0gdHJ1ZSkge1xuICAgICAgcmVmZXJlbmNlc1ttb2RlbE5hbWVdID0gXy5pc1VuZGVmaW5lZChtb2RlbCkgPyB7fSA6IG1vZGVsLmRlZmluaXRpb247XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsTmFtZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW1pdGl2ZVRvSFRNTChzY2hlbWEpIHtcbiAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BUeXBlXCI+JztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGh0bWwgKz0gJ0FycmF5Wyc7XG5cbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBodG1sICs9IF8ubWFwKHNjaGVtYS5pdGVtcywgYWRkUmVmZXJlbmNlKS5qb2luKCcsJyk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgJiYgXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGh0bWwgKz0gc2NoZW1hLml0ZW1zLnR5cGU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgSGVscGVycy5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHNjaGVtYSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgfVxuXG4gICAgICBodG1sICs9ICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgaHRtbCArPSBzY2hlbWEudHlwZTtcbiAgICB9XG5cbiAgICBodG1sICs9ICc8L3NwYW4+JztcblxuICAgIHJldHVybiBodG1sO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIGh0bWwpIHtcbiAgICB2YXIgb3B0aW9ucyA9ICcnO1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGlzQXJyYXkgPSB0eXBlID09PSAnYXJyYXknO1xuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSAmJiAhXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkpIHtcbiAgICAgICAgdHlwZSA9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZSA9ICdvYmplY3QnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRGVmYXVsdCcsIHNjaGVtYS5kZWZhdWx0KTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKHNjaGVtYS5taW5MZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIExlbmd0aCcsIHNjaGVtYS5taW5MZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heExlbmd0aCkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gTGVuZ3RoJywgc2NoZW1hLm1heExlbmd0aCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ1JlZy4gRXhwLicsIHNjaGVtYS5wYXR0ZXJuKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2ludGVnZXInOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICBpZiAoc2NoZW1hLm1pbmltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIFZhbHVlJywgc2NoZW1hLm1pbmltdW0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWluLicsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4aW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gVmFsdWUnLCBzY2hlbWEubWF4aW11bSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0V4Y2x1c2l2ZSBNYXguJywgJ3RydWUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tdWx0aXBsZU9mKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTXVsdGlwbGUgT2YnLCBzY2hlbWEubXVsdGlwbGVPZik7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoc2NoZW1hLm1pbkl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBJdGVtcycsIHNjaGVtYS5taW5JdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4SXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIEl0ZW1zJywgc2NoZW1hLm1heEl0ZW1zKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS51bmlxdWVJdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ1VuaXF1ZSBJdGVtcycsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0NvbGwuIEZvcm1hdCcsIHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgICB2YXIgZW51bVN0cmluZztcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ251bWJlcicgfHwgdHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICAgICAgZW51bVN0cmluZyA9IHNjaGVtYS5lbnVtLmpvaW4oJywgJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW51bVN0cmluZyA9ICdcIicgKyBzY2hlbWEuZW51bS5qb2luKCdcIiwgXCInKSArICdcIic7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0VudW0nLCBlbnVtU3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcFdyYXBcIj4nICsgaHRtbCArICc8dGFibGUgY2xhc3M9XCJvcHRpb25zV3JhcHBlclwiPjx0cj48dGggY29sc3Bhbj1cIjJcIj4nICsgdHlwZSArICc8L3RoPjwvdHI+JyArIG9wdGlvbnMgKyAnPC90YWJsZT48L3NwYW4+JztcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpIHtcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gc2NoZW1hLnR5cGUgPT09ICdhcnJheSc7XG4gICAgdmFyIGh0bWwgPSBzdHJvbmdPcGVuICsgbmFtZSArICcgJyArIChpc0FycmF5ID8gJ1snIDogJ3snKSArIHN0cm9uZ0Nsb3NlO1xuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIHNlZW5Nb2RlbHMucHVzaChuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIF8ubWFwKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICB2YXIgdHlwZSA9IGl0ZW0udHlwZSB8fCAnb2JqZWN0JztcblxuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKGl0ZW0uJHJlZikpIHtcbiAgICAgICAgICAgIGlmIChfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgdHlwZSkgPiAtMSkge1xuICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ29iamVjdCcgJiYgXy5pc1VuZGVmaW5lZChpdGVtLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdvYmplY3QnO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKGl0ZW0sIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0sIEhlbHBlcnMuc2ltcGxlUmVmKGl0ZW0uJHJlZikpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkuam9pbignLDwvZGl2PjxkaXY+Jyk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgIGlmIChfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgc2NoZW1hLml0ZW1zLnR5cGUgfHwgJ29iamVjdCcpID4gLTEpIHtcbiAgICAgICAgICAgIGlmICgoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgfHwgc2NoZW1hLml0ZW1zLnR5cGUgPT09ICdvYmplY3QnKSAmJiBfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYS5pdGVtcywgc2NoZW1hLml0ZW1zLnR5cGUpICsgJzwvZGl2Pic7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSkgKyAnPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgSGVscGVycy5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHByb3BlcnR5IGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUpICsgJzwvZGl2Pic7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgdmFyIGNvbnRlbnRzID0gXy5tYXAoc2NoZW1hLnByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wZXJ0eSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIHByb3BlcnR5SXNSZXF1aXJlZCA9IChfLmluZGV4T2Yoc2NoZW1hLnJlcXVpcmVkLCBuYW1lKSA+PSAwKTtcbiAgICAgICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIHZhciByZXF1aXJlZENsYXNzID0gcHJvcGVydHlJc1JlcXVpcmVkID8gJ3JlcXVpcmVkJyA6ICcnO1xuICAgICAgICAgICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wTmFtZSAnICsgcmVxdWlyZWRDbGFzcyArICdcIj4nICsgbmFtZSArICc8L3NwYW4+ICgnO1xuICAgICAgICAgICAgdmFyIG1vZGVsO1xuICAgICAgICAgICAgdmFyIHByb3BEZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgICAgICAgICAgIGNQcm9wZXJ0eSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICBwcm9wRGVzY3JpcHRpb24gPSBwcm9wZXJ0eS5kZXNjcmlwdGlvbiB8fCBjUHJvcGVydHkuZGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gaGFuZGxlIHByb3BlcnR5IHJlZmVyZW5jZXMgdG8gcHJpbWl0aXZlcyAoSXNzdWUgMzM5KVxuICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKGNQcm9wZXJ0eS4kcmVmKSkge1xuICAgICAgICAgICAgICBtb2RlbCA9IG1vZGVsc1tIZWxwZXJzLnNpbXBsZVJlZihjUHJvcGVydHkuJHJlZildO1xuXG4gICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkgJiYgXy5pbmRleE9mKFt1bmRlZmluZWQsICdhcnJheScsICdvYmplY3QnXSwgbW9kZWwuZGVmaW5pdGlvbi50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBVc2UgcmVmZXJlbmNlZCBzY2hlbWFcbiAgICAgICAgICAgICAgICBjUHJvcGVydHkgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEobW9kZWwuZGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSBwcmltaXRpdmVUb0hUTUwoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgaWYoIXByb3BlcnR5SXNSZXF1aXJlZCkge1xuICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcE9wdEtleVwiPm9wdGlvbmFsPC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmKHByb3BlcnR5LnJlYWRPbmx5KSB7XG4gICAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BSZWFkT25seVwiPnJlYWQgb25seTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBodG1sICs9ICcpJztcblxuICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHByb3BEZXNjcmlwdGlvbikpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnOiAnICsgJzxzcGFuIGNsYXNzPVwicHJvcERlc2NcIj4nICsgcHJvcERlc2NyaXB0aW9uICsgJzwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY1Byb3BlcnR5LmVudW0pIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnID0gPHNwYW4gY2xhc3M9XCJwcm9wVmFsc1wiPltcXCcnICsgY1Byb3BlcnR5LmVudW0uam9pbignXFwnLCBcXCcnKSArICdcXCddPC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAnPGRpdicgKyAocHJvcGVydHkucmVhZE9ubHkgPyAnIGNsYXNzPVwicmVhZE9ubHlcIicgOiAnJykgKyAnPicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKGNQcm9wZXJ0eSwgaHRtbCk7XG4gICAgICAgICAgfSkuam9pbignLDwvZGl2PicpO1xuXG4gICAgICAgICAgaWYgKGNvbnRlbnRzKSB7XG4gICAgICAgICAgICBodG1sICs9IGNvbnRlbnRzICsgJzwvZGl2Pic7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgdHlwZSkgKyAnPC9kaXY+JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbCArIHN0cm9uZ09wZW4gKyAoaXNBcnJheSA/ICddJyA6ICd9JykgKyBzdHJvbmdDbG9zZTtcbiAgfVxufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKVxufTtcblxudmFyIFN3YWdnZXJTcGVjQ29udmVydGVyID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZXJyb3JzID0gW107XG4gIHRoaXMud2FybmluZ3MgPSBbXTtcbiAgdGhpcy5tb2RlbE1hcCA9IHt9O1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbiA9IGZ1bmN0aW9uIChsb2NhdGlvbikge1xuICB0aGlzLmRvY0xvY2F0aW9uID0gbG9jYXRpb247XG59O1xuXG4vKipcbiAqIGNvbnZlcnRzIGEgcmVzb3VyY2UgbGlzdGluZyBPUiBhcGkgZGVjbGFyYXRpb25cbiAqKi9cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5jb252ZXJ0ID0gZnVuY3Rpb24gKG9iaiwgY2xpZW50QXV0aG9yaXphdGlvbnMsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIC8vIG5vdCBhIHZhbGlkIHNwZWNcbiAgaWYoIW9iaiB8fCAhQXJyYXkuaXNBcnJheShvYmouYXBpcykpIHtcbiAgICByZXR1cm4gdGhpcy5maW5pc2goY2FsbGJhY2ssIG51bGwpO1xuICB9XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBjbGllbnRBdXRob3JpemF0aW9ucztcblxuICAvLyBjcmVhdGUgYSBuZXcgc3dhZ2dlciBvYmplY3QgdG8gcmV0dXJuXG4gIHZhciBzd2FnZ2VyID0geyBzd2FnZ2VyOiAnMi4wJyB9O1xuXG4gIHN3YWdnZXIub3JpZ2luYWxWZXJzaW9uID0gb2JqLnN3YWdnZXJWZXJzaW9uO1xuXG4gIC8vIGFkZCB0aGUgaW5mb1xuICB0aGlzLmFwaUluZm8ob2JqLCBzd2FnZ2VyKTtcblxuICAvLyBhZGQgc2VjdXJpdHkgZGVmaW5pdGlvbnNcbiAgdGhpcy5zZWN1cml0eURlZmluaXRpb25zKG9iaiwgc3dhZ2dlcik7XG5cbiAgLy8gdGFrZSBiYXNlUGF0aCBpbnRvIGFjY291bnRcbiAgaWYgKG9iai5iYXNlUGF0aCkge1xuICAgIHRoaXMuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKG9iai5iYXNlUGF0aCk7XG4gIH1cblxuICAvLyBzZWUgaWYgdGhpcyBpcyBhIHNpbmdsZS1maWxlIHN3YWdnZXIgZGVmaW5pdGlvblxuICB2YXIgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IGZhbHNlO1xuICB2YXIgaTtcbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgaWYoQXJyYXkuaXNBcnJheShhcGkub3BlcmF0aW9ucykpIHtcbiAgICAgIGlzU2luZ2xlRmlsZVN3YWdnZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZihpc1NpbmdsZUZpbGVTd2FnZ2VyKSB7XG4gICAgdGhpcy5kZWNsYXJhdGlvbihvYmosIHN3YWdnZXIpO1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLnJlc291cmNlTGlzdGluZyhvYmosIHN3YWdnZXIsIG9wdHMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmRlY2xhcmF0aW9uID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIHZhciBuYW1lLCBpLCBwLCBwb3M7XG4gIGlmKCFvYmouYXBpcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cDovLycpID09PSAwKSB7XG4gICAgcCA9IG9iai5iYXNlUGF0aC5zdWJzdHJpbmcoJ2h0dHA6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLmJhc2VQYXRoLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cHM6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dhZ2dlci5iYXNlUGF0aCA9IG9iai5iYXNlUGF0aDtcbiAgfVxuXG4gIHZhciByZXNvdXJjZUxldmVsQXV0aDtcbiAgaWYob2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgcmVzb3VyY2VMZXZlbEF1dGggPSBvYmouYXV0aG9yaXphdGlvbnM7XG4gIH1cbiAgaWYob2JqLmNvbnN1bWVzKSB7XG4gICAgc3dhZ2dlci5jb25zdW1lcyA9IG9iai5jb25zdW1lcztcbiAgfVxuICBpZihvYmoucHJvZHVjZXMpIHtcbiAgICBzd2FnZ2VyLnByb2R1Y2VzID0gb2JqLnByb2R1Y2VzO1xuICB9XG5cbiAgLy8gYnVpbGQgYSBtYXBwaW5nIG9mIGlkIHRvIG5hbWUgZm9yIDEuMCBtb2RlbCByZXNvbHV0aW9uc1xuICBpZihfLmlzT2JqZWN0KG9iaikpIHtcbiAgICBmb3IobmFtZSBpbiBvYmoubW9kZWxzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdNb2RlbCA9IG9iai5tb2RlbHNbbmFtZV07XG4gICAgICB2YXIga2V5ID0gKGV4aXN0aW5nTW9kZWwuaWQgfHwgbmFtZSk7XG4gICAgICB0aGlzLm1vZGVsTWFwW2tleV0gPSBuYW1lO1xuICAgIH1cbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IG9iai5hcGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIHZhciBwYXRoID0gYXBpLnBhdGg7XG4gICAgdmFyIG9wZXJhdGlvbnMgPSBhcGkub3BlcmF0aW9ucztcbiAgICB0aGlzLm9wZXJhdGlvbnMocGF0aCwgb2JqLnJlc291cmNlUGF0aCwgb3BlcmF0aW9ucywgcmVzb3VyY2VMZXZlbEF1dGgsIHN3YWdnZXIpO1xuICB9XG5cbiAgdmFyIG1vZGVscyA9IG9iai5tb2RlbHMgfHwge307XG4gIHRoaXMubW9kZWxzKG1vZGVscywgc3dhZ2dlcik7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUubW9kZWxzID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKCFfLmlzT2JqZWN0KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG5hbWU7XG5cbiAgc3dhZ2dlci5kZWZpbml0aW9ucyA9IHN3YWdnZXIuZGVmaW5pdGlvbnMgfHwge307XG4gIGZvcihuYW1lIGluIG9iaikge1xuICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqW25hbWVdO1xuICAgIHZhciBfcmVxdWlyZWQgPSBbXTtcbiAgICB2YXIgc2NoZW1hID0geyBwcm9wZXJ0aWVzOiB7fX07XG4gICAgdmFyIHByb3BlcnR5TmFtZTtcbiAgICBmb3IocHJvcGVydHlOYW1lIGluIGV4aXN0aW5nTW9kZWwucHJvcGVydGllcykge1xuICAgICAgdmFyIGV4aXN0aW5nUHJvcGVydHkgPSBleGlzdGluZ01vZGVsLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgIHZhciBwcm9wZXJ0eSA9IHt9O1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1Byb3BlcnR5LCBwcm9wZXJ0eSk7XG4gICAgICBpZihleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uKSB7XG4gICAgICAgIHByb3BlcnR5LmRlc2NyaXB0aW9uID0gZXhpc3RpbmdQcm9wZXJ0eS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHlbJ2VudW0nXSkge1xuICAgICAgICBwcm9wZXJ0eVsnZW51bSddID0gZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICdib29sZWFuJyAmJiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICAgIF9yZXF1aXJlZC5wdXNoKHByb3BlcnR5TmFtZSk7XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ3N0cmluZycgJiYgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ3RydWUnKSB7XG4gICAgICAgIF9yZXF1aXJlZC5wdXNoKHByb3BlcnR5TmFtZSk7XG4gICAgICB9XG4gICAgICBzY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdID0gcHJvcGVydHk7XG4gICAgfVxuICAgIGlmKF9yZXF1aXJlZC5sZW5ndGggPiAwKSB7XG4gICAgICBzY2hlbWEucmVxdWlyZWQgPSBfcmVxdWlyZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjaGVtYS5yZXF1aXJlZCA9IGV4aXN0aW5nTW9kZWwucmVxdWlyZWQ7XG4gICAgfVxuICAgIHN3YWdnZXIuZGVmaW5pdGlvbnNbbmFtZV0gPSBzY2hlbWE7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5leHRyYWN0VGFnID0gZnVuY3Rpb24ocmVzb3VyY2VQYXRoKSB7XG4gIHZhciBwYXRoU3RyaW5nID0gcmVzb3VyY2VQYXRoIHx8ICdkZWZhdWx0JztcbiAgaWYocGF0aFN0cmluZy5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhdGhTdHJpbmcuaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZy5zcGxpdChbJy8nXSk7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmdbcGF0aFN0cmluZy5sZW5ndGggLTFdLnN1YnN0cmluZygpO1xuICB9XG4gIGlmKHBhdGhTdHJpbmcuZW5kc1dpdGgoJy5qc29uJykpIHtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZy5zdWJzdHJpbmcoMCwgcGF0aFN0cmluZy5sZW5ndGggLSAnLmpzb24nLmxlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIHBhdGhTdHJpbmcucmVwbGFjZSgnLycsJycpO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLm9wZXJhdGlvbnMgPSBmdW5jdGlvbihwYXRoLCByZXNvdXJjZVBhdGgsIG9iaiwgcmVzb3VyY2VMZXZlbEF1dGgsIHN3YWdnZXIpIHtcbiAgaWYoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgaTtcblxuICBpZighc3dhZ2dlci5wYXRocykge1xuICAgIHN3YWdnZXIucGF0aHMgPSB7fTtcbiAgfVxuXG4gIHZhciBwYXRoT2JqID0gc3dhZ2dlci5wYXRoc1twYXRoXSB8fCB7fTtcbiAgdmFyIHRhZyA9IHRoaXMuZXh0cmFjdFRhZyhyZXNvdXJjZVBhdGgpO1xuICBzd2FnZ2VyLnRhZ3MgPSBzd2FnZ2VyLnRhZ3MgfHwgW107XG4gIHZhciBtYXRjaGVkID0gZmFsc2U7XG4gIGZvcihpID0gMDsgaSA8IHN3YWdnZXIudGFncy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB0YWdPYmplY3QgPSBzd2FnZ2VyLnRhZ3NbaV07XG4gICAgaWYodGFnT2JqZWN0Lm5hbWUgPT09IHRhZykge1xuICAgICAgbWF0Y2hlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmKCFtYXRjaGVkKSB7XG4gICAgc3dhZ2dlci50YWdzLnB1c2goe25hbWU6IHRhZ30pO1xuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGV4aXN0aW5nT3BlcmF0aW9uID0gb2JqW2ldO1xuICAgIHZhciBtZXRob2QgPSAoZXhpc3RpbmdPcGVyYXRpb24ubWV0aG9kIHx8IGV4aXN0aW5nT3BlcmF0aW9uLmh0dHBNZXRob2QpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIG9wZXJhdGlvbiA9IHt0YWdzOiBbdGFnXX07XG4gICAgdmFyIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgPSBleGlzdGluZ09wZXJhdGlvbi5hdXRob3JpemF0aW9ucztcblxuICAgIGlmKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgJiYgT2JqZWN0LmtleXMoZXhpc3RpbmdBdXRob3JpemF0aW9ucykubGVuZ3RoID09PSAwKSB7XG4gICAgICBleGlzdGluZ0F1dGhvcml6YXRpb25zID0gcmVzb3VyY2VMZXZlbEF1dGg7XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgc2NvcGVzT2JqZWN0O1xuICAgICAgZm9yKHZhciBrZXkgaW4gZXhpc3RpbmdBdXRob3JpemF0aW9ucykge1xuICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkgPSBvcGVyYXRpb24uc2VjdXJpdHkgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSBleGlzdGluZ0F1dGhvcml6YXRpb25zW2tleV07XG4gICAgICAgIGlmKHNjb3Blcykge1xuICAgICAgICAgIHZhciBzZWN1cml0eVNjb3BlcyA9IFtdO1xuICAgICAgICAgIGZvcih2YXIgaiBpbiBzY29wZXMpIHtcbiAgICAgICAgICAgIHNlY3VyaXR5U2NvcGVzLnB1c2goc2NvcGVzW2pdLnNjb3BlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2NvcGVzT2JqZWN0ID0ge307XG4gICAgICAgICAgc2NvcGVzT2JqZWN0W2tleV0gPSBzZWN1cml0eVNjb3BlcztcbiAgICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkucHVzaChzY29wZXNPYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNjb3Blc09iamVjdCA9IHt9O1xuICAgICAgICAgIHNjb3Blc09iamVjdFtrZXldID0gW107XG4gICAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5LnB1c2goc2NvcGVzT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLmNvbnN1bWVzKSB7XG4gICAgICBvcGVyYXRpb24uY29uc3VtZXMgPSBleGlzdGluZ09wZXJhdGlvbi5jb25zdW1lcztcbiAgICB9XG4gICAgZWxzZSBpZihzd2FnZ2VyLmNvbnN1bWVzKSB7XG4gICAgICBvcGVyYXRpb24uY29uc3VtZXMgPSBzd2FnZ2VyLmNvbnN1bWVzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5wcm9kdWNlcykge1xuICAgICAgb3BlcmF0aW9uLnByb2R1Y2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucHJvZHVjZXM7XG4gICAgfVxuICAgIGVsc2UgaWYoc3dhZ2dlci5wcm9kdWNlcykge1xuICAgICAgb3BlcmF0aW9uLnByb2R1Y2VzID0gc3dhZ2dlci5wcm9kdWNlcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uc3VtbWFyeSkge1xuICAgICAgb3BlcmF0aW9uLnN1bW1hcnkgPSBleGlzdGluZ09wZXJhdGlvbi5zdW1tYXJ5O1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5ub3Rlcykge1xuICAgICAgb3BlcmF0aW9uLmRlc2NyaXB0aW9uID0gZXhpc3RpbmdPcGVyYXRpb24ubm90ZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLm5pY2tuYW1lKSB7XG4gICAgICBvcGVyYXRpb24ub3BlcmF0aW9uSWQgPSBleGlzdGluZ09wZXJhdGlvbi5uaWNrbmFtZTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uZGVwcmVjYXRlZCkge1xuICAgICAgb3BlcmF0aW9uLmRlcHJlY2F0ZWQgPSBleGlzdGluZ09wZXJhdGlvbi5kZXByZWNhdGVkO1xuICAgIH1cblxuICAgIHRoaXMuYXV0aG9yaXphdGlvbnMoZXhpc3RpbmdBdXRob3JpemF0aW9ucywgc3dhZ2dlcik7XG4gICAgdGhpcy5wYXJhbWV0ZXJzKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24ucGFyYW1ldGVycywgc3dhZ2dlcik7XG4gICAgdGhpcy5yZXNwb25zZU1lc3NhZ2VzKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24sIHN3YWdnZXIpO1xuXG4gICAgcGF0aE9ialttZXRob2RdID0gb3BlcmF0aW9uO1xuICB9XG5cbiAgc3dhZ2dlci5wYXRoc1twYXRoXSA9IHBhdGhPYmo7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzcG9uc2VNZXNzYWdlcyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24pIHtcbiAgaWYoIV8uaXNPYmplY3QoZXhpc3RpbmdPcGVyYXRpb24pKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGJ1aWxkIGRlZmF1bHQgcmVzcG9uc2UgZnJvbSB0aGUgb3BlcmF0aW9uICgxLngpXG4gIHZhciBkZWZhdWx0UmVzcG9uc2UgPSB7fTtcbiAgdGhpcy5kYXRhVHlwZShleGlzdGluZ09wZXJhdGlvbiwgZGVmYXVsdFJlc3BvbnNlKTtcbiAgLy8gVE9ETzogbG9vayBpbnRvIHRoZSByZWFsIHByb2JsZW0gb2YgcmVuZGVyaW5nIHJlc3BvbnNlcyBpbiBzd2FnZ2VyLXVpXG4gIC8vIC4uLi5zaG91bGQgcmVwb25zZVR5cGUgaGF2ZSBhbiBpbXBsaWNpdCBzY2hlbWE/XG4gIGlmKCFkZWZhdWx0UmVzcG9uc2Uuc2NoZW1hICYmIGRlZmF1bHRSZXNwb25zZS50eXBlKSB7XG4gICAgZGVmYXVsdFJlc3BvbnNlID0ge3NjaGVtYTogZGVmYXVsdFJlc3BvbnNlfTtcbiAgfVxuXG4gIG9wZXJhdGlvbi5yZXNwb25zZXMgPSBvcGVyYXRpb24ucmVzcG9uc2VzIHx8IHt9O1xuXG4gIC8vIGdyYWIgZnJvbSByZXNwb25zZU1lc3NhZ2VzICgxLjIpXG4gIHZhciBoYXMyMDAgPSBmYWxzZTtcbiAgaWYoQXJyYXkuaXNBcnJheShleGlzdGluZ09wZXJhdGlvbi5yZXNwb25zZU1lc3NhZ2VzKSkge1xuICAgIHZhciBpO1xuICAgIHZhciBleGlzdGluZ1Jlc3BvbnNlcyA9IGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXM7XG4gICAgZm9yKGkgPSAwOyBpIDwgZXhpc3RpbmdSZXNwb25zZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBleGlzdGluZ1Jlc3BvbnNlID0gZXhpc3RpbmdSZXNwb25zZXNbaV07XG4gICAgICB2YXIgcmVzcG9uc2UgPSB7IGRlc2NyaXB0aW9uOiBleGlzdGluZ1Jlc3BvbnNlLm1lc3NhZ2UgfTtcbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UuY29kZSA9PT0gMjAwKSB7XG4gICAgICAgIGhhczIwMCA9IHRydWU7XG4gICAgICB9XG4gICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlTW9kZWwgLT4gc2NoZW1heyRyZWY6IHJlc3BvbnNlTW9kZWx9XG4gICAgICBpZihleGlzdGluZ1Jlc3BvbnNlLnJlc3BvbnNlTW9kZWwpIHtcbiAgICAgICAgcmVzcG9uc2Uuc2NoZW1hID0geyckcmVmJzogJyMvZGVmaW5pdGlvbnMvJyArIGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbH07XG4gICAgICB9XG4gICAgICBvcGVyYXRpb24ucmVzcG9uc2VzWycnICsgZXhpc3RpbmdSZXNwb25zZS5jb2RlXSA9IHJlc3BvbnNlO1xuICAgIH1cbiAgfVxuXG4gIGlmKGhhczIwMCkge1xuICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJ2RlZmF1bHQnXSA9IGRlZmF1bHRSZXNwb25zZTtcbiAgfVxuICBlbHNlIHtcbiAgICBvcGVyYXRpb24ucmVzcG9uc2VzWycyMDAnXSA9IGRlZmF1bHRSZXNwb25zZTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24ob2JqKSB7XG4gIC8vIFRPRE9cbiAgaWYoIV8uaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnBhcmFtZXRlcnMgPSBmdW5jdGlvbihvcGVyYXRpb24sIG9iaikge1xuICBpZighQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBpO1xuICBmb3IoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXhpc3RpbmdQYXJhbWV0ZXIgPSBvYmpbaV07XG4gICAgdmFyIHBhcmFtZXRlciA9IHt9O1xuICAgIHBhcmFtZXRlci5uYW1lID0gZXhpc3RpbmdQYXJhbWV0ZXIubmFtZTtcbiAgICBwYXJhbWV0ZXIuZGVzY3JpcHRpb24gPSBleGlzdGluZ1BhcmFtZXRlci5kZXNjcmlwdGlvbjtcbiAgICBwYXJhbWV0ZXIucmVxdWlyZWQgPSBleGlzdGluZ1BhcmFtZXRlci5yZXF1aXJlZDtcbiAgICBwYXJhbWV0ZXIuaW4gPSBleGlzdGluZ1BhcmFtZXRlci5wYXJhbVR5cGU7XG5cbiAgICAvLyBwZXIgIzE2OFxuICAgIGlmKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICBwYXJhbWV0ZXIubmFtZSA9ICdib2R5JztcbiAgICB9XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnZm9ybScpIHtcbiAgICAgIHBhcmFtZXRlci5pbiA9ICdmb3JtRGF0YSc7XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuZW51bSkge1xuICAgICAgcGFyYW1ldGVyLmVudW0gPSBleGlzdGluZ1BhcmFtZXRlci5lbnVtO1xuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93TXVsdGlwbGUgPT09IHRydWUgfHwgZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gJ3RydWUnKSB7XG4gICAgICB2YXIgaW5uZXJUeXBlID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBpbm5lclR5cGUpO1xuICAgICAgcGFyYW1ldGVyLnR5cGUgPSAnYXJyYXknO1xuICAgICAgcGFyYW1ldGVyLml0ZW1zID0gaW5uZXJUeXBlO1xuXG4gICAgICBpZihleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXMpIHtcbiAgICAgICAgdmFyIGF2ID0gZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dhYmxlVmFsdWVzO1xuICAgICAgICBpZihhdi52YWx1ZVR5cGUgPT09ICdMSVNUJykge1xuICAgICAgICAgIHBhcmFtZXRlclsnZW51bSddID0gYXYudmFsdWVzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1BhcmFtZXRlciwgcGFyYW1ldGVyKTtcbiAgICB9XG4gICAgaWYodHlwZW9mIGV4aXN0aW5nUGFyYW1ldGVyLmRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHBhcmFtZXRlci5kZWZhdWx0ID0gZXhpc3RpbmdQYXJhbWV0ZXIuZGVmYXVsdFZhbHVlO1xuICAgIH1cblxuICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgW107XG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMucHVzaChwYXJhbWV0ZXIpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGF0YVR5cGUgPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCkge1xuICBpZighXy5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYoc291cmNlLm1pbmltdW0pIHtcbiAgICB0YXJnZXQubWluaW11bSA9IHNvdXJjZS5taW5pbXVtO1xuICB9XG4gIGlmKHNvdXJjZS5tYXhpbXVtKSB7XG4gICAgdGFyZ2V0Lm1heGltdW0gPSBzb3VyY2UubWF4aW11bTtcbiAgfVxuICBpZiAoc291cmNlLmZvcm1hdCkge1xuICAgIHRhcmdldC5mb3JtYXQgPSBzb3VyY2UuZm9ybWF0O1xuICB9XG5cbiAgLy8gZGVmYXVsdCBjYW4gYmUgJ2ZhbHNlJ1xuICBpZih0eXBlb2Ygc291cmNlLmRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0YXJnZXQuZGVmYXVsdCA9IHNvdXJjZS5kZWZhdWx0VmFsdWU7XG4gIH1cblxuICB2YXIganNvblNjaGVtYVR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYShzb3VyY2UpO1xuICBpZihqc29uU2NoZW1hVHlwZSkge1xuICAgIHRhcmdldCA9IHRhcmdldCB8fCB7fTtcbiAgICBpZihqc29uU2NoZW1hVHlwZS50eXBlKSB7XG4gICAgICB0YXJnZXQudHlwZSA9IGpzb25TY2hlbWFUeXBlLnR5cGU7XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLmZvcm1hdCkge1xuICAgICAgdGFyZ2V0LmZvcm1hdCA9IGpzb25TY2hlbWFUeXBlLmZvcm1hdDtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuJHJlZikge1xuICAgICAgdGFyZ2V0LnNjaGVtYSA9IHskcmVmOiBqc29uU2NoZW1hVHlwZS4kcmVmfTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuaXRlbXMpIHtcbiAgICAgIHRhcmdldC5pdGVtcyA9IGpzb25TY2hlbWFUeXBlLml0ZW1zO1xuICAgIH1cbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnRvSnNvblNjaGVtYSA9IGZ1bmN0aW9uKHNvdXJjZSkge1xuICBpZighc291cmNlKSB7XG4gICAgcmV0dXJuICdvYmplY3QnO1xuICB9XG4gIHZhciBkZXRlY3RlZFR5cGUgPSAoc291cmNlLnR5cGUgfHwgc291cmNlLmRhdGFUeXBlIHx8IHNvdXJjZS5yZXNwb25zZUNsYXNzIHx8ICcnKTtcbiAgdmFyIGxjVHlwZSA9IGRldGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpO1xuICB2YXIgZm9ybWF0ID0gKHNvdXJjZS5mb3JtYXQgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgaWYobGNUeXBlLmluZGV4T2YoJ2xpc3RbJykgPT09IDApIHtcbiAgICB2YXIgaW5uZXJUeXBlID0gZGV0ZWN0ZWRUeXBlLnN1YnN0cmluZyg1LCBkZXRlY3RlZFR5cGUubGVuZ3RoIC0gMSk7XG4gICAgdmFyIGpzb25UeXBlID0gdGhpcy50b0pzb25TY2hlbWEoe3R5cGU6IGlubmVyVHlwZX0pO1xuICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IGpzb25UeXBlfTtcbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ludCcgfHwgKGxjVHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDMyJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnbG9uZycgfHwgKGxjVHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0JykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDY0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnaW50ZWdlcicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDY0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZmxvYXQnIHx8IChsY1R5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2Zsb2F0JykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZmxvYXQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdkb3VibGUnIHx8IChsY1R5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ251bWJlcicsIGZvcm1hdDogJ2RvdWJsZSd9O31cbiAgfSBlbHNlIGlmKChsY1R5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHx8IChsY1R5cGUgPT09ICdkYXRlJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnc3RyaW5nJywgZm9ybWF0OiAnZGF0ZS10aW1lJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnc3RyaW5nJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdmaWxlJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdmaWxlJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnYm9vbGVhbid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2Jvb2xlYW4nfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdhcnJheScgfHwgbGNUeXBlID09PSAnbGlzdCcpIHtcbiAgICBpZihzb3VyY2UuaXRlbXMpIHtcbiAgICAgIHZhciBpdCA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZS5pdGVtcyk7XG4gICAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiBpdH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoge3R5cGU6ICdvYmplY3QnfX07XG4gICAgfVxuICB9IGVsc2UgaWYoc291cmNlLiRyZWYpIHtcbiAgICByZXR1cm4geyRyZWY6IHRoaXMubW9kZWxNYXBbc291cmNlLiRyZWZdID8gJyMvZGVmaW5pdGlvbnMvJyArIHRoaXMubW9kZWxNYXBbc291cmNlLiRyZWZdIDogc291cmNlLiRyZWZ9O1xuICB9IGVsc2UgaWYobGNUeXBlID09PSAndm9pZCcgfHwgbGNUeXBlID09PSAnJykge1xuICAgIHtyZXR1cm4ge307fVxuICB9IGVsc2UgaWYgKHRoaXMubW9kZWxNYXBbc291cmNlLnR5cGVdKSB7XG4gICAgLy8gSWYgdGhpcyBhIG1vZGVsIHVzaW5nIGB0eXBlYCBpbnN0ZWFkIG9mIGAkcmVmYCwgdGhhdCdzIGZpbmUuXG4gICAgcmV0dXJuIHskcmVmOiAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV19O1xuICB9IGVsc2Uge1xuICAgIC8vIFVua25vd24gbW9kZWwgdHlwZSBvciAnb2JqZWN0JywgcGFzcyBpdCBhbG9uZy5cbiAgICByZXR1cm4ge3R5cGU6IHNvdXJjZS50eXBlfTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnJlc291cmNlTGlzdGluZyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgdmFyIGk7XG4gIHZhciBwcm9jZXNzZWRDb3VudCA9IDA7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBzZWxmID0gdGhpczsgICAgICAgICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBleHBlY3RlZENvdW50ID0gb2JqLmFwaXMubGVuZ3RoO1xuICB2YXIgX3N3YWdnZXIgPSBzd2FnZ2VyOyAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgX29wdHMgPSB7fTtcblxuICBpZihvcHRzICYmIG9wdHMucmVxdWVzdEludGVyY2VwdG9yKXtcbiAgICBfb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKXtcbiAgICBfb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgdmFyIHN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9ICdhcHBsaWNhdGlvbi9qc29uJztcblxuICBpZihvcHRzICYmIG9wdHMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzKSB7XG4gICAgc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gb3B0cy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnM7XG4gIH1cblxuICBpZihleHBlY3RlZENvdW50ID09PSAwKSB7XG4gICAgdGhpcy5maW5pc2goY2FsbGJhY2ssIHN3YWdnZXIpO1xuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgZXhwZWN0ZWRDb3VudDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIHZhciBwYXRoID0gYXBpLnBhdGg7XG4gICAgdmFyIGFic29sdXRlUGF0aCA9IHRoaXMuZ2V0QWJzb2x1dGVQYXRoKG9iai5zd2FnZ2VyVmVyc2lvbiwgdGhpcy5kb2NMb2NhdGlvbiwgcGF0aCk7XG5cbiAgICBpZihhcGkuZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIudGFncyA9IHN3YWdnZXIudGFncyB8fCBbXTtcbiAgICAgIHN3YWdnZXIudGFncy5wdXNoKHtcbiAgICAgICAgbmFtZSA6IHRoaXMuZXh0cmFjdFRhZyhhcGkucGF0aCksXG4gICAgICAgIGRlc2NyaXB0aW9uIDogYXBpLmRlc2NyaXB0aW9uIHx8ICcnXG4gICAgICB9KTtcbiAgICB9XG4gICAgdmFyIGh0dHAgPSB7XG4gICAgICB1cmw6IGFic29sdXRlUGF0aCxcbiAgICAgIGhlYWRlcnM6IHsgYWNjZXB0OiBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfSxcbiAgICAgIG9uOiB7fSxcbiAgICAgIG1ldGhvZDogJ2dldCcsXG4gICAgICB0aW1lb3V0OiBvcHRzLnRpbWVvdXRcbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBodHRwLm9uLnJlc3BvbnNlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgcHJvY2Vzc2VkQ291bnQgKz0gMTtcbiAgICAgIHZhciBvYmogPSBkYXRhLm9iajtcbiAgICAgIGlmKG9iaikge1xuICAgICAgICBzZWxmLmRlY2xhcmF0aW9uKG9iaiwgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGh0dHAub24uZXJyb3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgcHJvY2Vzc2VkQ291bnQgKz0gMTtcbiAgICAgIGlmKHByb2Nlc3NlZENvdW50ID09PSBleHBlY3RlZENvdW50KSB7XG4gICAgICAgIHNlbGYuZmluaXNoKGNhbGxiYWNrLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgfTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgaWYodGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyAmJiB0eXBlb2YgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShodHRwKTtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKGh0dHAsIF9vcHRzKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmdldEFic29sdXRlUGF0aCA9IGZ1bmN0aW9uKHZlcnNpb24sIGRvY0xvY2F0aW9uLCBwYXRoKSAge1xuICBpZih2ZXJzaW9uID09PSAnMS4wJykge1xuICAgIGlmKGRvY0xvY2F0aW9uLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgICAvLyBnZXQgcm9vdCBwYXRoXG4gICAgICB2YXIgcG9zID0gZG9jTG9jYXRpb24ubGFzdEluZGV4T2YoJy8nKTtcbiAgICAgIGlmKHBvcyA+IDApIHtcbiAgICAgICAgZG9jTG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbG9jYXRpb24gPSBkb2NMb2NhdGlvbjtcbiAgaWYocGF0aC5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhdGguaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICBsb2NhdGlvbiA9IHBhdGg7XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy8nKSkge1xuICAgICAgbG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgZG9jTG9jYXRpb24ubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGxvY2F0aW9uICs9IHBhdGg7XG4gIH1cbiAgbG9jYXRpb24gPSBsb2NhdGlvbi5yZXBsYWNlKCd7Zm9ybWF0fScsICdqc29uJyk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZWN1cml0eURlZmluaXRpb25zID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHZhciBuYW1lO1xuICAgIGZvcihuYW1lIGluIG9iai5hdXRob3JpemF0aW9ucykge1xuICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB7XG4gICAgICAgIHZlbmRvckV4dGVuc2lvbnM6IHt9XG4gICAgICB9O1xuICAgICAgdmFyIGRlZmluaXRpb24gPSBvYmouYXV0aG9yaXphdGlvbnNbbmFtZV07XG4gICAgICBpZihkZWZpbml0aW9uLnR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ2FwaUtleSc7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5pbiA9IGRlZmluaXRpb24ucGFzc0FzO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24ubmFtZSA9IGRlZmluaXRpb24ua2V5bmFtZSB8fCBuYW1lO1xuICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYmFzaWNBdXRoJykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdiYXNpY0F1dGgnO1xuICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICB2YXIgZXhpc3RpbmdTY29wZXMgPSBkZWZpbml0aW9uLnNjb3BlcyB8fCBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IHt9O1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgaW4gZXhpc3RpbmdTY29wZXMpIHtcbiAgICAgICAgICB2YXIgc2NvcGUgPSBleGlzdGluZ1Njb3Blc1tpXTtcbiAgICAgICAgICBzY29wZXNbc2NvcGUuc2NvcGVdID0gc2NvcGUuZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnb2F1dGgyJztcbiAgICAgICAgaWYoaSA+IDApIHtcbiAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uc2NvcGVzID0gc2NvcGVzO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRlZmluaXRpb24uZ3JhbnRUeXBlcykge1xuICAgICAgICAgIGlmKGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdCkge1xuICAgICAgICAgICAgdmFyIGltcGxpY2l0ID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzLmltcGxpY2l0O1xuICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnaW1wbGljaXQnO1xuICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmF1dGhvcml6YXRpb25VcmwgPSBpbXBsaWNpdC5sb2dpbkVuZHBvaW50O1xuICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXNbJ2F1dGhvcml6YXRpb25fY29kZSddKSB7XG4gICAgICAgICAgICBpZighc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cpIHtcbiAgICAgICAgICAgICAgLy8gY2Fubm90IHNldCBpZiBmbG93IGlzIGFscmVhZHkgZGVmaW5lZFxuICAgICAgICAgICAgICB2YXIgYXV0aENvZGUgPSBkZWZpbml0aW9uLmdyYW50VHlwZXNbJ2F1dGhvcml6YXRpb25fY29kZSddO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uZmxvdyA9ICdhY2Nlc3NDb2RlJztcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmF1dGhvcml6YXRpb25VcmwgPSBhdXRoQ29kZS50b2tlblJlcXVlc3RFbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50b2tlblVybCA9IGF1dGhDb2RlLnRva2VuRW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoaXNWYWxpZCkge1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnMgfHwge307XG4gICAgICAgIHN3YWdnZXIuc2VjdXJpdHlEZWZpbml0aW9uc1tuYW1lXSA9IHNlY3VyaXR5RGVmaW5pdGlvbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5hcGlJbmZvID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIC8vIGluZm8gc2VjdGlvblxuICBpZihvYmouaW5mbykge1xuICAgIHZhciBpbmZvID0gb2JqLmluZm87XG4gICAgc3dhZ2dlci5pbmZvID0ge307XG5cbiAgICBpZihpbmZvLmNvbnRhY3QpIHtcbiAgICAgIHN3YWdnZXIuaW5mby5jb250YWN0ID0ge307XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdC5lbWFpbCA9IGluZm8uY29udGFjdDtcbiAgICB9XG4gICAgaWYoaW5mby5kZXNjcmlwdGlvbikge1xuICAgICAgc3dhZ2dlci5pbmZvLmRlc2NyaXB0aW9uID0gaW5mby5kZXNjcmlwdGlvbjtcbiAgICB9XG4gICAgaWYoaW5mby50aXRsZSkge1xuICAgICAgc3dhZ2dlci5pbmZvLnRpdGxlID0gaW5mby50aXRsZTtcbiAgICB9XG4gICAgaWYoaW5mby50ZXJtc09mU2VydmljZVVybCkge1xuICAgICAgc3dhZ2dlci5pbmZvLnRlcm1zT2ZTZXJ2aWNlID0gaW5mby50ZXJtc09mU2VydmljZVVybDtcbiAgICB9XG4gICAgaWYoaW5mby5saWNlbnNlIHx8IGluZm8ubGljZW5zZVVybCkge1xuICAgICAgc3dhZ2dlci5saWNlbnNlID0ge307XG4gICAgICBpZihpbmZvLmxpY2Vuc2UpIHtcbiAgICAgICAgc3dhZ2dlci5saWNlbnNlLm5hbWUgPSBpbmZvLmxpY2Vuc2U7XG4gICAgICB9XG4gICAgICBpZihpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgICAgc3dhZ2dlci5saWNlbnNlLnVybCA9IGluZm8ubGljZW5zZVVybDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy53YXJuaW5ncy5wdXNoKCdtaXNzaW5nIGluZm8gc2VjdGlvbicpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBvYmopIHtcbiAgY2FsbGJhY2sob2JqKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBsb2cgPSByZXF1aXJlKCcuLi9oZWxwZXJzJykubG9nO1xudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzU3RyaW5nOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcnKSxcbn07XG5cbnZhciBTY2hlbWFNYXJrdXAgPSByZXF1aXJlKCcuLi9zY2hlbWEtbWFya3VwLmpzJyk7XG52YXIganN5YW1sID0gcmVxdWlyZSgnanMteWFtbCcpO1xuXG52YXIgTW9kZWwgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uIHx8IHt9O1xuICB0aGlzLmlzQXJyYXkgPSBkZWZpbml0aW9uLnR5cGUgPT09ICdhcnJheSc7XG4gIHRoaXMubW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuICB0aGlzLm5hbWUgPSBuYW1lIHx8IGRlZmluaXRpb24udGl0bGUgfHwgJ0lubGluZSBNb2RlbCc7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gbW9kZWxQcm9wZXJ0eU1hY3JvIHx8IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgIHJldHVybiBwcm9wZXJ0eS5kZWZhdWx0O1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gTm90ZSEgIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSByZW1vdmVkIGluIDIuMi54IVxuTW9kZWwucHJvdG90eXBlLmNyZWF0ZUpTT05TYW1wbGUgPSBNb2RlbC5wcm90b3R5cGUuZ2V0U2FtcGxlVmFsdWUgPSBmdW5jdGlvbiAobW9kZWxzVG9JZ25vcmUpIHtcbiAgbW9kZWxzVG9JZ25vcmUgPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICBtb2RlbHNUb0lnbm9yZVt0aGlzLm5hbWVdID0gdGhpcztcblxuICAvLyBSZXNwb25zZSBzdXBwb3J0XG4gIGlmICh0aGlzLmV4YW1wbGVzICYmIF8uaXNQbGFpbk9iamVjdCh0aGlzLmV4YW1wbGVzKSAmJiB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ10pIHtcbiAgICB0aGlzLmRlZmluaXRpb24uZXhhbXBsZSA9IHRoaXMuZXhhbXBsZXNbJ2FwcGxpY2F0aW9uL2pzb24nXTtcblxuICAgIGlmIChfLmlzU3RyaW5nKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSkge1xuICAgICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSBqc3lhbWwuc2FmZUxvYWQodGhpcy5kZWZpbml0aW9uLmV4YW1wbGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUpIHtcbiAgICB0aGlzLmRlZmluaXRpb24uZXhhbXBsZSA9IHRoaXMuZXhhbXBsZXM7XG4gIH1cblxuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSlNPTih0aGlzLmRlZmluaXRpb24sIHRoaXMubW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xufTtcblxuTW9kZWwucHJvdG90eXBlLmdldE1vY2tTaWduYXR1cmUgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBTY2hlbWFNYXJrdXAuc2NoZW1hVG9IVE1MKHRoaXMubmFtZSwgdGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBpc1VuZGVmaW5lZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkJyksXG4gIGlzRW1wdHk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5JyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKVxufTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi9tb2RlbCcpO1xudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi4vaHR0cCcpO1xudmFyIFEgPSByZXF1aXJlKCdxJyk7XG5cbnZhciBPcGVyYXRpb24gPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwYXJlbnQsIHNjaGVtZSwgb3BlcmF0aW9uSWQsIGh0dHBNZXRob2QsIHBhdGgsIGFyZ3MsIGRlZmluaXRpb25zLCBtb2RlbHMsIGNsaWVudEF1dGhvcml6YXRpb25zKSB7XG4gIHZhciBlcnJvcnMgPSBbXTtcblxuICBwYXJlbnQgPSBwYXJlbnQgfHwge307XG4gIGFyZ3MgPSBhcmdzIHx8IHt9O1xuXG4gIGlmKHBhcmVudCAmJiBwYXJlbnQub3B0aW9ucykge1xuICAgIHRoaXMuY2xpZW50ID0gcGFyZW50Lm9wdGlvbnMuY2xpZW50IHx8IG51bGw7XG4gICAgdGhpcy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSBwYXJlbnQub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3IgfHwgbnVsbDtcbiAgICB0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSBwYXJlbnQub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXF1ZXN0QWdlbnQgPSBwYXJlbnQub3B0aW9ucy5yZXF1ZXN0QWdlbnQ7XG4gIH1cbiAgdGhpcy5hdXRob3JpemF0aW9ucyA9IGFyZ3Muc2VjdXJpdHk7XG4gIHRoaXMuYmFzZVBhdGggPSBwYXJlbnQuYmFzZVBhdGggfHwgJy8nO1xuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gY2xpZW50QXV0aG9yaXphdGlvbnM7XG4gIHRoaXMuY29uc3VtZXMgPSBhcmdzLmNvbnN1bWVzIHx8IHBhcmVudC5jb25zdW1lcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5wcm9kdWNlcyA9IGFyZ3MucHJvZHVjZXMgfHwgcGFyZW50LnByb2R1Y2VzIHx8IFsnYXBwbGljYXRpb24vanNvbiddO1xuICB0aGlzLmRlcHJlY2F0ZWQgPSBhcmdzLmRlcHJlY2F0ZWQ7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBhcmdzLmRlc2NyaXB0aW9uO1xuICB0aGlzLmhvc3QgPSBwYXJlbnQuaG9zdDtcbiAgdGhpcy5tZXRob2QgPSAoaHR0cE1ldGhvZCB8fCBlcnJvcnMucHVzaCgnT3BlcmF0aW9uICcgKyBvcGVyYXRpb25JZCArICcgaXMgbWlzc2luZyBtZXRob2QuJykpO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uaWNrbmFtZSA9IChvcGVyYXRpb25JZCB8fCBlcnJvcnMucHVzaCgnT3BlcmF0aW9ucyBtdXN0IGhhdmUgYSBuaWNrbmFtZS4nKSk7XG4gIHRoaXMub3BlcmF0aW9uID0gYXJncztcbiAgdGhpcy5vcGVyYXRpb25zID0ge307XG4gIHRoaXMucGFyYW1ldGVycyA9IGFyZ3MgIT09IG51bGwgPyAoYXJncy5wYXJhbWV0ZXJzIHx8IFtdKSA6IHt9O1xuICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgdGhpcy5wYXRoID0gKHBhdGggfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgdGhpcy5uaWNrbmFtZSArICcgaXMgbWlzc2luZyBwYXRoLicpKTtcbiAgdGhpcy5yZXNwb25zZXMgPSAoYXJncy5yZXNwb25zZXMgfHwge30pO1xuICB0aGlzLnNjaGVtZSA9IHNjaGVtZSB8fCBwYXJlbnQuc2NoZW1lIHx8ICdodHRwJztcbiAgdGhpcy5zY2hlbWVzID0gYXJncy5zY2hlbWVzIHx8IHBhcmVudC5zY2hlbWVzO1xuICB0aGlzLnNlY3VyaXR5ID0gYXJncy5zZWN1cml0eSB8fCBwYXJlbnQuc2VjdXJpdHk7XG4gIHRoaXMuc3VtbWFyeSA9IGFyZ3Muc3VtbWFyeSB8fCAnJztcbiAgdGhpcy50aW1lb3V0ID0gcGFyZW50LnRpbWVvdXQ7XG4gIHRoaXMudHlwZSA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gcGFyZW50LnVzZUpRdWVyeTtcbiAgdGhpcy5qcXVlcnlBamF4Q2FjaGUgPSBwYXJlbnQuanF1ZXJ5QWpheENhY2hlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBwYXJlbnQuZW5hYmxlQ29va2llcztcblxuICB2YXIga2V5O1xuXG4gIGlmKCF0aGlzLmhvc3QpIHtcbiAgICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5ob3N0ID0gd2luZG93LmxvY2F0aW9uLmhvc3Q7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5ob3N0ID0gJ2xvY2FsaG9zdCc7XG4gICAgfVxuICB9XG4gIHRoaXMucGFyYW1ldGVyTWFjcm8gPSBwYXJlbnQucGFyYW1ldGVyTWFjcm8gfHwgZnVuY3Rpb24gKG9wZXJhdGlvbiwgcGFyYW1ldGVyKSB7XG4gICAgcmV0dXJuIHBhcmFtZXRlci5kZWZhdWx0O1xuICB9O1xuXG4gIHRoaXMuaW5saW5lTW9kZWxzID0gW107XG5cbiAgaWYodGhpcy5iYXNlUGF0aCAhPT0gJy8nICYmIHRoaXMuYmFzZVBhdGguc2xpY2UoLTEpID09PSAnLycpIHtcbiAgICB0aGlzLmJhc2VQYXRoID0gdGhpcy5iYXNlUGF0aC5zbGljZSgwLCAtMSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHRoaXMuZGVwcmVjYXRlZCA9PT0gJ3N0cmluZycpIHtcbiAgICBzd2l0Y2godGhpcy5kZXByZWNhdGVkLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgJ3RydWUnOiBjYXNlICd5ZXMnOiBjYXNlICcxJzoge1xuICAgICAgICB0aGlzLmRlcHJlY2F0ZWQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnZmFsc2UnOiBjYXNlICdubyc6IGNhc2UgJzAnOiBjYXNlIG51bGw6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OiB0aGlzLmRlcHJlY2F0ZWQgPSBCb29sZWFuKHRoaXMuZGVwcmVjYXRlZCk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGksIG1vZGVsO1xuXG4gIGlmIChkZWZpbml0aW9ucykge1xuICAgIC8vIGFkZCB0byBnbG9iYWwgbW9kZWxzXG4gICAgZm9yIChrZXkgaW4gZGVmaW5pdGlvbnMpIHtcbiAgICAgIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgZGVmaW5pdGlvbnNba2V5XSwgdGhpcy5tb2RlbHMsIHBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgICBpZiAobW9kZWwpIHtcbiAgICAgICAgdGhpcy5tb2RlbHNba2V5XSA9IG1vZGVsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBkZWZpbml0aW9ucyA9IHt9O1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkLCBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgIHBhcmFtLmRlZmF1bHQgPSB0aGlzLnBhcmFtZXRlck1hY3JvKHRoaXMsIHBhcmFtKTtcblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW0uYWxsb3dNdWx0aXBsZSA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIGlubmVyVHlwZSA9IHRoaXMuZ2V0VHlwZShwYXJhbSk7XG5cbiAgICBpZiAoaW5uZXJUeXBlICYmIGlubmVyVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgPT09ICdib29sZWFuJykge1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID0ge307XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW1bJ2VudW0nXSA9IFt0cnVlLCBmYWxzZV07IC8vIHVzZSBhY3R1YWwgcHJpbWl0aXZlc1xuICAgIH1cblxuICAgIGZvcihrZXkgaW4gcGFyYW0pIHtcbiAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoa2V5LCBwYXJhbSk7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBwYXJhbVsneC1leGFtcGxlJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBkID0gcGFyYW1bJ3gtZXhhbXBsZSddO1xuICAgICAgcGFyYW0uZGVmYXVsdCA9IGQ7XG4gICAgfVxuICAgIGlmKHBhcmFtWyd4LWV4YW1wbGVzJ10pIHtcbiAgICAgIGQgPSBwYXJhbVsneC1leGFtcGxlcyddLmRlZmF1bHQ7XG4gICAgICBpZih0eXBlb2YgZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcGFyYW0uZGVmYXVsdCA9IGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGVudW1WYWx1ZXMgPSBwYXJhbVsnZW51bSddIHx8IChwYXJhbS5pdGVtcyAmJiBwYXJhbS5pdGVtc1snZW51bSddKTtcblxuICAgIGlmICh0eXBlb2YgZW51bVZhbHVlcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpZDtcblxuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID0ge307XG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMudmFsdWVzID0gW107XG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMuZGVzY3JpcHRpdmVWYWx1ZXMgPSBbXTtcblxuICAgICAgZm9yIChpZCA9IDA7IGlkIDwgZW51bVZhbHVlcy5sZW5ndGg7IGlkKyspIHtcbiAgICAgICAgdmFyIHZhbHVlID0gZW51bVZhbHVlc1tpZF07XG4gICAgICAgIHZhciBpc0RlZmF1bHQgPSAodmFsdWUgPT09IHBhcmFtLmRlZmF1bHQgfHwgdmFsdWUrJycgPT09IHBhcmFtLmRlZmF1bHQpO1xuXG4gICAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy52YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgIC8vIEFsd2F5cyBoYXZlIHN0cmluZyBmb3IgZGVzY3JpcHRpdmUgdmFsdWVzLi4uLlxuICAgICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMuZGVzY3JpcHRpdmVWYWx1ZXMucHVzaCh7dmFsdWUgOiB2YWx1ZSsnJywgaXNEZWZhdWx0OiBpc0RlZmF1bHR9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgaW5uZXJUeXBlID0gW2lubmVyVHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBjYW4ndCBzaG93IGFzIGEgbGlzdCBpZiBubyB2YWx1ZXMgdG8gc2VsZWN0IGZyb21cbiAgICAgICAgZGVsZXRlIHBhcmFtLmlzTGlzdDtcbiAgICAgICAgZGVsZXRlIHBhcmFtLmFsbG93TXVsdGlwbGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFyYW0ubW9kZWxTaWduYXR1cmUgPSB7dHlwZTogaW5uZXJUeXBlLCBkZWZpbml0aW9uczogdGhpcy5tb2RlbHN9O1xuICAgIHBhcmFtLnNpZ25hdHVyZSA9IHRoaXMuZ2V0TW9kZWxTaWduYXR1cmUoaW5uZXJUeXBlLCB0aGlzLm1vZGVscykudG9TdHJpbmcoKTtcbiAgICBwYXJhbS5zYW1wbGVKU09OID0gdGhpcy5nZXRNb2RlbFNhbXBsZUpTT04oaW5uZXJUeXBlLCB0aGlzLm1vZGVscyk7XG4gICAgcGFyYW0ucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9IHBhcmFtLnNpZ25hdHVyZTtcbiAgfVxuXG4gIHZhciBrZXluYW1lLCBkZWZhdWx0UmVzcG9uc2VDb2RlLCByZXNwb25zZSwgcmVzcG9uc2VzID0gdGhpcy5yZXNwb25zZXM7XG5cbiAgaWYgKHJlc3BvbnNlc1snMjAwJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAwJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDAnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAxJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAxJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDEnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAyJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAyJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDInO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAzJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAzJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDMnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA0J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDQnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA1J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA1J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDUnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA2J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA2J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDYnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snZGVmYXVsdCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJ2RlZmF1bHQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJ2RlZmF1bHQnO1xuICB9XG5cbiAgZm9yKGtleW5hbWUgaW4gcmVzcG9uc2VzKSB7XG4gICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhrZXluYW1lLCByZXNwb25zZXMpO1xuICAgIGlmKHR5cGVvZiBrZXluYW1lID09PSAnc3RyaW5nJyAmJiBrZXluYW1lLmluZGV4T2YoJ3gtJykgPT09IC0xKSB7XG4gICAgICB2YXIgcmVzcG9uc2VPYmplY3QgPSByZXNwb25zZXNba2V5bmFtZV07XG4gICAgICBpZih0eXBlb2YgcmVzcG9uc2VPYmplY3QgPT09ICdvYmplY3QnICYmIHR5cGVvZiByZXNwb25zZU9iamVjdC5oZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICB2YXIgaGVhZGVycyA9IHJlc3BvbnNlT2JqZWN0LmhlYWRlcnM7XG4gICAgICAgIGZvcih2YXIgaGVhZGVyTmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgICAgICAgdmFyIGhlYWRlciA9IGhlYWRlcnNbaGVhZGVyTmFtZV07XG4gICAgICAgICAgaWYodHlwZW9mIGhlYWRlciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGZvcih2YXIgaGVhZGVyS2V5IGluIGhlYWRlcikge1xuICAgICAgICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGhlYWRlcktleSwgaGVhZGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocmVzcG9uc2UpIHtcbiAgICBmb3Ioa2V5bmFtZSBpbiByZXNwb25zZSkge1xuICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhrZXluYW1lLCByZXNwb25zZSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnNjaGVtYSkge1xuICAgIHZhciByZXNvbHZlZE1vZGVsID0gdGhpcy5yZXNvbHZlTW9kZWwocmVzcG9uc2Uuc2NoZW1hLCBkZWZpbml0aW9ucyk7XG4gICAgdmFyIHN1Y2Nlc3NSZXNwb25zZTtcblxuICAgIGRlbGV0ZSByZXNwb25zZXNbZGVmYXVsdFJlc3BvbnNlQ29kZV07XG5cbiAgICBpZiAocmVzb2x2ZWRNb2RlbCkge1xuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzb2x2ZWRNb2RlbDtcbiAgICB9IGVsc2UgaWYgKCFyZXNwb25zZS5zY2hlbWEudHlwZSB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgfHwgcmVzcG9uc2Uuc2NoZW1hLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIC8vIElubGluZSBtb2RlbFxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gbmV3IE1vZGVsKHVuZGVmaW5lZCwgcmVzcG9uc2Uuc2NoZW1hIHx8IHt9LCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFByaW1pdGl2ZVxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzcG9uc2Uuc2NoZW1hO1xuICAgIH1cblxuICAgIGlmIChzdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZS52ZW5kb3JFeHRlbnNpb25zID0gcmVzcG9uc2UudmVuZG9yRXh0ZW5zaW9ucztcbiAgICAgIC8vIEF0dGFjaCByZXNwb25zZSBwcm9wZXJ0aWVzXG4gICAgICBpZiAocmVzcG9uc2UuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmRlc2NyaXB0aW9uID0gcmVzcG9uc2UuZGVzY3JpcHRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5leGFtcGxlcykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZXhhbXBsZXMgPSByZXNwb25zZS5leGFtcGxlcztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMpIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHlwZSA9IHJlc3BvbnNlO1xuICB9XG5cbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHRoaXMucmVzb3VyY2UgJiYgdGhpcy5yZXNvdXJjZS5hcGkgJiYgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbCkge1xuICAgICAgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbChlcnJvcnMpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5pc0RlZmF1bHRBcnJheUl0ZW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlLCBwYXJhbSkge1xuICBpZiAocGFyYW0uZGVmYXVsdCAmJiBBcnJheS5pc0FycmF5KHBhcmFtLmRlZmF1bHQpKSB7XG4gICAgcmV0dXJuIHBhcmFtLmRlZmF1bHQuaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICB9XG4gIHJldHVybiB2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uIChwYXJhbSkge1xuICB2YXIgdHlwZSA9IHBhcmFtLnR5cGU7XG4gIHZhciBmb3JtYXQgPSBwYXJhbS5mb3JtYXQ7XG4gIHZhciBpc0FycmF5ID0gZmFsc2U7XG4gIHZhciBzdHI7XG5cbiAgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0Jykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgc3RyID0gJ2RhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSAnc3RyaW5nJztcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIGlzQXJyYXkgPSB0cnVlO1xuXG4gICAgaWYgKHBhcmFtLml0ZW1zKSB7XG4gICAgICBzdHIgPSB0aGlzLmdldFR5cGUocGFyYW0uaXRlbXMpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnZmlsZScpIHtcbiAgICBzdHIgPSAnZmlsZSc7XG4gIH1cblxuICBpZiAocGFyYW0uJHJlZikge1xuICAgIHN0ciA9IGhlbHBlcnMuc2ltcGxlUmVmKHBhcmFtLiRyZWYpO1xuICB9XG5cbiAgdmFyIHNjaGVtYSA9IHBhcmFtLnNjaGVtYTtcblxuICBpZiAoc2NoZW1hKSB7XG4gICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuXG4gICAgaWYgKHJlZikge1xuICAgICAgcmVmID0gaGVscGVycy5zaW1wbGVSZWYocmVmKTtcblxuICAgICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIFsgcmVmIF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVmO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBpbmxpbmUgc2NoZW1hLCB3ZSBhZGQgaXQgb3VyIGludGVyYWwgaGFzaCAtPiB3aGljaCBnaXZlcyB1cyBpdCdzIElEIChpbnQpXG4gICAgICBpZihzY2hlbWEudHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkSW5saW5lTW9kZWwoc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmdldFR5cGUoc2NoZW1hKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzQXJyYXkpIHtcbiAgICByZXR1cm4gWyBzdHIgXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59O1xuXG4vKipcbiAqIGFkZHMgYW4gaW5saW5lIHNjaGVtYSAobW9kZWwpIHRvIGEgaGFzaCwgd2hlcmUgd2UgY2FuIHJlZiBpdCBsYXRlclxuICogQHBhcmFtIHtvYmplY3R9IHNjaGVtYSBhIHNjaGVtYVxuICogQHJldHVybiB7bnVtYmVyfSB0aGUgSUQgb2YgdGhlIHNjaGVtYSBiZWluZyBhZGRlZCwgb3IgbnVsbFxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5hZGRJbmxpbmVNb2RlbCA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgdmFyIGxlbiA9IHRoaXMuaW5saW5lTW9kZWxzLmxlbmd0aDtcbiAgdmFyIG1vZGVsID0gdGhpcy5yZXNvbHZlTW9kZWwoc2NoZW1hLCB7fSk7XG4gIGlmKG1vZGVsKSB7XG4gICAgdGhpcy5pbmxpbmVNb2RlbHMucHVzaChtb2RlbCk7XG4gICAgcmV0dXJuICdJbmxpbmUgTW9kZWwgJytsZW47IC8vIHJldHVybiBzdHJpbmcgcmVmIG9mIHRoZSBpbmxpbmUgbW9kZWwgKHVzZWQgd2l0aCAjZ2V0SW5saW5lTW9kZWwpXG4gIH1cbiAgcmV0dXJuIG51bGw7IC8vIHJlcG9ydCBlcnJvcnM/XG59O1xuXG4vKipcbiAqIGdldHMgdGhlIGludGVybmFsIHJlZiB0byBhbiBpbmxpbmUgbW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmxpbmVfc3RyIGEgc3RyaW5nIHJlZmVyZW5jZSB0byBhbiBpbmxpbmUgbW9kZWxcbiAqIEByZXR1cm4ge01vZGVsfSB0aGUgbW9kZWwgYmVpbmcgcmVmZXJlbmNlZC4gT3IgbnVsbFxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRJbmxpbmVNb2RlbCA9IGZ1bmN0aW9uKGlubGluZVN0cikge1xuICBpZigvXklubGluZSBNb2RlbCBcXGQrJC8udGVzdChpbmxpbmVTdHIpKSB7XG4gICAgdmFyIGlkID0gcGFyc2VJbnQoaW5saW5lU3RyLnN1YnN0cignSW5saW5lIE1vZGVsJy5sZW5ndGgpLnRyaW0oKSwxMCk7IC8vXG4gICAgdmFyIG1vZGVsID0gdGhpcy5pbmxpbmVNb2RlbHNbaWRdO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuICAvLyBJJ20gcmV0dXJuaW5nIG51bGwgaGVyZSwgc2hvdWxkIEkgcmF0aGVyIHRocm93IGFuIGVycm9yP1xuICByZXR1cm4gbnVsbDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUucmVzb2x2ZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSwgZGVmaW5pdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBzY2hlbWEuJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgIHJlZiA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgIH1cblxuICAgIGlmIChkZWZpbml0aW9uc1tyZWZdKSB7XG4gICAgICByZXR1cm4gbmV3IE1vZGVsKHJlZiwgZGVmaW5pdGlvbnNbcmVmXSwgdGhpcy5tb2RlbHMsIHRoaXMucGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgfVxuICAvLyBzY2hlbWEgbXVzdCBhdCBsZWFzdCBiZSBhbiBvYmplY3QgdG8gZ2V0IHJlc29sdmVkIHRvIGFuIGlubGluZSBNb2RlbFxuICB9IGVsc2UgaWYgKHNjaGVtYSAmJiB0eXBlb2Ygc2NoZW1hID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgKHNjaGVtYS50eXBlID09PSAnb2JqZWN0JyB8fCBfLmlzVW5kZWZpbmVkKHNjaGVtYS50eXBlKSkpIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKHVuZGVmaW5lZCwgc2NoZW1hLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5oZWxwID0gZnVuY3Rpb24gKGRvbnRQcmludCkge1xuICB2YXIgb3V0ID0gdGhpcy5uaWNrbmFtZSArICc6ICcgKyB0aGlzLnN1bW1hcnkgKyAnXFxuJztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICB2YXIgdHlwZUluZm8gPSBwYXJhbS5zaWduYXR1cmU7XG5cbiAgICBvdXQgKz0gJ1xcbiAgKiAnICsgcGFyYW0ubmFtZSArICcgKCcgKyB0eXBlSW5mbyArICcpOiAnICsgcGFyYW0uZGVzY3JpcHRpb247XG4gIH1cblxuICBpZiAodHlwZW9mIGRvbnRQcmludCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBoZWxwZXJzLmxvZyhvdXQpO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0TW9kZWxTaWduYXR1cmUgPSBmdW5jdGlvbiAodHlwZSwgZGVmaW5pdGlvbnMpIHtcbiAgdmFyIGlzUHJpbWl0aXZlLCBsaXN0VHlwZTtcblxuICBpZiAodHlwZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgbGlzdFR5cGUgPSB0cnVlO1xuICAgIHR5cGUgPSB0eXBlWzBdO1xuICB9XG5cbiAgLy8gQ29udmVydCB1bmRlZmluZWQgdG8gc3RyaW5nIG9mICd1bmRlZmluZWQnXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0eXBlID0gJ3VuZGVmaW5lZCc7XG4gICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuXG4gIH0gZWxzZSBpZiAoZGVmaW5pdGlvbnNbdHlwZV0pe1xuICAgIC8vIGEgbW9kZWwgZGVmIGV4aXN0cz9cbiAgICB0eXBlID0gZGVmaW5pdGlvbnNbdHlwZV07IC8qIE1vZGVsICovXG4gICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICB9IGVsc2UgaWYgKHRoaXMuZ2V0SW5saW5lTW9kZWwodHlwZSkpIHtcbiAgICB0eXBlID0gdGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSB7XG4gICAgLy8gV2UgZGVmYXVsdCB0byBwcmltaXRpdmVcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG4gIH1cblxuICBpZiAoaXNQcmltaXRpdmUpIHtcbiAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUgKyAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0eXBlLnRvU3RyaW5nKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZS5nZXRNb2NrU2lnbmF0dXJlKCkgKyAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0eXBlLmdldE1vY2tTaWduYXR1cmUoKTtcbiAgICB9XG4gIH1cbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnBhcmVudC5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRIZWFkZXJQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgaGVhZGVycyA9IHRoaXMuc2V0Q29udGVudFR5cGVzKGFyZ3MsIHt9KTtcbiAgdmFyIGhlYWRlclBhcmFtc0J5TG93ZXJDYXNlID0ge307XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdoZWFkZXInKSB7XG4gICAgICBoZWFkZXJQYXJhbXNCeUxvd2VyQ2FzZVtwYXJhbS5uYW1lLnRvTG93ZXJDYXNlKCldID0gcGFyYW07XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgYXJnIGluIGFyZ3MpIHtcbiAgICB2YXIgaGVhZGVyUGFyYW0gPSBoZWFkZXJQYXJhbXNCeUxvd2VyQ2FzZVthcmcudG9Mb3dlckNhc2UoKV07XG4gICAgaWYgKHR5cGVvZiBoZWFkZXJQYXJhbSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFyZ3NbYXJnXTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaGVhZGVyc1toZWFkZXJQYXJhbS5uYW1lXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS51cmxpZnkgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgZm9ybVBhcmFtcyA9IHt9O1xuICB2YXIgcmVxdWVzdFVybCA9IHRoaXMucGF0aC5yZXBsYWNlKC8jLiovLCAnJyk7IC8vIHJlbW92ZSBVUkwgZnJhZ21lbnRcbiAgdmFyIHF1ZXJ5c3RyaW5nID0gJyc7IC8vIGdyYWIgcGFyYW1zIGZyb20gdGhlIGFyZ3MsIGJ1aWxkIHRoZSBxdWVyeXN0cmluZyBhbG9uZyB0aGUgd2F5XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAodHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAocGFyYW0uaW4gPT09ICdwYXRoJykge1xuICAgICAgICB2YXIgcmVnID0gbmV3IFJlZ0V4cCgnXFx7JyArIHBhcmFtLm5hbWUgKyAnXFx9JywgJ2dpJyk7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZ3NbcGFyYW0ubmFtZV07XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmVuY29kZVBhdGhDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtLm5hbWUsIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuZW5jb2RlUGF0aFBhcmFtKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcXVlc3RVcmwgPSByZXF1ZXN0VXJsLnJlcGxhY2UocmVnLCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAncXVlcnknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAocXVlcnlzdHJpbmcgPT09ICcnICYmIHJlcXVlc3RVcmwuaW5kZXhPZignPycpIDwgMCkge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICc/JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdmFyIHFwID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHFwKSkge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgcXApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KHBhcmFtLm5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKGFyZ3NbcGFyYW0ubmFtZV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KHBhcmFtLm5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKGFyZ3NbcGFyYW0ubmFtZV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgdXJsID0gdGhpcy5zY2hlbWUgKyAnOi8vJyArIHRoaXMuaG9zdDtcblxuICBpZiAodGhpcy5iYXNlUGF0aCAhPT0gJy8nKSB7XG4gICAgdXJsICs9IHRoaXMuYmFzZVBhdGg7XG4gIH1cbiAgcmV0dXJuIHVybCArIHJlcXVlc3RVcmwgKyBxdWVyeXN0cmluZztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0TWlzc2luZ1BhcmFtcyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBtaXNzaW5nUGFyYW1zID0gW107IC8vIGNoZWNrIHJlcXVpcmVkIHBhcmFtcywgdHJhY2sgdGhlIG9uZXMgdGhhdCBhcmUgbWlzc2luZ1xuICB2YXIgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHBhcmFtLnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG1pc3NpbmdQYXJhbXMgPSBwYXJhbS5uYW1lO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtaXNzaW5nUGFyYW1zO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRCb2R5ID0gZnVuY3Rpb24gKGhlYWRlcnMsIGFyZ3MpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fSwgaGFzRm9ybVBhcmFtcywgcGFyYW0sIGJvZHksIGtleSwgdmFsdWUsIGhhc0JvZHkgPSBmYWxzZTtcblxuICAvLyBsb29rIGF0IGVhY2ggcGFyYW0gYW5kIHB1dCBmb3JtIHBhcmFtcyBpbiBhbiBvYmplY3RcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICBpZiAodHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAocGFyYW0uaW4gPT09ICdib2R5Jykge1xuICAgICAgICBib2R5ID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgZm9ybVBhcmFtc1twYXJhbS5uYW1lXSA9IHtcbiAgICAgICAgICBwYXJhbTogcGFyYW0sXG4gICAgICAgICAgdmFsdWU6IGFyZ3NbcGFyYW0ubmFtZV1cbiAgICAgICAgfTtcbiAgICAgICAgaGFzRm9ybVBhcmFtcyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYocGFyYW0uaW4gPT09ICdib2R5Jykge1xuICAgICAgICBoYXNCb2R5ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiBib2R5IGlzIG51bGwgYW5kIGhhc0JvZHkgaXMgdHJ1ZSwgQU5EIGEgSlNPTiBib2R5IGlzIHJlcXVlc3RlZCwgc2VuZCBlbXB0eSB7fVxuICBpZihoYXNCb2R5ICYmIHR5cGVvZiBib2R5ID09PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjb250ZW50VHlwZSA9IGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIGlmKGNvbnRlbnRUeXBlICYmIGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCkge1xuICAgICAgYm9keSA9ICd7fSc7XG4gICAgfVxuICB9XG5cbiAgdmFyIGlzTXVsdGlQYXJ0ID0gZmFsc2U7XG4gIGlmKGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddICYmIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA+PSAwKSB7XG4gICAgaXNNdWx0aVBhcnQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaGFuZGxlIGZvcm0gcGFyYW1zXG4gIGlmIChoYXNGb3JtUGFyYW1zICYmICFpc011bHRpUGFydCkge1xuICAgIHZhciBlbmNvZGVkID0gJyc7XG5cbiAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgIHZhbHVlID0gZm9ybVBhcmFtc1trZXldLnZhbHVlO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBpZiAoZW5jb2RlZCAhPT0gJycpIHtcbiAgICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW5jb2RlZCArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBib2R5ID0gZW5jb2RlZDtcbiAgfSBlbHNlIGlmIChpc011bHRpUGFydCkge1xuICAgIHZhciBib2R5UGFyYW07XG4gICAgaWYgKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgYm9keVBhcmFtID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgIGJvZHlQYXJhbS50eXBlID0gJ2Zvcm1EYXRhJztcblxuICAgICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgICBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseSh2YWx1ZSkgPT09ICdbb2JqZWN0IEZpbGVdJykge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAodmFsdWUudHlwZSA9PT0gJ2ZpbGUnICYmIHZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUudmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgaWYocGFyYW0uY29sbGVjdGlvbkZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIHYgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZVt2XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlKS5zcGxpdCgnPScpLnNsaWNlKDEpLmpvaW4oJz0nKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBib2R5UGFyYW0gPSB7fTtcbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhciBkZWxpbWV0ZXI7XG4gICAgICAgICAgdmFyIGZvcm1hdCA9IHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgfHwgJ211bHRpJztcbiAgICAgICAgICBpZihmb3JtYXQgPT09ICdzc3YnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnICc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAncGlwZXMnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnfCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAndHN2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ1xcdCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAnbXVsdGknKSB7XG4gICAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJywnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgICAgIGlmKGRhdGEpIHtcbiAgICAgICAgICAgICAgZGF0YSArPSBkZWxpbWV0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZGF0YSA9ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YSArPSB2O1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJvZHlQYXJhbVtrZXldID0gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBib2R5ID0gYm9keVBhcmFtO1xuICAgIH1cbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgfVxuXG4gIHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBnZXRzIHNhbXBsZSByZXNwb25zZSBmb3IgYSBzaW5nbGUgb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2FtcGxlSlNPTiA9IGZ1bmN0aW9uICh0eXBlLCBtb2RlbHMpIHtcbiAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICBsaXN0VHlwZSA9ICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpO1xuICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgc2FtcGxlSnNvbiA9IG1vZGVsc1tpbm5lclR5cGVdLmNyZWF0ZUpTT05TYW1wbGUoKTtcbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgIHNhbXBsZUpzb24gPSB0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkuY3JlYXRlSlNPTlNhbXBsZSgpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICB9XG5cblxuICBpZiAoc2FtcGxlSnNvbikge1xuICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICBpZiAodHlwZW9mIHNhbXBsZUpzb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qoc2FtcGxlSnNvbikpIHtcbiAgICAgIHZhciB0ID0gc2FtcGxlSnNvbjtcblxuICAgICAgaWYgKHNhbXBsZUpzb24gaW5zdGFuY2VvZiBBcnJheSAmJiBzYW1wbGVKc29uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdCA9IHNhbXBsZUpzb25bMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0Lm5vZGVOYW1lICYmIHR5cGVvZiB0ID09PSAnTm9kZScpIHtcbiAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBsZWdhY3kgYmluZGluZ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5kbyA9IGZ1bmN0aW9uIChhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCkge1xuICByZXR1cm4gdGhpcy5leGVjdXRlKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KTtcbn07XG5cbi8qKlxuICogZXhlY3V0ZXMgYW4gb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgcGFyZW50KSB7XG4gIHZhciBhcmdzID0gYXJnMSB8fCB7fTtcbiAgdmFyIG9wdHMgPSB7fSwgc3VjY2VzcywgZXJyb3IsIGRlZmVycmVkLCB0aW1lb3V0O1xuXG4gIGlmIChfLmlzT2JqZWN0KGFyZzIpKSB7XG4gICAgb3B0cyA9IGFyZzI7XG4gICAgc3VjY2VzcyA9IGFyZzM7XG4gICAgZXJyb3IgPSBhcmc0O1xuICB9XG5cbiAgdGltZW91dCA9IHR5cGVvZiBvcHRzLnRpbWVvdXQgIT09ICd1bmRlZmluZWQnID8gb3B0cy50aW1lb3V0IDogdGhpcy50aW1lb3V0O1xuXG4gIGlmKHRoaXMuY2xpZW50KSB7XG4gICAgb3B0cy5jbGllbnQgPSB0aGlzLmNsaWVudDtcbiAgfVxuXG4gIGlmKHRoaXMucmVxdWVzdEFnZW50KSB7XG4gICAgb3B0cy5yZXF1ZXN0QWdlbnQgPSB0aGlzLnJlcXVlc3RBZ2VudDtcbiAgfVxuXG4gIC8vIGFkZCB0aGUgcmVxdWVzdCBpbnRlcmNlcHRvciBmcm9tIHBhcmVudCwgaWYgbm9uZSBzZW50IGZyb20gY2xpZW50XG4gIGlmKCFvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciAmJiB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciApIHtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMucmVxdWVzdEludGVyY2VwdG9yIDtcbiAgfVxuXG4gIGlmKCFvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgJiYgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBhcmcyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc3VjY2VzcyA9IGFyZzI7XG4gICAgZXJyb3IgPSBhcmczO1xuICB9XG5cbiAgaWYgKHRoaXMucGFyZW50LnVzZVByb21pc2UpIHtcbiAgICBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgfSBlbHNlIHtcbiAgICBzdWNjZXNzID0gKHN1Y2Nlc3MgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayB8fCBoZWxwZXJzLmxvZyk7XG4gICAgZXJyb3IgPSAoZXJyb3IgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9IHRoaXMuanF1ZXJ5QWpheENhY2hlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBqcXVlcnlBamF4Q2FjaGU6IG9wdHMuanF1ZXJ5QWpheENhY2hlLFxuICAgIGRlZmVycmVkOiBkZWZlcnJlZCxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIGNsaWVudEF1dGhvcml6YXRpb25zOiBvcHRzLmNsaWVudEF1dGhvcml6YXRpb25zLFxuICAgIG9uOiB7XG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzdWNjZXNzKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBlcnJvcihyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBpZiAodGltZW91dCkge1xuICAgIG9iai50aW1lb3V0ID0gdGltZW91dDtcbiAgfVxuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqLCB0aGlzLm9wZXJhdGlvbi5zZWN1cml0eSk7XG4gIGlmIChvcHRzLm1vY2sgPT09IHRydWUpIHtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgb3B0cyk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGl0ZW1CeVByaW9yaXR5KGNvbCwgaXRlbVByaW9yaXR5KSB7XG5cbiAgLy8gTm8gcHJpb3JpdGllcz8gcmV0dXJuIGZpcnN0Li4uXG4gIGlmKF8uaXNFbXB0eShpdGVtUHJpb3JpdHkpKSB7XG4gICAgcmV0dXJuIGNvbFswXTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBpdGVtUHJpb3JpdHkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZihjb2wuaW5kZXhPZihpdGVtUHJpb3JpdHlbaV0pID4gLTEpIHtcbiAgICAgIHJldHVybiBpdGVtUHJpb3JpdHlbaV07XG4gICAgfVxuICB9XG5cbiAgLy8gT3RoZXJ3aXNlIHJldHVybiBmaXJzdFxuICByZXR1cm4gY29sWzBdO1xufVxuXG5PcGVyYXRpb24ucHJvdG90eXBlLnNldENvbnRlbnRUeXBlcyA9IGZ1bmN0aW9uIChhcmdzLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgdHlwZVxuICB2YXIgYWxsRGVmaW5lZFBhcmFtcyA9IHRoaXMucGFyYW1ldGVycztcbiAgdmFyIGJvZHk7XG4gIHZhciBjb25zdW1lcyA9IGFyZ3MucGFyYW1ldGVyQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5jb25zdW1lcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBhY2NlcHRzID0gb3B0cy5yZXNwb25zZUNvbnRlbnRUeXBlIHx8IGl0ZW1CeVByaW9yaXR5KHRoaXMucHJvZHVjZXMsIFsnYXBwbGljYXRpb24vanNvbicsICdhcHBsaWNhdGlvbi95YW1sJ10pO1xuICB2YXIgZGVmaW5lZEZpbGVQYXJhbXMgPSBbXTtcbiAgdmFyIGRlZmluZWRGb3JtUGFyYW1zID0gW107XG4gIHZhciBoZWFkZXJzID0ge307XG4gIHZhciBpO1xuXG4gIC8vIGdldCBwYXJhbXMgZnJvbSB0aGUgb3BlcmF0aW9uIGFuZCBzZXQgdGhlbSBpbiBkZWZpbmVkRmlsZVBhcmFtcywgZGVmaW5lZEZvcm1QYXJhbXMsIGhlYWRlcnNcbiAgZm9yIChpID0gMDsgaSA8IGFsbERlZmluZWRQYXJhbXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSBhbGxEZWZpbmVkUGFyYW1zW2ldO1xuXG4gICAgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIGRlZmluZWRGaWxlUGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVmaW5lZEZvcm1QYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2hlYWRlcicgJiYgb3B0cykge1xuICAgICAgdmFyIGtleSA9IHBhcmFtLm5hbWU7XG4gICAgICB2YXIgaGVhZGVyVmFsdWUgPSBvcHRzW3BhcmFtLm5hbWVdO1xuXG4gICAgICBpZiAodHlwZW9mIG9wdHNbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGhlYWRlcnNba2V5XSA9IGhlYWRlclZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdib2R5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGJvZHkgPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZXJlJ3MgYSBib2R5LCBuZWVkIHRvIHNldCB0aGUgY29uc3VtZXMgaGVhZGVyIHZpYSByZXF1ZXN0Q29udGVudFR5cGVcbiAgdmFyIGhhc0JvZHkgPSBib2R5IHx8IGRlZmluZWRGaWxlUGFyYW1zLmxlbmd0aCB8fCBkZWZpbmVkRm9ybVBhcmFtcy5sZW5ndGg7XG4gIGlmICh0aGlzLm1ldGhvZCA9PT0gJ3Bvc3QnIHx8IHRoaXMubWV0aG9kID09PSAncHV0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3BhdGNoJyB8fFxuICAgICAgKCh0aGlzLm1ldGhvZCA9PT0gJ2RlbGV0ZScgfHwgdGhpcy5tZXRob2QgPT09ICdnZXQnKSAmJiBoYXNCb2R5KSkge1xuICAgIGlmIChvcHRzLnJlcXVlc3RDb250ZW50VHlwZSkge1xuICAgICAgY29uc3VtZXMgPSBvcHRzLnJlcXVlc3RDb250ZW50VHlwZTtcbiAgICB9XG4gICAgLy8gaWYgYW55IGZvcm0gcGFyYW1zLCBjb250ZW50IHR5cGUgbXVzdCBiZSBzZXRcbiAgICBpZiAoZGVmaW5lZEZvcm1QYXJhbXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3VtZXMgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHsgICAgICAgICAgICAgLy8gb3ZlcnJpZGUgaWYgc2V0XG4gICAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgICB9IGVsc2UgaWYgKGRlZmluZWRGaWxlUGFyYW1zLmxlbmd0aCA+IDApIHsgLy8gaWYgYSBmaWxlLCBtdXN0IGJlIG11bHRpcGFydC9mb3JtLWRhdGFcbiAgICAgICAgY29uc3VtZXMgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5jb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAvLyB1c2UgdGhlIGNvbnN1bWVzIHNldHRpbmdcbiAgICAgICAgICBmb3IodmFyIGMgaW4gdGhpcy5jb25zdW1lcykge1xuICAgICAgICAgICAgdmFyIGNoayA9IHRoaXMuY29uc3VtZXNbY107XG4gICAgICAgICAgICBpZihjaGsuaW5kZXhPZignYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykgPT09IDAgfHwgY2hrLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA9PT0gMCkge1xuICAgICAgICAgICAgICBjb25zdW1lcyA9IGNoaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBjb25zdW1lcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mcm9tLXVybGVuY29kZWRcbiAgICAgICAgY29uc3VtZXMgPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgY29uc3VtZXMgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMpIHtcbiAgICBpZiAodGhpcy5jb25zdW1lcy5pbmRleE9mKGNvbnN1bWVzKSA9PT0gLTEpIHtcbiAgICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgZG9lc25cXCd0IGNvbnN1bWUgJyArIGNvbnN1bWVzICsgJywgdHJ5ICcgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbnN1bWVzKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0aGlzLm1hdGNoZXNBY2NlcHQoYWNjZXB0cykpIHtcbiAgICBoZWxwZXJzLmxvZygnc2VydmVyIGNhblxcJ3QgcHJvZHVjZSAnICsgYWNjZXB0cyk7XG4gIH1cblxuICBpZiAoKGNvbnN1bWVzICYmIGJvZHkgIT09ICcnKSB8fCAoY29uc3VtZXMgPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSkge1xuICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gY29uc3VtZXM7XG4gIH1cbiAgZWxzZSBpZih0aGlzLmNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMubGVuZ3RoID4gMCAmJiB0aGlzLmNvbnN1bWVzWzBdID09PSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykge1xuICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gdGhpcy5jb25zdW1lc1swXTtcbiAgfVxuXG4gIGlmIChhY2NlcHRzKSB7XG4gICAgaGVhZGVycy5BY2NlcHQgPSBhY2NlcHRzO1xuICB9XG5cbiAgcmV0dXJuIGhlYWRlcnM7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVxdWVzdCBhY2NlcHRzIGhlYWRlciBtYXRjaGVzIGFueXRoaW5nIGluIHRoaXMucHJvZHVjZXMuXG4gKiAgSWYgdGhpcy5wcm9kdWNlcyBjb250YWlucyAqIC8gKiwgaWdub3JlIHRoZSBhY2NlcHQgaGVhZGVyLlxuICogQHBhcmFtIHtzdHJpbmc9fSBhY2NlcHRzIFRoZSBjbGllbnQgcmVxdWVzdCBhY2NlcHQgaGVhZGVyLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5tYXRjaGVzQWNjZXB0ID0gZnVuY3Rpb24oYWNjZXB0cykge1xuICAvLyBubyBhY2NlcHRzIG9yIHByb2R1Y2VzLCBubyBwcm9ibGVtIVxuICBpZiAoIWFjY2VwdHMgfHwgIXRoaXMucHJvZHVjZXMpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gdGhpcy5wcm9kdWNlcy5pbmRleE9mKGFjY2VwdHMpICE9PSAtMSB8fCB0aGlzLnByb2R1Y2VzLmluZGV4T2YoJyovKicpICE9PSAtMTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuYXNDdXJsID0gZnVuY3Rpb24gKGFyZ3MxLCBhcmdzMikge1xuICB2YXIgb3B0cyA9IHttb2NrOiB0cnVlfTtcbiAgaWYgKHR5cGVvZiBhcmdzMiA9PT0gJ29iamVjdCcpIHtcbiAgICBmb3IgKHZhciBhcmdLZXkgaW4gYXJnczIpIHtcbiAgICAgIG9wdHNbYXJnS2V5XSA9IGFyZ3MyW2FyZ0tleV07XG4gICAgfVxuICB9XG4gIHZhciBvYmogPSB0aGlzLmV4ZWN1dGUoYXJnczEsIG9wdHMpO1xuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqLCB0aGlzLm9wZXJhdGlvbi5zZWN1cml0eSk7XG5cbiAgdmFyIHJlc3VsdHMgPSBbXTtcblxuICByZXN1bHRzLnB1c2goJy1YICcgKyB0aGlzLm1ldGhvZC50b1VwcGVyQ2FzZSgpKTtcblxuICBpZiAodHlwZW9mIG9iai5oZWFkZXJzICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBrZXk7XG5cbiAgICBmb3IgKGtleSBpbiBvYmouaGVhZGVycykge1xuICAgICAgdmFyIHZhbHVlID0gb2JqLmhlYWRlcnNba2V5XTtcbiAgICAgIGlmKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpe1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL1xcJy9nLCAnXFxcXHUwMDI3Jyk7XG4gICAgICB9XG4gICAgICByZXN1bHRzLnB1c2goJy0taGVhZGVyIFxcJycgKyBrZXkgKyAnOiAnICsgdmFsdWUgKyAnXFwnJyk7XG4gICAgfVxuICB9XG4gIHZhciBpc0Zvcm1EYXRhID0gZmFsc2U7XG4gIHZhciBpc011bHRpcGFydCA9IGZhbHNlO1xuXG4gIHZhciB0eXBlID0gb2JqLmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICBpZih0eXBlICYmIHR5cGUuaW5kZXhPZignYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykgPT09IDApIHtcbiAgICBpc0Zvcm1EYXRhID0gdHJ1ZTtcbiAgfVxuICBlbHNlIGlmICh0eXBlICYmIHR5cGUuaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID09PSAwKSB7XG4gICAgaXNGb3JtRGF0YSA9IHRydWU7XG4gICAgaXNNdWx0aXBhcnQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKG9iai5ib2R5KSB7XG4gICAgdmFyIGJvZHk7XG4gICAgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICBpZihpc011bHRpcGFydCkge1xuICAgICAgICBpc011bHRpcGFydCA9IHRydWU7XG4gICAgICAgIC8vIGFkZCB0aGUgZm9ybSBkYXRhXG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgcGFyYW1ldGVyID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgICAgICAgIGlmKHBhcmFtZXRlci5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICAgICAgaWYgKCFib2R5KSB7XG4gICAgICAgICAgICAgIGJvZHkgPSAnJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBhcmFtVmFsdWU7XG4gICAgICAgICAgICBpZih0eXBlb2YgRm9ybURhdGEgPT09ICdmdW5jdGlvbicgJiYgb2JqLmJvZHkgaW5zdGFuY2VvZiBGb3JtRGF0YSkge1xuICAgICAgICAgICAgICBwYXJhbVZhbHVlID0gb2JqLmJvZHkuZ2V0QWxsKHBhcmFtZXRlci5uYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBwYXJhbVZhbHVlID0gb2JqLmJvZHlbcGFyYW1ldGVyLm5hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhcmFtVmFsdWUpIHtcbiAgICAgICAgICAgICAgaWYgKHBhcmFtZXRlci50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgICAgICAgICBpZihwYXJhbVZhbHVlLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyBwYXJhbWV0ZXIubmFtZSArICc9QFwiJyArIHBhcmFtVmFsdWUubmFtZSArICdcIiAnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbVZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgaWYocGFyYW1ldGVyLmNvbGxlY3Rpb25Gb3JtYXQgPT09ICdtdWx0aScpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciB2IGluIHBhcmFtVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbWV0ZXIubmFtZSkgKyAnPScgKyBwYXJhbVZhbHVlW3ZdICsgJyAnO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtZXRlci5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbWV0ZXIubmFtZSwgcGFyYW1WYWx1ZSkgKyAnICc7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyB0aGlzLmVuY29kZVF1ZXJ5S2V5KHBhcmFtZXRlci5uYW1lKSArICc9JyArIHBhcmFtVmFsdWUgKyAnICc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZighYm9keSkge1xuICAgICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBib2R5ID0gb2JqLmJvZHk7XG4gICAgfVxuICAgIC8vIGVzY2FwZSBAID0+ICU0MCwgJyA9PiAlMjdcbiAgICBib2R5ID0gYm9keS5yZXBsYWNlKC9cXCcvZywgJyUyNycpLnJlcGxhY2UoL1xcbi9nLCAnIFxcXFwgXFxuICcpO1xuXG4gICAgaWYoIWlzRm9ybURhdGEpIHtcbiAgICAgIC8vIGVzY2FwZSAmID0+ICUyNlxuICAgICAgYm9keSA9IGJvZHkucmVwbGFjZSgvJi9nLCAnJTI2Jyk7XG4gICAgfVxuICAgIGlmKGlzTXVsdGlwYXJ0KSB7XG4gICAgICByZXN1bHRzLnB1c2goYm9keSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmVzdWx0cy5wdXNoKCctZCBcXCcnICsgYm9keS5yZXBsYWNlKC9AL2csICclNDAnKSArICdcXCcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gJ2N1cmwgJyArIChyZXN1bHRzLmpvaW4oJyAnKSkgKyAnIFxcJycgKyBvYmoudXJsICsgJ1xcJyc7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVBhdGhDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG4gIHZhciBpO1xuICB2YXIgc2VwYXJhdG9yID0gJyc7XG5cbiAgaWYgKHR5cGUgPT09ICdzc3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJyUyMCc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RzdicpIHtcbiAgICBzZXBhcmF0b3IgPSAnJTA5JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAncGlwZXMnKSB7XG4gICAgc2VwYXJhdG9yID0gJ3wnO1xuICB9IGVsc2Uge1xuICAgIHNlcGFyYXRvciA9ICcsJztcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RlZCArPSBzZXBhcmF0b3IgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG5cbiAgdHlwZSA9IHR5cGUgfHwgJ2RlZmF1bHQnO1xuICBpZiAodHlwZSA9PT0gJ2RlZmF1bHQnIHx8IHR5cGUgPT09ICdtdWx0aScpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChpID4gMCkge2VuY29kZWQgKz0gJyYnO31cblxuICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KG5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gICAgaWYgKHR5cGUgPT09ICdjc3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnLCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJyUyMCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJyUwOSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAncGlwZXMnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnfCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYnJhY2tldHMnKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgIT09IDApIHtcbiAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICdbXT0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VwYXJhdG9yICE9PSAnJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUtleSA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpXG4gICAgICAucmVwbGFjZSgnJTVCJywnWycpLnJlcGxhY2UoJyU1RCcsICddJykucmVwbGFjZSgnJTI0JywgJyQnKTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlQYXJhbSA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpO1xufTtcblxuLyoqXG4gKiBUT0RPIHJldmlzaXQsIG1pZ2h0IG5vdCB3YW50IHRvIGxlYXZlICcvJ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoUGFyYW0gPSBmdW5jdGlvbiAocGF0aFBhcmFtKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQocGF0aFBhcmFtKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBPcGVyYXRpb25Hcm91cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhZywgZGVzY3JpcHRpb24sIGV4dGVybmFsRG9jcywgb3BlcmF0aW9uKSB7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgdGhpcy5leHRlcm5hbERvY3MgPSBleHRlcm5hbERvY3M7XG4gIHRoaXMubmFtZSA9IHRhZztcbiAgdGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247XG4gIHRoaXMub3BlcmF0aW9uc0FycmF5ID0gW107XG4gIHRoaXMucGF0aCA9IHRhZztcbiAgdGhpcy50YWcgPSB0YWc7XG59O1xuXG5PcGVyYXRpb25Hcm91cC5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uICgpIHtcblxufTtcblxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuICAgIHZhciBjdXJyZW50UXVldWU7XG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHZhciBpID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtpXSgpO1xuICAgICAgICB9XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbn1cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgcXVldWUucHVzaChmdW4pO1xuICAgIGlmICghZHJhaW5pbmcpIHtcbiAgICAgICAgc2V0VGltZW91dChkcmFpblF1ZXVlLCAwKTtcbiAgICB9XG59O1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIihmdW5jdGlvbiAoQnVmZmVyKXtcbihmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIGZ1bmN0aW9uIGJ0b2Eoc3RyKSB7XG4gICAgdmFyIGJ1ZmZlclxuICAgICAgO1xuXG4gICAgaWYgKHN0ciBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgYnVmZmVyID0gc3RyO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIgPSBuZXcgQnVmZmVyKHN0ci50b1N0cmluZygpLCAnYmluYXJ5Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IGJ0b2E7XG59KCkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5aWRHOWhMMmx1WkdWNExtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdYQ0oxYzJVZ2MzUnlhV04wWENJN1hHNWNiaUFnWm5WdVkzUnBiMjRnWW5SdllTaHpkSElwSUh0Y2JpQWdJQ0IyWVhJZ1luVm1abVZ5WEc0Z0lDQWdJQ0E3WEc1Y2JpQWdJQ0JwWmlBb2MzUnlJR2x1YzNSaGJtTmxiMllnUW5WbVptVnlLU0I3WEc0Z0lDQWdJQ0JpZFdabVpYSWdQU0J6ZEhJN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJR0oxWm1abGNpQTlJRzVsZHlCQ2RXWm1aWElvYzNSeUxuUnZVM1J5YVc1bktDa3NJQ2RpYVc1aGNua25LVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQnlaWFIxY200Z1luVm1abVZ5TG5SdlUzUnlhVzVuS0NkaVlYTmxOalFuS1R0Y2JpQWdmVnh1WEc0Z0lHMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1luUnZZVHRjYm4wb0tTazdYRzRpWFgwPSIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpcy1hcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG52YXIgcm9vdFBhcmVudCA9IHt9XG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gU2FmYXJpIDUtNyBsYWNrcyBzdXBwb3J0IGZvciBjaGFuZ2luZyB0aGUgYE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3JgIHByb3BlcnR5XG4gKiAgICAgb24gb2JqZWN0cy5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQmFyICgpIHt9XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLmZvbyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgICBhcnIuY29uc3RydWN0b3IgPSBCYXJcbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICBhcnIuY29uc3RydWN0b3IgPT09IEJhciAmJiAvLyBjb25zdHJ1Y3RvciBjYW4gYmUgc2V0XG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufSkoKVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKGFyZykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIC8vIEF2b2lkIGdvaW5nIHRocm91Z2ggYW4gQXJndW1lbnRzQWRhcHRvclRyYW1wb2xpbmUgaW4gdGhlIGNvbW1vbiBjYXNlLlxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBhcmd1bWVudHNbMV0pXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnKVxuICB9XG5cbiAgdGhpcy5sZW5ndGggPSAwXG4gIHRoaXMucGFyZW50ID0gdW5kZWZpbmVkXG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMsIGFyZylcbiAgfVxuXG4gIC8vIFNsaWdodGx5IGxlc3MgY29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoaXMsIGFyZywgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiAndXRmOCcpXG4gIH1cblxuICAvLyBVbnVzdWFsLlxuICByZXR1cm4gZnJvbU9iamVjdCh0aGlzLCBhcmcpXG59XG5cbmZ1bmN0aW9uIGZyb21OdW1iZXIgKHRoYXQsIGxlbmd0aCkge1xuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGxlbmd0aCkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgLy8gQXNzdW1wdGlvbjogYnl0ZUxlbmd0aCgpIHJldHVybiB2YWx1ZSBpcyBhbHdheXMgPCBrTWF4TGVuZ3RoLlxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHJldHVybiBmcm9tQnVmZmVyKHRoYXQsIG9iamVjdClcblxuICBpZiAoaXNBcnJheShvYmplY3QpKSByZXR1cm4gZnJvbUFycmF5KHRoYXQsIG9iamVjdClcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtdXN0IHN0YXJ0IHdpdGggbnVtYmVyLCBidWZmZXIsIGFycmF5IG9yIHN0cmluZycpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChvYmplY3QuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tVHlwZWRBcnJheSh0aGF0LCBvYmplY3QpXG4gICAgfVxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCBvYmplY3QpXG4gICAgfVxuICB9XG5cbiAgaWYgKG9iamVjdC5sZW5ndGgpIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iamVjdClcblxuICByZXR1cm4gZnJvbUpzb25PYmplY3QodGhhdCwgb2JqZWN0KVxufVxuXG5mdW5jdGlvbiBmcm9tQnVmZmVyICh0aGF0LCBidWZmZXIpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYnVmZmVyLmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGJ1ZmZlci5jb3B5KHRoYXQsIDAsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5ICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLy8gRHVwbGljYXRlIG9mIGZyb21BcnJheSgpIHRvIGtlZXAgZnJvbUFycmF5KCkgbW9ub21vcnBoaWMuXG5mdW5jdGlvbiBmcm9tVHlwZWRBcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgLy8gVHJ1bmNhdGluZyB0aGUgZWxlbWVudHMgaXMgcHJvYmFibHkgbm90IHdoYXQgcGVvcGxlIGV4cGVjdCBmcm9tIHR5cGVkXG4gIC8vIGFycmF5cyB3aXRoIEJZVEVTX1BFUl9FTEVNRU5UID4gMSBidXQgaXQncyBjb21wYXRpYmxlIHdpdGggdGhlIGJlaGF2aW9yXG4gIC8vIG9mIHRoZSBvbGQgQnVmZmVyIGNvbnN0cnVjdG9yLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdGhhdCA9IEJ1ZmZlci5fYXVnbWVudChuZXcgVWludDhBcnJheShhcnJheSkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tVHlwZWRBcnJheSh0aGF0LCBuZXcgVWludDhBcnJheShhcnJheSkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIERlc2VyaWFsaXplIHsgdHlwZTogJ0J1ZmZlcicsIGRhdGE6IFsxLDIsMywuLi5dIH0gaW50byBhIEJ1ZmZlciBvYmplY3QuXG4vLyBSZXR1cm5zIGEgemVyby1sZW5ndGggYnVmZmVyIGZvciBpbnB1dHMgdGhhdCBkb24ndCBjb25mb3JtIHRvIHRoZSBzcGVjLlxuZnVuY3Rpb24gZnJvbUpzb25PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICB2YXIgYXJyYXlcbiAgdmFyIGxlbmd0aCA9IDBcblxuICBpZiAob2JqZWN0LnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqZWN0LmRhdGEpKSB7XG4gICAgYXJyYXkgPSBvYmplY3QuZGF0YVxuICAgIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgfVxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBhbGxvY2F0ZSAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgICB0aGF0Ll9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBmcm9tUG9vbCA9IGxlbmd0aCAhPT0gMCAmJiBsZW5ndGggPD0gQnVmZmVyLnBvb2xTaXplID4+PiAxXG4gIGlmIChmcm9tUG9vbCkgdGhhdC5wYXJlbnQgPSByb290UGFyZW50XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChzdWJqZWN0LCBlbmNvZGluZykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2xvd0J1ZmZlcikpIHJldHVybiBuZXcgU2xvd0J1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcbiAgZGVsZXRlIGJ1Zi5wYXJlbnRcbiAgcmV0dXJuIGJ1ZlxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgdmFyIGkgPSAwXG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSBicmVha1xuXG4gICAgKytpXG4gIH1cblxuICBpZiAoaSAhPT0gbGVuKSB7XG4gICAgeCA9IGFbaV1cbiAgICB5ID0gYltpXVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0IGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycy4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykgc3RyaW5nID0gJycgKyBzdHJpbmdcblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIC8vIERlcHJlY2F0ZWRcbiAgICAgIGNhc2UgJ3Jhdyc6XG4gICAgICBjYXNlICdyYXdzJzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbi8vIHByZS1zZXQgZm9yIHZhbHVlcyB0aGF0IG1heSBleGlzdCBpbiB0aGUgZnV0dXJlXG5CdWZmZXIucHJvdG90eXBlLmxlbmd0aCA9IHVuZGVmaW5lZFxuQnVmZmVyLnByb3RvdHlwZS5wYXJlbnQgPSB1bmRlZmluZWRcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIHN0YXJ0ID0gc3RhcnQgfCAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCB8IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG4vLyBgZ2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldCAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoIHwgMFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J1ZmZlciBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndmFsdWUgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuX3NldCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksIHRhcmdldFN0YXJ0KVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIGlmICghdmFsdWUpIHZhbHVlID0gMFxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQpIGVuZCA9IHRoaXMubGVuZ3RoXG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIDwgc3RhcnQnKVxuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3N0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSB1dGY4VG9CeXRlcyh2YWx1ZS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5QnVmZmVyYCB3aXRoIHRoZSAqY29waWVkKiBtZW1vcnkgb2YgdGhlIGJ1ZmZlciBpbnN0YW5jZS5cbiAqIEFkZGVkIGluIE5vZGUgMC4xMi4gT25seSBhdmFpbGFibGUgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEFycmF5QnVmZmVyLlxuICovXG5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiB0b0FycmF5QnVmZmVyICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKHRoaXMpKS5idWZmZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICB9XG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCdWZmZXIudG9BcnJheUJ1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gIH1cbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgQlAgPSBCdWZmZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXVnbWVudCBhIFVpbnQ4QXJyYXkgKmluc3RhbmNlKiAobm90IHRoZSBVaW50OEFycmF5IGNsYXNzISkgd2l0aCBCdWZmZXIgbWV0aG9kc1xuICovXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiBfYXVnbWVudCAoYXJyKSB7XG4gIGFyci5jb25zdHJ1Y3RvciA9IEJ1ZmZlclxuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgc2V0IG1ldGhvZCBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZFxuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5pbmRleE9mID0gQlAuaW5kZXhPZlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50TEUgPSBCUC5yZWFkVUludExFXG4gIGFyci5yZWFkVUludEJFID0gQlAucmVhZFVJbnRCRVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnRMRSA9IEJQLnJlYWRJbnRMRVxuICBhcnIucmVhZEludEJFID0gQlAucmVhZEludEJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludExFID0gQlAud3JpdGVVSW50TEVcbiAgYXJyLndyaXRlVUludEJFID0gQlAud3JpdGVVSW50QkVcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludExFID0gQlAud3JpdGVJbnRMRVxuICBhcnIud3JpdGVJbnRCRSA9IEJQLndyaXRlSW50QkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSBsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwIHwgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG4iLCJ2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiXG4vKipcbiAqIGlzQXJyYXlcbiAqL1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbi8qKlxuICogdG9TdHJpbmdcbiAqL1xuXG52YXIgc3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBXaGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gYHZhbGBcbiAqIGlzIGFuIGFycmF5LlxuICpcbiAqIGV4YW1wbGU6XG4gKlxuICogICAgICAgIGlzQXJyYXkoW10pO1xuICogICAgICAgIC8vID4gdHJ1ZVxuICogICAgICAgIGlzQXJyYXkoYXJndW1lbnRzKTtcbiAqICAgICAgICAvLyA+IGZhbHNlXG4gKiAgICAgICAgaXNBcnJheSgnJyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICpcbiAqIEBwYXJhbSB7bWl4ZWR9IHZhbFxuICogQHJldHVybiB7Ym9vbH1cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXkgfHwgZnVuY3Rpb24gKHZhbCkge1xuICByZXR1cm4gISEgdmFsICYmICdbb2JqZWN0IEFycmF5XScgPT0gc3RyLmNhbGwodmFsKTtcbn07XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuKGZ1bmN0aW9uICgpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCkge1xuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENvb2tpZUFjY2Vzc0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMuZG9tYWluID0gZG9tYWluIHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IHBhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB0aGlzLnNlY3VyZSA9ICEhc2VjdXJlO1xuICAgICAgICAgICAgdGhpcy5zY3JpcHQgPSAhIXNjcmlwdDtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llQWNjZXNzSW5mbyhkb21haW4sIHBhdGgsIHNlY3VyZSwgc2NyaXB0KTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWVBY2Nlc3NJbmZvID0gQ29va2llQWNjZXNzSW5mbztcblxuICAgIGZ1bmN0aW9uIENvb2tpZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgaWYgKGNvb2tpZXN0ciBpbnN0YW5jZW9mIENvb2tpZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvb2tpZXN0cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENvb2tpZSkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSBJbmZpbml0eTtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IFN0cmluZyhyZXF1ZXN0X3BhdGggfHwgXCIvXCIpO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9wYXRoID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluIHx8IG51bGw7XG4gICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSBmYWxzZTsgLy9ob3cgdG8gZGVmaW5lIGRlZmF1bHQ/XG4gICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gZmFsc2U7IC8vaHR0cG9ubHlcbiAgICAgICAgICAgIGlmIChjb29raWVzdHIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcnNlKGNvb2tpZXN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZSA9IENvb2tpZTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgdmFyIHN0ciA9IFt0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWVdO1xuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uX2RhdGUgIT09IEluZmluaXR5KSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImV4cGlyZXM9XCIgKyAobmV3IERhdGUodGhpcy5leHBpcmF0aW9uX2RhdGUpKS50b0dNVFN0cmluZygpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kb21haW4pIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiZG9tYWluPVwiICsgdGhpcy5kb21haW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGgpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwicGF0aD1cIiArIHRoaXMucGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2VjdXJlKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInNlY3VyZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5ub3NjcmlwdCkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJodHRwb25seVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyLmpvaW4oXCI7IFwiKTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS50b1ZhbHVlU3RyaW5nID0gZnVuY3Rpb24gdG9WYWx1ZVN0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZSArIFwiPVwiICsgdGhpcy52YWx1ZTtcbiAgICB9O1xuXG4gICAgdmFyIGNvb2tpZV9zdHJfc3BsaXR0ZXIgPSAvWzpdKD89XFxzKlthLXpBLVowLTlfXFwtXStcXHMqWz1dKS9nO1xuICAgIENvb2tpZS5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdChcIjtcIikuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gISF2YWx1ZTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBwYWlyID0gcGFydHNbMF0ubWF0Y2goLyhbXj1dKyk9KFtcXHNcXFNdKikvKSxcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLFxuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXSxcbiAgICAgICAgICAgICAgICBpO1xuICAgICAgICAgICAgdGhpcy5uYW1lID0ga2V5O1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBwYWlyID0gcGFydHNbaV0ubWF0Y2goLyhbXj1dKykoPzo9KFtcXHNcXFNdKikpPy8pO1xuICAgICAgICAgICAgICAgIGtleSA9IHBhaXJbMV0udHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYWlyWzJdO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcImh0dHBvbmx5XCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9zY3JpcHQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiZXhwaXJlc1wiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGlyYXRpb25fZGF0ZSA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1iZXIoRGF0ZS5wYXJzZSh2YWx1ZSkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmZpbml0eTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXRoID0gdmFsdWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnRyaW0oKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9wYXRoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImRvbWFpblwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfZG9tYWluID0gISF0aGlzLmRvbWFpbjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNlY3VyZVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlY3VyZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmV4cGxpY2l0X3BhdGgpIHtcbiAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHJlcXVlc3RfcGF0aCB8fCBcIi9cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9kb21haW4pIHtcbiAgICAgICAgICAgICAgIHRoaXMuZG9tYWluID0gcmVxdWVzdF9kb21haW47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llKCkucGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5tYXRjaGVzID0gZnVuY3Rpb24gbWF0Y2hlcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICBpZiAodGhpcy5ub3NjcmlwdCAmJiBhY2Nlc3NfaW5mby5zY3JpcHQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLnNlY3VyZSAmJiAhYWNjZXNzX2luZm8uc2VjdXJlIHx8XG4gICAgICAgICAgICAgICAgIXRoaXMuY29sbGlkZXNXaXRoKGFjY2Vzc19pbmZvKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBDb29raWUucHJvdG90eXBlLmNvbGxpZGVzV2l0aCA9IGZ1bmN0aW9uIGNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykge1xuICAgICAgICBpZiAoKHRoaXMucGF0aCAmJiAhYWNjZXNzX2luZm8ucGF0aCkgfHwgKHRoaXMuZG9tYWluICYmICFhY2Nlc3NfaW5mby5kb21haW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucGF0aCAmJiBhY2Nlc3NfaW5mby5wYXRoLmluZGV4T2YodGhpcy5wYXRoKSAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmV4cGxpY2l0X3BhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKCB0aGlzLnBhdGggKSAhPT0gMCkge1xuICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFjY2Vzc19kb21haW4gPSBhY2Nlc3NfaW5mby5kb21haW4gJiYgYWNjZXNzX2luZm8uZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICB2YXIgY29va2llX2RvbWFpbiA9IHRoaXMuZG9tYWluICYmIHRoaXMuZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICBpZiAoY29va2llX2RvbWFpbiA9PT0gYWNjZXNzX2RvbWFpbikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9kb21haW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIHdlIGFscmVhZHkgY2hlY2tlZCBpZiB0aGUgZG9tYWlucyB3ZXJlIGV4YWN0bHkgdGhlIHNhbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB3aWxkY2FyZCA9IGFjY2Vzc19kb21haW4uaW5kZXhPZihjb29raWVfZG9tYWluKTtcbiAgICAgICAgICAgIGlmICh3aWxkY2FyZCA9PT0gLTEgfHwgd2lsZGNhcmQgIT09IGFjY2Vzc19kb21haW4ubGVuZ3RoIC0gY29va2llX2RvbWFpbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gQ29va2llSmFyKCkge1xuICAgICAgICB2YXIgY29va2llcywgY29va2llc19saXN0LCBjb2xsaWRhYmxlX2Nvb2tpZTtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVKYXIpIHtcbiAgICAgICAgICAgIGNvb2tpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpOyAvL25hbWU6IFtDb29raWVdXG5cbiAgICAgICAgICAgIHRoaXMuc2V0Q29va2llID0gZnVuY3Rpb24gc2V0Q29va2llKGNvb2tpZSwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICAgICAgICAgIHZhciByZW1vdmUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llID0gbmV3IENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgICAgIC8vRGVsZXRlIHRoZSBjb29raWUgaWYgdGhlIHNldCBpcyBwYXN0IHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgICAgICAgICByZW1vdmUgPSBjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNbY29va2llLm5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29raWVzX2xpc3QubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpZGFibGVfY29va2llID0gY29va2llc19saXN0W2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxpZGFibGVfY29va2llLmNvbGxpZGVzV2l0aChjb29raWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llc19saXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0W2ldID0gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb29raWVzW2Nvb2tpZS5uYW1lXSA9IFtjb29raWVdO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvL3JldHVybnMgYSBjb29raWVcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29va2llID0gZnVuY3Rpb24gZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBjb29raWUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWVfbmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKCFjb29raWVzX2xpc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZS5leHBpcmF0aW9uX2RhdGUgPD0gRGF0ZS5ub3coKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUubWF0Y2hlcyhhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgbGlzdCBvZiBjb29raWVzXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZXMgPSBmdW5jdGlvbiBnZXRDb29raWVzKGFjY2Vzc19pbmZvKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSBbXSwgY29va2llX25hbWUsIGNvb2tpZTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvb2tpZV9uYW1lIGluIGNvb2tpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29va2llID0gdGhpcy5nZXRDb29raWUoY29va2llX25hbWUsIGFjY2Vzc19pbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlcy5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbWF0Y2hlcy50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5qb2luKFwiOlwiKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVzLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMudG9WYWx1ZVN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICB9KS5qb2luKCc7Jyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcztcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llSmFyKCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llSmFyID0gQ29va2llSmFyO1xuXG4gICAgLy9yZXR1cm5zIGxpc3Qgb2YgY29va2llcyB0aGF0IHdlcmUgc2V0IGNvcnJlY3RseS4gQ29va2llcyB0aGF0IGFyZSBleHBpcmVkIGFuZCByZW1vdmVkIGFyZSBub3QgcmV0dXJuZWQuXG4gICAgQ29va2llSmFyLnByb3RvdHlwZS5zZXRDb29raWVzID0gZnVuY3Rpb24gc2V0Q29va2llcyhjb29raWVzLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGNvb2tpZXMgPSBBcnJheS5pc0FycmF5KGNvb2tpZXMpID9cbiAgICAgICAgICAgICAgICBjb29raWVzIDpcbiAgICAgICAgICAgICAgICBjb29raWVzLnNwbGl0KGNvb2tpZV9zdHJfc3BsaXR0ZXIpO1xuICAgICAgICB2YXIgc3VjY2Vzc2Z1bCA9IFtdLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGNvb2tpZTtcbiAgICAgICAgY29va2llcyA9IGNvb2tpZXMubWFwKGZ1bmN0aW9uKGl0ZW0pe1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoaXRlbSwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29va2llID0gY29va2llc1tpXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpKSB7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc2Z1bC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NmdWw7XG4gICAgfTtcbn0oKSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIHlhbWwgPSByZXF1aXJlKCcuL2xpYi9qcy15YW1sLmpzJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB5YW1sO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBsb2FkZXIgPSByZXF1aXJlKCcuL2pzLXlhbWwvbG9hZGVyJyk7XG52YXIgZHVtcGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2R1bXBlcicpO1xuXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZWQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gJyArIG5hbWUgKyAnIGlzIGRlcHJlY2F0ZWQgYW5kIGNhbm5vdCBiZSB1c2VkLicpO1xuICB9O1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLlR5cGUgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvdHlwZScpO1xubW9kdWxlLmV4cG9ydHMuU2NoZW1hICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEnKTtcbm1vZHVsZS5leHBvcnRzLkZBSUxTQUZFX1NDSEVNQSAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5KU09OX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9qc29uJyk7XG5tb2R1bGUuZXhwb3J0cy5DT1JFX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9jb3JlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgICAgICAgICA9IGxvYWRlci5sb2FkO1xubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgICAgICAgICA9IGxvYWRlci5sb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWQgICAgICAgICAgICA9IGxvYWRlci5zYWZlTG9hZDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkQWxsICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5kdW1wICAgICAgICAgICAgICAgID0gZHVtcGVyLmR1bXA7XG5tb2R1bGUuZXhwb3J0cy5zYWZlRHVtcCAgICAgICAgICAgID0gZHVtcGVyLnNhZmVEdW1wO1xubW9kdWxlLmV4cG9ydHMuWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9leGNlcHRpb24nKTtcblxuLy8gRGVwcmVjYXRlZCBzY2hlbWEgbmFtZXMgZnJvbSBKUy1ZQU1MIDIuMC54XG5tb2R1bGUuZXhwb3J0cy5NSU5JTUFMX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZmFpbHNhZmUnKTtcbm1vZHVsZS5leHBvcnRzLlNBRkVfU0NIRU1BICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcblxuLy8gRGVwcmVjYXRlZCBmdW5jdGlvbnMgZnJvbSBKUy1ZQU1MIDEueC54XG5tb2R1bGUuZXhwb3J0cy5zY2FuICAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3NjYW4nKTtcbm1vZHVsZS5leHBvcnRzLnBhcnNlICAgICAgICAgID0gZGVwcmVjYXRlZCgncGFyc2UnKTtcbm1vZHVsZS5leHBvcnRzLmNvbXBvc2UgICAgICAgID0gZGVwcmVjYXRlZCgnY29tcG9zZScpO1xubW9kdWxlLmV4cG9ydHMuYWRkQ29uc3RydWN0b3IgPSBkZXByZWNhdGVkKCdhZGRDb25zdHJ1Y3RvcicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbmZ1bmN0aW9uIGlzTm90aGluZyhzdWJqZWN0KSB7XG4gIHJldHVybiAodHlwZW9mIHN1YmplY3QgPT09ICd1bmRlZmluZWQnKSB8fCAoc3ViamVjdCA9PT0gbnVsbCk7XG59XG5cblxuZnVuY3Rpb24gaXNPYmplY3Qoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JykgJiYgKHN1YmplY3QgIT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIHRvQXJyYXkoc2VxdWVuY2UpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VxdWVuY2UpKSByZXR1cm4gc2VxdWVuY2U7XG4gIGVsc2UgaWYgKGlzTm90aGluZyhzZXF1ZW5jZSkpIHJldHVybiBbXTtcblxuICByZXR1cm4gWyBzZXF1ZW5jZSBdO1xufVxuXG5cbmZ1bmN0aW9uIGV4dGVuZCh0YXJnZXQsIHNvdXJjZSkge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwga2V5LCBzb3VyY2VLZXlzO1xuXG4gIGlmIChzb3VyY2UpIHtcbiAgICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5cbmZ1bmN0aW9uIHJlcGVhdChzdHJpbmcsIGNvdW50KSB7XG4gIHZhciByZXN1bHQgPSAnJywgY3ljbGU7XG5cbiAgZm9yIChjeWNsZSA9IDA7IGN5Y2xlIDwgY291bnQ7IGN5Y2xlICs9IDEpIHtcbiAgICByZXN1bHQgKz0gc3RyaW5nO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBpc05lZ2F0aXZlWmVybyhudW1iZXIpIHtcbiAgcmV0dXJuIChudW1iZXIgPT09IDApICYmIChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgPT09IDEgLyBudW1iZXIpO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLmlzTm90aGluZyAgICAgID0gaXNOb3RoaW5nO1xubW9kdWxlLmV4cG9ydHMuaXNPYmplY3QgICAgICAgPSBpc09iamVjdDtcbm1vZHVsZS5leHBvcnRzLnRvQXJyYXkgICAgICAgID0gdG9BcnJheTtcbm1vZHVsZS5leHBvcnRzLnJlcGVhdCAgICAgICAgID0gcmVwZWF0O1xubW9kdWxlLmV4cG9ydHMuaXNOZWdhdGl2ZVplcm8gPSBpc05lZ2F0aXZlWmVybztcbm1vZHVsZS5leHBvcnRzLmV4dGVuZCAgICAgICAgID0gZXh0ZW5kO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIERFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5cbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBDSEFSX1RBQiAgICAgICAgICAgICAgICAgID0gMHgwOTsgLyogVGFiICovXG52YXIgQ0hBUl9MSU5FX0ZFRUQgICAgICAgICAgICA9IDB4MEE7IC8qIExGICovXG52YXIgQ0hBUl9TUEFDRSAgICAgICAgICAgICAgICA9IDB4MjA7IC8qIFNwYWNlICovXG52YXIgQ0hBUl9FWENMQU1BVElPTiAgICAgICAgICA9IDB4MjE7IC8qICEgKi9cbnZhciBDSEFSX0RPVUJMRV9RVU9URSAgICAgICAgID0gMHgyMjsgLyogXCIgKi9cbnZhciBDSEFSX1NIQVJQICAgICAgICAgICAgICAgID0gMHgyMzsgLyogIyAqL1xudmFyIENIQVJfUEVSQ0VOVCAgICAgICAgICAgICAgPSAweDI1OyAvKiAlICovXG52YXIgQ0hBUl9BTVBFUlNBTkQgICAgICAgICAgICA9IDB4MjY7IC8qICYgKi9cbnZhciBDSEFSX1NJTkdMRV9RVU9URSAgICAgICAgID0gMHgyNzsgLyogJyAqL1xudmFyIENIQVJfQVNURVJJU0sgICAgICAgICAgICAgPSAweDJBOyAvKiAqICovXG52YXIgQ0hBUl9DT01NQSAgICAgICAgICAgICAgICA9IDB4MkM7IC8qICwgKi9cbnZhciBDSEFSX01JTlVTICAgICAgICAgICAgICAgID0gMHgyRDsgLyogLSAqL1xudmFyIENIQVJfQ09MT04gICAgICAgICAgICAgICAgPSAweDNBOyAvKiA6ICovXG52YXIgQ0hBUl9HUkVBVEVSX1RIQU4gICAgICAgICA9IDB4M0U7IC8qID4gKi9cbnZhciBDSEFSX1FVRVNUSU9OICAgICAgICAgICAgID0gMHgzRjsgLyogPyAqL1xudmFyIENIQVJfQ09NTUVSQ0lBTF9BVCAgICAgICAgPSAweDQwOyAvKiBAICovXG52YXIgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUICA9IDB4NUI7IC8qIFsgKi9cbnZhciBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUID0gMHg1RDsgLyogXSAqL1xudmFyIENIQVJfR1JBVkVfQUNDRU5UICAgICAgICAgPSAweDYwOyAvKiBgICovXG52YXIgQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVQgICA9IDB4N0I7IC8qIHsgKi9cbnZhciBDSEFSX1ZFUlRJQ0FMX0xJTkUgICAgICAgID0gMHg3QzsgLyogfCAqL1xudmFyIENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVCAgPSAweDdEOyAvKiB9ICovXG5cbnZhciBFU0NBUEVfU0VRVUVOQ0VTID0ge307XG5cbkVTQ0FQRV9TRVFVRU5DRVNbMHgwMF0gICA9ICdcXFxcMCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDddICAgPSAnXFxcXGEnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA4XSAgID0gJ1xcXFxiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOV0gICA9ICdcXFxcdCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MEFdICAgPSAnXFxcXG4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBCXSAgID0gJ1xcXFx2JztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQ10gICA9ICdcXFxcZic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MERdICAgPSAnXFxcXHInO1xuRVNDQVBFX1NFUVVFTkNFU1sweDFCXSAgID0gJ1xcXFxlJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMl0gICA9ICdcXFxcXCInO1xuRVNDQVBFX1NFUVVFTkNFU1sweDVDXSAgID0gJ1xcXFxcXFxcJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg4NV0gICA9ICdcXFxcTic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4QTBdICAgPSAnXFxcXF8nO1xuRVNDQVBFX1NFUVVFTkNFU1sweDIwMjhdID0gJ1xcXFxMJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI5XSA9ICdcXFxcUCc7XG5cbnZhciBERVBSRUNBVEVEX0JPT0xFQU5TX1NZTlRBWCA9IFtcbiAgJ3knLCAnWScsICd5ZXMnLCAnWWVzJywgJ1lFUycsICdvbicsICdPbicsICdPTicsXG4gICduJywgJ04nLCAnbm8nLCAnTm8nLCAnTk8nLCAnb2ZmJywgJ09mZicsICdPRkYnXG5dO1xuXG5mdW5jdGlvbiBjb21waWxlU3R5bGVNYXAoc2NoZW1hLCBtYXApIHtcbiAgdmFyIHJlc3VsdCwga2V5cywgaW5kZXgsIGxlbmd0aCwgdGFnLCBzdHlsZSwgdHlwZTtcblxuICBpZiAobWFwID09PSBudWxsKSByZXR1cm4ge307XG5cbiAgcmVzdWx0ID0ge307XG4gIGtleXMgPSBPYmplY3Qua2V5cyhtYXApO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICB0YWcgPSBrZXlzW2luZGV4XTtcbiAgICBzdHlsZSA9IFN0cmluZyhtYXBbdGFnXSk7XG5cbiAgICBpZiAodGFnLnNsaWNlKDAsIDIpID09PSAnISEnKSB7XG4gICAgICB0YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZy5zbGljZSgyKTtcbiAgICB9XG5cbiAgICB0eXBlID0gc2NoZW1hLmNvbXBpbGVkVHlwZU1hcFt0YWddO1xuXG4gICAgaWYgKHR5cGUgJiYgX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5zdHlsZUFsaWFzZXMsIHN0eWxlKSkge1xuICAgICAgc3R5bGUgPSB0eXBlLnN0eWxlQWxpYXNlc1tzdHlsZV07XG4gICAgfVxuXG4gICAgcmVzdWx0W3RhZ10gPSBzdHlsZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGVuY29kZUhleChjaGFyYWN0ZXIpIHtcbiAgdmFyIHN0cmluZywgaGFuZGxlLCBsZW5ndGg7XG5cbiAgc3RyaW5nID0gY2hhcmFjdGVyLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuXG4gIGlmIChjaGFyYWN0ZXIgPD0gMHhGRikge1xuICAgIGhhbmRsZSA9ICd4JztcbiAgICBsZW5ndGggPSAyO1xuICB9IGVsc2UgaWYgKGNoYXJhY3RlciA8PSAweEZGRkYpIHtcbiAgICBoYW5kbGUgPSAndSc7XG4gICAgbGVuZ3RoID0gNDtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGRkZGRikge1xuICAgIGhhbmRsZSA9ICdVJztcbiAgICBsZW5ndGggPSA4O1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdjb2RlIHBvaW50IHdpdGhpbiBhIHN0cmluZyBtYXkgbm90IGJlIGdyZWF0ZXIgdGhhbiAweEZGRkZGRkZGJyk7XG4gIH1cblxuICByZXR1cm4gJ1xcXFwnICsgaGFuZGxlICsgY29tbW9uLnJlcGVhdCgnMCcsIGxlbmd0aCAtIHN0cmluZy5sZW5ndGgpICsgc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBTdGF0ZShvcHRpb25zKSB7XG4gIHRoaXMuc2NoZW1hICAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5pbmRlbnQgICAgICAgPSBNYXRoLm1heCgxLCAob3B0aW9uc1snaW5kZW50J10gfHwgMikpO1xuICB0aGlzLnNraXBJbnZhbGlkICA9IG9wdGlvbnNbJ3NraXBJbnZhbGlkJ10gfHwgZmFsc2U7XG4gIHRoaXMuZmxvd0xldmVsICAgID0gKGNvbW1vbi5pc05vdGhpbmcob3B0aW9uc1snZmxvd0xldmVsJ10pID8gLTEgOiBvcHRpb25zWydmbG93TGV2ZWwnXSk7XG4gIHRoaXMuc3R5bGVNYXAgICAgID0gY29tcGlsZVN0eWxlTWFwKHRoaXMuc2NoZW1hLCBvcHRpb25zWydzdHlsZXMnXSB8fCBudWxsKTtcbiAgdGhpcy5zb3J0S2V5cyAgICAgPSBvcHRpb25zWydzb3J0S2V5cyddIHx8IGZhbHNlO1xuICB0aGlzLmxpbmVXaWR0aCAgICA9IG9wdGlvbnNbJ2xpbmVXaWR0aCddIHx8IDgwO1xuICB0aGlzLm5vUmVmcyAgICAgICA9IG9wdGlvbnNbJ25vUmVmcyddIHx8IGZhbHNlO1xuICB0aGlzLm5vQ29tcGF0TW9kZSA9IG9wdGlvbnNbJ25vQ29tcGF0TW9kZSddIHx8IGZhbHNlO1xuXG4gIHRoaXMuaW1wbGljaXRUeXBlcyA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkSW1wbGljaXQ7XG4gIHRoaXMuZXhwbGljaXRUeXBlcyA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkRXhwbGljaXQ7XG5cbiAgdGhpcy50YWcgPSBudWxsO1xuICB0aGlzLnJlc3VsdCA9ICcnO1xuXG4gIHRoaXMuZHVwbGljYXRlcyA9IFtdO1xuICB0aGlzLnVzZWREdXBsaWNhdGVzID0gbnVsbDtcbn1cblxuLy8gSW5kZW50cyBldmVyeSBsaW5lIGluIGEgc3RyaW5nLiBFbXB0eSBsaW5lcyAoXFxuIG9ubHkpIGFyZSBub3QgaW5kZW50ZWQuXG5mdW5jdGlvbiBpbmRlbnRTdHJpbmcoc3RyaW5nLCBzcGFjZXMpIHtcbiAgdmFyIGluZCA9IGNvbW1vbi5yZXBlYXQoJyAnLCBzcGFjZXMpLFxuICAgICAgcG9zaXRpb24gPSAwLFxuICAgICAgbmV4dCA9IC0xLFxuICAgICAgcmVzdWx0ID0gJycsXG4gICAgICBsaW5lLFxuICAgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXh0ID0gc3RyaW5nLmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV4dCA9PT0gLTEpIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24pO1xuICAgICAgcG9zaXRpb24gPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24sIG5leHQgKyAxKTtcbiAgICAgIHBvc2l0aW9uID0gbmV4dCArIDE7XG4gICAgfVxuXG4gICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcXG4nKSByZXN1bHQgKz0gaW5kO1xuXG4gICAgcmVzdWx0ICs9IGxpbmU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCkge1xuICByZXR1cm4gJ1xcbicgKyBjb21tb24ucmVwZWF0KCcgJywgc3RhdGUuaW5kZW50ICogbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cikge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwgdHlwZTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbaW5kZXhdO1xuXG4gICAgaWYgKHR5cGUucmVzb2x2ZShzdHIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFszM10gcy13aGl0ZSA6Oj0gcy1zcGFjZSB8IHMtdGFiXG5mdW5jdGlvbiBpc1doaXRlc3BhY2UoYykge1xuICByZXR1cm4gYyA9PT0gQ0hBUl9TUEFDRSB8fCBjID09PSBDSEFSX1RBQjtcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgY2FuIGJlIHByaW50ZWQgd2l0aG91dCBlc2NhcGluZy5cbi8vIEZyb20gWUFNTCAxLjI6IFwiYW55IGFsbG93ZWQgY2hhcmFjdGVycyBrbm93biB0byBiZSBub24tcHJpbnRhYmxlXG4vLyBzaG91bGQgYWxzbyBiZSBlc2NhcGVkLiBbSG93ZXZlcixdIFRoaXMgaXNu4oCZdCBtYW5kYXRvcnlcIlxuLy8gRGVyaXZlZCBmcm9tIG5iLWNoYXIgLSBcXHQgLSAjeDg1IC0gI3hBMCAtICN4MjAyOCAtICN4MjAyOS5cbmZ1bmN0aW9uIGlzUHJpbnRhYmxlKGMpIHtcbiAgcmV0dXJuICAoMHgwMDAyMCA8PSBjICYmIGMgPD0gMHgwMDAwN0UpXG4gICAgICB8fCAoKDB4MDAwQTEgPD0gYyAmJiBjIDw9IDB4MDBEN0ZGKSAmJiBjICE9PSAweDIwMjggJiYgYyAhPT0gMHgyMDI5KVxuICAgICAgfHwgKCgweDBFMDAwIDw9IGMgJiYgYyA8PSAweDAwRkZGRCkgJiYgYyAhPT0gMHhGRUZGIC8qIEJPTSAqLylcbiAgICAgIHx8ICAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpO1xufVxuXG4vLyBTaW1wbGlmaWVkIHRlc3QgZm9yIHZhbHVlcyBhbGxvd2VkIGFmdGVyIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gcGxhaW4gc3R5bGUuXG5mdW5jdGlvbiBpc1BsYWluU2FmZShjKSB7XG4gIC8vIFVzZXMgYSBzdWJzZXQgb2YgbmItY2hhciAtIGMtZmxvdy1pbmRpY2F0b3IgLSBcIjpcIiAtIFwiI1wiXG4gIC8vIHdoZXJlIG5iLWNoYXIgOjo9IGMtcHJpbnRhYmxlIC0gYi1jaGFyIC0gYy1ieXRlLW9yZGVyLW1hcmsuXG4gIHJldHVybiBpc1ByaW50YWJsZShjKSAmJiBjICE9PSAweEZFRkZcbiAgICAvLyAtIGMtZmxvdy1pbmRpY2F0b3JcbiAgICAmJiBjICE9PSBDSEFSX0NPTU1BXG4gICAgJiYgYyAhPT0gQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUXG4gICAgLy8gLSBcIjpcIiAtIFwiI1wiXG4gICAgJiYgYyAhPT0gQ0hBUl9DT0xPTlxuICAgICYmIGMgIT09IENIQVJfU0hBUlA7XG59XG5cbi8vIFNpbXBsaWZpZWQgdGVzdCBmb3IgdmFsdWVzIGFsbG93ZWQgYXMgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiBwbGFpbiBzdHlsZS5cbmZ1bmN0aW9uIGlzUGxhaW5TYWZlRmlyc3QoYykge1xuICAvLyBVc2VzIGEgc3Vic2V0IG9mIG5zLWNoYXIgLSBjLWluZGljYXRvclxuICAvLyB3aGVyZSBucy1jaGFyID0gbmItY2hhciAtIHMtd2hpdGUuXG4gIHJldHVybiBpc1ByaW50YWJsZShjKSAmJiBjICE9PSAweEZFRkZcbiAgICAmJiAhaXNXaGl0ZXNwYWNlKGMpIC8vIC0gcy13aGl0ZVxuICAgIC8vIC0gKGMtaW5kaWNhdG9yIDo6PVxuICAgIC8vIOKAnC3igJ0gfCDigJw/4oCdIHwg4oCcOuKAnSB8IOKAnCzigJ0gfCDigJxb4oCdIHwg4oCcXeKAnSB8IOKAnHvigJ0gfCDigJx94oCdXG4gICAgJiYgYyAhPT0gQ0hBUl9NSU5VU1xuICAgICYmIGMgIT09IENIQVJfUVVFU1RJT05cbiAgICAmJiBjICE9PSBDSEFSX0NPTE9OXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NQVxuICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVFxuICAgIC8vIHwg4oCcI+KAnSB8IOKAnCbigJ0gfCDigJwq4oCdIHwg4oCcIeKAnSB8IOKAnHzigJ0gfCDigJw+4oCdIHwg4oCcJ+KAnSB8IOKAnFwi4oCdXG4gICAgJiYgYyAhPT0gQ0hBUl9TSEFSUFxuICAgICYmIGMgIT09IENIQVJfQU1QRVJTQU5EXG4gICAgJiYgYyAhPT0gQ0hBUl9BU1RFUklTS1xuICAgICYmIGMgIT09IENIQVJfRVhDTEFNQVRJT05cbiAgICAmJiBjICE9PSBDSEFSX1ZFUlRJQ0FMX0xJTkVcbiAgICAmJiBjICE9PSBDSEFSX0dSRUFURVJfVEhBTlxuICAgICYmIGMgIT09IENIQVJfU0lOR0xFX1FVT1RFXG4gICAgJiYgYyAhPT0gQ0hBUl9ET1VCTEVfUVVPVEVcbiAgICAvLyB8IOKAnCXigJ0gfCDigJxA4oCdIHwg4oCcYOKAnSlcbiAgICAmJiBjICE9PSBDSEFSX1BFUkNFTlRcbiAgICAmJiBjICE9PSBDSEFSX0NPTU1FUkNJQUxfQVRcbiAgICAmJiBjICE9PSBDSEFSX0dSQVZFX0FDQ0VOVDtcbn1cblxudmFyIFNUWUxFX1BMQUlOICAgPSAxLFxuICAgIFNUWUxFX1NJTkdMRSAgPSAyLFxuICAgIFNUWUxFX0xJVEVSQUwgPSAzLFxuICAgIFNUWUxFX0ZPTERFRCAgPSA0LFxuICAgIFNUWUxFX0RPVUJMRSAgPSA1O1xuXG4vLyBEZXRlcm1pbmVzIHdoaWNoIHNjYWxhciBzdHlsZXMgYXJlIHBvc3NpYmxlIGFuZCByZXR1cm5zIHRoZSBwcmVmZXJyZWQgc3R5bGUuXG4vLyBsaW5lV2lkdGggPSAtMSA9PiBubyBsaW1pdC5cbi8vIFByZS1jb25kaXRpb25zOiBzdHIubGVuZ3RoID4gMC5cbi8vIFBvc3QtY29uZGl0aW9uczpcbi8vICAgIFNUWUxFX1BMQUlOIG9yIFNUWUxFX1NJTkdMRSA9PiBubyBcXG4gYXJlIGluIHRoZSBzdHJpbmcuXG4vLyAgICBTVFlMRV9MSVRFUkFMID0+IG5vIGxpbmVzIGFyZSBzdWl0YWJsZSBmb3IgZm9sZGluZyAob3IgbGluZVdpZHRoIGlzIC0xKS5cbi8vICAgIFNUWUxFX0ZPTERFRCA9PiBhIGxpbmUgPiBsaW5lV2lkdGggYW5kIGNhbiBiZSBmb2xkZWQgKGFuZCBsaW5lV2lkdGggIT0gLTEpLlxuZnVuY3Rpb24gY2hvb3NlU2NhbGFyU3R5bGUoc3RyaW5nLCBzaW5nbGVMaW5lT25seSwgaW5kZW50UGVyTGV2ZWwsIGxpbmVXaWR0aCwgdGVzdEFtYmlndW91c1R5cGUpIHtcbiAgdmFyIGk7XG4gIHZhciBjaGFyO1xuICB2YXIgaGFzTGluZUJyZWFrID0gZmFsc2U7XG4gIHZhciBoYXNGb2xkYWJsZUxpbmUgPSBmYWxzZTsgLy8gb25seSBjaGVja2VkIGlmIHNob3VsZFRyYWNrV2lkdGhcbiAgdmFyIHNob3VsZFRyYWNrV2lkdGggPSBsaW5lV2lkdGggIT09IC0xO1xuICB2YXIgcHJldmlvdXNMaW5lQnJlYWsgPSAtMTsgLy8gY291bnQgdGhlIGZpcnN0IGxpbmUgY29ycmVjdGx5XG4gIHZhciBwbGFpbiA9IGlzUGxhaW5TYWZlRmlyc3Qoc3RyaW5nLmNoYXJDb2RlQXQoMCkpXG4gICAgICAgICAgJiYgIWlzV2hpdGVzcGFjZShzdHJpbmcuY2hhckNvZGVBdChzdHJpbmcubGVuZ3RoIC0gMSkpO1xuXG4gIGlmIChzaW5nbGVMaW5lT25seSkge1xuICAgIC8vIENhc2U6IG5vIGJsb2NrIHN0eWxlcy5cbiAgICAvLyBDaGVjayBmb3IgZGlzYWxsb3dlZCBjaGFyYWN0ZXJzIHRvIHJ1bGUgb3V0IHBsYWluIGFuZCBzaW5nbGUuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKCFpc1ByaW50YWJsZShjaGFyKSkge1xuICAgICAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICAgICAgfVxuICAgICAgcGxhaW4gPSBwbGFpbiAmJiBpc1BsYWluU2FmZShjaGFyKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gQ2FzZTogYmxvY2sgc3R5bGVzIHBlcm1pdHRlZC5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY2hhciA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgICAgaGFzTGluZUJyZWFrID0gdHJ1ZTtcbiAgICAgICAgLy8gQ2hlY2sgaWYgYW55IGxpbmUgY2FuIGJlIGZvbGRlZC5cbiAgICAgICAgaWYgKHNob3VsZFRyYWNrV2lkdGgpIHtcbiAgICAgICAgICBoYXNGb2xkYWJsZUxpbmUgPSBoYXNGb2xkYWJsZUxpbmUgfHxcbiAgICAgICAgICAgIC8vIEZvbGRhYmxlIGxpbmUgPSB0b28gbG9uZywgYW5kIG5vdCBtb3JlLWluZGVudGVkLlxuICAgICAgICAgICAgKGkgLSBwcmV2aW91c0xpbmVCcmVhayAtIDEgPiBsaW5lV2lkdGggJiZcbiAgICAgICAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKTtcbiAgICAgICAgICBwcmV2aW91c0xpbmVCcmVhayA9IGk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWlzUHJpbnRhYmxlKGNoYXIpKSB7XG4gICAgICAgIHJldHVybiBTVFlMRV9ET1VCTEU7XG4gICAgICB9XG4gICAgICBwbGFpbiA9IHBsYWluICYmIGlzUGxhaW5TYWZlKGNoYXIpO1xuICAgIH1cbiAgICAvLyBpbiBjYXNlIHRoZSBlbmQgaXMgbWlzc2luZyBhIFxcblxuICAgIGhhc0ZvbGRhYmxlTGluZSA9IGhhc0ZvbGRhYmxlTGluZSB8fCAoc2hvdWxkVHJhY2tXaWR0aCAmJlxuICAgICAgKGkgLSBwcmV2aW91c0xpbmVCcmVhayAtIDEgPiBsaW5lV2lkdGggJiZcbiAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKSk7XG4gIH1cbiAgLy8gQWx0aG91Z2ggZXZlcnkgc3R5bGUgY2FuIHJlcHJlc2VudCBcXG4gd2l0aG91dCBlc2NhcGluZywgcHJlZmVyIGJsb2NrIHN0eWxlc1xuICAvLyBmb3IgbXVsdGlsaW5lLCBzaW5jZSB0aGV5J3JlIG1vcmUgcmVhZGFibGUgYW5kIHRoZXkgZG9uJ3QgYWRkIGVtcHR5IGxpbmVzLlxuICAvLyBBbHNvIHByZWZlciBmb2xkaW5nIGEgc3VwZXItbG9uZyBsaW5lLlxuICBpZiAoIWhhc0xpbmVCcmVhayAmJiAhaGFzRm9sZGFibGVMaW5lKSB7XG4gICAgLy8gU3RyaW5ncyBpbnRlcnByZXRhYmxlIGFzIGFub3RoZXIgdHlwZSBoYXZlIHRvIGJlIHF1b3RlZDtcbiAgICAvLyBlLmcuIHRoZSBzdHJpbmcgJ3RydWUnIHZzLiB0aGUgYm9vbGVhbiB0cnVlLlxuICAgIHJldHVybiBwbGFpbiAmJiAhdGVzdEFtYmlndW91c1R5cGUoc3RyaW5nKVxuICAgICAgPyBTVFlMRV9QTEFJTiA6IFNUWUxFX1NJTkdMRTtcbiAgfVxuICAvLyBFZGdlIGNhc2U6IGJsb2NrIGluZGVudGF0aW9uIGluZGljYXRvciBjYW4gb25seSBoYXZlIG9uZSBkaWdpdC5cbiAgaWYgKHN0cmluZ1swXSA9PT0gJyAnICYmIGluZGVudFBlckxldmVsID4gOSkge1xuICAgIHJldHVybiBTVFlMRV9ET1VCTEU7XG4gIH1cbiAgLy8gQXQgdGhpcyBwb2ludCB3ZSBrbm93IGJsb2NrIHN0eWxlcyBhcmUgdmFsaWQuXG4gIC8vIFByZWZlciBsaXRlcmFsIHN0eWxlIHVubGVzcyB3ZSB3YW50IHRvIGZvbGQuXG4gIHJldHVybiBoYXNGb2xkYWJsZUxpbmUgPyBTVFlMRV9GT0xERUQgOiBTVFlMRV9MSVRFUkFMO1xufVxuXG4vLyBOb3RlOiBsaW5lIGJyZWFraW5nL2ZvbGRpbmcgaXMgaW1wbGVtZW50ZWQgZm9yIG9ubHkgdGhlIGZvbGRlZCBzdHlsZS5cbi8vIE5CLiBXZSBkcm9wIHRoZSBsYXN0IHRyYWlsaW5nIG5ld2xpbmUgKGlmIGFueSkgb2YgYSByZXR1cm5lZCBibG9jayBzY2FsYXJcbi8vICBzaW5jZSB0aGUgZHVtcGVyIGFkZHMgaXRzIG93biBuZXdsaW5lLiBUaGlzIGFsd2F5cyB3b3Jrczpcbi8vICAgIOKAoiBObyBlbmRpbmcgbmV3bGluZSA9PiB1bmFmZmVjdGVkOyBhbHJlYWR5IHVzaW5nIHN0cmlwIFwiLVwiIGNob21waW5nLlxuLy8gICAg4oCiIEVuZGluZyBuZXdsaW5lICAgID0+IHJlbW92ZWQgdGhlbiByZXN0b3JlZC5cbi8vICBJbXBvcnRhbnRseSwgdGhpcyBrZWVwcyB0aGUgXCIrXCIgY2hvbXAgaW5kaWNhdG9yIGZyb20gZ2FpbmluZyBhbiBleHRyYSBsaW5lLlxuZnVuY3Rpb24gd3JpdGVTY2FsYXIoc3RhdGUsIHN0cmluZywgbGV2ZWwsIGlza2V5KSB7XG4gIHN0YXRlLmR1bXAgPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmIChzdHJpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gXCInJ1wiO1xuICAgIH1cbiAgICBpZiAoIXN0YXRlLm5vQ29tcGF0TW9kZSAmJlxuICAgICAgICBERVBSRUNBVEVEX0JPT0xFQU5TX1NZTlRBWC5pbmRleE9mKHN0cmluZykgIT09IC0xKSB7XG4gICAgICByZXR1cm4gXCInXCIgKyBzdHJpbmcgKyBcIidcIjtcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gc3RhdGUuaW5kZW50ICogTWF0aC5tYXgoMSwgbGV2ZWwpOyAvLyBubyAwLWluZGVudCBzY2FsYXJzXG4gICAgLy8gQXMgaW5kZW50YXRpb24gZ2V0cyBkZWVwZXIsIGxldCB0aGUgd2lkdGggZGVjcmVhc2UgbW9ub3RvbmljYWxseVxuICAgIC8vIHRvIHRoZSBsb3dlciBib3VuZCBtaW4oc3RhdGUubGluZVdpZHRoLCA0MCkuXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaW1wbGllc1xuICAgIC8vICBzdGF0ZS5saW5lV2lkdGgg4omkIDQwICsgc3RhdGUuaW5kZW50OiB3aWR0aCBpcyBmaXhlZCBhdCB0aGUgbG93ZXIgYm91bmQuXG4gICAgLy8gIHN0YXRlLmxpbmVXaWR0aCA+IDQwICsgc3RhdGUuaW5kZW50OiB3aWR0aCBkZWNyZWFzZXMgdW50aWwgdGhlIGxvd2VyIGJvdW5kLlxuICAgIC8vIFRoaXMgYmVoYXZlcyBiZXR0ZXIgdGhhbiBhIGNvbnN0YW50IG1pbmltdW0gd2lkdGggd2hpY2ggZGlzYWxsb3dzIG5hcnJvd2VyIG9wdGlvbnMsXG4gICAgLy8gb3IgYW4gaW5kZW50IHRocmVzaG9sZCB3aGljaCBjYXVzZXMgdGhlIHdpZHRoIHRvIHN1ZGRlbmx5IGluY3JlYXNlLlxuICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGggPT09IC0xXG4gICAgICA/IC0xIDogTWF0aC5tYXgoTWF0aC5taW4oc3RhdGUubGluZVdpZHRoLCA0MCksIHN0YXRlLmxpbmVXaWR0aCAtIGluZGVudCk7XG5cbiAgICAvLyBXaXRob3V0IGtub3dpbmcgaWYga2V5cyBhcmUgaW1wbGljaXQvZXhwbGljaXQsIGFzc3VtZSBpbXBsaWNpdCBmb3Igc2FmZXR5LlxuICAgIHZhciBzaW5nbGVMaW5lT25seSA9IGlza2V5XG4gICAgICAvLyBObyBibG9jayBzdHlsZXMgaW4gZmxvdyBtb2RlLlxuICAgICAgfHwgKHN0YXRlLmZsb3dMZXZlbCA+IC0xICYmIGxldmVsID49IHN0YXRlLmZsb3dMZXZlbCk7XG4gICAgZnVuY3Rpb24gdGVzdEFtYmlndWl0eShzdHJpbmcpIHtcbiAgICAgIHJldHVybiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cmluZyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChjaG9vc2VTY2FsYXJTdHlsZShzdHJpbmcsIHNpbmdsZUxpbmVPbmx5LCBzdGF0ZS5pbmRlbnQsIGxpbmVXaWR0aCwgdGVzdEFtYmlndWl0eSkpIHtcbiAgICAgIGNhc2UgU1RZTEVfUExBSU46XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICBjYXNlIFNUWUxFX1NJTkdMRTpcbiAgICAgICAgcmV0dXJuIFwiJ1wiICsgc3RyaW5nLnJlcGxhY2UoLycvZywgXCInJ1wiKSArIFwiJ1wiO1xuICAgICAgY2FzZSBTVFlMRV9MSVRFUkFMOlxuICAgICAgICByZXR1cm4gJ3wnICsgYmxvY2tIZWFkZXIoc3RyaW5nLCBzdGF0ZS5pbmRlbnQpXG4gICAgICAgICAgKyBkcm9wRW5kaW5nTmV3bGluZShpbmRlbnRTdHJpbmcoc3RyaW5nLCBpbmRlbnQpKTtcbiAgICAgIGNhc2UgU1RZTEVfRk9MREVEOlxuICAgICAgICByZXR1cm4gJz4nICsgYmxvY2tIZWFkZXIoc3RyaW5nLCBzdGF0ZS5pbmRlbnQpXG4gICAgICAgICAgKyBkcm9wRW5kaW5nTmV3bGluZShpbmRlbnRTdHJpbmcoZm9sZFN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCksIGluZGVudCkpO1xuICAgICAgY2FzZSBTVFlMRV9ET1VCTEU6XG4gICAgICAgIHJldHVybiAnXCInICsgZXNjYXBlU3RyaW5nKHN0cmluZywgbGluZVdpZHRoKSArICdcIic7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignaW1wb3NzaWJsZSBlcnJvcjogaW52YWxpZCBzY2FsYXIgc3R5bGUnKTtcbiAgICB9XG4gIH0oKSk7XG59XG5cbi8vIFByZS1jb25kaXRpb25zOiBzdHJpbmcgaXMgdmFsaWQgZm9yIGEgYmxvY2sgc2NhbGFyLCAxIDw9IGluZGVudFBlckxldmVsIDw9IDkuXG5mdW5jdGlvbiBibG9ja0hlYWRlcihzdHJpbmcsIGluZGVudFBlckxldmVsKSB7XG4gIHZhciBpbmRlbnRJbmRpY2F0b3IgPSAoc3RyaW5nWzBdID09PSAnICcpID8gU3RyaW5nKGluZGVudFBlckxldmVsKSA6ICcnO1xuXG4gIC8vIG5vdGUgdGhlIHNwZWNpYWwgY2FzZTogdGhlIHN0cmluZyAnXFxuJyBjb3VudHMgYXMgYSBcInRyYWlsaW5nXCIgZW1wdHkgbGluZS5cbiAgdmFyIGNsaXAgPSAgICAgICAgICBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXFxuJztcbiAgdmFyIGtlZXAgPSBjbGlwICYmIChzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDJdID09PSAnXFxuJyB8fCBzdHJpbmcgPT09ICdcXG4nKTtcbiAgdmFyIGNob21wID0ga2VlcCA/ICcrJyA6IChjbGlwID8gJycgOiAnLScpO1xuXG4gIHJldHVybiBpbmRlbnRJbmRpY2F0b3IgKyBjaG9tcCArICdcXG4nO1xufVxuXG4vLyAoU2VlIHRoZSBub3RlIGZvciB3cml0ZVNjYWxhci4pXG5mdW5jdGlvbiBkcm9wRW5kaW5nTmV3bGluZShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZ1tzdHJpbmcubGVuZ3RoIC0gMV0gPT09ICdcXG4nID8gc3RyaW5nLnNsaWNlKDAsIC0xKSA6IHN0cmluZztcbn1cblxuLy8gTm90ZTogYSBsb25nIGxpbmUgd2l0aG91dCBhIHN1aXRhYmxlIGJyZWFrIHBvaW50IHdpbGwgZXhjZWVkIHRoZSB3aWR0aCBsaW1pdC5cbi8vIFByZS1jb25kaXRpb25zOiBldmVyeSBjaGFyIGluIHN0ciBpc1ByaW50YWJsZSwgc3RyLmxlbmd0aCA+IDAsIHdpZHRoID4gMC5cbmZ1bmN0aW9uIGZvbGRTdHJpbmcoc3RyaW5nLCB3aWR0aCkge1xuICAvLyBJbiBmb2xkZWQgc3R5bGUsICRrJCBjb25zZWN1dGl2ZSBuZXdsaW5lcyBvdXRwdXQgYXMgJGsrMSQgbmV3bGluZXPigJRcbiAgLy8gdW5sZXNzIHRoZXkncmUgYmVmb3JlIG9yIGFmdGVyIGEgbW9yZS1pbmRlbnRlZCBsaW5lLCBvciBhdCB0aGUgdmVyeVxuICAvLyBiZWdpbm5pbmcgb3IgZW5kLCBpbiB3aGljaCBjYXNlICRrJCBtYXBzIHRvICRrJC5cbiAgLy8gVGhlcmVmb3JlLCBwYXJzZSBlYWNoIGNodW5rIGFzIG5ld2xpbmUocykgZm9sbG93ZWQgYnkgYSBjb250ZW50IGxpbmUuXG4gIHZhciBsaW5lUmUgPSAvKFxcbispKFteXFxuXSopL2c7XG5cbiAgLy8gZmlyc3QgbGluZSAocG9zc2libHkgYW4gZW1wdHkgbGluZSlcbiAgdmFyIHJlc3VsdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG5leHRMRiA9IHN0cmluZy5pbmRleE9mKCdcXG4nKTtcbiAgICBuZXh0TEYgPSBuZXh0TEYgIT09IC0xID8gbmV4dExGIDogc3RyaW5nLmxlbmd0aDtcbiAgICBsaW5lUmUubGFzdEluZGV4ID0gbmV4dExGO1xuICAgIHJldHVybiBmb2xkTGluZShzdHJpbmcuc2xpY2UoMCwgbmV4dExGKSwgd2lkdGgpO1xuICB9KCkpO1xuICAvLyBJZiB3ZSBoYXZlbid0IHJlYWNoZWQgdGhlIGZpcnN0IGNvbnRlbnQgbGluZSB5ZXQsIGRvbid0IGFkZCBhbiBleHRyYSBcXG4uXG4gIHZhciBwcmV2TW9yZUluZGVudGVkID0gc3RyaW5nWzBdID09PSAnXFxuJyB8fCBzdHJpbmdbMF0gPT09ICcgJztcbiAgdmFyIG1vcmVJbmRlbnRlZDtcblxuICAvLyByZXN0IG9mIHRoZSBsaW5lc1xuICB2YXIgbWF0Y2g7XG4gIHdoaWxlICgobWF0Y2ggPSBsaW5lUmUuZXhlYyhzdHJpbmcpKSkge1xuICAgIHZhciBwcmVmaXggPSBtYXRjaFsxXSwgbGluZSA9IG1hdGNoWzJdO1xuICAgIG1vcmVJbmRlbnRlZCA9IChsaW5lWzBdID09PSAnICcpO1xuICAgIHJlc3VsdCArPSBwcmVmaXhcbiAgICAgICsgKCFwcmV2TW9yZUluZGVudGVkICYmICFtb3JlSW5kZW50ZWQgJiYgbGluZSAhPT0gJydcbiAgICAgICAgPyAnXFxuJyA6ICcnKVxuICAgICAgKyBmb2xkTGluZShsaW5lLCB3aWR0aCk7XG4gICAgcHJldk1vcmVJbmRlbnRlZCA9IG1vcmVJbmRlbnRlZDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEdyZWVkeSBsaW5lIGJyZWFraW5nLlxuLy8gUGlja3MgdGhlIGxvbmdlc3QgbGluZSB1bmRlciB0aGUgbGltaXQgZWFjaCB0aW1lLFxuLy8gb3RoZXJ3aXNlIHNldHRsZXMgZm9yIHRoZSBzaG9ydGVzdCBsaW5lIG92ZXIgdGhlIGxpbWl0LlxuLy8gTkIuIE1vcmUtaW5kZW50ZWQgbGluZXMgKmNhbm5vdCogYmUgZm9sZGVkLCBhcyB0aGF0IHdvdWxkIGFkZCBhbiBleHRyYSBcXG4uXG5mdW5jdGlvbiBmb2xkTGluZShsaW5lLCB3aWR0aCkge1xuICBpZiAobGluZSA9PT0gJycgfHwgbGluZVswXSA9PT0gJyAnKSByZXR1cm4gbGluZTtcblxuICAvLyBTaW5jZSBhIG1vcmUtaW5kZW50ZWQgbGluZSBhZGRzIGEgXFxuLCBicmVha3MgY2FuJ3QgYmUgZm9sbG93ZWQgYnkgYSBzcGFjZS5cbiAgdmFyIGJyZWFrUmUgPSAvIFteIF0vZzsgLy8gbm90ZTogdGhlIG1hdGNoIGluZGV4IHdpbGwgYWx3YXlzIGJlIDw9IGxlbmd0aC0yLlxuICB2YXIgbWF0Y2g7XG4gIC8vIHN0YXJ0IGlzIGFuIGluY2x1c2l2ZSBpbmRleC4gZW5kLCBjdXJyLCBhbmQgbmV4dCBhcmUgZXhjbHVzaXZlLlxuICB2YXIgc3RhcnQgPSAwLCBlbmQsIGN1cnIgPSAwLCBuZXh0ID0gMDtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuXG4gIC8vIEludmFyaWFudHM6IDAgPD0gc3RhcnQgPD0gbGVuZ3RoLTEuXG4gIC8vICAgMCA8PSBjdXJyIDw9IG5leHQgPD0gbWF4KDAsIGxlbmd0aC0yKS4gY3VyciAtIHN0YXJ0IDw9IHdpZHRoLlxuICAvLyBJbnNpZGUgdGhlIGxvb3A6XG4gIC8vICAgQSBtYXRjaCBpbXBsaWVzIGxlbmd0aCA+PSAyLCBzbyBjdXJyIGFuZCBuZXh0IGFyZSA8PSBsZW5ndGgtMi5cbiAgd2hpbGUgKChtYXRjaCA9IGJyZWFrUmUuZXhlYyhsaW5lKSkpIHtcbiAgICBuZXh0ID0gbWF0Y2guaW5kZXg7XG4gICAgLy8gbWFpbnRhaW4gaW52YXJpYW50OiBjdXJyIC0gc3RhcnQgPD0gd2lkdGhcbiAgICBpZiAobmV4dCAtIHN0YXJ0ID4gd2lkdGgpIHtcbiAgICAgIGVuZCA9IChjdXJyID4gc3RhcnQpID8gY3VyciA6IG5leHQ7IC8vIGRlcml2ZSBlbmQgPD0gbGVuZ3RoLTJcbiAgICAgIHJlc3VsdCArPSAnXFxuJyArIGxpbmUuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgICAvLyBza2lwIHRoZSBzcGFjZSB0aGF0IHdhcyBvdXRwdXQgYXMgXFxuXG4gICAgICBzdGFydCA9IGVuZCArIDE7ICAgICAgICAgICAgICAgICAgICAvLyBkZXJpdmUgc3RhcnQgPD0gbGVuZ3RoLTFcbiAgICB9XG4gICAgY3VyciA9IG5leHQ7XG4gIH1cblxuICAvLyBCeSB0aGUgaW52YXJpYW50cywgc3RhcnQgPD0gbGVuZ3RoLTEsIHNvIHRoZXJlIGlzIHNvbWV0aGluZyBsZWZ0IG92ZXIuXG4gIC8vIEl0IGlzIGVpdGhlciB0aGUgd2hvbGUgc3RyaW5nIG9yIGEgcGFydCBzdGFydGluZyBmcm9tIG5vbi13aGl0ZXNwYWNlLlxuICByZXN1bHQgKz0gJ1xcbic7XG4gIC8vIEluc2VydCBhIGJyZWFrIGlmIHRoZSByZW1haW5kZXIgaXMgdG9vIGxvbmcgYW5kIHRoZXJlIGlzIGEgYnJlYWsgYXZhaWxhYmxlLlxuICBpZiAobGluZS5sZW5ndGggLSBzdGFydCA+IHdpZHRoICYmIGN1cnIgPiBzdGFydCkge1xuICAgIHJlc3VsdCArPSBsaW5lLnNsaWNlKHN0YXJ0LCBjdXJyKSArICdcXG4nICsgbGluZS5zbGljZShjdXJyICsgMSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ICs9IGxpbmUuc2xpY2Uoc3RhcnQpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdC5zbGljZSgxKTsgLy8gZHJvcCBleHRyYSBcXG4gam9pbmVyXG59XG5cbi8vIEVzY2FwZXMgYSBkb3VibGUtcXVvdGVkIHN0cmluZy5cbmZ1bmN0aW9uIGVzY2FwZVN0cmluZyhzdHJpbmcpIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICB2YXIgY2hhcjtcbiAgdmFyIGVzY2FwZVNlcTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICBlc2NhcGVTZXEgPSBFU0NBUEVfU0VRVUVOQ0VTW2NoYXJdO1xuICAgIHJlc3VsdCArPSAhZXNjYXBlU2VxICYmIGlzUHJpbnRhYmxlKGNoYXIpXG4gICAgICA/IHN0cmluZ1tpXVxuICAgICAgOiBlc2NhcGVTZXEgfHwgZW5jb2RlSGV4KGNoYXIpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG93U2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgPSAnJyxcbiAgICAgIF90YWcgICAgPSBzdGF0ZS50YWcsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAvLyBXcml0ZSBvbmx5IHZhbGlkIGVsZW1lbnRzLlxuICAgIGlmICh3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3RbaW5kZXhdLCBmYWxzZSwgZmFsc2UpKSB7XG4gICAgICBpZiAoaW5kZXggIT09IDApIF9yZXN1bHQgKz0gJywgJztcbiAgICAgIF9yZXN1bHQgKz0gc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ1snICsgX3Jlc3VsdCArICddJztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBjb21wYWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFtpbmRleF0sIHRydWUsIHRydWUpKSB7XG4gICAgICBpZiAoIWNvbXBhY3QgfHwgaW5kZXggIT09IDApIHtcbiAgICAgICAgX3Jlc3VsdCArPSBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCk7XG4gICAgICB9XG4gICAgICBfcmVzdWx0ICs9ICctICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSBfcmVzdWx0IHx8ICdbXSc7IC8vIEVtcHR5IHNlcXVlbmNlIGlmIG5vIHZhbGlkIHZhbHVlcy5cbn1cblxuZnVuY3Rpb24gd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIG9iamVjdCkge1xuICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLFxuICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGgsXG4gICAgICBvYmplY3RLZXksXG4gICAgICBvYmplY3RWYWx1ZSxcbiAgICAgIHBhaXJCdWZmZXI7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXJCdWZmZXIgPSAnJztcblxuICAgIGlmIChpbmRleCAhPT0gMCkgcGFpckJ1ZmZlciArPSAnLCAnO1xuXG4gICAgb2JqZWN0S2V5ID0gb2JqZWN0S2V5TGlzdFtpbmRleF07XG4gICAgb2JqZWN0VmFsdWUgPSBvYmplY3Rbb2JqZWN0S2V5XTtcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0S2V5LCBmYWxzZSwgZmFsc2UpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIGtleTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcC5sZW5ndGggPiAxMDI0KSBwYWlyQnVmZmVyICs9ICc/ICc7XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXAgKyAnOiAnO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3RWYWx1ZSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICAvLyBCb3RoIGtleSBhbmQgdmFsdWUgYXJlIHZhbGlkLlxuICAgIF9yZXN1bHQgKz0gcGFpckJ1ZmZlcjtcbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSAneycgKyBfcmVzdWx0ICsgJ30nO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLFxuICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGgsXG4gICAgICBvYmplY3RLZXksXG4gICAgICBvYmplY3RWYWx1ZSxcbiAgICAgIGV4cGxpY2l0UGFpcixcbiAgICAgIHBhaXJCdWZmZXI7XG5cbiAgLy8gQWxsb3cgc29ydGluZyBrZXlzIHNvIHRoYXQgdGhlIG91dHB1dCBmaWxlIGlzIGRldGVybWluaXN0aWNcbiAgaWYgKHN0YXRlLnNvcnRLZXlzID09PSB0cnVlKSB7XG4gICAgLy8gRGVmYXVsdCBzb3J0aW5nXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHN0YXRlLnNvcnRLZXlzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gQ3VzdG9tIHNvcnQgZnVuY3Rpb25cbiAgICBvYmplY3RLZXlMaXN0LnNvcnQoc3RhdGUuc29ydEtleXMpO1xuICB9IGVsc2UgaWYgKHN0YXRlLnNvcnRLZXlzKSB7XG4gICAgLy8gU29tZXRoaW5nIGlzIHdyb25nXG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3NvcnRLZXlzIG11c3QgYmUgYSBib29sZWFuIG9yIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoIWNvbXBhY3QgfHwgaW5kZXggIT09IDApIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgIH1cblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RLZXksIHRydWUsIHRydWUsIHRydWUpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIGtleS5cbiAgICB9XG5cbiAgICBleHBsaWNpdFBhaXIgPSAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fFxuICAgICAgICAgICAgICAgICAgIChzdGF0ZS5kdW1wICYmIHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCk7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFpckJ1ZmZlciArPSAnPyAnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIGlmIChleHBsaWNpdFBhaXIpIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgIH1cblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFZhbHVlLCB0cnVlLCBleHBsaWNpdFBhaXIpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIHZhbHVlLlxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5kdW1wICYmIENIQVJfTElORV9GRUVEID09PSBzdGF0ZS5kdW1wLmNoYXJDb2RlQXQoMCkpIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gJzonO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6ICc7XG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAne30nOyAvLyBFbXB0eSBtYXBwaW5nIGlmIG5vIHZhbGlkIHBhaXJzLlxufVxuXG5mdW5jdGlvbiBkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGV4cGxpY2l0KSB7XG4gIHZhciBfcmVzdWx0LCB0eXBlTGlzdCwgaW5kZXgsIGxlbmd0aCwgdHlwZSwgc3R5bGU7XG5cbiAgdHlwZUxpc3QgPSBleHBsaWNpdCA/IHN0YXRlLmV4cGxpY2l0VHlwZXMgOiBzdGF0ZS5pbXBsaWNpdFR5cGVzO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB0eXBlTGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHR5cGVMaXN0W2luZGV4XTtcblxuICAgIGlmICgodHlwZS5pbnN0YW5jZU9mICB8fCB0eXBlLnByZWRpY2F0ZSkgJiZcbiAgICAgICAgKCF0eXBlLmluc3RhbmNlT2YgfHwgKCh0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JykgJiYgKG9iamVjdCBpbnN0YW5jZW9mIHR5cGUuaW5zdGFuY2VPZikpKSAmJlxuICAgICAgICAoIXR5cGUucHJlZGljYXRlICB8fCB0eXBlLnByZWRpY2F0ZShvYmplY3QpKSkge1xuXG4gICAgICBzdGF0ZS50YWcgPSBleHBsaWNpdCA/IHR5cGUudGFnIDogJz8nO1xuXG4gICAgICBpZiAodHlwZS5yZXByZXNlbnQpIHtcbiAgICAgICAgc3R5bGUgPSBzdGF0ZS5zdHlsZU1hcFt0eXBlLnRhZ10gfHwgdHlwZS5kZWZhdWx0U3R5bGU7XG5cbiAgICAgICAgaWYgKF90b1N0cmluZy5jYWxsKHR5cGUucmVwcmVzZW50KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudChvYmplY3QsIHN0eWxlKTtcbiAgICAgICAgfSBlbHNlIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbCh0eXBlLnJlcHJlc2VudCwgc3R5bGUpKSB7XG4gICAgICAgICAgX3Jlc3VsdCA9IHR5cGUucmVwcmVzZW50W3N0eWxlXShvYmplY3QsIHN0eWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignITwnICsgdHlwZS50YWcgKyAnPiB0YWcgcmVzb2x2ZXIgYWNjZXB0cyBub3QgXCInICsgc3R5bGUgKyAnXCIgc3R5bGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlLmR1bXAgPSBfcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFNlcmlhbGl6ZXMgYG9iamVjdGAgYW5kIHdyaXRlcyBpdCB0byBnbG9iYWwgYHJlc3VsdGAuXG4vLyBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcywgb3IgZmFsc2Ugb24gaW52YWxpZCBvYmplY3QuXG4vL1xuZnVuY3Rpb24gd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBibG9jaywgY29tcGFjdCwgaXNrZXkpIHtcbiAgc3RhdGUudGFnID0gbnVsbDtcbiAgc3RhdGUuZHVtcCA9IG9iamVjdDtcblxuICBpZiAoIWRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgZmFsc2UpKSB7XG4gICAgZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCB0cnVlKTtcbiAgfVxuXG4gIHZhciB0eXBlID0gX3RvU3RyaW5nLmNhbGwoc3RhdGUuZHVtcCk7XG5cbiAgaWYgKGJsb2NrKSB7XG4gICAgYmxvY2sgPSAoc3RhdGUuZmxvd0xldmVsIDwgMCB8fCBzdGF0ZS5mbG93TGV2ZWwgPiBsZXZlbCk7XG4gIH1cblxuICB2YXIgb2JqZWN0T3JBcnJheSA9IHR5cGUgPT09ICdbb2JqZWN0IE9iamVjdF0nIHx8IHR5cGUgPT09ICdbb2JqZWN0IEFycmF5XScsXG4gICAgICBkdXBsaWNhdGVJbmRleCxcbiAgICAgIGR1cGxpY2F0ZTtcblxuICBpZiAob2JqZWN0T3JBcnJheSkge1xuICAgIGR1cGxpY2F0ZUluZGV4ID0gc3RhdGUuZHVwbGljYXRlcy5pbmRleE9mKG9iamVjdCk7XG4gICAgZHVwbGljYXRlID0gZHVwbGljYXRlSW5kZXggIT09IC0xO1xuICB9XG5cbiAgaWYgKChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnPycpIHx8IGR1cGxpY2F0ZSB8fCAoc3RhdGUuaW5kZW50ICE9PSAyICYmIGxldmVsID4gMCkpIHtcbiAgICBjb21wYWN0ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoZHVwbGljYXRlICYmIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSkge1xuICAgIHN0YXRlLmR1bXAgPSAnKnJlZl8nICsgZHVwbGljYXRlSW5kZXg7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9iamVjdE9yQXJyYXkgJiYgZHVwbGljYXRlICYmICFzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICAgIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgaWYgKGJsb2NrICYmIChPYmplY3Qua2V5cyhzdGF0ZS5kdW1wKS5sZW5ndGggIT09IDApKSB7XG4gICAgICAgIHdyaXRlQmxvY2tNYXBwaW5nKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCwgY29tcGFjdCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgc3RhdGUuZHVtcDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEFycmF5XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoc3RhdGUuZHVtcC5sZW5ndGggIT09IDApKSB7XG4gICAgICAgIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgJyAnICsgc3RhdGUuZHVtcDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ1tvYmplY3QgU3RyaW5nXScpIHtcbiAgICAgIGlmIChzdGF0ZS50YWcgIT09ICc/Jykge1xuICAgICAgICB3cml0ZVNjYWxhcihzdGF0ZSwgc3RhdGUuZHVtcCwgbGV2ZWwsIGlza2V5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLnNraXBJbnZhbGlkKSByZXR1cm4gZmFsc2U7XG4gICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbigndW5hY2NlcHRhYmxlIGtpbmQgb2YgYW4gb2JqZWN0IHRvIGR1bXAgJyArIHR5cGUpO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgIHN0YXRlLmR1bXAgPSAnITwnICsgc3RhdGUudGFnICsgJz4gJyArIHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMob2JqZWN0LCBzdGF0ZSkge1xuICB2YXIgb2JqZWN0cyA9IFtdLFxuICAgICAgZHVwbGljYXRlc0luZGV4ZXMgPSBbXSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBkdXBsaWNhdGVzSW5kZXhlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgc3RhdGUuZHVwbGljYXRlcy5wdXNoKG9iamVjdHNbZHVwbGljYXRlc0luZGV4ZXNbaW5kZXhdXSk7XG4gIH1cbiAgc3RhdGUudXNlZER1cGxpY2F0ZXMgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gaW5zcGVjdE5vZGUob2JqZWN0LCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcykge1xuICB2YXIgb2JqZWN0S2V5TGlzdCxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGlmIChvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpIHtcbiAgICBpbmRleCA9IG9iamVjdHMuaW5kZXhPZihvYmplY3QpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIGlmIChkdXBsaWNhdGVzSW5kZXhlcy5pbmRleE9mKGluZGV4KSA9PT0gLTEpIHtcbiAgICAgICAgZHVwbGljYXRlc0luZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iamVjdHMucHVzaChvYmplY3QpO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtpbmRleF0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0S2V5TGlzdCA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG5cbiAgICAgICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtvYmplY3RLZXlMaXN0W2luZGV4XV0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkdW1wKGlucHV0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBzdGF0ZSA9IG5ldyBTdGF0ZShvcHRpb25zKTtcblxuICBpZiAoIXN0YXRlLm5vUmVmcykgZ2V0RHVwbGljYXRlUmVmZXJlbmNlcyhpbnB1dCwgc3RhdGUpO1xuXG4gIGlmICh3cml0ZU5vZGUoc3RhdGUsIDAsIGlucHV0LCB0cnVlLCB0cnVlKSkgcmV0dXJuIHN0YXRlLmR1bXAgKyAnXFxuJztcblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIHNhZmVEdW1wKGlucHV0LCBvcHRpb25zKSB7XG4gIHJldHVybiBkdW1wKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgPSBkdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgPSBzYWZlRHVtcDtcbiIsIi8vIFlBTUwgZXJyb3IgY2xhc3MuIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvODQ1ODk4NFxuLy9cbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gWUFNTEV4Y2VwdGlvbihyZWFzb24sIG1hcmspIHtcbiAgLy8gU3VwZXIgY29uc3RydWN0b3JcbiAgRXJyb3IuY2FsbCh0aGlzKTtcblxuICAvLyBJbmNsdWRlIHN0YWNrIHRyYWNlIGluIGVycm9yIG9iamVjdFxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAvLyBDaHJvbWUgYW5kIE5vZGVKU1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuICB9IGVsc2Uge1xuICAgIC8vIEZGLCBJRSAxMCsgYW5kIFNhZmFyaSA2Ky4gRmFsbGJhY2sgZm9yIG90aGVyc1xuICAgIHRoaXMuc3RhY2sgPSAobmV3IEVycm9yKCkpLnN0YWNrIHx8ICcnO1xuICB9XG5cbiAgdGhpcy5uYW1lID0gJ1lBTUxFeGNlcHRpb24nO1xuICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgdGhpcy5tYXJrID0gbWFyaztcbiAgdGhpcy5tZXNzYWdlID0gKHRoaXMucmVhc29uIHx8ICcodW5rbm93biByZWFzb24pJykgKyAodGhpcy5tYXJrID8gJyAnICsgdGhpcy5tYXJrLnRvU3RyaW5nKCkgOiAnJyk7XG59XG5cblxuLy8gSW5oZXJpdCBmcm9tIEVycm9yXG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbllBTUxFeGNlcHRpb24ucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gWUFNTEV4Y2VwdGlvbjtcblxuXG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHJlc3VsdCA9IHRoaXMubmFtZSArICc6ICc7XG5cbiAgcmVzdWx0ICs9IHRoaXMucmVhc29uIHx8ICcodW5rbm93biByZWFzb24pJztcblxuICBpZiAoIWNvbXBhY3QgJiYgdGhpcy5tYXJrKSB7XG4gICAgcmVzdWx0ICs9ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBZQU1MRXhjZXB0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4sbm8tdXNlLWJlZm9yZS1kZWZpbmUqL1xuXG52YXIgY29tbW9uICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgTWFyayAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vbWFyaycpO1xudmFyIERFRkFVTFRfU0FGRV9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cblxudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cblxudmFyIENPTlRFWFRfRkxPV19JTiAgID0gMTtcbnZhciBDT05URVhUX0ZMT1dfT1VUICA9IDI7XG52YXIgQ09OVEVYVF9CTE9DS19JTiAgPSAzO1xudmFyIENPTlRFWFRfQkxPQ0tfT1VUID0gNDtcblxuXG52YXIgQ0hPTVBJTkdfQ0xJUCAgPSAxO1xudmFyIENIT01QSU5HX1NUUklQID0gMjtcbnZhciBDSE9NUElOR19LRUVQICA9IDM7XG5cblxudmFyIFBBVFRFUk5fTk9OX1BSSU5UQUJMRSAgICAgICAgID0gL1tcXHgwMC1cXHgwOFxceDBCXFx4MENcXHgwRS1cXHgxRlxceDdGLVxceDg0XFx4ODYtXFx4OUZcXHVGRkZFXFx1RkZGRl18W1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD86W15cXHVEODAwLVxcdURCRkZdfF4pW1xcdURDMDAtXFx1REZGRl0vO1xudmFyIFBBVFRFUk5fTk9OX0FTQ0lJX0xJTkVfQlJFQUtTID0gL1tcXHg4NVxcdTIwMjhcXHUyMDI5XS87XG52YXIgUEFUVEVSTl9GTE9XX0lORElDQVRPUlMgICAgICAgPSAvWyxcXFtcXF1cXHtcXH1dLztcbnZhciBQQVRURVJOX1RBR19IQU5ETEUgICAgICAgICAgICA9IC9eKD86IXwhIXwhW2EtelxcLV0rISkkL2k7XG52YXIgUEFUVEVSTl9UQUdfVVJJICAgICAgICAgICAgICAgPSAvXig/OiF8W14sXFxbXFxdXFx7XFx9XSkoPzolWzAtOWEtZl17Mn18WzAtOWEtelxcLSM7XFwvXFw/OkAmPVxcK1xcJCxfXFwuIX5cXConXFwoXFwpXFxbXFxdXSkqJC9pO1xuXG5cbmZ1bmN0aW9uIGlzX0VPTChjKSB7XG4gIHJldHVybiAoYyA9PT0gMHgwQS8qIExGICovKSB8fCAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV0hJVEVfU1BBQ0UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MDkvKiBUYWIgKi8pIHx8IChjID09PSAweDIwLyogU3BhY2UgKi8pO1xufVxuXG5mdW5jdGlvbiBpc19XU19PUl9FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MDkvKiBUYWIgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgyMC8qIFNwYWNlICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MEEvKiBMRiAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBELyogQ1IgKi8pO1xufVxuXG5mdW5jdGlvbiBpc19GTE9XX0lORElDQVRPUihjKSB7XG4gIHJldHVybiBjID09PSAweDJDLyogLCAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg1Qi8qIFsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUQvKiBdICovIHx8XG4gICAgICAgICBjID09PSAweDdCLyogeyAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3RC8qIH0gKi87XG59XG5cbmZ1bmN0aW9uIGZyb21IZXhDb2RlKGMpIHtcbiAgdmFyIGxjO1xuXG4gIGlmICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB7XG4gICAgcmV0dXJuIGMgLSAweDMwO1xuICB9XG5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1iaXR3aXNlKi9cbiAgbGMgPSBjIHwgMHgyMDtcblxuICBpZiAoKDB4NjEvKiBhICovIDw9IGxjKSAmJiAobGMgPD0gMHg2Ni8qIGYgKi8pKSB7XG4gICAgcmV0dXJuIGxjIC0gMHg2MSArIDEwO1xuICB9XG5cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVkSGV4TGVuKGMpIHtcbiAgaWYgKGMgPT09IDB4NzgvKiB4ICovKSB7IHJldHVybiAyOyB9XG4gIGlmIChjID09PSAweDc1LyogdSAqLykgeyByZXR1cm4gNDsgfVxuICBpZiAoYyA9PT0gMHg1NS8qIFUgKi8pIHsgcmV0dXJuIDg7IH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGZyb21EZWNpbWFsQ29kZShjKSB7XG4gIGlmICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB7XG4gICAgcmV0dXJuIGMgLSAweDMwO1xuICB9XG5cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVFc2NhcGVTZXF1ZW5jZShjKSB7XG4gIHJldHVybiAoYyA9PT0gMHgzMC8qIDAgKi8pID8gJ1xceDAwJyA6XG4gICAgICAgIChjID09PSAweDYxLyogYSAqLykgPyAnXFx4MDcnIDpcbiAgICAgICAgKGMgPT09IDB4NjIvKiBiICovKSA/ICdcXHgwOCcgOlxuICAgICAgICAoYyA9PT0gMHg3NC8qIHQgKi8pID8gJ1xceDA5JyA6XG4gICAgICAgIChjID09PSAweDA5LyogVGFiICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHg2RS8qIG4gKi8pID8gJ1xceDBBJyA6XG4gICAgICAgIChjID09PSAweDc2LyogdiAqLykgPyAnXFx4MEInIDpcbiAgICAgICAgKGMgPT09IDB4NjYvKiBmICovKSA/ICdcXHgwQycgOlxuICAgICAgICAoYyA9PT0gMHg3Mi8qIHIgKi8pID8gJ1xceDBEJyA6XG4gICAgICAgIChjID09PSAweDY1LyogZSAqLykgPyAnXFx4MUInIDpcbiAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgPyAnICcgOlxuICAgICAgICAoYyA9PT0gMHgyMi8qIFwiICovKSA/ICdcXHgyMicgOlxuICAgICAgICAoYyA9PT0gMHgyRi8qIC8gKi8pID8gJy8nIDpcbiAgICAgICAgKGMgPT09IDB4NUMvKiBcXCAqLykgPyAnXFx4NUMnIDpcbiAgICAgICAgKGMgPT09IDB4NEUvKiBOICovKSA/ICdcXHg4NScgOlxuICAgICAgICAoYyA9PT0gMHg1Ri8qIF8gKi8pID8gJ1xceEEwJyA6XG4gICAgICAgIChjID09PSAweDRDLyogTCAqLykgPyAnXFx1MjAyOCcgOlxuICAgICAgICAoYyA9PT0gMHg1MC8qIFAgKi8pID8gJ1xcdTIwMjknIDogJyc7XG59XG5cbmZ1bmN0aW9uIGNoYXJGcm9tQ29kZXBvaW50KGMpIHtcbiAgaWYgKGMgPD0gMHhGRkZGKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gIH1cbiAgLy8gRW5jb2RlIFVURi0xNiBzdXJyb2dhdGUgcGFpclxuICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtMTYjQ29kZV9wb2ludHNfVS4yQjAxMDAwMF90b19VLjJCMTBGRkZGXG4gIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAtIDB4MDEwMDAwKSA+PiAxMCkgKyAweEQ4MDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYyAtIDB4MDEwMDAwKSAmIDB4MDNGRikgKyAweERDMDApO1xufVxuXG52YXIgc2ltcGxlRXNjYXBlQ2hlY2sgPSBuZXcgQXJyYXkoMjU2KTsgLy8gaW50ZWdlciwgZm9yIGZhc3QgYWNjZXNzXG52YXIgc2ltcGxlRXNjYXBlTWFwID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gIHNpbXBsZUVzY2FwZUNoZWNrW2ldID0gc2ltcGxlRXNjYXBlU2VxdWVuY2UoaSkgPyAxIDogMDtcbiAgc2ltcGxlRXNjYXBlTWFwW2ldID0gc2ltcGxlRXNjYXBlU2VxdWVuY2UoaSk7XG59XG5cblxuZnVuY3Rpb24gU3RhdGUoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdGhpcy5pbnB1dCA9IGlucHV0O1xuXG4gIHRoaXMuZmlsZW5hbWUgID0gb3B0aW9uc1snZmlsZW5hbWUnXSAgfHwgbnVsbDtcbiAgdGhpcy5zY2hlbWEgICAgPSBvcHRpb25zWydzY2hlbWEnXSAgICB8fCBERUZBVUxUX0ZVTExfU0NIRU1BO1xuICB0aGlzLm9uV2FybmluZyA9IG9wdGlvbnNbJ29uV2FybmluZyddIHx8IG51bGw7XG4gIHRoaXMubGVnYWN5ICAgID0gb3B0aW9uc1snbGVnYWN5J10gICAgfHwgZmFsc2U7XG4gIHRoaXMuanNvbiAgICAgID0gb3B0aW9uc1snanNvbiddICAgICAgfHwgZmFsc2U7XG4gIHRoaXMubGlzdGVuZXIgID0gb3B0aW9uc1snbGlzdGVuZXInXSAgfHwgbnVsbDtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLnR5cGVNYXAgICAgICAgPSB0aGlzLnNjaGVtYS5jb21waWxlZFR5cGVNYXA7XG5cbiAgdGhpcy5sZW5ndGggICAgID0gaW5wdXQubGVuZ3RoO1xuICB0aGlzLnBvc2l0aW9uICAgPSAwO1xuICB0aGlzLmxpbmUgICAgICAgPSAwO1xuICB0aGlzLmxpbmVTdGFydCAgPSAwO1xuICB0aGlzLmxpbmVJbmRlbnQgPSAwO1xuXG4gIHRoaXMuZG9jdW1lbnRzID0gW107XG5cbiAgLypcbiAgdGhpcy52ZXJzaW9uO1xuICB0aGlzLmNoZWNrTGluZUJyZWFrcztcbiAgdGhpcy50YWdNYXA7XG4gIHRoaXMuYW5jaG9yTWFwO1xuICB0aGlzLnRhZztcbiAgdGhpcy5hbmNob3I7XG4gIHRoaXMua2luZDtcbiAgdGhpcy5yZXN1bHQ7Ki9cblxufVxuXG5cbmZ1bmN0aW9uIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIG5ldyBZQU1MRXhjZXB0aW9uKFxuICAgIG1lc3NhZ2UsXG4gICAgbmV3IE1hcmsoc3RhdGUuZmlsZW5hbWUsIHN0YXRlLmlucHV0LCBzdGF0ZS5wb3NpdGlvbiwgc3RhdGUubGluZSwgKHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0KSkpO1xufVxuXG5mdW5jdGlvbiB0aHJvd0Vycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHRocm93IGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpO1xufVxuXG5mdW5jdGlvbiB0aHJvd1dhcm5pbmcoc3RhdGUsIG1lc3NhZ2UpIHtcbiAgaWYgKHN0YXRlLm9uV2FybmluZykge1xuICAgIHN0YXRlLm9uV2FybmluZy5jYWxsKG51bGwsIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpKTtcbiAgfVxufVxuXG5cbnZhciBkaXJlY3RpdmVIYW5kbGVycyA9IHtcblxuICBZQU1MOiBmdW5jdGlvbiBoYW5kbGVZYW1sRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgbWF0Y2gsIG1ham9yLCBtaW5vcjtcblxuICAgIGlmIChzdGF0ZS52ZXJzaW9uICE9PSBudWxsKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgJVlBTUwgZGlyZWN0aXZlJyk7XG4gICAgfVxuXG4gICAgaWYgKGFyZ3MubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnWUFNTCBkaXJlY3RpdmUgYWNjZXB0cyBleGFjdGx5IG9uZSBhcmd1bWVudCcpO1xuICAgIH1cblxuICAgIG1hdGNoID0gL14oWzAtOV0rKVxcLihbMC05XSspJC8uZXhlYyhhcmdzWzBdKTtcblxuICAgIGlmIChtYXRjaCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgYXJndW1lbnQgb2YgdGhlIFlBTUwgZGlyZWN0aXZlJyk7XG4gICAgfVxuXG4gICAgbWFqb3IgPSBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgIG1pbm9yID0gcGFyc2VJbnQobWF0Y2hbMl0sIDEwKTtcblxuICAgIGlmIChtYWpvciAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuXG4gICAgc3RhdGUudmVyc2lvbiA9IGFyZ3NbMF07XG4gICAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gKG1pbm9yIDwgMik7XG5cbiAgICBpZiAobWlub3IgIT09IDEgJiYgbWlub3IgIT09IDIpIHtcbiAgICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ3Vuc3VwcG9ydGVkIFlBTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQnKTtcbiAgICB9XG4gIH0sXG5cbiAgVEFHOiBmdW5jdGlvbiBoYW5kbGVUYWdEaXJlY3RpdmUoc3RhdGUsIG5hbWUsIGFyZ3MpIHtcblxuICAgIHZhciBoYW5kbGUsIHByZWZpeDtcblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1RBRyBkaXJlY3RpdmUgYWNjZXB0cyBleGFjdGx5IHR3byBhcmd1bWVudHMnKTtcbiAgICB9XG5cbiAgICBoYW5kbGUgPSBhcmdzWzBdO1xuICAgIHByZWZpeCA9IGFyZ3NbMV07XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX0hBTkRMRS50ZXN0KGhhbmRsZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBoYW5kbGUgKGZpcnN0IGFyZ3VtZW50KSBvZiB0aGUgVEFHIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIGhhbmRsZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0aGVyZSBpcyBhIHByZXZpb3VzbHkgZGVjbGFyZWQgc3VmZml4IGZvciBcIicgKyBoYW5kbGUgKyAnXCIgdGFnIGhhbmRsZScpO1xuICAgIH1cblxuICAgIGlmICghUEFUVEVSTl9UQUdfVVJJLnRlc3QocHJlZml4KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgdGFnIHByZWZpeCAoc2Vjb25kIGFyZ3VtZW50KSBvZiB0aGUgVEFHIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIHN0YXRlLnRhZ01hcFtoYW5kbGVdID0gcHJlZml4O1xuICB9XG59O1xuXG5cbmZ1bmN0aW9uIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBzdGFydCwgZW5kLCBjaGVja0pzb24pIHtcbiAgdmFyIF9wb3NpdGlvbiwgX2xlbmd0aCwgX2NoYXJhY3RlciwgX3Jlc3VsdDtcblxuICBpZiAoc3RhcnQgPCBlbmQpIHtcbiAgICBfcmVzdWx0ID0gc3RhdGUuaW5wdXQuc2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBpZiAoY2hlY2tKc29uKSB7XG4gICAgICBmb3IgKF9wb3NpdGlvbiA9IDAsIF9sZW5ndGggPSBfcmVzdWx0Lmxlbmd0aDtcbiAgICAgICAgICAgX3Bvc2l0aW9uIDwgX2xlbmd0aDtcbiAgICAgICAgICAgX3Bvc2l0aW9uICs9IDEpIHtcbiAgICAgICAgX2NoYXJhY3RlciA9IF9yZXN1bHQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuICAgICAgICBpZiAoIShfY2hhcmFjdGVyID09PSAweDA5IHx8XG4gICAgICAgICAgICAgICgweDIwIDw9IF9jaGFyYWN0ZXIgJiYgX2NoYXJhY3RlciA8PSAweDEwRkZGRikpKSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2V4cGVjdGVkIHZhbGlkIEpTT04gY2hhcmFjdGVyJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFBBVFRFUk5fTk9OX1BSSU5UQUJMRS50ZXN0KF9yZXN1bHQpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlIHN0cmVhbSBjb250YWlucyBub24tcHJpbnRhYmxlIGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS5yZXN1bHQgKz0gX3Jlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZU1hcHBpbmdzKHN0YXRlLCBkZXN0aW5hdGlvbiwgc291cmNlLCBvdmVycmlkYWJsZUtleXMpIHtcbiAgdmFyIHNvdXJjZUtleXMsIGtleSwgaW5kZXgsIHF1YW50aXR5O1xuXG4gIGlmICghY29tbW9uLmlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2Fubm90IG1lcmdlIG1hcHBpbmdzOyB0aGUgcHJvdmlkZWQgc291cmNlIG9iamVjdCBpcyB1bmFjY2VwdGFibGUnKTtcbiAgfVxuXG4gIHNvdXJjZUtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHNvdXJjZUtleXMubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAga2V5ID0gc291cmNlS2V5c1tpbmRleF07XG5cbiAgICBpZiAoIV9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRlc3RpbmF0aW9uLCBrZXkpKSB7XG4gICAgICBkZXN0aW5hdGlvbltrZXldID0gc291cmNlW2tleV07XG4gICAgICBvdmVycmlkYWJsZUtleXNba2V5XSA9IHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpIHtcbiAgdmFyIGluZGV4LCBxdWFudGl0eTtcblxuICBrZXlOb2RlID0gU3RyaW5nKGtleU5vZGUpO1xuXG4gIGlmIChfcmVzdWx0ID09PSBudWxsKSB7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9XG5cbiAgaWYgKGtleVRhZyA9PT0gJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlTm9kZSkpIHtcbiAgICAgIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHZhbHVlTm9kZS5sZW5ndGg7IGluZGV4IDwgcXVhbnRpdHk7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgX3Jlc3VsdCwgdmFsdWVOb2RlW2luZGV4XSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgX3Jlc3VsdCwgdmFsdWVOb2RlLCBvdmVycmlkYWJsZUtleXMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoIXN0YXRlLmpzb24gJiZcbiAgICAgICAgIV9oYXNPd25Qcm9wZXJ0eS5jYWxsKG92ZXJyaWRhYmxlS2V5cywga2V5Tm9kZSkgJiZcbiAgICAgICAgX2hhc093blByb3BlcnR5LmNhbGwoX3Jlc3VsdCwga2V5Tm9kZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGVkIG1hcHBpbmcga2V5Jyk7XG4gICAgfVxuICAgIF9yZXN1bHRba2V5Tm9kZV0gPSB2YWx1ZU5vZGU7XG4gICAgZGVsZXRlIG92ZXJyaWRhYmxlS2V5c1trZXlOb2RlXTtcbiAgfVxuXG4gIHJldHVybiBfcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZWFkTGluZUJyZWFrKHN0YXRlKSB7XG4gIHZhciBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgwQS8qIExGICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgwRC8qIENSICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgICBpZiAoc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgPT09IDB4MEEvKiBMRiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2EgbGluZSBicmVhayBpcyBleHBlY3RlZCcpO1xuICB9XG5cbiAgc3RhdGUubGluZSArPSAxO1xuICBzdGF0ZS5saW5lU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcbn1cblxuZnVuY3Rpb24gc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgYWxsb3dDb21tZW50cywgY2hlY2tJbmRlbnQpIHtcbiAgdmFyIGxpbmVCcmVha3MgPSAwLFxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93Q29tbWVudHMgJiYgY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBkbyB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH0gd2hpbGUgKGNoICE9PSAweDBBLyogTEYgKi8gJiYgY2ggIT09IDB4MEQvKiBDUiAqLyAmJiBjaCAhPT0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgbGluZUJyZWFrcysrO1xuICAgICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICAgIHdoaWxlIChjaCA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKztcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoY2hlY2tJbmRlbnQgIT09IC0xICYmIGxpbmVCcmVha3MgIT09IDAgJiYgc3RhdGUubGluZUluZGVudCA8IGNoZWNrSW5kZW50KSB7XG4gICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAnZGVmaWNpZW50IGluZGVudGF0aW9uJyk7XG4gIH1cblxuICByZXR1cm4gbGluZUJyZWFrcztcbn1cblxuZnVuY3Rpb24gdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gIC8vIENvbmRpdGlvbiBzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0IGlzIHRlc3RlZFxuICAvLyBpbiBwYXJlbnQgb24gZWFjaCBjYWxsLCBmb3IgZWZmaWNpZW5jeS4gTm8gbmVlZHMgdG8gdGVzdCBoZXJlIGFnYWluLlxuICBpZiAoKGNoID09PSAweDJELyogLSAqLyB8fCBjaCA9PT0gMHgyRS8qIC4gKi8pICYmXG4gICAgICBjaCA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24gKyAxKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMikpIHtcblxuICAgIF9wb3NpdGlvbiArPSAzO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDAgfHwgaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBjb3VudCkge1xuICBpZiAoY291bnQgPT09IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gJyAnO1xuICB9IGVsc2UgaWYgKGNvdW50ID4gMSkge1xuICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBjb3VudCAtIDEpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gcmVhZFBsYWluU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50LCB3aXRoaW5GbG93Q29sbGVjdGlvbikge1xuICB2YXIgcHJlY2VkaW5nLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgY2FwdHVyZVN0YXJ0LFxuICAgICAgY2FwdHVyZUVuZCxcbiAgICAgIGhhc1BlbmRpbmdDb250ZW50LFxuICAgICAgX2xpbmUsXG4gICAgICBfbGluZVN0YXJ0LFxuICAgICAgX2xpbmVJbmRlbnQsXG4gICAgICBfa2luZCA9IHN0YXRlLmtpbmQsXG4gICAgICBfcmVzdWx0ID0gc3RhdGUucmVzdWx0LFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoaXNfV1NfT1JfRU9MKGNoKSAgICAgIHx8XG4gICAgICBpc19GTE9XX0lORElDQVRPUihjaCkgfHxcbiAgICAgIGNoID09PSAweDIzLyogIyAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjYvKiAmICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyQS8qICogKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIxLyogISAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4N0MvKiB8ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgzRS8qID4gKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI3LyogJyAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjIvKiBcIiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjUvKiAlICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg0MC8qIEAgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDYwLyogYCAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4MkQvKiAtICovKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGZvbGxvd2luZykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7XG4gIHN0YXRlLnJlc3VsdCA9ICcnO1xuICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICBpZiAoaXNfV1NfT1JfRU9MKGZvbGxvd2luZykgfHxcbiAgICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgIHByZWNlZGluZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gLSAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChwcmVjZWRpbmcpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB8fFxuICAgICAgICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgICBicmVhaztcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgICAgX2xpbmVTdGFydCA9IHN0YXRlLmxpbmVTdGFydDtcbiAgICAgIF9saW5lSW5kZW50ID0gc3RhdGUubGluZUluZGVudDtcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCAtMSk7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID49IG5vZGVJbmRlbnQpIHtcbiAgICAgICAgaGFzUGVuZGluZ0NvbnRlbnQgPSB0cnVlO1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uID0gY2FwdHVyZUVuZDtcbiAgICAgICAgc3RhdGUubGluZSA9IF9saW5lO1xuICAgICAgICBzdGF0ZS5saW5lU3RhcnQgPSBfbGluZVN0YXJ0O1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50ID0gX2xpbmVJbmRlbnQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChoYXNQZW5kaW5nQ29udGVudCkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgZmFsc2UpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc3RhdGUubGluZSAtIF9saW5lKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCFpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbiArIDE7XG4gICAgfVxuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgZmFsc2UpO1xuXG4gIGlmIChzdGF0ZS5yZXN1bHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSBfa2luZDtcbiAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiByZWFkU2luZ2xlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjaCxcbiAgICAgIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyNy8qICcgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7XG4gIHN0YXRlLnJlc3VsdCA9ICcnO1xuICBzdGF0ZS5wb3NpdGlvbisrO1xuICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgaWYgKGNoID09PSAweDI3LyogJyAqLykge1xuICAgICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgc2luZ2xlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWREb3VibGVRdW90ZWRTY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoZXhMZW5ndGgsXG4gICAgICBoZXhSZXN1bHQsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyMi8qIFwiICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjIvKiBcIiAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgfSBlbHNlIGlmIChjaCA9PT0gMHg1Qy8qIFxcICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KTtcblxuICAgICAgICAvLyBUT0RPOiByZXdvcmsgdG8gaW5saW5lIGZuIHdpdGggbm8gdHlwZSBjYXN0P1xuICAgICAgfSBlbHNlIGlmIChjaCA8IDI1NiAmJiBzaW1wbGVFc2NhcGVDaGVja1tjaF0pIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IHNpbXBsZUVzY2FwZU1hcFtjaF07XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICAgIH0gZWxzZSBpZiAoKHRtcCA9IGVzY2FwZWRIZXhMZW4oY2gpKSA+IDApIHtcbiAgICAgICAgaGV4TGVuZ3RoID0gdG1wO1xuICAgICAgICBoZXhSZXN1bHQgPSAwO1xuXG4gICAgICAgIGZvciAoOyBoZXhMZW5ndGggPiAwOyBoZXhMZW5ndGgtLSkge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICgodG1wID0gZnJvbUhleENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICAgICAgICBoZXhSZXN1bHQgPSAoaGV4UmVzdWx0IDw8IDQpICsgdG1wO1xuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCBoZXhhZGVjaW1hbCBjaGFyYWN0ZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY2hhckZyb21Db2RlcG9pbnQoaGV4UmVzdWx0KTtcblxuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biBlc2NhcGUgc2VxdWVuY2UnKTtcbiAgICAgIH1cblxuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBjYXB0dXJlRW5kLCB0cnVlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB9IGVsc2UgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBkb2N1bWVudCB3aXRoaW4gYSBkb3VibGUgcXVvdGVkIHNjYWxhcicpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgfVxuICB9XG5cbiAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBzdHJlYW0gd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcbn1cblxuZnVuY3Rpb24gcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciByZWFkTmV4dCA9IHRydWUsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgID0gc3RhdGUudGFnLFxuICAgICAgX3Jlc3VsdCxcbiAgICAgIF9hbmNob3IgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgdGVybWluYXRvcixcbiAgICAgIGlzUGFpcixcbiAgICAgIGlzRXhwbGljaXRQYWlyLFxuICAgICAgaXNNYXBwaW5nLFxuICAgICAgb3ZlcnJpZGFibGVLZXlzID0ge30sXG4gICAgICBrZXlOb2RlLFxuICAgICAga2V5VGFnLFxuICAgICAgdmFsdWVOb2RlLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4NUIvKiBbICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4NUQ7LyogXSAqL1xuICAgIGlzTWFwcGluZyA9IGZhbHNlO1xuICAgIF9yZXN1bHQgPSBbXTtcbiAgfSBlbHNlIGlmIChjaCA9PT0gMHg3Qi8qIHsgKi8pIHtcbiAgICB0ZXJtaW5hdG9yID0gMHg3RDsvKiB9ICovXG4gICAgaXNNYXBwaW5nID0gdHJ1ZTtcbiAgICBfcmVzdWx0ID0ge307XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IHRlcm1pbmF0b3IpIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICBzdGF0ZS50YWcgPSBfdGFnO1xuICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgIHN0YXRlLmtpbmQgPSBpc01hcHBpbmcgPyAnbWFwcGluZycgOiAnc2VxdWVuY2UnO1xuICAgICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoIXJlYWROZXh0KSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbWlzc2VkIGNvbW1hIGJldHdlZW4gZmxvdyBjb2xsZWN0aW9uIGVudHJpZXMnKTtcbiAgICB9XG5cbiAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICBpc1BhaXIgPSBpc0V4cGxpY2l0UGFpciA9IGZhbHNlO1xuXG4gICAgaWYgKGNoID09PSAweDNGLyogPyAqLykge1xuICAgICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICBpZiAoaXNfV1NfT1JfRU9MKGZvbGxvd2luZykpIHtcbiAgICAgICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSB0cnVlO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfbGluZSA9IHN0YXRlLmxpbmU7XG4gICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfRkxPV19JTiwgZmFsc2UsIHRydWUpO1xuICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoaXNFeHBsaWNpdFBhaXIgfHwgc3RhdGUubGluZSA9PT0gX2xpbmUpICYmIGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgaXNQYWlyID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuICAgICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfRkxPV19JTiwgZmFsc2UsIHRydWUpO1xuICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgIH1cblxuICAgIGlmIChpc01hcHBpbmcpIHtcbiAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpO1xuICAgIH0gZWxzZSBpZiAoaXNQYWlyKSB7XG4gICAgICBfcmVzdWx0LnB1c2goc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgbnVsbCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfcmVzdWx0LnB1c2goa2V5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAweDJDLyogLCAqLykge1xuICAgICAgcmVhZE5leHQgPSB0cnVlO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWFkTmV4dCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGZsb3cgY29sbGVjdGlvbicpO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIGNhcHR1cmVTdGFydCxcbiAgICAgIGZvbGRpbmcsXG4gICAgICBjaG9tcGluZyAgICAgICA9IENIT01QSU5HX0NMSVAsXG4gICAgICBkaWRSZWFkQ29udGVudCA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWRJbmRlbnQgPSBmYWxzZSxcbiAgICAgIHRleHRJbmRlbnQgICAgID0gbm9kZUluZGVudCxcbiAgICAgIGVtcHR5TGluZXMgICAgID0gMCxcbiAgICAgIGF0TW9yZUluZGVudGVkID0gZmFsc2UsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHg3Qy8qIHwgKi8pIHtcbiAgICBmb2xkaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4M0UvKiA+ICovKSB7XG4gICAgZm9sZGluZyA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDB4MkIvKiArICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgICAgaWYgKENIT01QSU5HX0NMSVAgPT09IGNob21waW5nKSB7XG4gICAgICAgIGNob21waW5nID0gKGNoID09PSAweDJCLyogKyAqLykgPyBDSE9NUElOR19LRUVQIDogQ0hPTVBJTkdfU1RSSVA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGEgY2hvbXBpbmcgbW9kZSBpZGVudGlmaWVyJyk7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKCh0bXAgPSBmcm9tRGVjaW1hbENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICBpZiAodG1wID09PSAwKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgZXhwbGljaXQgaW5kZW50YXRpb24gd2lkdGggb2YgYSBibG9jayBzY2FsYXI7IGl0IGNhbm5vdCBiZSBsZXNzIHRoYW4gb25lJyk7XG4gICAgICB9IGVsc2UgaWYgKCFkZXRlY3RlZEluZGVudCkge1xuICAgICAgICB0ZXh0SW5kZW50ID0gbm9kZUluZGVudCArIHRtcCAtIDE7XG4gICAgICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYW4gaW5kZW50YXRpb24gd2lkdGggaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpO1xuXG4gICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKTtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcbiAgICBzdGF0ZS5saW5lSW5kZW50ID0gMDtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICB3aGlsZSAoKCFkZXRlY3RlZEluZGVudCB8fCBzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkgJiZcbiAgICAgICAgICAgKGNoID09PSAweDIwLyogU3BhY2UgKi8pKSB7XG4gICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKCFkZXRlY3RlZEluZGVudCAmJiBzdGF0ZS5saW5lSW5kZW50ID4gdGV4dEluZGVudCkge1xuICAgICAgdGV4dEluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGVtcHR5TGluZXMrKztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIEVuZCBvZiB0aGUgc2NhbGFyLlxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkge1xuXG4gICAgICAvLyBQZXJmb3JtIHRoZSBjaG9tcGluZy5cbiAgICAgIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfS0VFUCkge1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuICAgICAgfSBlbHNlIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfQ0xJUCkge1xuICAgICAgICBpZiAoZGlkUmVhZENvbnRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHRoZSBzY2FsYXIgaXMgbm90IGVtcHR5LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnXFxuJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBCcmVhayB0aGlzIGB3aGlsZWAgY3ljbGUgYW5kIGdvIHRvIHRoZSBmdW5jaXRvbidzIGVwaWxvZ3VlLlxuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gRm9sZGVkIHN0eWxlOiB1c2UgZmFuY3kgcnVsZXMgdG8gaGFuZGxlIGxpbmUgYnJlYWtzLlxuICAgIGlmIChmb2xkaW5nKSB7XG5cbiAgICAgIC8vIExpbmVzIHN0YXJ0aW5nIHdpdGggd2hpdGUgc3BhY2UgY2hhcmFjdGVycyAobW9yZS1pbmRlbnRlZCBsaW5lcykgYXJlIG5vdCBmb2xkZWQuXG4gICAgICBpZiAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgIGF0TW9yZUluZGVudGVkID0gdHJ1ZTtcbiAgICAgICAgLy8gZXhjZXB0IGZvciB0aGUgZmlyc3QgY29udGVudCBsaW5lIChjZi4gRXhhbXBsZSA4LjEpXG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7XG5cbiAgICAgIC8vIEVuZCBvZiBtb3JlLWluZGVudGVkIGJsb2NrLlxuICAgICAgfSBlbHNlIGlmIChhdE1vcmVJbmRlbnRlZCkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlO1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuXG4gICAgICAvLyBKdXN0IG9uZSBsaW5lIGJyZWFrIC0gcGVyY2VpdmUgYXMgdGhlIHNhbWUgbGluZS5cbiAgICAgIH0gZWxzZSBpZiAoZW1wdHlMaW5lcyA9PT0gMCkge1xuICAgICAgICBpZiAoZGlkUmVhZENvbnRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHdlIGhhdmUgYWxyZWFkeSByZWFkIHNvbWUgc2NhbGFyIGNvbnRlbnQuXG4gICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgICAgICAgfVxuXG4gICAgICAvLyBTZXZlcmFsIGxpbmUgYnJlYWtzIC0gcGVyY2VpdmUgYXMgZGlmZmVyZW50IGxpbmVzLlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMpO1xuICAgICAgfVxuXG4gICAgLy8gTGl0ZXJhbCBzdHlsZToganVzdCBhZGQgZXhhY3QgbnVtYmVyIG9mIGxpbmUgYnJlYWtzIGJldHdlZW4gY29udGVudCBsaW5lcy5cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gS2VlcCBhbGwgbGluZSBicmVha3MgZXhjZXB0IHRoZSBoZWFkZXIgbGluZSBicmVhay5cbiAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7XG4gICAgfVxuXG4gICAgZGlkUmVhZENvbnRlbnQgPSB0cnVlO1xuICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICBlbXB0eUxpbmVzID0gMDtcbiAgICBjYXB0dXJlU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgX2xpbmUsXG4gICAgICBfdGFnICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgPSBzdGF0ZS5hbmNob3IsXG4gICAgICBfcmVzdWx0ICAgPSBbXSxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGRldGVjdGVkICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG5cbiAgICBpZiAoY2ggIT09IDB4MkQvKiAtICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7XG5cbiAgICBpZiAoIWlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDw9IG5vZGVJbmRlbnQpIHtcbiAgICAgICAgX3Jlc3VsdC5wdXNoKG51bGwpO1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfbGluZSA9IHN0YXRlLmxpbmU7XG4gICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfQkxPQ0tfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBfcmVzdWx0LnB1c2goc3RhdGUucmVzdWx0KTtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKChzdGF0ZS5saW5lID09PSBfbGluZSB8fCBzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBpbmRlbnRhdGlvbiBvZiBhIHNlcXVlbmNlIGVudHJ5Jyk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnc2VxdWVuY2UnO1xuICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBub2RlSW5kZW50LCBmbG93SW5kZW50KSB7XG4gIHZhciBmb2xsb3dpbmcsXG4gICAgICBhbGxvd0NvbXBhY3QsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgICAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgICAgICA9IHt9LFxuICAgICAgb3ZlcnJpZGFibGVLZXlzID0ge30sXG4gICAgICBrZXlUYWcgICAgICAgID0gbnVsbCxcbiAgICAgIGtleU5vZGUgICAgICAgPSBudWxsLFxuICAgICAgdmFsdWVOb2RlICAgICA9IG51bGwsXG4gICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2UsXG4gICAgICBkZXRlY3RlZCAgICAgID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBfcmVzdWx0O1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7XG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lOyAvLyBTYXZlIHRoZSBjdXJyZW50IGxpbmUuXG5cbiAgICAvL1xuICAgIC8vIEV4cGxpY2l0IG5vdGF0aW9uIGNhc2UuIFRoZXJlIGFyZSB0d28gc2VwYXJhdGUgYmxvY2tzOlxuICAgIC8vIGZpcnN0IGZvciB0aGUga2V5IChkZW5vdGVkIGJ5IFwiP1wiKSBhbmQgc2Vjb25kIGZvciB0aGUgdmFsdWUgKGRlbm90ZWQgYnkgXCI6XCIpXG4gICAgLy9cbiAgICBpZiAoKGNoID09PSAweDNGLyogPyAqLyB8fCBjaCA9PT0gMHgzQS8qIDogKi8pICYmIGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSB0cnVlO1xuICAgICAgICBhbGxvd0NvbXBhY3QgPSB0cnVlO1xuXG4gICAgICB9IGVsc2UgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgLy8gaS5lLiAweDNBLyogOiAqLyA9PT0gY2hhcmFjdGVyIGFmdGVyIHRoZSBleHBsaWNpdCBrZXkuXG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSBmYWxzZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2luY29tcGxldGUgZXhwbGljaXQgbWFwcGluZyBwYWlyOyBhIGtleSBub2RlIGlzIG1pc3NlZCcpO1xuICAgICAgfVxuXG4gICAgICBzdGF0ZS5wb3NpdGlvbiArPSAxO1xuICAgICAgY2ggPSBmb2xsb3dpbmc7XG5cbiAgICAvL1xuICAgIC8vIEltcGxpY2l0IG5vdGF0aW9uIGNhc2UuIEZsb3ctc3R5bGUgbm9kZSBhcyB0aGUga2V5IGZpcnN0LCB0aGVuIFwiOlwiLCBhbmQgdGhlIHZhbHVlLlxuICAgIC8vXG4gICAgfSBlbHNlIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX09VVCwgZmFsc2UsIHRydWUpKSB7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lID09PSBfbGluZSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2ggPT09IDB4M0EvKiA6ICovKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgICAgaWYgKCFpc19XU19PUl9FT0woY2gpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYSB3aGl0ZXNwYWNlIGNoYXJhY3RlciBpcyBleHBlY3RlZCBhZnRlciB0aGUga2V5LXZhbHVlIHNlcGFyYXRvciB3aXRoaW4gYSBibG9jayBtYXBwaW5nJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCBudWxsKTtcbiAgICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRldGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgICAgYWxsb3dDb21wYWN0ID0gZmFsc2U7XG4gICAgICAgICAga2V5VGFnID0gc3RhdGUudGFnO1xuICAgICAgICAgIGtleU5vZGUgPSBzdGF0ZS5yZXN1bHQ7XG5cbiAgICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW4gbm90IHJlYWQgYW4gaW1wbGljaXQgbWFwcGluZyBwYWlyOyBhIGNvbG9uIGlzIG1pc3NlZCcpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgICAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2UgaWYgKGRldGVjdGVkKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW4gbm90IHJlYWQgYSBibG9jayBtYXBwaW5nIGVudHJ5OyBhIG11bHRpbGluZSBrZXkgbWF5IG5vdCBiZSBhbiBpbXBsaWNpdCBrZXknKTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgcmV0dXJuIHRydWU7IC8vIEtlZXAgdGhlIHJlc3VsdCBvZiBgY29tcG9zZU5vZGVgLlxuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrOyAvLyBSZWFkaW5nIGlzIGRvbmUuIEdvIHRvIHRoZSBlcGlsb2d1ZS5cbiAgICB9XG5cbiAgICAvL1xuICAgIC8vIENvbW1vbiByZWFkaW5nIGNvZGUgZm9yIGJvdGggZXhwbGljaXQgYW5kIGltcGxpY2l0IG5vdGF0aW9ucy5cbiAgICAvL1xuICAgIGlmIChzdGF0ZS5saW5lID09PSBfbGluZSB8fCBzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCkge1xuICAgICAgaWYgKGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX09VVCwgdHJ1ZSwgYWxsb3dDb21wYWN0KSkge1xuICAgICAgICBpZiAoYXRFeHBsaWNpdEtleSkge1xuICAgICAgICAgIGtleU5vZGUgPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghYXRFeHBsaWNpdEtleSkge1xuICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICAgICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBub2RlSW5kZW50ICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBtYXBwaW5nIGVudHJ5Jyk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLy9cbiAgLy8gRXBpbG9ndWUuXG4gIC8vXG5cbiAgLy8gU3BlY2lhbCBjYXNlOiBsYXN0IG1hcHBpbmcncyBub2RlIGNvbnRhaW5zIG9ubHkgdGhlIGtleSBpbiBleHBsaWNpdCBub3RhdGlvbi5cbiAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gIH1cblxuICAvLyBFeHBvc2UgdGhlIHJlc3VsdGluZyBtYXBwaW5nLlxuICBpZiAoZGV0ZWN0ZWQpIHtcbiAgICBzdGF0ZS50YWcgPSBfdGFnO1xuICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgc3RhdGUua2luZCA9ICdtYXBwaW5nJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICB9XG5cbiAgcmV0dXJuIGRldGVjdGVkO1xufVxuXG5mdW5jdGlvbiByZWFkVGFnUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGlzVmVyYmF0aW0gPSBmYWxzZSxcbiAgICAgIGlzTmFtZWQgICAgPSBmYWxzZSxcbiAgICAgIHRhZ0hhbmRsZSxcbiAgICAgIHRhZ05hbWUsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyMS8qICEgKi8pIHJldHVybiBmYWxzZTtcblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mIGEgdGFnIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDNDLyogPCAqLykge1xuICAgIGlzVmVyYmF0aW0gPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2UgaWYgKGNoID09PSAweDIxLyogISAqLykge1xuICAgIGlzTmFtZWQgPSB0cnVlO1xuICAgIHRhZ0hhbmRsZSA9ICchISc7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIH0gZWxzZSB7XG4gICAgdGFnSGFuZGxlID0gJyEnO1xuICB9XG5cbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChjaCAhPT0gMCAmJiBjaCAhPT0gMHgzRS8qID4gKi8pO1xuXG4gICAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgc3RhdGUubGVuZ3RoKSB7XG4gICAgICB0YWdOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIHZlcmJhdGltIHRhZycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcblxuICAgICAgaWYgKGNoID09PSAweDIxLyogISAqLykge1xuICAgICAgICBpZiAoIWlzTmFtZWQpIHtcbiAgICAgICAgICB0YWdIYW5kbGUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24gLSAxLCBzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICAgICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdCh0YWdIYW5kbGUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZWQgdGFnIGhhbmRsZSBjYW5ub3QgY29udGFpbiBzdWNoIGNoYXJhY3RlcnMnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICAgICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbiArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBzdWZmaXggY2Fubm90IGNvbnRhaW4gZXhjbGFtYXRpb24gbWFya3MnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTLnRlc3QodGFnTmFtZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGZsb3cgaW5kaWNhdG9yIGNoYXJhY3RlcnMnKTtcbiAgICB9XG4gIH1cblxuICBpZiAodGFnTmFtZSAmJiAhUEFUVEVSTl9UQUdfVVJJLnRlc3QodGFnTmFtZSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIG5hbWUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzOiAnICsgdGFnTmFtZSk7XG4gIH1cblxuICBpZiAoaXNWZXJiYXRpbSkge1xuICAgIHN0YXRlLnRhZyA9IHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIHRhZ0hhbmRsZSkpIHtcbiAgICBzdGF0ZS50YWcgPSBzdGF0ZS50YWdNYXBbdGFnSGFuZGxlXSArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICh0YWdIYW5kbGUgPT09ICchJykge1xuICAgIHN0YXRlLnRhZyA9ICchJyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICh0YWdIYW5kbGUgPT09ICchIScpIHtcbiAgICBzdGF0ZS50YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5kZWNsYXJlZCB0YWcgaGFuZGxlIFwiJyArIHRhZ0hhbmRsZSArICdcIicpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjYvKiAmICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhbiBhbmNob3IgcHJvcGVydHknKTtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpICYmICFpc19GTE9XX0lORElDQVRPUihjaCkpIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFuY2hvciBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBzdGF0ZS5hbmNob3IgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbGlhcyhzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLCBhbGlhcyxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDJBLyogKiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpICYmICFpc19GTE9XX0lORElDQVRPUihjaCkpIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFsaWFzIG5vZGUgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXInKTtcbiAgfVxuXG4gIGFsaWFzID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKCFzdGF0ZS5hbmNob3JNYXAuaGFzT3duUHJvcGVydHkoYWxpYXMpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuaWRlbnRpZmllZCBhbGlhcyBcIicgKyBhbGlhcyArICdcIicpO1xuICB9XG5cbiAgc3RhdGUucmVzdWx0ID0gc3RhdGUuYW5jaG9yTWFwW2FsaWFzXTtcbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29tcG9zZU5vZGUoc3RhdGUsIHBhcmVudEluZGVudCwgbm9kZUNvbnRleHQsIGFsbG93VG9TZWVrLCBhbGxvd0NvbXBhY3QpIHtcbiAgdmFyIGFsbG93QmxvY2tTdHlsZXMsXG4gICAgICBhbGxvd0Jsb2NrU2NhbGFycyxcbiAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyxcbiAgICAgIGluZGVudFN0YXR1cyA9IDEsIC8vIDE6IHRoaXM+cGFyZW50LCAwOiB0aGlzPXBhcmVudCwgLTE6IHRoaXM8cGFyZW50XG4gICAgICBhdE5ld0xpbmUgID0gZmFsc2UsXG4gICAgICBoYXNDb250ZW50ID0gZmFsc2UsXG4gICAgICB0eXBlSW5kZXgsXG4gICAgICB0eXBlUXVhbnRpdHksXG4gICAgICB0eXBlLFxuICAgICAgZmxvd0luZGVudCxcbiAgICAgIGJsb2NrSW5kZW50O1xuXG4gIGlmIChzdGF0ZS5saXN0ZW5lciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmxpc3RlbmVyKCdvcGVuJywgc3RhdGUpO1xuICB9XG5cbiAgc3RhdGUudGFnICAgID0gbnVsbDtcbiAgc3RhdGUuYW5jaG9yID0gbnVsbDtcbiAgc3RhdGUua2luZCAgID0gbnVsbDtcbiAgc3RhdGUucmVzdWx0ID0gbnVsbDtcblxuICBhbGxvd0Jsb2NrU3R5bGVzID0gYWxsb3dCbG9ja1NjYWxhcnMgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPVxuICAgIENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCB8fFxuICAgIENPTlRFWFRfQkxPQ0tfSU4gID09PSBub2RlQ29udGV4dDtcblxuICBpZiAoYWxsb3dUb1NlZWspIHtcbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAxO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZW50U3RhdHVzID09PSAxKSB7XG4gICAgd2hpbGUgKHJlYWRUYWdQcm9wZXJ0eShzdGF0ZSkgfHwgcmVhZEFuY2hvclByb3BlcnR5KHN0YXRlKSkge1xuICAgICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuICAgICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhbGxvd0Jsb2NrU3R5bGVzO1xuXG4gICAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucykge1xuICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGF0TmV3TGluZSB8fCBhbGxvd0NvbXBhY3Q7XG4gIH1cblxuICBpZiAoaW5kZW50U3RhdHVzID09PSAxIHx8IENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgIGlmIChDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0IHx8IENPTlRFWFRfRkxPV19PVVQgPT09IG5vZGVDb250ZXh0KSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50ICsgMTtcbiAgICB9XG5cbiAgICBibG9ja0luZGVudCA9IHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0O1xuXG4gICAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgICAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJlxuICAgICAgICAgIChyZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpIHx8XG4gICAgICAgICAgIHJlYWRCbG9ja01hcHBpbmcoc3RhdGUsIGJsb2NrSW5kZW50LCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICByZWFkRmxvd0NvbGxlY3Rpb24oc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKChhbGxvd0Jsb2NrU2NhbGFycyAmJiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB8fFxuICAgICAgICAgICAgcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCkgfHxcbiAgICAgICAgICAgIHJlYWREb3VibGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWFkQWxpYXMoc3RhdGUpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsIHx8IHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2FsaWFzIG5vZGUgc2hvdWxkIG5vdCBoYXZlIGFueSBwcm9wZXJ0aWVzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZFBsYWluU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50LCBDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhdGUudGFnID0gJz8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaW5kZW50U3RhdHVzID09PSAwKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2U6IGJsb2NrIHNlcXVlbmNlcyBhcmUgYWxsb3dlZCB0byBoYXZlIHNhbWUgaW5kZW50YXRpb24gbGV2ZWwgYXMgdGhlIHBhcmVudC5cbiAgICAgIC8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjc5OTc4NFxuICAgICAgaGFzQ29udGVudCA9IGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnIScpIHtcbiAgICBpZiAoc3RhdGUudGFnID09PSAnPycpIHtcbiAgICAgIGZvciAodHlwZUluZGV4ID0gMCwgdHlwZVF1YW50aXR5ID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7XG4gICAgICAgICAgIHR5cGVJbmRleCA8IHR5cGVRdWFudGl0eTtcbiAgICAgICAgICAgdHlwZUluZGV4ICs9IDEpIHtcbiAgICAgICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbdHlwZUluZGV4XTtcblxuICAgICAgICAvLyBJbXBsaWNpdCByZXNvbHZpbmcgaXMgbm90IGFsbG93ZWQgZm9yIG5vbi1zY2FsYXIgdHlwZXMsIGFuZCAnPydcbiAgICAgICAgLy8gbm9uLXNwZWNpZmljIHRhZyBpcyBvbmx5IGFzc2lnbmVkIHRvIHBsYWluIHNjYWxhcnMuIFNvLCBpdCBpc24ndFxuICAgICAgICAvLyBuZWVkZWQgdG8gY2hlY2sgZm9yICdraW5kJyBjb25mb3JtaXR5LlxuXG4gICAgICAgIGlmICh0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgPSB0eXBlLmNvbnN0cnVjdChzdGF0ZS5yZXN1bHQpO1xuICAgICAgICAgIHN0YXRlLnRhZyA9IHR5cGUudGFnO1xuICAgICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudHlwZU1hcCwgc3RhdGUudGFnKSkge1xuICAgICAgdHlwZSA9IHN0YXRlLnR5cGVNYXBbc3RhdGUudGFnXTtcblxuICAgICAgaWYgKHN0YXRlLnJlc3VsdCAhPT0gbnVsbCAmJiB0eXBlLmtpbmQgIT09IHN0YXRlLmtpbmQpIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBub2RlIGtpbmQgZm9yICE8JyArIHN0YXRlLnRhZyArICc+IHRhZzsgaXQgc2hvdWxkIGJlIFwiJyArIHR5cGUua2luZCArICdcIiwgbm90IFwiJyArIHN0YXRlLmtpbmQgKyAnXCInKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCByZXNvbHZlIGEgbm9kZSB3aXRoICE8JyArIHN0YXRlLnRhZyArICc+IGV4cGxpY2l0IHRhZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmtub3duIHRhZyAhPCcgKyBzdGF0ZS50YWcgKyAnPicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdGF0ZS5saXN0ZW5lciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmxpc3RlbmVyKCdjbG9zZScsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gc3RhdGUudGFnICE9PSBudWxsIHx8ICBzdGF0ZS5hbmNob3IgIT09IG51bGwgfHwgaGFzQ29udGVudDtcbn1cblxuZnVuY3Rpb24gcmVhZERvY3VtZW50KHN0YXRlKSB7XG4gIHZhciBkb2N1bWVudFN0YXJ0ID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBfcG9zaXRpb24sXG4gICAgICBkaXJlY3RpdmVOYW1lLFxuICAgICAgZGlyZWN0aXZlQXJncyxcbiAgICAgIGhhc0RpcmVjdGl2ZXMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIHN0YXRlLnZlcnNpb24gPSBudWxsO1xuICBzdGF0ZS5jaGVja0xpbmVCcmVha3MgPSBzdGF0ZS5sZWdhY3k7XG4gIHN0YXRlLnRhZ01hcCA9IHt9O1xuICBzdGF0ZS5hbmNob3JNYXAgPSB7fTtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gMCB8fCBjaCAhPT0gMHgyNS8qICUgKi8pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGhhc0RpcmVjdGl2ZXMgPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGRpcmVjdGl2ZU5hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgICBkaXJlY3RpdmVBcmdzID0gW107XG5cbiAgICBpZiAoZGlyZWN0aXZlTmFtZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlIG5hbWUgbXVzdCBub3QgYmUgbGVzcyB0aGFuIG9uZSBjaGFyYWN0ZXIgaW4gbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgICAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX0VPTChjaCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzX0VPTChjaCkpIGJyZWFrO1xuXG4gICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgZGlyZWN0aXZlQXJncy5wdXNoKHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pKTtcbiAgICB9XG5cbiAgICBpZiAoY2ggIT09IDApIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuXG4gICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRpcmVjdGl2ZUhhbmRsZXJzLCBkaXJlY3RpdmVOYW1lKSkge1xuICAgICAgZGlyZWN0aXZlSGFuZGxlcnNbZGlyZWN0aXZlTmFtZV0oc3RhdGUsIGRpcmVjdGl2ZU5hbWUsIGRpcmVjdGl2ZUFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bmtub3duIGRvY3VtZW50IGRpcmVjdGl2ZSBcIicgKyBkaXJlY3RpdmVOYW1lICsgJ1wiJyk7XG4gICAgfVxuICB9XG5cbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSAwICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSAgICAgPT09IDB4MkQvKiAtICovICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSkgPT09IDB4MkQvKiAtICovICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMikgPT09IDB4MkQvKiAtICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgfSBlbHNlIGlmIChoYXNEaXJlY3RpdmVzKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZXMgZW5kIG1hcmsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIGNvbXBvc2VOb2RlKHN0YXRlLCBzdGF0ZS5saW5lSW5kZW50IC0gMSwgQ09OVEVYVF9CTE9DS19PVVQsIGZhbHNlLCB0cnVlKTtcbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIGlmIChzdGF0ZS5jaGVja0xpbmVCcmVha3MgJiZcbiAgICAgIFBBVFRFUk5fTk9OX0FTQ0lJX0xJTkVfQlJFQUtTLnRlc3Qoc3RhdGUuaW5wdXQuc2xpY2UoZG9jdW1lbnRTdGFydCwgc3RhdGUucG9zaXRpb24pKSkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ25vbi1BU0NJSSBsaW5lIGJyZWFrcyBhcmUgaW50ZXJwcmV0ZWQgYXMgY29udGVudCcpO1xuICB9XG5cbiAgc3RhdGUuZG9jdW1lbnRzLnB1c2goc3RhdGUucmVzdWx0KTtcblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG5cbiAgICBpZiAoc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgPT09IDB4MkUvKiAuICovKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbiArPSAzO1xuICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZW5kIG9mIHRoZSBzdHJlYW0gb3IgYSBkb2N1bWVudCBzZXBhcmF0b3IgaXMgZXhwZWN0ZWQnKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm47XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKSB7XG4gIGlucHV0ID0gU3RyaW5nKGlucHV0KTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgaWYgKGlucHV0Lmxlbmd0aCAhPT0gMCkge1xuXG4gICAgLy8gQWRkIHRhaWxpbmcgYFxcbmAgaWYgbm90IGV4aXN0c1xuICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KGlucHV0Lmxlbmd0aCAtIDEpICE9PSAweDBBLyogTEYgKi8gJiZcbiAgICAgICAgaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwRC8qIENSICovKSB7XG4gICAgICBpbnB1dCArPSAnXFxuJztcbiAgICB9XG5cbiAgICAvLyBTdHJpcCBCT01cbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdCgwKSA9PT0gMHhGRUZGKSB7XG4gICAgICBpbnB1dCA9IGlucHV0LnNsaWNlKDEpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdGF0ZSA9IG5ldyBTdGF0ZShpbnB1dCwgb3B0aW9ucyk7XG5cbiAgLy8gVXNlIDAgYXMgc3RyaW5nIHRlcm1pbmF0b3IuIFRoYXQgc2lnbmlmaWNhbnRseSBzaW1wbGlmaWVzIGJvdW5kcyBjaGVjay5cbiAgc3RhdGUuaW5wdXQgKz0gJ1xcMCc7XG5cbiAgd2hpbGUgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDIwLyogU3BhY2UgKi8pIHtcbiAgICBzdGF0ZS5saW5lSW5kZW50ICs9IDE7XG4gICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgfVxuXG4gIHdoaWxlIChzdGF0ZS5wb3NpdGlvbiA8IChzdGF0ZS5sZW5ndGggLSAxKSkge1xuICAgIHJlYWREb2N1bWVudChzdGF0ZSk7XG4gIH1cblxuICByZXR1cm4gc3RhdGUuZG9jdW1lbnRzO1xufVxuXG5cbmZ1bmN0aW9uIGxvYWRBbGwoaW5wdXQsIGl0ZXJhdG9yLCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKSwgaW5kZXgsIGxlbmd0aDtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZG9jdW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBpdGVyYXRvcihkb2N1bWVudHNbaW5kZXhdKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGxvYWQoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIGRvY3VtZW50cyA9IGxvYWREb2N1bWVudHMoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIGlmIChkb2N1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQqL1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gZWxzZSBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBkb2N1bWVudHNbMF07XG4gIH1cbiAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2V4cGVjdGVkIGEgc2luZ2xlIGRvY3VtZW50IGluIHRoZSBzdHJlYW0sIGJ1dCBmb3VuZCBtb3JlJyk7XG59XG5cblxuZnVuY3Rpb24gc2FmZUxvYWRBbGwoaW5wdXQsIG91dHB1dCwgb3B0aW9ucykge1xuICBsb2FkQWxsKGlucHV0LCBvdXRwdXQsIGNvbW1vbi5leHRlbmQoeyBzY2hlbWE6IERFRkFVTFRfU0FGRV9TQ0hFTUEgfSwgb3B0aW9ucykpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHJldHVybiBsb2FkKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5sb2FkQWxsICAgICA9IGxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5sb2FkICAgICAgICA9IGxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCA9IHNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWQgICAgPSBzYWZlTG9hZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuXG5mdW5jdGlvbiBNYXJrKG5hbWUsIGJ1ZmZlciwgcG9zaXRpb24sIGxpbmUsIGNvbHVtbikge1xuICB0aGlzLm5hbWUgICAgID0gbmFtZTtcbiAgdGhpcy5idWZmZXIgICA9IGJ1ZmZlcjtcbiAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICB0aGlzLmxpbmUgICAgID0gbGluZTtcbiAgdGhpcy5jb2x1bW4gICA9IGNvbHVtbjtcbn1cblxuXG5NYXJrLnByb3RvdHlwZS5nZXRTbmlwcGV0ID0gZnVuY3Rpb24gZ2V0U25pcHBldChpbmRlbnQsIG1heExlbmd0aCkge1xuICB2YXIgaGVhZCwgc3RhcnQsIHRhaWwsIGVuZCwgc25pcHBldDtcblxuICBpZiAoIXRoaXMuYnVmZmVyKSByZXR1cm4gbnVsbDtcblxuICBpbmRlbnQgPSBpbmRlbnQgfHwgNDtcbiAgbWF4TGVuZ3RoID0gbWF4TGVuZ3RoIHx8IDc1O1xuXG4gIGhlYWQgPSAnJztcbiAgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChzdGFydCA+IDAgJiYgJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoc3RhcnQgLSAxKSkgPT09IC0xKSB7XG4gICAgc3RhcnQgLT0gMTtcbiAgICBpZiAodGhpcy5wb3NpdGlvbiAtIHN0YXJ0ID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgaGVhZCA9ICcgLi4uICc7XG4gICAgICBzdGFydCArPSA1O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgdGFpbCA9ICcnO1xuICBlbmQgPSB0aGlzLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChlbmQgPCB0aGlzLmJ1ZmZlci5sZW5ndGggJiYgJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoZW5kKSkgPT09IC0xKSB7XG4gICAgZW5kICs9IDE7XG4gICAgaWYgKGVuZCAtIHRoaXMucG9zaXRpb24gPiAobWF4TGVuZ3RoIC8gMiAtIDEpKSB7XG4gICAgICB0YWlsID0gJyAuLi4gJztcbiAgICAgIGVuZCAtPSA1O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc25pcHBldCA9IHRoaXMuYnVmZmVyLnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gIHJldHVybiBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50KSArIGhlYWQgKyBzbmlwcGV0ICsgdGFpbCArICdcXG4nICtcbiAgICAgICAgIGNvbW1vbi5yZXBlYXQoJyAnLCBpbmRlbnQgKyB0aGlzLnBvc2l0aW9uIC0gc3RhcnQgKyBoZWFkLmxlbmd0aCkgKyAnXic7XG59O1xuXG5cbk1hcmsucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoY29tcGFjdCkge1xuICB2YXIgc25pcHBldCwgd2hlcmUgPSAnJztcblxuICBpZiAodGhpcy5uYW1lKSB7XG4gICAgd2hlcmUgKz0gJ2luIFwiJyArIHRoaXMubmFtZSArICdcIiAnO1xuICB9XG5cbiAgd2hlcmUgKz0gJ2F0IGxpbmUgJyArICh0aGlzLmxpbmUgKyAxKSArICcsIGNvbHVtbiAnICsgKHRoaXMuY29sdW1uICsgMSk7XG5cbiAgaWYgKCFjb21wYWN0KSB7XG4gICAgc25pcHBldCA9IHRoaXMuZ2V0U25pcHBldCgpO1xuXG4gICAgaWYgKHNuaXBwZXQpIHtcbiAgICAgIHdoZXJlICs9ICc6XFxuJyArIHNuaXBwZXQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdoZXJlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcms7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qZXNsaW50LWRpc2FibGUgbWF4LWxlbiovXG5cbnZhciBjb21tb24gICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBUeXBlICAgICAgICAgID0gcmVxdWlyZSgnLi90eXBlJyk7XG5cblxuZnVuY3Rpb24gY29tcGlsZUxpc3Qoc2NoZW1hLCBuYW1lLCByZXN1bHQpIHtcbiAgdmFyIGV4Y2x1ZGUgPSBbXTtcblxuICBzY2hlbWEuaW5jbHVkZS5mb3JFYWNoKGZ1bmN0aW9uIChpbmNsdWRlZFNjaGVtYSkge1xuICAgIHJlc3VsdCA9IGNvbXBpbGVMaXN0KGluY2x1ZGVkU2NoZW1hLCBuYW1lLCByZXN1bHQpO1xuICB9KTtcblxuICBzY2hlbWFbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoY3VycmVudFR5cGUpIHtcbiAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAocHJldmlvdXNUeXBlLCBwcmV2aW91c0luZGV4KSB7XG4gICAgICBpZiAocHJldmlvdXNUeXBlLnRhZyA9PT0gY3VycmVudFR5cGUudGFnKSB7XG4gICAgICAgIGV4Y2x1ZGUucHVzaChwcmV2aW91c0luZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlc3VsdC5wdXNoKGN1cnJlbnRUeXBlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdC5maWx0ZXIoZnVuY3Rpb24gKHR5cGUsIGluZGV4KSB7XG4gICAgcmV0dXJuIGV4Y2x1ZGUuaW5kZXhPZihpbmRleCkgPT09IC0xO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBjb21waWxlTWFwKC8qIGxpc3RzLi4uICovKSB7XG4gIHZhciByZXN1bHQgPSB7fSwgaW5kZXgsIGxlbmd0aDtcblxuICBmdW5jdGlvbiBjb2xsZWN0VHlwZSh0eXBlKSB7XG4gICAgcmVzdWx0W3R5cGUudGFnXSA9IHR5cGU7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBhcmd1bWVudHNbaW5kZXhdLmZvckVhY2goY29sbGVjdFR5cGUpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBTY2hlbWEoZGVmaW5pdGlvbikge1xuICB0aGlzLmluY2x1ZGUgID0gZGVmaW5pdGlvbi5pbmNsdWRlICB8fCBbXTtcbiAgdGhpcy5pbXBsaWNpdCA9IGRlZmluaXRpb24uaW1wbGljaXQgfHwgW107XG4gIHRoaXMuZXhwbGljaXQgPSBkZWZpbml0aW9uLmV4cGxpY2l0IHx8IFtdO1xuXG4gIHRoaXMuaW1wbGljaXQuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIGlmICh0eXBlLmxvYWRLaW5kICYmIHR5cGUubG9hZEtpbmQgIT09ICdzY2FsYXInKSB7XG4gICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVGhlcmUgaXMgYSBub24tc2NhbGFyIHR5cGUgaW4gdGhlIGltcGxpY2l0IGxpc3Qgb2YgYSBzY2hlbWEuIEltcGxpY2l0IHJlc29sdmluZyBvZiBzdWNoIHR5cGVzIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9KTtcblxuICB0aGlzLmNvbXBpbGVkSW1wbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnaW1wbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRFeHBsaWNpdCA9IGNvbXBpbGVMaXN0KHRoaXMsICdleHBsaWNpdCcsIFtdKTtcbiAgdGhpcy5jb21waWxlZFR5cGVNYXAgID0gY29tcGlsZU1hcCh0aGlzLmNvbXBpbGVkSW1wbGljaXQsIHRoaXMuY29tcGlsZWRFeHBsaWNpdCk7XG59XG5cblxuU2NoZW1hLkRFRkFVTFQgPSBudWxsO1xuXG5cblNjaGVtYS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGVTY2hlbWEoKSB7XG4gIHZhciBzY2hlbWFzLCB0eXBlcztcblxuICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBjYXNlIDE6XG4gICAgICBzY2hlbWFzID0gU2NoZW1hLkRFRkFVTFQ7XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1swXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAyOlxuICAgICAgc2NoZW1hcyA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHR5cGVzID0gYXJndW1lbnRzWzFdO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1dyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIFNjaGVtYS5jcmVhdGUgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIHNjaGVtYXMgPSBjb21tb24udG9BcnJheShzY2hlbWFzKTtcbiAgdHlwZXMgPSBjb21tb24udG9BcnJheSh0eXBlcyk7XG5cbiAgaWYgKCFzY2hlbWFzLmV2ZXJ5KGZ1bmN0aW9uIChzY2hlbWEpIHsgcmV0dXJuIHNjaGVtYSBpbnN0YW5jZW9mIFNjaGVtYTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2Ygc3VwZXIgc2NoZW1hcyAob3IgYSBzaW5nbGUgU2NoZW1hIG9iamVjdCkgY29udGFpbnMgYSBub24tU2NoZW1hIG9iamVjdC4nKTtcbiAgfVxuXG4gIGlmICghdHlwZXMuZXZlcnkoZnVuY3Rpb24gKHR5cGUpIHsgcmV0dXJuIHR5cGUgaW5zdGFuY2VvZiBUeXBlOyB9KSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdTcGVjaWZpZWQgbGlzdCBvZiBZQU1MIHR5cGVzIChvciBhIHNpbmdsZSBUeXBlIG9iamVjdCkgY29udGFpbnMgYSBub24tVHlwZSBvYmplY3QuJyk7XG4gIH1cblxuICByZXR1cm4gbmV3IFNjaGVtYSh7XG4gICAgaW5jbHVkZTogc2NoZW1hcyxcbiAgICBleHBsaWNpdDogdHlwZXNcbiAgfSk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gU2NoZW1hO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hLlxuLy8gaHR0cDovL3d3dy55YW1sLm9yZy9zcGVjLzEuMi9zcGVjLmh0bWwjaWQyODA0OTIzXG4vL1xuLy8gTk9URTogSlMtWUFNTCBkb2VzIG5vdCBzdXBwb3J0IHNjaGVtYS1zcGVjaWZpYyB0YWcgcmVzb2x1dGlvbiByZXN0cmljdGlvbnMuXG4vLyBTbywgQ29yZSBzY2hlbWEgaGFzIG5vIGRpc3RpbmN0aW9ucyBmcm9tIEpTT04gc2NoZW1hIGlzIEpTLVlBTUwuXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9qc29uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBsb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBKUy1ZQU1MJ3MgZGVmYXVsdCBzYWZlIHNjaGVtYSBhbmQgaW5jbHVkZXNcbi8vIEphdmFTY3JpcHQtc3BlY2lmaWMgdHlwZXM6ICEhanMvdW5kZWZpbmVkLCAhIWpzL3JlZ2V4cCBhbmQgISFqcy9mdW5jdGlvbi5cbi8vXG4vLyBBbHNvIHRoaXMgc2NoZW1hIGlzIHVzZWQgYXMgZGVmYXVsdCBiYXNlIHNjaGVtYSBhdCBgU2NoZW1hLmNyZWF0ZWAgZnVuY3Rpb24uXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYS5ERUZBVUxUID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2RlZmF1bHRfc2FmZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy91bmRlZmluZWQnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL3JlZ2V4cCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvZnVuY3Rpb24nKVxuICBdXG59KTtcbiIsIi8vIEpTLVlBTUwncyBkZWZhdWx0IHNjaGVtYSBmb3IgYHNhZmVMb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBzdGFuZGFyZCBZQU1MJ3MgQ29yZSBzY2hlbWEgYW5kIGluY2x1ZGVzIG1vc3Qgb2Zcbi8vIGV4dHJhIHR5cGVzIGRlc2NyaWJlZCBhdCBZQU1MIHRhZyByZXBvc2l0b3J5LiAoaHR0cDovL3lhbWwub3JnL3R5cGUvKVxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vY29yZScpXG4gIF0sXG4gIGltcGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS90aW1lc3RhbXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL21lcmdlJylcbiAgXSxcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL2JpbmFyeScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvb21hcCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvcGFpcnMnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NldCcpXG4gIF1cbn0pO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIEZhaWxzYWZlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMjM0NlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL3N0cicpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvc2VxJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tYXAnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBKU09OIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMzIzMVxuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIHRoaXMgc2NoZW1hIGlzIG5vdCBzdWNoIHN0cmljdCBhcyBkZWZpbmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vLyBJdCBhbGxvd3MgbnVtYmVycyBpbiBiaW5hcnkgbm90YWlvbiwgdXNlIGBOdWxsYCBhbmQgYE5VTExgIGFzIGBudWxsYCwgZXRjLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vZmFpbHNhZmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvbnVsbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvYm9vbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvaW50JyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9mbG9hdCcpXG4gIF1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG5cbnZhciBUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMgPSBbXG4gICdraW5kJyxcbiAgJ3Jlc29sdmUnLFxuICAnY29uc3RydWN0JyxcbiAgJ2luc3RhbmNlT2YnLFxuICAncHJlZGljYXRlJyxcbiAgJ3JlcHJlc2VudCcsXG4gICdkZWZhdWx0U3R5bGUnLFxuICAnc3R5bGVBbGlhc2VzJ1xuXTtcblxudmFyIFlBTUxfTk9ERV9LSU5EUyA9IFtcbiAgJ3NjYWxhcicsXG4gICdzZXF1ZW5jZScsXG4gICdtYXBwaW5nJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlQWxpYXNlcyhtYXApIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuXG4gIGlmIChtYXAgIT09IG51bGwpIHtcbiAgICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgICBtYXBbc3R5bGVdLmZvckVhY2goZnVuY3Rpb24gKGFsaWFzKSB7XG4gICAgICAgIHJlc3VsdFtTdHJpbmcoYWxpYXMpXSA9IHN0eWxlO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBUeXBlKHRhZywgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKFRZUEVfQ09OU1RSVUNUT1JfT1BUSU9OUy5pbmRleE9mKG5hbWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1Vua25vd24gb3B0aW9uIFwiJyArIG5hbWUgKyAnXCIgaXMgbWV0IGluIGRlZmluaXRpb24gb2YgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFRPRE86IEFkZCB0YWcgZm9ybWF0IGNoZWNrLlxuICB0aGlzLnRhZyAgICAgICAgICA9IHRhZztcbiAgdGhpcy5raW5kICAgICAgICAgPSBvcHRpb25zWydraW5kJ10gICAgICAgICB8fCBudWxsO1xuICB0aGlzLnJlc29sdmUgICAgICA9IG9wdGlvbnNbJ3Jlc29sdmUnXSAgICAgIHx8IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XG4gIHRoaXMuY29uc3RydWN0ICAgID0gb3B0aW9uc1snY29uc3RydWN0J10gICAgfHwgZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGE7IH07XG4gIHRoaXMuaW5zdGFuY2VPZiAgID0gb3B0aW9uc1snaW5zdGFuY2VPZiddICAgfHwgbnVsbDtcbiAgdGhpcy5wcmVkaWNhdGUgICAgPSBvcHRpb25zWydwcmVkaWNhdGUnXSAgICB8fCBudWxsO1xuICB0aGlzLnJlcHJlc2VudCAgICA9IG9wdGlvbnNbJ3JlcHJlc2VudCddICAgIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdFN0eWxlID0gb3B0aW9uc1snZGVmYXVsdFN0eWxlJ10gfHwgbnVsbDtcbiAgdGhpcy5zdHlsZUFsaWFzZXMgPSBjb21waWxlU3R5bGVBbGlhc2VzKG9wdGlvbnNbJ3N0eWxlQWxpYXNlcyddIHx8IG51bGwpO1xuXG4gIGlmIChZQU1MX05PREVfS0lORFMuaW5kZXhPZih0aGlzLmtpbmQpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIGtpbmQgXCInICsgdGhpcy5raW5kICsgJ1wiIGlzIHNwZWNpZmllZCBmb3IgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG5cbnZhciBOb2RlQnVmZmVyO1xuXG50cnkge1xuICAvLyBBIHRyaWNrIGZvciBicm93c2VyaWZpZWQgdmVyc2lvbiwgdG8gbm90IGluY2x1ZGUgYEJ1ZmZlcmAgc2hpbVxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBOb2RlQnVmZmVyID0gX3JlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbn0gY2F0Y2ggKF9fKSB7fVxuXG52YXIgVHlwZSAgICAgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuXG4vLyBbIDY0LCA2NSwgNjYgXSAtPiBbIHBhZGRpbmcsIENSLCBMRiBdXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVxcblxccic7XG5cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCaW5hcnkoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBjb2RlLCBpZHgsIGJpdGxlbiA9IDAsIG1heCA9IGRhdGEubGVuZ3RoLCBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgb25lIGJ5IG9uZS5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgY29kZSA9IG1hcC5pbmRleE9mKGRhdGEuY2hhckF0KGlkeCkpO1xuXG4gICAgLy8gU2tpcCBDUi9MRlxuICAgIGlmIChjb2RlID4gNjQpIGNvbnRpbnVlO1xuXG4gICAgLy8gRmFpbCBvbiBpbGxlZ2FsIGNoYXJhY3RlcnNcbiAgICBpZiAoY29kZSA8IDApIHJldHVybiBmYWxzZTtcblxuICAgIGJpdGxlbiArPSA2O1xuICB9XG5cbiAgLy8gSWYgdGhlcmUgYXJlIGFueSBiaXRzIGxlZnQsIHNvdXJjZSB3YXMgY29ycnVwdGVkXG4gIHJldHVybiAoYml0bGVuICUgOCkgPT09IDA7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCaW5hcnkoZGF0YSkge1xuICB2YXIgaWR4LCB0YWlsYml0cyxcbiAgICAgIGlucHV0ID0gZGF0YS5yZXBsYWNlKC9bXFxyXFxuPV0vZywgJycpLCAvLyByZW1vdmUgQ1IvTEYgJiBwYWRkaW5nIHRvIHNpbXBsaWZ5IHNjYW5cbiAgICAgIG1heCA9IGlucHV0Lmxlbmd0aCxcbiAgICAgIG1hcCA9IEJBU0U2NF9NQVAsXG4gICAgICBiaXRzID0gMCxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIC8vIENvbGxlY3QgYnkgNio0IGJpdHMgKDMgYnl0ZXMpXG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSA0ID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gOCkgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKGJpdHMgJiAweEZGKTtcbiAgICB9XG5cbiAgICBiaXRzID0gKGJpdHMgPDwgNikgfCBtYXAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB0YWlsYml0cyA9IChtYXggJSA0KSAqIDY7XG5cbiAgaWYgKHRhaWxiaXRzID09PSAwKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMTYpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gOCkgJiAweEZGKTtcbiAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDE4KSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMTApICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMikgJiAweEZGKTtcbiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTIpIHtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiA0KSAmIDB4RkYpO1xuICB9XG5cbiAgLy8gV3JhcCBpbnRvIEJ1ZmZlciBmb3IgTm9kZUpTIGFuZCBsZWF2ZSBBcnJheSBmb3IgYnJvd3NlclxuICBpZiAoTm9kZUJ1ZmZlcikgcmV0dXJuIG5ldyBOb2RlQnVmZmVyKHJlc3VsdCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50WWFtbEJpbmFyeShvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcnLCBiaXRzID0gMCwgaWR4LCB0YWlsLFxuICAgICAgbWF4ID0gb2JqZWN0Lmxlbmd0aCxcbiAgICAgIG1hcCA9IEJBU0U2NF9NQVA7XG5cbiAgLy8gQ29udmVydCBldmVyeSB0aHJlZSBieXRlcyB0byA0IEFTQ0lJIGNoYXJhY3RlcnMuXG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSAzID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTgpICYgMHgzRl07XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEyKSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFtiaXRzICYgMHgzRl07XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDgpICsgb2JqZWN0W2lkeF07XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB0YWlsID0gbWF4ICUgMztcblxuICBpZiAodGFpbCA9PT0gMCkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTgpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDYpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFtiaXRzICYgMHgzRl07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMikge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTApICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA0KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPDwgMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgfSBlbHNlIGlmICh0YWlsID09PSAxKSB7XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAyKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPDwgNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGlzQmluYXJ5KG9iamVjdCkge1xuICByZXR1cm4gTm9kZUJ1ZmZlciAmJiBOb2RlQnVmZmVyLmlzQnVmZmVyKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJpbmFyeScsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sQmluYXJ5LFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxCaW5hcnksXG4gIHByZWRpY2F0ZTogaXNCaW5hcnksXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEJpbmFyeVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbEJvb2xlYW4oZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBtYXggPSBkYXRhLmxlbmd0aDtcblxuICByZXR1cm4gKG1heCA9PT0gNCAmJiAoZGF0YSA9PT0gJ3RydWUnIHx8IGRhdGEgPT09ICdUcnVlJyB8fCBkYXRhID09PSAnVFJVRScpKSB8fFxuICAgICAgICAgKG1heCA9PT0gNSAmJiAoZGF0YSA9PT0gJ2ZhbHNlJyB8fCBkYXRhID09PSAnRmFsc2UnIHx8IGRhdGEgPT09ICdGQUxTRScpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbEJvb2xlYW4oZGF0YSkge1xuICByZXR1cm4gZGF0YSA9PT0gJ3RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVHJ1ZScgfHxcbiAgICAgICAgIGRhdGEgPT09ICdUUlVFJztcbn1cblxuZnVuY3Rpb24gaXNCb29sZWFuKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEJvb2xlYW5dJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6Ym9vbCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sQm9vbGVhbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQm9vbGVhbixcbiAgcHJlZGljYXRlOiBpc0Jvb2xlYW4sXG4gIHJlcHJlc2VudDoge1xuICAgIGxvd2VyY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ3RydWUnIDogJ2ZhbHNlJzsgfSxcbiAgICB1cHBlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICdUUlVFJyA6ICdGQUxTRSc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVHJ1ZScgOiAnRmFsc2UnOyB9XG4gIH0sXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgWUFNTF9GTE9BVF9QQVRURVJOID0gbmV3IFJlZ0V4cChcbiAgJ14oPzpbLStdPyg/OlswLTldWzAtOV9dKilcXFxcLlswLTlfXSooPzpbZUVdWy0rXVswLTldKyk/JyArXG4gICd8XFxcXC5bMC05X10rKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFstK10/WzAtOV1bMC05X10qKD86OlswLTVdP1swLTldKStcXFxcLlswLTlfXSonICtcbiAgJ3xbLStdP1xcXFwuKD86aW5mfEluZnxJTkYpJyArXG4gICd8XFxcXC4oPzpuYW58TmFOfE5BTikpJCcpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbEZsb2F0KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICBpZiAoIVlBTUxfRkxPQVRfUEFUVEVSTi50ZXN0KGRhdGEpKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxGbG9hdChkYXRhKSB7XG4gIHZhciB2YWx1ZSwgc2lnbiwgYmFzZSwgZGlnaXRzO1xuXG4gIHZhbHVlICA9IGRhdGEucmVwbGFjZSgvXy9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgc2lnbiAgID0gdmFsdWVbMF0gPT09ICctJyA/IC0xIDogMTtcbiAgZGlnaXRzID0gW107XG5cbiAgaWYgKCcrLScuaW5kZXhPZih2YWx1ZVswXSkgPj0gMCkge1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gIH1cblxuICBpZiAodmFsdWUgPT09ICcuaW5mJykge1xuICAgIHJldHVybiAoc2lnbiA9PT0gMSkgPyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cbiAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJy5uYW4nKSB7XG4gICAgcmV0dXJuIE5hTjtcblxuICB9IGVsc2UgaWYgKHZhbHVlLmluZGV4T2YoJzonKSA+PSAwKSB7XG4gICAgdmFsdWUuc3BsaXQoJzonKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgICBkaWdpdHMudW5zaGlmdChwYXJzZUZsb2F0KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDAuMDtcbiAgICBiYXNlID0gMTtcblxuICAgIGRpZ2l0cy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YWx1ZSArPSBkICogYmFzZTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cbiAgcmV0dXJuIHNpZ24gKiBwYXJzZUZsb2F0KHZhbHVlLCAxMCk7XG59XG5cblxudmFyIFNDSUVOVElGSUNfV0lUSE9VVF9ET1QgPSAvXlstK10/WzAtOV0rZS87XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxGbG9hdChvYmplY3QsIHN0eWxlKSB7XG4gIHZhciByZXM7XG5cbiAgaWYgKGlzTmFOKG9iamVjdCkpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy5uYW4nO1xuICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICcuTkFOJztcbiAgICAgIGNhc2UgJ2NhbWVsY2FzZSc6IHJldHVybiAnLk5hTic7XG4gICAgfVxuICB9IGVsc2UgaWYgKE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA9PT0gb2JqZWN0KSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcuaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLklORic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5JbmYnO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLS5pbmYnO1xuICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICctLklORic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy0uSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpIHtcbiAgICByZXR1cm4gJy0wLjAnO1xuICB9XG5cbiAgcmVzID0gb2JqZWN0LnRvU3RyaW5nKDEwKTtcblxuICAvLyBKUyBzdHJpbmdpZmllciBjYW4gYnVpbGQgc2NpZW50aWZpYyBmb3JtYXQgd2l0aG91dCBkb3RzOiA1ZS0xMDAsXG4gIC8vIHdoaWxlIFlBTUwgcmVxdXJlcyBkb3Q6IDUuZS0xMDAuIEZpeCBpdCB3aXRoIHNpbXBsZSBoYWNrXG5cbiAgcmV0dXJuIFNDSUVOVElGSUNfV0lUSE9VVF9ET1QudGVzdChyZXMpID8gcmVzLnJlcGxhY2UoJ2UnLCAnLmUnKSA6IHJlcztcbn1cblxuZnVuY3Rpb24gaXNGbG9hdChvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgTnVtYmVyXScpICYmXG4gICAgICAgICAob2JqZWN0ICUgMSAhPT0gMCB8fCBjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0Jywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxGbG9hdCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sRmxvYXQsXG4gIHByZWRpY2F0ZTogaXNGbG9hdCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sRmxvYXQsXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiBpc0hleENvZGUoYykge1xuICByZXR1cm4gKCgweDMwLyogMCAqLyA8PSBjKSAmJiAoYyA8PSAweDM5LyogOSAqLykpIHx8XG4gICAgICAgICAoKDB4NDEvKiBBICovIDw9IGMpICYmIChjIDw9IDB4NDYvKiBGICovKSkgfHxcbiAgICAgICAgICgoMHg2MS8qIGEgKi8gPD0gYykgJiYgKGMgPD0gMHg2Ni8qIGYgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNPY3RDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzNy8qIDcgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNEZWNDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGgsXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBoYXNEaWdpdHMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmICghbWF4KSByZXR1cm4gZmFsc2U7XG5cbiAgY2ggPSBkYXRhW2luZGV4XTtcblxuICAvLyBzaWduXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG4gIH1cblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIC8vIDBcbiAgICBpZiAoaW5kZXggKyAxID09PSBtYXgpIHJldHVybiB0cnVlO1xuICAgIGNoID0gZGF0YVsrK2luZGV4XTtcblxuICAgIC8vIGJhc2UgMiwgYmFzZSA4LCBiYXNlIDE2XG5cbiAgICBpZiAoY2ggPT09ICdiJykge1xuICAgICAgLy8gYmFzZSAyXG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoY2ggIT09ICcwJyAmJiBjaCAhPT0gJzEnKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzRGlnaXRzO1xuICAgIH1cblxuXG4gICAgaWYgKGNoID09PSAneCcpIHtcbiAgICAgIC8vIGJhc2UgMTZcbiAgICAgIGluZGV4Kys7XG5cbiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICAgIGlmICghaXNIZXhDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzRGlnaXRzO1xuICAgIH1cblxuICAgIC8vIGJhc2UgOFxuICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgIGlmICghaXNPY3RDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzRGlnaXRzO1xuICB9XG5cbiAgLy8gYmFzZSAxMCAoZXhjZXB0IDApIG9yIGJhc2UgNjBcblxuICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICBpZiAoY2ggPT09ICc6JykgYnJlYWs7XG4gICAgaWYgKCFpc0RlY0NvZGUoZGF0YS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghaGFzRGlnaXRzKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gaWYgIWJhc2U2MCAtIGRvbmU7XG4gIGlmIChjaCAhPT0gJzonKSByZXR1cm4gdHJ1ZTtcblxuICAvLyBiYXNlNjAgYWxtb3N0IG5vdCB1c2VkLCBubyBuZWVkcyB0byBvcHRpbWl6ZVxuICByZXR1cm4gL14oOlswLTVdP1swLTldKSskLy50ZXN0KGRhdGEuc2xpY2UoaW5kZXgpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbEludGVnZXIoZGF0YSkge1xuICB2YXIgdmFsdWUgPSBkYXRhLCBzaWduID0gMSwgY2gsIGJhc2UsIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICh2YWx1ZS5pbmRleE9mKCdfJykgIT09IC0xKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9fL2csICcnKTtcbiAgfVxuXG4gIGNoID0gdmFsdWVbMF07XG5cbiAgaWYgKGNoID09PSAnLScgfHwgY2ggPT09ICcrJykge1xuICAgIGlmIChjaCA9PT0gJy0nKSBzaWduID0gLTE7XG4gICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTtcbiAgICBjaCA9IHZhbHVlWzBdO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnMCcpIHJldHVybiAwO1xuXG4gIGlmIChjaCA9PT0gJzAnKSB7XG4gICAgaWYgKHZhbHVlWzFdID09PSAnYicpIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIDIpO1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ3gnKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxNik7XG4gICAgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgOCk7XG4gIH1cblxuICBpZiAodmFsdWUuaW5kZXhPZignOicpICE9PSAtMSkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VJbnQodiwgMTApKTtcbiAgICB9KTtcblxuICAgIHZhbHVlID0gMDtcbiAgICBiYXNlID0gMTtcblxuICAgIGRpZ2l0cy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YWx1ZSArPSAoZCAqIGJhc2UpO1xuICAgICAgYmFzZSAqPSA2MDtcbiAgICB9KTtcblxuICAgIHJldHVybiBzaWduICogdmFsdWU7XG5cbiAgfVxuXG4gIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDEwKTtcbn1cblxuZnVuY3Rpb24gaXNJbnRlZ2VyKG9iamVjdCkge1xuICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiZcbiAgICAgICAgIChvYmplY3QgJSAxID09PSAwICYmICFjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sSW50ZWdlcixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sSW50ZWdlcixcbiAgcHJlZGljYXRlOiBpc0ludGVnZXIsXG4gIHJlcHJlc2VudDoge1xuICAgIGJpbmFyeTogICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAnMGInICsgb2JqZWN0LnRvU3RyaW5nKDIpOyB9LFxuICAgIG9jdGFsOiAgICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAnMCcgICsgb2JqZWN0LnRvU3RyaW5nKDgpOyB9LFxuICAgIGRlY2ltYWw6ICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAgICAgICAgb2JqZWN0LnRvU3RyaW5nKDEwKTsgfSxcbiAgICBoZXhhZGVjaW1hbDogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzB4JyArIG9iamVjdC50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdkZWNpbWFsJyxcbiAgc3R5bGVBbGlhc2VzOiB7XG4gICAgYmluYXJ5OiAgICAgIFsgMiwgICdiaW4nIF0sXG4gICAgb2N0YWw6ICAgICAgIFsgOCwgICdvY3QnIF0sXG4gICAgZGVjaW1hbDogICAgIFsgMTAsICdkZWMnIF0sXG4gICAgaGV4YWRlY2ltYWw6IFsgMTYsICdoZXgnIF1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBlc3ByaW1hO1xuXG4vLyBCcm93c2VyaWZpZWQgdmVyc2lvbiBkb2VzIG5vdCBoYXZlIGVzcHJpbWFcbi8vXG4vLyAxLiBGb3Igbm9kZS5qcyBqdXN0IHJlcXVpcmUgbW9kdWxlIGFzIGRlcHNcbi8vIDIuIEZvciBicm93c2VyIHRyeSB0byByZXF1aXJlIG11ZHVsZSB2aWEgZXh0ZXJuYWwgQU1EIHN5c3RlbS5cbi8vICAgIElmIG5vdCBmb3VuZCAtIHRyeSB0byBmYWxsYmFjayB0byB3aW5kb3cuZXNwcmltYS4gSWYgbm90XG4vLyAgICBmb3VuZCB0b28gLSB0aGVuIGZhaWwgdG8gcGFyc2UuXG4vL1xudHJ5IHtcbiAgLy8gd29ya2Fyb3VuZCB0byBleGNsdWRlIHBhY2thZ2UgZnJvbSBicm93c2VyaWZ5IGxpc3QuXG4gIHZhciBfcmVxdWlyZSA9IHJlcXVpcmU7XG4gIGVzcHJpbWEgPSBfcmVxdWlyZSgnZXNwcmltYScpO1xufSBjYXRjaCAoXykge1xuICAvKmdsb2JhbCB3aW5kb3cgKi9cbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSBlc3ByaW1hID0gd2luZG93LmVzcHJpbWE7XG59XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB0cnkge1xuICAgIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLFxuICAgICAgICBhc3QgICAgPSBlc3ByaW1hLnBhcnNlKHNvdXJjZSwgeyByYW5nZTogdHJ1ZSB9KTtcblxuICAgIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgICBhc3QuYm9keS5sZW5ndGggICAgICAgICAgICAgIT09IDEgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgICBhc3QuYm9keVswXS50eXBlICAgICAgICAgICAgIT09ICdFeHByZXNzaW9uU3RhdGVtZW50JyB8fFxuICAgICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24oZGF0YSkge1xuICAvKmpzbGludCBldmlsOnRydWUqL1xuXG4gIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLFxuICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSksXG4gICAgICBwYXJhbXMgPSBbXSxcbiAgICAgIGJvZHk7XG5cbiAgaWYgKGFzdC50eXBlICAgICAgICAgICAgICAgICAgICAhPT0gJ1Byb2dyYW0nICAgICAgICAgICAgIHx8XG4gICAgICBhc3QuYm9keS5sZW5ndGggICAgICAgICAgICAgIT09IDEgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgIGFzdC5ib2R5WzBdLmV4cHJlc3Npb24udHlwZSAhPT0gJ0Z1bmN0aW9uRXhwcmVzc2lvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBhc3QuYm9keVswXS5leHByZXNzaW9uLnBhcmFtcy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgIHBhcmFtcy5wdXNoKHBhcmFtLm5hbWUpO1xuICB9KTtcblxuICBib2R5ID0gYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5ib2R5LnJhbmdlO1xuXG4gIC8vIEVzcHJpbWEncyByYW5nZXMgaW5jbHVkZSB0aGUgZmlyc3QgJ3snIGFuZCB0aGUgbGFzdCAnfScgY2hhcmFjdGVycyBvblxuICAvLyBmdW5jdGlvbiBleHByZXNzaW9ucy4gU28gY3V0IHRoZW0gb3V0LlxuICAvKmVzbGludC1kaXNhYmxlIG5vLW5ldy1mdW5jKi9cbiAgcmV0dXJuIG5ldyBGdW5jdGlvbihwYXJhbXMsIHNvdXJjZS5zbGljZShib2R5WzBdICsgMSwgYm9keVsxXSAtIDEpKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdEZ1bmN0aW9uKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvZnVuY3Rpb24nLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRGdW5jdGlvbixcbiAgcHJlZGljYXRlOiBpc0Z1bmN0aW9uLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciByZWdleHAgPSBkYXRhLFxuICAgICAgdGFpbCAgID0gL1xcLyhbZ2ltXSopJC8uZXhlYyhkYXRhKSxcbiAgICAgIG1vZGlmaWVycyA9ICcnO1xuXG4gIC8vIGlmIHJlZ2V4cCBzdGFydHMgd2l0aCAnLycgaXQgY2FuIGhhdmUgbW9kaWZpZXJzIGFuZCBtdXN0IGJlIHByb3Blcmx5IGNsb3NlZFxuICAvLyBgL2Zvby9naW1gIC0gbW9kaWZpZXJzIHRhaWwgY2FuIGJlIG1heGltdW0gMyBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcblxuICAgIGlmIChtb2RpZmllcnMubGVuZ3RoID4gMykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIGlmIGV4cHJlc3Npb24gc3RhcnRzIHdpdGggLywgaXMgc2hvdWxkIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWRcbiAgICBpZiAocmVnZXhwW3JlZ2V4cC5sZW5ndGggLSBtb2RpZmllcnMubGVuZ3RoIC0gMV0gIT09ICcvJykgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBgL2Zvby9naW1gIC0gdGFpbCBjYW4gYmUgbWF4aW11bSA0IGNoYXJzXG4gIGlmIChyZWdleHBbMF0gPT09ICcvJykge1xuICAgIGlmICh0YWlsKSBtb2RpZmllcnMgPSB0YWlsWzFdO1xuICAgIHJlZ2V4cCA9IHJlZ2V4cC5zbGljZSgxLCByZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDEpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWdFeHAocmVnZXhwLCBtb2RpZmllcnMpO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0UmVnRXhwKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICB2YXIgcmVzdWx0ID0gJy8nICsgb2JqZWN0LnNvdXJjZSArICcvJztcblxuICBpZiAob2JqZWN0Lmdsb2JhbCkgcmVzdWx0ICs9ICdnJztcbiAgaWYgKG9iamVjdC5tdWx0aWxpbmUpIHJlc3VsdCArPSAnbSc7XG4gIGlmIChvYmplY3QuaWdub3JlQ2FzZSkgcmVzdWx0ICs9ICdpJztcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc1JlZ0V4cChvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvcmVnZXhwJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0SmF2YXNjcmlwdFJlZ0V4cCxcbiAgcHJlZGljYXRlOiBpc1JlZ0V4cCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0UmVnRXhwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi8uLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQqL1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ3VuZGVmaW5lZCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3VuZGVmaW5lZCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQsXG4gIHByZWRpY2F0ZTogaXNVbmRlZmluZWQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjptYXAnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiB7fTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE1lcmdlKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICc8PCcgfHwgZGF0YSA9PT0gbnVsbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWVyZ2UnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE1lcmdlXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sTnVsbChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDEgJiYgZGF0YSA9PT0gJ34nKSB8fFxuICAgICAgICAgKG1heCA9PT0gNCAmJiAoZGF0YSA9PT0gJ251bGwnIHx8IGRhdGEgPT09ICdOdWxsJyB8fCBkYXRhID09PSAnTlVMTCcpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE51bGwoKSB7XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc051bGwob2JqZWN0KSB7XG4gIHJldHVybiBvYmplY3QgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm51bGwnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE51bGwsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbE51bGwsXG4gIHByZWRpY2F0ZTogaXNOdWxsLFxuICByZXByZXNlbnQ6IHtcbiAgICBjYW5vbmljYWw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICd+JzsgICAgfSxcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdudWxsJzsgfSxcbiAgICB1cHBlcmNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdOVUxMJzsgfSxcbiAgICBjYW1lbGNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdOdWxsJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIF90b1N0cmluZyAgICAgICA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sT21hcChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIgb2JqZWN0S2V5cyA9IFtdLCBpbmRleCwgbGVuZ3RoLCBwYWlyLCBwYWlyS2V5LCBwYWlySGFzS2V5LFxuICAgICAgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcbiAgICBwYWlySGFzS2V5ID0gZmFsc2U7XG5cbiAgICBpZiAoX3RvU3RyaW5nLmNhbGwocGFpcikgIT09ICdbb2JqZWN0IE9iamVjdF0nKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHBhaXJLZXkgaW4gcGFpcikge1xuICAgICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhaXIsIHBhaXJLZXkpKSB7XG4gICAgICAgIGlmICghcGFpckhhc0tleSkgcGFpckhhc0tleSA9IHRydWU7XG4gICAgICAgIGVsc2UgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcGFpckhhc0tleSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKG9iamVjdEtleXMuaW5kZXhPZihwYWlyS2V5KSA9PT0gLTEpIG9iamVjdEtleXMucHVzaChwYWlyS2V5KTtcbiAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sT21hcChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IFtdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpvbWFwJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE9tYXAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbE9tYXBcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIF90b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sUGFpcnMoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgaWYgKGtleXMubGVuZ3RoICE9PSAxKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBbXTtcblxuICB2YXIgaW5kZXgsIGxlbmd0aCwgcGFpciwga2V5cywgcmVzdWx0LFxuICAgICAgb2JqZWN0ID0gZGF0YTtcblxuICByZXN1bHQgPSBuZXcgQXJyYXkob2JqZWN0Lmxlbmd0aCk7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG5cbiAgICBrZXlzID0gT2JqZWN0LmtleXMocGFpcik7XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpwYWlycycsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxQYWlycyxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sUGFpcnNcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c2VxJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IFtdOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFNldChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIga2V5LCBvYmplY3QgPSBkYXRhO1xuXG4gIGZvciAoa2V5IGluIG9iamVjdCkge1xuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIGlmIChvYmplY3Rba2V5XSAhPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sU2V0KGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNldCcsIHtcbiAga2luZDogJ21hcHBpbmcnLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbFNldCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sU2V0XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnN0cicsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDogJyc7IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfREFURV9SRUdFWFAgPSBuZXcgUmVnRXhwKFxuICAnXihbMC05XVswLTldWzAtOV1bMC05XSknICAgICAgICAgICsgLy8gWzFdIHllYXJcbiAgJy0oWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFsyXSBtb250aFxuICAnLShbMC05XVswLTldKSQnKTsgICAgICAgICAgICAgICAgICAgLy8gWzNdIGRheVxuXG52YXIgWUFNTF9USU1FU1RBTVBfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFszXSBkYXlcbiAgJyg/OltUdF18WyBcXFxcdF0rKScgICAgICAgICAgICAgICAgICsgLy8gLi4uXG4gICcoWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNF0gaG91clxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzVdIG1pbnV0ZVxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzZdIHNlY29uZFxuICAnKD86XFxcXC4oWzAtOV0qKSk/JyAgICAgICAgICAgICAgICAgKyAvLyBbN10gZnJhY3Rpb25cbiAgJyg/OlsgXFxcXHRdKihafChbLStdKShbMC05XVswLTldPyknICsgLy8gWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91clxuICAnKD86OihbMC05XVswLTldKSk/KSk/JCcpOyAgICAgICAgICAgLy8gWzExXSB0el9taW51dGVcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxUaW1lc3RhbXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpICE9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKFlBTUxfVElNRVNUQU1QX1JFR0VYUC5leGVjKGRhdGEpICE9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sVGltZXN0YW1wKGRhdGEpIHtcbiAgdmFyIG1hdGNoLCB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgZnJhY3Rpb24gPSAwLFxuICAgICAgZGVsdGEgPSBudWxsLCB0el9ob3VyLCB0el9taW51dGUsIGRhdGU7XG5cbiAgbWF0Y2ggPSBZQU1MX0RBVEVfUkVHRVhQLmV4ZWMoZGF0YSk7XG4gIGlmIChtYXRjaCA9PT0gbnVsbCkgbWF0Y2ggPSBZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKTtcblxuICBpZiAobWF0Y2ggPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignRGF0ZSByZXNvbHZlIGVycm9yJyk7XG5cbiAgLy8gbWF0Y2g6IFsxXSB5ZWFyIFsyXSBtb250aCBbM10gZGF5XG5cbiAgeWVhciA9ICsobWF0Y2hbMV0pO1xuICBtb250aCA9ICsobWF0Y2hbMl0pIC0gMTsgLy8gSlMgbW9udGggc3RhcnRzIHdpdGggMFxuICBkYXkgPSArKG1hdGNoWzNdKTtcblxuICBpZiAoIW1hdGNoWzRdKSB7IC8vIG5vIGhvdXJcbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSkpO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs0XSBob3VyIFs1XSBtaW51dGUgWzZdIHNlY29uZCBbN10gZnJhY3Rpb25cblxuICBob3VyID0gKyhtYXRjaFs0XSk7XG4gIG1pbnV0ZSA9ICsobWF0Y2hbNV0pO1xuICBzZWNvbmQgPSArKG1hdGNoWzZdKTtcblxuICBpZiAobWF0Y2hbN10pIHtcbiAgICBmcmFjdGlvbiA9IG1hdGNoWzddLnNsaWNlKDAsIDMpO1xuICAgIHdoaWxlIChmcmFjdGlvbi5sZW5ndGggPCAzKSB7IC8vIG1pbGxpLXNlY29uZHNcbiAgICAgIGZyYWN0aW9uICs9ICcwJztcbiAgICB9XG4gICAgZnJhY3Rpb24gPSArZnJhY3Rpb247XG4gIH1cblxuICAvLyBtYXRjaDogWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91ciBbMTFdIHR6X21pbnV0ZVxuXG4gIGlmIChtYXRjaFs5XSkge1xuICAgIHR6X2hvdXIgPSArKG1hdGNoWzEwXSk7XG4gICAgdHpfbWludXRlID0gKyhtYXRjaFsxMV0gfHwgMCk7XG4gICAgZGVsdGEgPSAodHpfaG91ciAqIDYwICsgdHpfbWludXRlKSAqIDYwMDAwOyAvLyBkZWx0YSBpbiBtaWxpLXNlY29uZHNcbiAgICBpZiAobWF0Y2hbOV0gPT09ICctJykgZGVsdGEgPSAtZGVsdGE7XG4gIH1cblxuICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uKSk7XG5cbiAgaWYgKGRlbHRhKSBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgLSBkZWx0YSk7XG5cbiAgcmV0dXJuIGRhdGU7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxUaW1lc3RhbXAob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6dGltZXN0YW1wJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxUaW1lc3RhbXAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFRpbWVzdGFtcCxcbiAgaW5zdGFuY2VPZjogRGF0ZSxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sVGltZXN0YW1wXG59KTtcbiIsInZhciBiYXNlSW5kZXhPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VJbmRleE9mJyksXG4gICAgYmluYXJ5SW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5hcnlJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGB2YWx1ZWAgaXMgZm91bmQgaW4gYGFycmF5YFxuICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBzb3J0ZWQgcHJvdmlkaW5nIGB0cnVlYCBmb3IgYGZyb21JbmRleGBcbiAqIHBlcmZvcm1zIGEgZmFzdGVyIGJpbmFyeSBzZWFyY2guXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge2Jvb2xlYW58bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbSBvciBgdHJ1ZWBcbiAqICB0byBwZXJmb3JtIGEgYmluYXJ5IHNlYXJjaCBvbiBhIHNvcnRlZCBhcnJheS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIpO1xuICogLy8gPT4gMVxuICpcbiAqIC8vIHVzaW5nIGBmcm9tSW5kZXhgXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAqIC8vID0+IDNcbiAqXG4gKiAvLyBwZXJmb3JtaW5nIGEgYmluYXJ5IHNlYXJjaFxuICogXy5pbmRleE9mKFsxLCAxLCAyLCAyXSwgMiwgdHJ1ZSk7XG4gKiAvLyA9PiAyXG4gKi9cbmZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggPT0gJ251bWJlcicpIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiBmcm9tSW5kZXg7XG4gIH0gZWxzZSBpZiAoZnJvbUluZGV4KSB7XG4gICAgdmFyIGluZGV4ID0gYmluYXJ5SW5kZXgoYXJyYXksIHZhbHVlKTtcbiAgICBpZiAoaW5kZXggPCBsZW5ndGggJiZcbiAgICAgICAgKHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gYXJyYXlbaW5kZXhdKSA6IChhcnJheVtpbmRleF0gIT09IGFycmF5W2luZGV4XSkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXggfHwgMCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5kZXhPZjtcbiIsIi8qKlxuICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xhenlXcmFwcGVyJyksXG4gICAgTG9kYXNoV3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xvZGFzaFdyYXBwZXInKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUxvZGFzaCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICB3cmFwcGVyQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC93cmFwcGVyQ2xvbmUnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBsb2Rhc2hgIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBpbXBsaWNpdCBjaGFpbmluZy5cbiAqIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucywgYW5kIGZ1bmN0aW9ucyBjYW5cbiAqIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZSBvciBtYXkgcmV0dXJuIGFcbiAqIHByaW1pdGl2ZSB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgZW5kIHRoZSBjaGFpbiByZXR1cm5pbmcgdGhlIHVud3JhcHBlZFxuICogdmFsdWUuIEV4cGxpY2l0IGNoYWluaW5nIG1heSBiZSBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC4gVGhlIGV4ZWN1dGlvbiBvZlxuICogY2hhaW5lZCBtZXRob2RzIGlzIGxhenksIHRoYXQgaXMsIGV4ZWN1dGlvbiBpcyBkZWZlcnJlZCB1bnRpbCBgXyN2YWx1ZWBcbiAqIGlzIGltcGxpY2l0bHkgb3IgZXhwbGljaXRseSBjYWxsZWQuXG4gKlxuICogTGF6eSBldmFsdWF0aW9uIGFsbG93cyBzZXZlcmFsIG1ldGhvZHMgdG8gc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24uIFNob3J0Y3V0XG4gKiBmdXNpb24gaXMgYW4gb3B0aW1pemF0aW9uIHN0cmF0ZWd5IHdoaWNoIG1lcmdlIGl0ZXJhdGVlIGNhbGxzOyB0aGlzIGNhbiBoZWxwXG4gKiB0byBhdm9pZCB0aGUgY3JlYXRpb24gb2YgaW50ZXJtZWRpYXRlIGRhdGEgc3RydWN0dXJlcyBhbmQgZ3JlYXRseSByZWR1Y2UgdGhlXG4gKiBudW1iZXIgb2YgaXRlcmF0ZWUgZXhlY3V0aW9ucy5cbiAqXG4gKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGluY2x1ZGVkIGluIHRoZSBidWlsZC5cbiAqXG4gKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICpcbiAqIFRoZSB3cmFwcGVyIGBBcnJheWAgbWV0aG9kcyBhcmU6XG4gKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgcmV2ZXJzZWAsIGBzaGlmdGAsIGBzbGljZWAsIGBzb3J0YCxcbiAqIGBzcGxpY2VgLCBhbmQgYHVuc2hpZnRgXG4gKlxuICogVGhlIHdyYXBwZXIgYFN0cmluZ2AgbWV0aG9kcyBhcmU6XG4gKiBgcmVwbGFjZWAgYW5kIGBzcGxpdGBcbiAqXG4gKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24gYXJlOlxuICogYGNvbXBhY3RgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGZpbHRlcmAsXG4gKiBgZmlyc3RgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGBwbHVja2AsIGByZWplY3RgLCBgcmVzdGAsIGByZXZlcnNlYCxcbiAqIGBzbGljZWAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdG9BcnJheWAsXG4gKiBhbmQgYHdoZXJlYFxuICpcbiAqIFRoZSBjaGFpbmFibGUgd3JhcHBlciBtZXRob2RzIGFyZTpcbiAqIGBhZnRlcmAsIGBhcnlgLCBgYXNzaWduYCwgYGF0YCwgYGJlZm9yZWAsIGBiaW5kYCwgYGJpbmRBbGxgLCBgYmluZEtleWAsXG4gKiBgY2FsbGJhY2tgLCBgY2hhaW5gLCBgY2h1bmtgLCBgY29tbWl0YCwgYGNvbXBhY3RgLCBgY29uY2F0YCwgYGNvbnN0YW50YCxcbiAqIGBjb3VudEJ5YCwgYGNyZWF0ZWAsIGBjdXJyeWAsIGBkZWJvdW5jZWAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLFxuICogYGRlZmVyYCwgYGRlbGF5YCwgYGRpZmZlcmVuY2VgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFJpZ2h0V2hpbGVgLFxuICogYGRyb3BXaGlsZWAsIGBmaWxsYCwgYGZpbHRlcmAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCwgYGZsb3dgLCBgZmxvd1JpZ2h0YCxcbiAqIGBmb3JFYWNoYCwgYGZvckVhY2hSaWdodGAsIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsXG4gKiBgZnVuY3Rpb25zYCwgYGdyb3VwQnlgLCBgaW5kZXhCeWAsIGBpbml0aWFsYCwgYGludGVyc2VjdGlvbmAsIGBpbnZlcnRgLFxuICogYGludm9rZWAsIGBrZXlzYCwgYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsXG4gKiBgbWF0Y2hlc1Byb3BlcnR5YCwgYG1lbW9pemVgLCBgbWVyZ2VgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCxcbiAqIGBtb2RBcmdzYCwgYG5lZ2F0ZWAsIGBvbWl0YCwgYG9uY2VgLCBgcGFpcnNgLCBgcGFydGlhbGAsIGBwYXJ0aWFsUmlnaHRgLFxuICogYHBhcnRpdGlvbmAsIGBwaWNrYCwgYHBsYW50YCwgYHBsdWNrYCwgYHByb3BlcnR5YCwgYHByb3BlcnR5T2ZgLCBgcHVsbGAsXG4gKiBgcHVsbEF0YCwgYHB1c2hgLCBgcmFuZ2VgLCBgcmVhcmdgLCBgcmVqZWN0YCwgYHJlbW92ZWAsIGByZXN0YCwgYHJlc3RQYXJhbWAsXG4gKiBgcmV2ZXJzZWAsIGBzZXRgLCBgc2h1ZmZsZWAsIGBzbGljZWAsIGBzb3J0YCwgYHNvcnRCeWAsIGBzb3J0QnlBbGxgLFxuICogYHNvcnRCeU9yZGVyYCwgYHNwbGljZWAsIGBzcHJlYWRgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLFxuICogYHRha2VXaGlsZWAsIGB0YXBgLCBgdGhyb3R0bGVgLCBgdGhydWAsIGB0aW1lc2AsIGB0b0FycmF5YCwgYHRvUGxhaW5PYmplY3RgLFxuICogYHRyYW5zZm9ybWAsIGB1bmlvbmAsIGB1bmlxYCwgYHVuc2hpZnRgLCBgdW56aXBgLCBgdW56aXBXaXRoYCwgYHZhbHVlc2AsXG4gKiBgdmFsdWVzSW5gLCBgd2hlcmVgLCBgd2l0aG91dGAsIGB3cmFwYCwgYHhvcmAsIGB6aXBgLCBgemlwT2JqZWN0YCwgYHppcFdpdGhgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IGFyZSAqKm5vdCoqIGNoYWluYWJsZSBieSBkZWZhdWx0IGFyZTpcbiAqIGBhZGRgLCBgYXR0ZW1wdGAsIGBjYW1lbENhc2VgLCBgY2FwaXRhbGl6ZWAsIGBjZWlsYCwgYGNsb25lYCwgYGNsb25lRGVlcGAsXG4gKiBgZGVidXJyYCwgYGVuZHNXaXRoYCwgYGVzY2FwZWAsIGBlc2NhcGVSZWdFeHBgLCBgZXZlcnlgLCBgZmluZGAsIGBmaW5kSW5kZXhgLFxuICogYGZpbmRLZXlgLCBgZmluZExhc3RgLCBgZmluZExhc3RJbmRleGAsIGBmaW5kTGFzdEtleWAsIGBmaW5kV2hlcmVgLCBgZmlyc3RgLFxuICogYGZsb29yYCwgYGdldGAsIGBndGAsIGBndGVgLCBgaGFzYCwgYGlkZW50aXR5YCwgYGluY2x1ZGVzYCwgYGluZGV4T2ZgLFxuICogYGluUmFuZ2VgLCBgaXNBcmd1bWVudHNgLCBgaXNBcnJheWAsIGBpc0Jvb2xlYW5gLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsXG4gKiBgaXNFbXB0eWAsIGBpc0VxdWFsYCwgYGlzRXJyb3JgLCBgaXNGaW5pdGVgIGBpc0Z1bmN0aW9uYCwgYGlzTWF0Y2hgLFxuICogYGlzTmF0aXZlYCwgYGlzTmFOYCwgYGlzTnVsbGAsIGBpc051bWJlcmAsIGBpc09iamVjdGAsIGBpc1BsYWluT2JqZWN0YCxcbiAqIGBpc1JlZ0V4cGAsIGBpc1N0cmluZ2AsIGBpc1VuZGVmaW5lZGAsIGBpc1R5cGVkQXJyYXlgLCBgam9pbmAsIGBrZWJhYkNhc2VgLFxuICogYGxhc3RgLCBgbGFzdEluZGV4T2ZgLCBgbHRgLCBgbHRlYCwgYG1heGAsIGBtaW5gLCBgbm9Db25mbGljdGAsIGBub29wYCxcbiAqIGBub3dgLCBgcGFkYCwgYHBhZExlZnRgLCBgcGFkUmlnaHRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLFxuICogYHJlZHVjZVJpZ2h0YCwgYHJlcGVhdGAsIGByZXN1bHRgLCBgcm91bmRgLCBgcnVuSW5Db250ZXh0YCwgYHNoaWZ0YCwgYHNpemVgLFxuICogYHNuYWtlQ2FzZWAsIGBzb21lYCwgYHNvcnRlZEluZGV4YCwgYHNvcnRlZExhc3RJbmRleGAsIGBzdGFydENhc2VgLFxuICogYHN0YXJ0c1dpdGhgLCBgc3VtYCwgYHRlbXBsYXRlYCwgYHRyaW1gLCBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCxcbiAqIGB1bmVzY2FwZWAsIGB1bmlxdWVJZGAsIGB2YWx1ZWAsIGFuZCBgd29yZHNgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kIGBzYW1wbGVgIHdpbGwgcmV0dXJuIGEgd3JhcHBlZCB2YWx1ZSB3aGVuIGBuYCBpcyBwcm92aWRlZCxcbiAqIG90aGVyd2lzZSBhbiB1bndyYXBwZWQgdmFsdWUgaXMgcmV0dXJuZWQuXG4gKlxuICogQG5hbWUgX1xuICogQGNvbnN0cnVjdG9yXG4gKiBAY2F0ZWdvcnkgQ2hhaW5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAgaW4gYSBgbG9kYXNoYCBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDIsIDNdKTtcbiAqXG4gKiAvLyByZXR1cm5zIGFuIHVud3JhcHBlZCB2YWx1ZVxuICogd3JhcHBlZC5yZWR1Y2UoZnVuY3Rpb24odG90YWwsIG4pIHtcbiAqICAgcmV0dXJuIHRvdGFsICsgbjtcbiAqIH0pO1xuICogLy8gPT4gNlxuICpcbiAqIC8vIHJldHVybnMgYSB3cmFwcGVkIHZhbHVlXG4gKiB2YXIgc3F1YXJlcyA9IHdyYXBwZWQubWFwKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIG4gKiBuO1xuICogfSk7XG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmICFpc0FycmF5KHZhbHVlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpKSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fY2hhaW5fXycpICYmIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX3dyYXBwZWRfXycpKSB7XG4gICAgICByZXR1cm4gd3JhcHBlckNsb25lKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHZhbHVlKTtcbn1cblxuLy8gRW5zdXJlIHdyYXBwZXJzIGFyZSBpbnN0YW5jZXMgb2YgYGJhc2VMb2Rhc2hgLlxubG9kYXNoLnByb3RvdHlwZSA9IGJhc2VMb2Rhc2gucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mb3JFYWNoJyk7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZpbmQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGaW5kJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmRcbiAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIGRldGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAqICBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICogXTtcbiAqXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIGZ1bmN0aW9uKGNocikge1xuICogICByZXR1cm4gY2hyLmFnZSA8IDQwO1xuICogfSksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzYCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSksICd1c2VyJyk7XG4gKiAvLyA9PiAncGViYmxlcydcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgJ2FjdGl2ZScsIGZhbHNlKSwgJ3VzZXInKTtcbiAqIC8vID0+ICdmcmVkJ1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAqIC8vID0+ICdiYXJuZXknXG4gKi9cbnZhciBmaW5kID0gY3JlYXRlRmluZChiYXNlRWFjaCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZmluZDtcbiIsInZhciBhcnJheUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9hcnJheUVhY2gnKSxcbiAgICBiYXNlRWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VFYWNoJyksXG4gICAgY3JlYXRlRm9yRWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2NyZWF0ZUZvckVhY2gnKTtcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvciBlYWNoIGVsZW1lbnQuXG4gKiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHlcbiAqIGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgXCJDb2xsZWN0aW9uc1wiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhIFwibGVuZ3RoXCIgcHJvcGVydHlcbiAqIGFyZSBpdGVyYXRlZCBsaWtlIGFycmF5cy4gVG8gYXZvaWQgdGhpcyBiZWhhdmlvciBgXy5mb3JJbmAgb3IgYF8uZm9yT3duYFxuICogbWF5IGJlIHVzZWQgZm9yIG9iamVjdCBpdGVyYXRpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBlYWNoXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8oWzEsIDJdKS5mb3JFYWNoKGZ1bmN0aW9uKG4pIHtcbiAqICAgY29uc29sZS5sb2cobik7XG4gKiB9KS52YWx1ZSgpO1xuICogLy8gPT4gbG9ncyBlYWNoIHZhbHVlIGZyb20gbGVmdCB0byByaWdodCBhbmQgcmV0dXJucyB0aGUgYXJyYXlcbiAqXG4gKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbihuLCBrZXkpIHtcbiAqICAgY29uc29sZS5sb2cobiwga2V5KTtcbiAqIH0pO1xuICogLy8gPT4gbG9ncyBlYWNoIHZhbHVlLWtleSBwYWlyIGFuZCByZXR1cm5zIHRoZSBvYmplY3QgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xudmFyIGZvckVhY2ggPSBjcmVhdGVGb3JFYWNoKGFycmF5RWFjaCwgYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZvckVhY2g7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGdldExlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldExlbmd0aCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0l0ZXJhdGVlQ2FsbCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSXRlcmF0ZWVDYWxsJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi4vbGFuZy9pc1N0cmluZycpLFxuICAgIHZhbHVlcyA9IHJlcXVpcmUoJy4uL29iamVjdC92YWx1ZXMnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHRhcmdldGAgaXMgaW4gYGNvbGxlY3Rpb25gIHVzaW5nXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBJZiBgZnJvbUluZGV4YCBpcyBuZWdhdGl2ZSwgaXQncyB1c2VkIGFzIHRoZSBvZmZzZXRcbiAqIGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBjb250YWlucywgaW5jbHVkZVxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHRhcmdldCBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5yZWR1Y2VgLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGEgbWF0Y2hpbmcgZWxlbWVudCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluY2x1ZGVzKFsxLCAyLCAzXSwgMSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEsIDIpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmluY2x1ZGVzKHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9LCAnZnJlZCcpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoJ3BlYmJsZXMnLCAnZWInKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaW5jbHVkZXMoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgsIGd1YXJkKSB7XG4gIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgY29sbGVjdGlvbiA9IHZhbHVlcyhjb2xsZWN0aW9uKTtcbiAgICBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgfVxuICBpZiAodHlwZW9mIGZyb21JbmRleCAhPSAnbnVtYmVyJyB8fCAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwodGFyZ2V0LCBmcm9tSW5kZXgsIGd1YXJkKSkpIHtcbiAgICBmcm9tSW5kZXggPSAwO1xuICB9IGVsc2Uge1xuICAgIGZyb21JbmRleCA9IGZyb21JbmRleCA8IDAgPyBuYXRpdmVNYXgobGVuZ3RoICsgZnJvbUluZGV4LCAwKSA6IChmcm9tSW5kZXggfHwgMCk7XG4gIH1cbiAgcmV0dXJuICh0eXBlb2YgY29sbGVjdGlvbiA9PSAnc3RyaW5nJyB8fCAhaXNBcnJheShjb2xsZWN0aW9uKSAmJiBpc1N0cmluZyhjb2xsZWN0aW9uKSlcbiAgICA/IChmcm9tSW5kZXggPD0gbGVuZ3RoICYmIGNvbGxlY3Rpb24uaW5kZXhPZih0YXJnZXQsIGZyb21JbmRleCkgPiAtMSlcbiAgICA6ICghIWxlbmd0aCAmJiBiYXNlSW5kZXhPZihjb2xsZWN0aW9uLCB0YXJnZXQsIGZyb21JbmRleCkgPiAtMSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5jbHVkZXM7XG4iLCJ2YXIgYXJyYXlNYXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9hcnJheU1hcCcpLFxuICAgIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDYWxsYmFjaycpLFxuICAgIGJhc2VNYXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlTWFwJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJvdWdoXG4gKiBgaXRlcmF0ZWVgLiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZVxuICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gKlxuICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gKiBgYXJ5YCwgYGNhbGxiYWNrYCwgYGNodW5rYCwgYGNsb25lYCwgYGNyZWF0ZWAsIGBjdXJyeWAsIGBjdXJyeVJpZ2h0YCxcbiAqIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsIGBmaWxsYCwgYGZsYXR0ZW5gLCBgaW52ZXJ0YCwgYG1heGAsIGBtaW5gLFxuICogYHBhcnNlSW50YCwgYHNsaWNlYCwgYHNvcnRCeWAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0ZW1wbGF0ZWAsIGB0cmltYCxcbiAqIGB0cmltTGVmdGAsIGB0cmltUmlnaHRgLCBgdHJ1bmNgLCBgcmFuZG9tYCwgYHJhbmdlYCwgYHNhbXBsZWAsIGBzb21lYCxcbiAqIGBzdW1gLCBgdW5pcWAsIGFuZCBgd29yZHNgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBjb2xsZWN0XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiB0aW1lc1RocmVlKG4pIHtcbiAqICAgcmV0dXJuIG4gKiAzO1xuICogfVxuICpcbiAqIF8ubWFwKFsxLCAyXSwgdGltZXNUaHJlZSk7XG4gKiAvLyA9PiBbMywgNl1cbiAqXG4gKiBfLm1hcCh7ICdhJzogMSwgJ2InOiAyIH0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScgfSxcbiAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gKiBdO1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLm1hcCh1c2VycywgJ3VzZXInKTtcbiAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICovXG5mdW5jdGlvbiBtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICBpdGVyYXRlZSA9IGJhc2VDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXA7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTm93ID0gZ2V0TmF0aXZlKERhdGUsICdub3cnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBVbml4IGVwb2NoXG4gKiAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IERhdGVcbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBsb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBmdW5jdGlvbiB0byBiZSBpbnZva2VkXG4gKi9cbnZhciBub3cgPSBuYXRpdmVOb3cgfHwgZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbm93O1xuIiwidmFyIGNyZWF0ZVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVXcmFwcGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9yZXBsYWNlSG9sZGVycycpLFxuICAgIHJlc3RQYXJhbSA9IHJlcXVpcmUoJy4vcmVzdFBhcmFtJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBQQVJUSUFMX0ZMQUcgPSAzMjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2BcbiAqIGFuZCBwcmVwZW5kcyBhbnkgYWRkaXRpb25hbCBgXy5iaW5kYCBhcmd1bWVudHMgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlXG4gKiBib3VuZCBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAgdGhpcyBtZXRob2QgZG9lcyBub3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGdyZWV0ID0gZnVuY3Rpb24oZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gKiAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICogfTtcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICpcbiAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCAnaGknKTtcbiAqIGJvdW5kKCchJyk7XG4gKiAvLyA9PiAnaGkgZnJlZCEnXG4gKlxuICogLy8gdXNpbmcgcGxhY2Vob2xkZXJzXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgXywgJyEnKTtcbiAqIGJvdW5kKCdoaScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICovXG52YXIgYmluZCA9IHJlc3RQYXJhbShmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgYml0bWFzayA9IEJJTkRfRkxBRztcbiAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGJpbmQucGxhY2Vob2xkZXIpO1xuICAgIGJpdG1hc2sgfD0gUEFSVElBTF9GTEFHO1xuICB9XG4gIHJldHVybiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbn0pO1xuXG4vLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG5iaW5kLnBsYWNlaG9sZGVyID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZDtcbiIsIi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZVxuICogY3JlYXRlZCBmdW5jdGlvbiBhbmQgYXJndW1lbnRzIGZyb20gYHN0YXJ0YCBhbmQgYmV5b25kIHByb3ZpZGVkIGFzIGFuIGFycmF5LlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGUgW3Jlc3QgcGFyYW1ldGVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgc2F5ID0gXy5yZXN0UGFyYW0oZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6ICgrc3RhcnQgfHwgMCksIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdFtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgcmVzdCk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgcmVzdCk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gcmVzdDtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RQYXJhbTtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4vYmFzZUxvZGFzaCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciBgLUluZmluaXR5YCBhbmQgYEluZmluaXR5YC4gKi9cbnZhciBQT1NJVElWRV9JTkZJTklUWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fZGlyX18gPSAxO1xuICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICB0aGlzLl9faXRlcmF0ZWVzX18gPSBbXTtcbiAgdGhpcy5fX3Rha2VDb3VudF9fID0gUE9TSVRJVkVfSU5GSU5JVFk7XG4gIHRoaXMuX192aWV3c19fID0gW107XG59XG5cbkxhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTGF6eVdyYXBwZXI7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBjaGFpbmluZyBmb3IgYWxsIHdyYXBwZXIgbWV0aG9kcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthY3Rpb25zPVtdXSBBY3Rpb25zIHRvIHBlZm9ybSB0byByZXNvbHZlIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsLCBhY3Rpb25zKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IGFjdGlvbnMgfHwgW107XG4gIHRoaXMuX19jaGFpbl9fID0gISFjaGFpbkFsbDtcbn1cblxuTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTG9kYXNoV3JhcHBlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBMb2Rhc2hXcmFwcGVyO1xuIiwiLyoqXG4gKiBDb3BpZXMgdGhlIHZhbHVlcyBvZiBgc291cmNlYCB0byBgYXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXk9W11dIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyB0by5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheUNvcHkoc291cmNlLCBhcnJheSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG5cbiAgYXJyYXkgfHwgKGFycmF5ID0gQXJyYXkobGVuZ3RoKSk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbaW5kZXhdID0gc291cmNlW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlDb3B5O1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNYXA7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gKiAgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQ29weSA9IHJlcXVpcmUoJy4vYmFzZUNvcHknKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsXG4gKiBtdWx0aXBsZSBzb3VyY2VzLCBhbmQgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgcmV0dXJuIHNvdXJjZSA9PSBudWxsXG4gICAgPyBvYmplY3RcbiAgICA6IGJhc2VDb3B5KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ247XG4iLCJ2YXIgYmFzZU1hdGNoZXMgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzJyksXG4gICAgYmFzZU1hdGNoZXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYmFzZU1hdGNoZXNQcm9wZXJ0eScpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgcHJvcGVydHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L3Byb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY2FsbGJhY2tgIHdoaWNoIHN1cHBvcnRzIHNwZWNpZnlpbmcgdGhlXG4gKiBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcmdDb3VudF0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBiYXNlQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgZnVuYztcbiAgaWYgKHR5cGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICAgID8gZnVuY1xuICAgICAgOiBiaW5kQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpO1xuICB9XG4gIGlmIChmdW5jID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHR5cGUgPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gYmFzZU1hdGNoZXMoZnVuYyk7XG4gIH1cbiAgcmV0dXJuIHRoaXNBcmcgPT09IHVuZGVmaW5lZFxuICAgID8gcHJvcGVydHkoZnVuYylcbiAgICA6IGJhc2VNYXRjaGVzUHJvcGVydHkoZnVuYywgdGhpc0FyZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNhbGxiYWNrO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi9hcnJheUVhY2gnKSxcbiAgICBiYXNlQXNzaWduID0gcmVxdWlyZSgnLi9iYXNlQXNzaWduJyksXG4gICAgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vYmFzZUZvck93bicpLFxuICAgIGluaXRDbG9uZUFycmF5ID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVBcnJheScpLFxuICAgIGluaXRDbG9uZUJ5VGFnID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vaW5pdENsb25lT2JqZWN0JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSG9zdE9iamVjdCA9IHJlcXVpcmUoJy4vaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgc3VwcG9ydGVkIGJ5IGBfLmNsb25lYC4gKi9cbnZhciBjbG9uZWFibGVUYWdzID0ge307XG5jbG9uZWFibGVUYWdzW2FyZ3NUYWddID0gY2xvbmVhYmxlVGFnc1thcnJheVRhZ10gPVxuY2xvbmVhYmxlVGFnc1thcnJheUJ1ZmZlclRhZ10gPSBjbG9uZWFibGVUYWdzW2Jvb2xUYWddID1cbmNsb25lYWJsZVRhZ3NbZGF0ZVRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDhUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQzMlRhZ10gPVxuY2xvbmVhYmxlVGFnc1tudW1iZXJUYWddID0gY2xvbmVhYmxlVGFnc1tvYmplY3RUYWddID1cbmNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc2V0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nXG4gKiBhbmQgYHRoaXNgIGJpbmRpbmcgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleV0gVGhlIGtleSBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgYHZhbHVlYCBiZWxvbmdzIHRvLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIEFzc29jaWF0ZXMgY2xvbmVzIHdpdGggc291cmNlIGNvdW50ZXJwYXJ0cy5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBjbG9uZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VDbG9uZSh2YWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIG9iamVjdCwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCkgOiBjdXN0b21pemVyKHZhbHVlKTtcbiAgfVxuICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICBpZiAoaXNBcnIpIHtcbiAgICByZXN1bHQgPSBpbml0Q2xvbmVBcnJheSh2YWx1ZSk7XG4gICAgaWYgKCFpc0RlZXApIHtcbiAgICAgIHJldHVybiBhcnJheUNvcHkodmFsdWUsIHJlc3VsdCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciB0YWcgPSBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSxcbiAgICAgICAgaXNGdW5jID0gdGFnID09IGZ1bmNUYWc7XG5cbiAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICBpZiAoaXNIb3N0T2JqZWN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID8gdmFsdWUgOiB7fTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IGluaXRDbG9uZU9iamVjdChpc0Z1bmMgPyB7fSA6IHZhbHVlKTtcbiAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY2xvbmVhYmxlVGFnc1t0YWddXG4gICAgICAgID8gaW5pdENsb25lQnlUYWcodmFsdWUsIHRhZywgaXNEZWVwKVxuICAgICAgICA6IChvYmplY3QgPyB2YWx1ZSA6IHt9KTtcbiAgICB9XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgc3RhY2tBIHx8IChzdGFja0EgPSBbXSk7XG4gIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xuXG4gIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICBpZiAoc3RhY2tBW2xlbmd0aF0gPT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXTtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIHRoZSBzb3VyY2UgdmFsdWUgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCBpdHMgY2xvbmUuXG4gIHN0YWNrQS5wdXNoKHZhbHVlKTtcbiAgc3RhY2tCLnB1c2gocmVzdWx0KTtcblxuICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAoaXNBcnIgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKSh2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIHJlc3VsdFtrZXldID0gYmFzZUNsb25lKHN1YlZhbHVlLCBpc0RlZXAsIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrQSwgc3RhY2tCKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwiLyoqXG4gKiBDb3BpZXMgcHJvcGVydGllcyBvZiBgc291cmNlYCB0byBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGNvcHkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQ29weShzb3VyY2UsIHByb3BzLCBvYmplY3QpIHtcbiAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIG9iamVjdFtrZXldID0gc291cmNlW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ29weTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gKi9cbnZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICByZXR1cm4gZnVuY3Rpb24ocHJvdG90eXBlKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvdHlwZSkpIHtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQgfHwge307XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDcmVhdGU7XG4iLCJ2YXIgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vYmFzZUZvck93bicpLFxuICAgIGNyZWF0ZUJhc2VFYWNoID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRWFjaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R8c3RyaW5nfSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAqL1xudmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUVhY2g7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbmRgLCBgXy5maW5kTGFzdGAsIGBfLmZpbmRLZXlgLCBhbmQgYF8uZmluZExhc3RLZXlgLFxuICogd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZywgd2hpY2ggaXRlcmF0ZXNcbiAqIG92ZXIgYGNvbGxlY3Rpb25gIHVzaW5nIHRoZSBwcm92aWRlZCBgZWFjaEZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEtleV0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGtleSBvZiB0aGUgZm91bmQgZWxlbWVudFxuICogIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZvdW5kIGVsZW1lbnQgb3IgaXRzIGtleSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYywgcmV0S2V5KSB7XG4gIHZhciByZXN1bHQ7XG4gIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pKSB7XG4gICAgICByZXN1bHQgPSByZXRLZXkgPyBrZXkgOiB2YWx1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGaW5kO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kSW5kZXhgIGFuZCBgXy5maW5kTGFzdEluZGV4YCB3aXRob3V0XG4gKiBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZEluZGV4O1xuIiwidmFyIGNyZWF0ZUJhc2VGb3IgPSByZXF1aXJlKCcuL2NyZWF0ZUJhc2VGb3InKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvckluYCBhbmQgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBvYmplY3RgIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvclxuICogZWFjaCBwcm9wZXJ0eS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5XG4gKiByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xudmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZvcjtcbiIsInZhciBiYXNlRm9yID0gcmVxdWlyZSgnLi9iYXNlRm9yJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckluYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlRm9ySW4ob2JqZWN0LCBpdGVyYXRlZSkge1xuICByZXR1cm4gYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzSW4pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JJbjtcbiIsInZhciBiYXNlRm9yID0gcmVxdWlyZSgnLi9iYXNlRm9yJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZvck93bjtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0cmluZyBwYXRoc1xuICogYW5kIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGhLZXldIFRoZSBrZXkgcmVwcmVzZW50YXRpb24gb2YgcGF0aC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gIGlmIChwYXRoS2V5ICE9PSB1bmRlZmluZWQgJiYgcGF0aEtleSBpbiBvYmplY3QpIHtcbiAgICBwYXRoID0gW3BhdGhLZXldO1xuICB9XG4gIHZhciBpbmRleCA9IDAsXG4gICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDtcblxuICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHtcbiAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpW3BhdGhbaW5kZXgrK11dO1xuICB9XG4gIHJldHVybiAoaW5kZXggJiYgaW5kZXggPT0gbGVuZ3RoKSA/IG9iamVjdCA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0O1xuIiwidmFyIGluZGV4T2ZOYU4gPSByZXF1aXJlKCcuL2luZGV4T2ZOYU4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbmRleE9mYCB3aXRob3V0IHN1cHBvcnQgZm9yIGJpbmFyeSBzZWFyY2hlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIGlmICh2YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICByZXR1cm4gaW5kZXhPZk5hTihhcnJheSwgZnJvbUluZGV4KTtcbiAgfVxuICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJbmRleE9mO1xuIiwidmFyIGJhc2VJc0VxdWFsRGVlcCA9IHJlcXVpcmUoJy4vYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aXRob3V0IHN1cHBvcnQgZm9yIGB0aGlzYCBiaW5kaW5nXG4gKiBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQl0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAodmFsdWUgPT0gbnVsbCB8fCBvdGhlciA9PSBudWxsIHx8ICghaXNPYmplY3QodmFsdWUpICYmICFpc09iamVjdExpa2Uob3RoZXIpKSkge1xuICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyO1xuICB9XG4gIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiYXNlSXNFcXVhbCwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc0VxdWFsO1xuIiwidmFyIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9lcXVhbEFycmF5cycpLFxuICAgIGVxdWFsQnlUYWcgPSByZXF1aXJlKCcuL2VxdWFsQnlUYWcnKSxcbiAgICBlcXVhbE9iamVjdHMgPSByZXF1aXJlKCcuL2VxdWFsT2JqZWN0cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNUeXBlZEFycmF5Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gKiBkZWVwIGNvbXBhcmlzb25zIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgb2JqZWN0cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNFcXVhbERlZXAob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICBvdGhJc0FyciA9IGlzQXJyYXkob3RoZXIpLFxuICAgICAgb2JqVGFnID0gYXJyYXlUYWcsXG4gICAgICBvdGhUYWcgPSBhcnJheVRhZztcblxuICBpZiAoIW9iaklzQXJyKSB7XG4gICAgb2JqVGFnID0gb2JqVG9TdHJpbmcuY2FsbChvYmplY3QpO1xuICAgIGlmIChvYmpUYWcgPT0gYXJnc1RhZykge1xuICAgICAgb2JqVGFnID0gb2JqZWN0VGFnO1xuICAgIH0gZWxzZSBpZiAob2JqVGFnICE9IG9iamVjdFRhZykge1xuICAgICAgb2JqSXNBcnIgPSBpc1R5cGVkQXJyYXkob2JqZWN0KTtcbiAgICB9XG4gIH1cbiAgaWYgKCFvdGhJc0Fycikge1xuICAgIG90aFRhZyA9IG9ialRvU3RyaW5nLmNhbGwob3RoZXIpO1xuICAgIGlmIChvdGhUYWcgPT0gYXJnc1RhZykge1xuICAgICAgb3RoVGFnID0gb2JqZWN0VGFnO1xuICAgIH0gZWxzZSBpZiAob3RoVGFnICE9IG9iamVjdFRhZykge1xuICAgICAgb3RoSXNBcnIgPSBpc1R5cGVkQXJyYXkob3RoZXIpO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqSXNPYmogPSBvYmpUYWcgPT0gb2JqZWN0VGFnICYmICFpc0hvc3RPYmplY3Qob2JqZWN0KSxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG90aGVyKSxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiAhKG9iaklzQXJyIHx8IG9iaklzT2JqKSkge1xuICAgIHJldHVybiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIG9ialRhZyk7XG4gIH1cbiAgaWYgKCFpc0xvb3NlKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpJc1dyYXBwZWQgPyBvYmplY3QudmFsdWUoKSA6IG9iamVjdCwgb3RoSXNXcmFwcGVkID8gb3RoZXIudmFsdWUoKSA6IG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgfVxuICB9XG4gIGlmICghaXNTYW1lVGFnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgLy8gRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gZGV0ZWN0aW5nIGNpcmN1bGFyIHJlZmVyZW5jZXMgc2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jSk8uXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IG9iamVjdCkge1xuICAgICAgcmV0dXJuIHN0YWNrQltsZW5ndGhdID09IG90aGVyO1xuICAgIH1cbiAgfVxuICAvLyBBZGQgYG9iamVjdGAgYW5kIGBvdGhlcmAgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICBzdGFja0EucHVzaChvYmplY3QpO1xuICBzdGFja0IucHVzaChvdGhlcik7XG5cbiAgdmFyIHJlc3VsdCA9IChvYmpJc0FyciA/IGVxdWFsQXJyYXlzIDogZXF1YWxPYmplY3RzKShvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcblxuICBzdGFja0EucG9wKCk7XG4gIHN0YWNrQi5wb3AoKTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc0VxdWFsRGVlcDtcbiIsInZhciBiYXNlSXNFcXVhbCA9IHJlcXVpcmUoJy4vYmFzZUlzRXF1YWwnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hdGNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0FycmF5fSBtYXRjaERhdGEgVGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc01hdGNoKG9iamVjdCwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7XG4gIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBpbmRleCxcbiAgICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyO1xuXG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiAhbGVuZ3RoO1xuICB9XG4gIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gIHdoaWxlIChpbmRleC0tKSB7XG4gICAgdmFyIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgIGlmICgobm9DdXN0b21pemVyICYmIGRhdGFbMl0pXG4gICAgICAgICAgPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV1cbiAgICAgICAgICA6ICEoZGF0YVswXSBpbiBvYmplY3QpXG4gICAgICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgIHZhciBrZXkgPSBkYXRhWzBdLFxuICAgICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07XG5cbiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0pIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXkpIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIGN1c3RvbWl6ZXIsIHRydWUpIDogcmVzdWx0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc01hdGNoO1xuIiwiLyoqXG4gKiBUaGUgZnVuY3Rpb24gd2hvc2UgcHJvdG90eXBlIGFsbCBjaGFpbmluZyB3cmFwcGVycyBpbmhlcml0IGZyb20uXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYmFzZUxvZGFzaCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTG9kYXNoO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9iYXNlRWFjaCcpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzXG4gKiBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlTWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXA7XG4iLCJ2YXIgYmFzZUlzTWF0Y2ggPSByZXF1aXJlKCcuL2Jhc2VJc01hdGNoJyksXG4gICAgZ2V0TWF0Y2hEYXRhID0gcmVxdWlyZSgnLi9nZXRNYXRjaERhdGEnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2VzIG5vdCBjbG9uZSBgc291cmNlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlcyhzb3VyY2UpIHtcbiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgIHZhciBrZXkgPSBtYXRjaERhdGFbMF1bMF0sXG4gICAgICAgIHZhbHVlID0gbWF0Y2hEYXRhWzBdWzFdO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHZhbHVlICYmICh2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gb2JqZWN0KSk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGJhc2VJc01hdGNoKG9iamVjdCwgbWF0Y2hEYXRhKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlcztcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9iYXNlR2V0JyksXG4gICAgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgYmFzZVNsaWNlID0gcmVxdWlyZSgnLi9iYXNlU2xpY2UnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuL2lzS2V5JyksXG4gICAgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBsYXN0ID0gcmVxdWlyZSgnLi4vYXJyYXkvbGFzdCcpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc1Byb3BlcnR5YCB3aGljaCBkb2VzIG5vdCBjbG9uZSBgc3JjVmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gIHZhciBpc0FyciA9IGlzQXJyYXkocGF0aCksXG4gICAgICBpc0NvbW1vbiA9IGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSksXG4gICAgICBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG5cbiAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIga2V5ID0gcGF0aEtleTtcbiAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgIGlmICgoaXNBcnIgfHwgIWlzQ29tbW9uKSAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICBvYmplY3QgPSBwYXRoLmxlbmd0aCA9PSAxID8gb2JqZWN0IDogYmFzZUdldChvYmplY3QsIGJhc2VTbGljZShwYXRoLCAwLCAtMSkpO1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGtleSA9IGxhc3QocGF0aCk7XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlXG4gICAgICA/IChzcmNWYWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gb2JqZWN0KSlcbiAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9iamVjdFtrZXldLCB1bmRlZmluZWQsIHRydWUpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXRjaGVzUHJvcGVydHk7XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogdG9PYmplY3Qob2JqZWN0KVtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9iYXNlR2V0JyksXG4gICAgdG9QYXRoID0gcmVxdWlyZSgnLi90b1BhdGgnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VQcm9wZXJ0eWAgd2hpY2ggc3VwcG9ydHMgZGVlcCBwYXRocy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpIHtcbiAgdmFyIHBhdGhLZXkgPSAocGF0aCArICcnKTtcbiAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgcGF0aCwgcGF0aEtleSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVByb3BlcnR5RGVlcDtcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKSxcbiAgICBtZXRhTWFwID0gcmVxdWlyZSgnLi9tZXRhTWFwJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldERhdGFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3AgZGV0ZWN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAqIEBwYXJhbSB7Kn0gZGF0YSBUaGUgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICovXG52YXIgYmFzZVNldERhdGEgPSAhbWV0YU1hcCA/IGlkZW50aXR5IDogZnVuY3Rpb24oZnVuYywgZGF0YSkge1xuICBtZXRhTWFwLnNldChmdW5jLCBkYXRhKTtcbiAgcmV0dXJuIGZ1bmM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTZXREYXRhO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zbGljZWAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHN0YXJ0ID0gc3RhcnQgPT0gbnVsbCA/IDAgOiAoK3N0YXJ0IHx8IDApO1xuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgfVxuICBlbmQgPSAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gbGVuZ3RoKSA/IGxlbmd0aCA6ICgrZW5kIHx8IDApO1xuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5ndGg7XG4gIH1cbiAgbGVuZ3RoID0gc3RhcnQgPiBlbmQgPyAwIDogKChlbmQgLSBzdGFydCkgPj4+IDApO1xuICBzdGFydCA+Pj49IDA7XG5cbiAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVNsaWNlO1xuIiwiLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGlmIGl0J3Mgbm90IG9uZS4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkXG4gKiBmb3IgYG51bGxgIG9yIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiAodmFsdWUgKyAnJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVRvU3RyaW5nO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICogYXJyYXkgb2YgYG9iamVjdGAgcHJvcGVydHkgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzXG4gKiBvZiBgcHJvcHNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gb2JqZWN0W3Byb3BzW2luZGV4XV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVmFsdWVzO1xuIiwidmFyIGJpbmFyeUluZGV4QnkgPSByZXF1aXJlKCcuL2JpbmFyeUluZGV4QnknKSxcbiAgICBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbnZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICBIQUxGX01BWF9BUlJBWV9MRU5HVEggPSBNQVhfQVJSQVlfTEVOR1RIID4+PiAxO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBvZiBgYXJyYXlgIHRvIGRldGVybWluZSB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYFxuICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICogIGludG8gYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmluYXJ5SW5kZXgoYXJyYXksIHZhbHVlLCByZXRIaWdoZXN0KSB7XG4gIHZhciBsb3cgPSAwLFxuICAgICAgaGlnaCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogbG93O1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT09IHZhbHVlICYmIGhpZ2ggPD0gSEFMRl9NQVhfQVJSQVlfTEVOR1RIKSB7XG4gICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgIHZhciBtaWQgPSAobG93ICsgaGlnaCkgPj4+IDEsXG4gICAgICAgICAgY29tcHV0ZWQgPSBhcnJheVttaWRdO1xuXG4gICAgICBpZiAoKHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpKSAmJiBjb21wdXRlZCAhPT0gbnVsbCkge1xuICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhpZ2g7XG4gIH1cbiAgcmV0dXJuIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpZGVudGl0eSwgcmV0SGlnaGVzdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluYXJ5SW5kZXg7XG4iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUZsb29yID0gTWF0aC5mbG9vcixcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbnZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICBNQVhfQVJSQVlfSU5ERVggPSBNQVhfQVJSQVlfTEVOR1RIIC0gMTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJpbmFyeUluZGV4YCBleGNlcHQgdGhhdCBpdCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yXG4gKiBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlIHRoZWlyIHNvcnQgcmFua2luZy4gVGhlXG4gKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAodmFsdWUpLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICogIGludG8gYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmluYXJ5SW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlLCByZXRIaWdoZXN0KSB7XG4gIHZhbHVlID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gIHZhciBsb3cgPSAwLFxuICAgICAgaGlnaCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgIHZhbElzTmFOID0gdmFsdWUgIT09IHZhbHVlLFxuICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICB2YWxJc1VuZGVmID0gdmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgIHZhciBtaWQgPSBuYXRpdmVGbG9vcigobG93ICsgaGlnaCkgLyAyKSxcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZShhcnJheVttaWRdKSxcbiAgICAgICAgaXNEZWYgPSBjb21wdXRlZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgICBpc1JlZmxleGl2ZSA9IGNvbXB1dGVkID09PSBjb21wdXRlZDtcblxuICAgIGlmICh2YWxJc05hTikge1xuICAgICAgdmFyIHNldExvdyA9IGlzUmVmbGV4aXZlIHx8IHJldEhpZ2hlc3Q7XG4gICAgfSBlbHNlIGlmICh2YWxJc051bGwpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIGlzRGVmICYmIChyZXRIaWdoZXN0IHx8IGNvbXB1dGVkICE9IG51bGwpO1xuICAgIH0gZWxzZSBpZiAodmFsSXNVbmRlZikge1xuICAgICAgc2V0TG93ID0gaXNSZWZsZXhpdmUgJiYgKHJldEhpZ2hlc3QgfHwgaXNEZWYpO1xuICAgIH0gZWxzZSBpZiAoY29tcHV0ZWQgPT0gbnVsbCkge1xuICAgICAgc2V0TG93ID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldExvdyA9IHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpO1xuICAgIH1cbiAgICBpZiAoc2V0TG93KSB7XG4gICAgICBsb3cgPSBtaWQgKyAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWdoID0gbWlkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmF0aXZlTWluKGhpZ2gsIE1BWF9BUlJBWV9JTkRFWCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluYXJ5SW5kZXhCeTtcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VDYWxsYmFja2Agd2hpY2ggb25seSBzdXBwb3J0cyBgdGhpc2AgYmluZGluZ1xuICogYW5kIHNwZWNpZnlpbmcgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0aGlzQXJnID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZnVuYztcbiAgfVxuICBzd2l0Y2ggKGFyZ0NvdW50KSB7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUpO1xuICAgIH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA1OiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIG90aGVyLCBrZXksIG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiaW5kQ2FsbGJhY2s7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIEFycmF5QnVmZmVyID0gZ2xvYmFsLkFycmF5QnVmZmVyLFxuICAgIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGdpdmVuIGFycmF5IGJ1ZmZlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYnVmZmVyIFRoZSBhcnJheSBidWZmZXIgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7QXJyYXlCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBhcnJheSBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIGJ1ZmZlckNsb25lKGJ1ZmZlcikge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5QnVmZmVyKGJ1ZmZlci5ieXRlTGVuZ3RoKSxcbiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheShyZXN1bHQpO1xuXG4gIHZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlcikpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlckNsb25lO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wySjFabVpsY2tOc2IyNWxMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRWlMQ0ptYVd4bElqb2laMlZ1WlhKaGRHVmtMbXB6SWl3aWMyOTFjbU5sVW05dmRDSTZJaUlzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWk4cUtpQk9ZWFJwZG1VZ2JXVjBhRzlrSUhKbFptVnlaVzVqWlhNdUlDb3ZYRzUyWVhJZ1FYSnlZWGxDZFdabVpYSWdQU0JuYkc5aVlXd3VRWEp5WVhsQ2RXWm1aWElzWEc0Z0lDQWdWV2x1ZERoQmNuSmhlU0E5SUdkc2IySmhiQzVWYVc1ME9FRnljbUY1TzF4dVhHNHZLaXBjYmlBcUlFTnlaV0YwWlhNZ1lTQmpiRzl1WlNCdlppQjBhR1VnWjJsMlpXNGdZWEp5WVhrZ1luVm1abVZ5TGx4dUlDcGNiaUFxSUVCd2NtbDJZWFJsWEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1UW5WbVptVnlmU0JpZFdabVpYSWdWR2hsSUdGeWNtRjVJR0oxWm1abGNpQjBieUJqYkc5dVpTNWNiaUFxSUVCeVpYUjFjbTV6SUh0QmNuSmhlVUoxWm1abGNuMGdVbVYwZFhKdWN5QjBhR1VnWTJ4dmJtVmtJR0Z5Y21GNUlHSjFabVpsY2k1Y2JpQXFMMXh1Wm5WdVkzUnBiMjRnWW5WbVptVnlRMnh2Ym1Vb1luVm1abVZ5S1NCN1hHNGdJSFpoY2lCeVpYTjFiSFFnUFNCdVpYY2dRWEp5WVhsQ2RXWm1aWElvWW5WbVptVnlMbUo1ZEdWTVpXNW5kR2dwTEZ4dUlDQWdJQ0FnZG1sbGR5QTlJRzVsZHlCVmFXNTBPRUZ5Y21GNUtISmxjM1ZzZENrN1hHNWNiaUFnZG1sbGR5NXpaWFFvYm1WM0lGVnBiblE0UVhKeVlYa29ZblZtWm1WeUtTazdYRzRnSUhKbGRIVnliaUJ5WlhOMWJIUTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1luVm1abVZ5UTJ4dmJtVTdYRzRpWFgwPSIsIi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSB0aGF0IGlzIHRoZSBjb21wb3NpdGlvbiBvZiBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMsXG4gKiBwbGFjZWhvbGRlcnMsIGFuZCBwcm92aWRlZCBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICBhcmdzSW5kZXggPSAtMSxcbiAgICAgIGFyZ3NMZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKTtcblxuICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgcmVzdWx0W2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICB9XG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29tcG9zZUFyZ3M7XG4iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgY29tcG9zZUFyZ3NgIGV4Y2VwdCB0aGF0IHRoZSBhcmd1bWVudHMgY29tcG9zaXRpb25cbiAqIGlzIHRhaWxvcmVkIGZvciBgXy5wYXJ0aWFsUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHMsIGhvbGRlcnMpIHtcbiAgdmFyIGhvbGRlcnNJbmRleCA9IC0xLFxuICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICByaWdodExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGFyZ3NMZW5ndGggKyByaWdodExlbmd0aCk7XG5cbiAgd2hpbGUgKCsrYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgIHJlc3VsdFthcmdzSW5kZXhdID0gYXJnc1thcmdzSW5kZXhdO1xuICB9XG4gIHZhciBvZmZzZXQgPSBhcmdzSW5kZXg7XG4gIHdoaWxlICgrK3JpZ2h0SW5kZXggPCByaWdodExlbmd0aCkge1xuICAgIHJlc3VsdFtvZmZzZXQgKyByaWdodEluZGV4XSA9IHBhcnRpYWxzW3JpZ2h0SW5kZXhdO1xuICB9XG4gIHdoaWxlICgrK2hvbGRlcnNJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29tcG9zZUFyZ3NSaWdodDtcbiIsInZhciBnZXRMZW5ndGggPSByZXF1aXJlKCcuL2dldExlbmd0aCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VFYWNoKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24gPyBnZXRMZW5ndGgoY29sbGVjdGlvbikgOiAwO1xuICAgIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsXG4gICAgICAgIGl0ZXJhYmxlID0gdG9PYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VFYWNoO1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBgXy5mb3JJbmAgb3IgYF8uZm9ySW5SaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmFzZUZvcihmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7XG4gICAgdmFyIGl0ZXJhYmxlID0gdG9PYmplY3Qob2JqZWN0KSxcbiAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQmFzZUZvcjtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmluZFdyYXBwZXIoZnVuYywgdGhpc0FyZykge1xuICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmd1bWVudHMpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJpbmRXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLbHh1SUNvZ1EzSmxZWFJsY3lCaElHWjFibU4wYVc5dUlIUm9ZWFFnZDNKaGNITWdZR1oxYm1OZ0lHRnVaQ0JwYm5admEyVnpJR2wwSUhkcGRHZ2dkR2hsSUdCMGFHbHpZRnh1SUNvZ1ltbHVaR2x1WnlCdlppQmdkR2hwYzBGeVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdaMWJtTWdWR2hsSUdaMWJtTjBhVzl1SUhSdklHSnBibVF1WEc0Z0tpQkFjR0Z5WVcwZ2V5cDlJRnQwYUdselFYSm5YU0JVYUdVZ1lIUm9hWE5nSUdKcGJtUnBibWNnYjJZZ1lHWjFibU5nTGx4dUlDb2dRSEpsZEhWeWJuTWdlMFoxYm1OMGFXOXVmU0JTWlhSMWNtNXpJSFJvWlNCdVpYY2dZbTkxYm1RZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVUpwYm1SWGNtRndjR1Z5S0daMWJtTXNJSFJvYVhOQmNtY3BJSHRjYmlBZ2RtRnlJRU4wYjNJZ1BTQmpjbVZoZEdWRGRHOXlWM0poY0hCbGNpaG1kVzVqS1R0Y2JseHVJQ0JtZFc1amRHbHZiaUIzY21Gd2NHVnlLQ2tnZTF4dUlDQWdJSFpoY2lCbWJpQTlJQ2gwYUdseklDWW1JSFJvYVhNZ0lUMDlJR2RzYjJKaGJDQW1KaUIwYUdseklHbHVjM1JoYm1ObGIyWWdkM0poY0hCbGNpa2dQeUJEZEc5eUlEb2dablZ1WXp0Y2JpQWdJQ0J5WlhSMWNtNGdabTR1WVhCd2JIa29kR2hwYzBGeVp5d2dZWEpuZFcxbGJuUnpLVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdkM0poY0hCbGNqdGNibjFjYmx4dWJXOWtkV3hsTG1WNGNHOXlkSE1nUFNCamNtVmhkR1ZDYVc1a1YzSmhjSEJsY2p0Y2JpSmRmUT09IiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBpbnN0YW5jZSBvZiBgQ3RvcmAgcmVnYXJkbGVzcyBvZlxuICogd2hldGhlciBpdCB3YXMgaW52b2tlZCBhcyBwYXJ0IG9mIGEgYG5ld2AgZXhwcmVzc2lvbiBvciBieSBgY2FsbGAgb3IgYGFwcGx5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gQ3RvciBUaGUgY29uc3RydWN0b3IgdG8gd3JhcC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUN0b3JXcmFwcGVyKEN0b3IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLlxuICAgIC8vIFNlZSBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEN0b3I7XG4gICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgY2FzZSA2OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7XG4gICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gYmFzZUNyZWF0ZShDdG9yLnByb3RvdHlwZSksXG4gICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgLy8gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDEzLjIuMiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQ3RvcldyYXBwZXI7XG4iLCJ2YXIgYmFzZUNhbGxiYWNrID0gcmVxdWlyZSgnLi9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlRmluZCA9IHJlcXVpcmUoJy4vYmFzZUZpbmQnKSxcbiAgICBiYXNlRmluZEluZGV4ID0gcmVxdWlyZSgnLi9iYXNlRmluZEluZGV4JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgXy5maW5kYCBvciBgXy5maW5kTGFzdGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGaW5kKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgIHByZWRpY2F0ZSA9IGJhc2VDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgIGlmIChpc0FycmF5KGNvbGxlY3Rpb24pKSB7XG4gICAgICB2YXIgaW5kZXggPSBiYXNlRmluZEluZGV4KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbVJpZ2h0KTtcbiAgICAgIHJldHVybiBpbmRleCA+IC0xID8gY29sbGVjdGlvbltpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBiYXNlRmluZChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGVhY2hGdW5jKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGaW5kO1xuIiwidmFyIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBmb3IgYF8uZm9yRWFjaGAgb3IgYF8uZm9yRWFjaFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYW4gYXJyYXkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGVhY2ggZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZvckVhY2goYXJyYXlGdW5jLCBlYWNoRnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIHRoaXNBcmcgPT09IHVuZGVmaW5lZCAmJiBpc0FycmF5KGNvbGxlY3Rpb24pKVxuICAgICAgPyBhcnJheUZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpXG4gICAgICA6IGVhY2hGdW5jKGNvbGxlY3Rpb24sIGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZvckVhY2g7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyksXG4gICAgaXNMYXppYWJsZSA9IHJlcXVpcmUoJy4vaXNMYXppYWJsZScpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL3Jlb3JkZXInKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vcmVwbGFjZUhvbGRlcnMnKSxcbiAgICBzZXREYXRhID0gcmVxdWlyZSgnLi9zZXREYXRhJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBCSU5EX0tFWV9GTEFHID0gMixcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBDVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgQVJZX0ZMQUcgPSAxMjg7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc1JpZ2h0XSBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBBUllfRkxBRyxcbiAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgIGlzQ3VycnkgPSBiaXRtYXNrICYgQ1VSUllfRkxBRyxcbiAgICAgIGlzQ3VycnlCb3VuZCA9IGJpdG1hc2sgJiBDVVJSWV9CT1VORF9GTEFHLFxuICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCB0byBvdGhlciBmdW5jdGlvbnMuXG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzUmlnaHQpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgfVxuICAgIGlmIChpc0N1cnJ5IHx8IGlzQ3VycnlSaWdodCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICBhcmdzSG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgICAgbGVuZ3RoIC09IGFyZ3NIb2xkZXJzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICB2YXIgbmV3QXJnUG9zID0gYXJnUG9zID8gYXJyYXlDb3B5KGFyZ1BvcykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzSG9sZGVycyxcbiAgICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IGFyZ3MgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFBBUlRJQUxfRkxBRyA6IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gUEFSVElBTF9SSUdIVF9GTEFHIDogUEFSVElBTF9GTEFHKTtcblxuICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgIGJpdG1hc2sgJj0gfihCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcblxuICAgICAgICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgIGZuID0gaXNCaW5kS2V5ID8gdGhpc0JpbmRpbmdbZnVuY10gOiBmdW5jO1xuXG4gICAgaWYgKGFyZ1Bvcykge1xuICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICB9XG4gICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlSHlicmlkV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1lYSnlZWGxEYjNCNUlEMGdjbVZ4ZFdseVpTZ25MaTloY25KaGVVTnZjSGtuS1N4Y2JpQWdJQ0JqYjIxd2IzTmxRWEpuY3lBOUlISmxjWFZwY21Vb0p5NHZZMjl0Y0c5elpVRnlaM01uS1N4Y2JpQWdJQ0JqYjIxd2IzTmxRWEpuYzFKcFoyaDBJRDBnY21WeGRXbHlaU2duTGk5amIyMXdiM05sUVhKbmMxSnBaMmgwSnlrc1hHNGdJQ0FnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElnUFNCeVpYRjFhWEpsS0NjdUwyTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUp5a3NYRzRnSUNBZ2FYTk1ZWHBwWVdKc1pTQTlJSEpsY1hWcGNtVW9KeTR2YVhOTVlYcHBZV0pzWlNjcExGeHVJQ0FnSUhKbGIzSmtaWElnUFNCeVpYRjFhWEpsS0NjdUwzSmxiM0prWlhJbktTeGNiaUFnSUNCeVpYQnNZV05sU0c5c1pHVnljeUE5SUhKbGNYVnBjbVVvSnk0dmNtVndiR0ZqWlVodmJHUmxjbk1uS1N4Y2JpQWdJQ0J6WlhSRVlYUmhJRDBnY21WeGRXbHlaU2duTGk5elpYUkVZWFJoSnlrN1hHNWNiaThxS2lCVmMyVmtJSFJ2SUdOdmJYQnZjMlVnWW1sMGJXRnphM01nWm05eUlIZHlZWEJ3WlhJZ2JXVjBZV1JoZEdFdUlDb3ZYRzUyWVhJZ1FrbE9SRjlHVEVGSElEMGdNU3hjYmlBZ0lDQkNTVTVFWDB0RldWOUdURUZISUQwZ01peGNiaUFnSUNCRFZWSlNXVjlDVDFWT1JGOUdURUZISUQwZ05DeGNiaUFnSUNCRFZWSlNXVjlHVEVGSElEMGdPQ3hjYmlBZ0lDQkRWVkpTV1Y5U1NVZElWRjlHVEVGSElEMGdNVFlzWEc0Z0lDQWdVRUZTVkVsQlRGOUdURUZISUQwZ016SXNYRzRnSUNBZ1VFRlNWRWxCVEY5U1NVZElWRjlHVEVGSElEMGdOalFzWEc0Z0lDQWdRVkpaWDBaTVFVY2dQU0F4TWpnN1hHNWNiaThxSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeUJtYjNJZ2RHaHZjMlVnZDJsMGFDQjBhR1VnYzJGdFpTQnVZVzFsSUdGeklHOTBhR1Z5SUdCc2IyUmhjMmhnSUcxbGRHaHZaSE11SUNvdlhHNTJZWElnYm1GMGFYWmxUV0Y0SUQwZ1RXRjBhQzV0WVhnN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnYjNCMGFXOXVZV3dnWUhSb2FYTmdYRzRnS2lCaWFXNWthVzVuSUc5bUxDQndZWEowYVdGc0lHRndjR3hwWTJGMGFXOXVMQ0JoYm1RZ1kzVnljbmxwYm1jdVhHNGdLbHh1SUNvZ1FIQnlhWFpoZEdWY2JpQXFJRUJ3WVhKaGJTQjdSblZ1WTNScGIyNThjM1J5YVc1bmZTQm1kVzVqSUZSb1pTQm1kVzVqZEdsdmJpQnZjaUJ0WlhSb2IyUWdibUZ0WlNCMGJ5QnlaV1psY21WdVkyVXVYRzRnS2lCQWNHRnlZVzBnZTI1MWJXSmxjbjBnWW1sMGJXRnpheUJVYUdVZ1ltbDBiV0Z6YXlCdlppQm1iR0ZuY3k0Z1UyVmxJR0JqY21WaGRHVlhjbUZ3Y0dWeVlDQm1iM0lnYlc5eVpTQmtaWFJoYVd4ekxseHVJQ29nUUhCaGNtRnRJSHNxZlNCYmRHaHBjMEZ5WjEwZ1ZHaGxJR0IwYUdsellDQmlhVzVrYVc1bklHOW1JR0JtZFc1allDNWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMTBnVkdobElHRnlaM1Z0Wlc1MGN5QjBieUJ3Y21Wd1pXNWtJSFJ2SUhSb2IzTmxJSEJ5YjNacFpHVmtJSFJ2SUhSb1pTQnVaWGNnWm5WdVkzUnBiMjR1WEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1ZlNCYmFHOXNaR1Z5YzEwZ1ZHaGxJR0J3WVhKMGFXRnNjMkFnY0d4aFkyVm9iMnhrWlhJZ2FXNWtaWGhsY3k1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlGdHdZWEowYVdGc2MxSnBaMmgwWFNCVWFHVWdZWEpuZFcxbGJuUnpJSFJ2SUdGd2NHVnVaQ0IwYnlCMGFHOXpaU0J3Y205MmFXUmxaQ0IwYnlCMGFHVWdibVYzSUdaMWJtTjBhVzl1TGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVgwZ1cyaHZiR1JsY25OU2FXZG9kRjBnVkdobElHQndZWEowYVdGc2MxSnBaMmgwWUNCd2JHRmpaV2h2YkdSbGNpQnBibVJsZUdWekxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMkZ5WjFCdmMxMGdWR2hsSUdGeVozVnRaVzUwSUhCdmMybDBhVzl1Y3lCdlppQjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY25sZElGUm9aU0JoY21sMGVTQmpZWEFnYjJZZ1lHWjFibU5nTGx4dUlDb2dRSEJoY21GdElIdHVkVzFpWlhKOUlGdGhjbWwwZVYwZ1ZHaGxJR0Z5YVhSNUlHOW1JR0JtZFc1allDNWNiaUFxSUVCeVpYUjFjbTV6SUh0R2RXNWpkR2x2Ym4wZ1VtVjBkWEp1Y3lCMGFHVWdibVYzSUhkeVlYQndaV1FnWm5WdVkzUnBiMjR1WEc0Z0tpOWNibVoxYm1OMGFXOXVJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWElvWm5WdVl5d2dZbWwwYldGemF5d2dkR2hwYzBGeVp5d2djR0Z5ZEdsaGJITXNJR2h2YkdSbGNuTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ3dnWVhKblVHOXpMQ0JoY25rc0lHRnlhWFI1S1NCN1hHNGdJSFpoY2lCcGMwRnllU0E5SUdKcGRHMWhjMnNnSmlCQlVsbGZSa3hCUnl4Y2JpQWdJQ0FnSUdselFtbHVaQ0E5SUdKcGRHMWhjMnNnSmlCQ1NVNUVYMFpNUVVjc1hHNGdJQ0FnSUNCcGMwSnBibVJMWlhrZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5TFJWbGZSa3hCUnl4Y2JpQWdJQ0FnSUdselEzVnljbmtnUFNCaWFYUnRZWE5ySUNZZ1ExVlNVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25sQ2IzVnVaQ0E5SUdKcGRHMWhjMnNnSmlCRFZWSlNXVjlDVDFWT1JGOUdURUZITEZ4dUlDQWdJQ0FnYVhORGRYSnllVkpwWjJoMElEMGdZbWwwYldGemF5QW1JRU5WVWxKWlgxSkpSMGhVWDBaTVFVY3NYRzRnSUNBZ0lDQkRkRzl5SUQwZ2FYTkNhVzVrUzJWNUlEOGdkVzVrWldacGJtVmtJRG9nWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzVjYmlBZ1puVnVZM1JwYjI0Z2QzSmhjSEJsY2lncElIdGNiaUFnSUNBdkx5QkJkbTlwWkNCZ1lYSm5kVzFsYm5SellDQnZZbXBsWTNRZ2RYTmxJR1JwYzNGMVlXeHBabmxwYm1jZ2IzQjBhVzFwZW1GMGFXOXVjeUJpZVZ4dUlDQWdJQzh2SUdOdmJuWmxjblJwYm1jZ2FYUWdkRzhnWVc0Z1lYSnlZWGtnWW1WbWIzSmxJSEJ5YjNacFpHbHVaeUJwZENCMGJ5QnZkR2hsY2lCbWRXNWpkR2x2Ym5NdVhHNGdJQ0FnZG1GeUlHeGxibWQwYUNBOUlHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnc1hHNGdJQ0FnSUNBZ0lHbHVaR1Y0SUQwZ2JHVnVaM1JvTEZ4dUlDQWdJQ0FnSUNCaGNtZHpJRDBnUVhKeVlYa29iR1Z1WjNSb0tUdGNibHh1SUNBZ0lIZG9hV3hsSUNocGJtUmxlQzB0S1NCN1hHNGdJQ0FnSUNCaGNtZHpXMmx1WkdWNFhTQTlJR0Z5WjNWdFpXNTBjMXRwYm1SbGVGMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHdZWEowYVdGc2N5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlHTnZiWEJ2YzJWQmNtZHpLR0Z5WjNNc0lIQmhjblJwWVd4ekxDQm9iMnhrWlhKektUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIQmhjblJwWVd4elVtbG5hSFFwSUh0Y2JpQWdJQ0FnSUdGeVozTWdQU0JqYjIxd2IzTmxRWEpuYzFKcFoyaDBLR0Z5WjNNc0lIQmhjblJwWVd4elVtbG5hSFFzSUdodmJHUmxjbk5TYVdkb2RDazdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBjME4xY25KNUlIeDhJR2x6UTNWeWNubFNhV2RvZENrZ2UxeHVJQ0FnSUNBZ2RtRnlJSEJzWVdObGFHOXNaR1Z5SUQwZ2QzSmhjSEJsY2k1d2JHRmpaV2h2YkdSbGNpeGNiaUFnSUNBZ0lDQWdJQ0JoY21kelNHOXNaR1Z5Y3lBOUlISmxjR3hoWTJWSWIyeGtaWEp6S0dGeVozTXNJSEJzWVdObGFHOXNaR1Z5S1R0Y2JseHVJQ0FnSUNBZ2JHVnVaM1JvSUMwOUlHRnlaM05JYjJ4a1pYSnpMbXhsYm1kMGFEdGNiaUFnSUNBZ0lHbG1JQ2hzWlc1bmRHZ2dQQ0JoY21sMGVTa2dlMXh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVjNRWEpuVUc5eklEMGdZWEpuVUc5eklEOGdZWEp5WVhsRGIzQjVLR0Z5WjFCdmN5a2dPaUIxYm1SbFptbHVaV1FzWEc0Z0lDQWdJQ0FnSUNBZ0lDQnVaWGRCY21sMGVTQTlJRzVoZEdsMlpVMWhlQ2hoY21sMGVTQXRJR3hsYm1kMGFDd2dNQ2tzWEc0Z0lDQWdJQ0FnSUNBZ0lDQnVaWGR6U0c5c1pHVnljeUE5SUdselEzVnljbmtnUHlCaGNtZHpTRzlzWkdWeWN5QTZJSFZ1WkdWbWFXNWxaQ3hjYmlBZ0lDQWdJQ0FnSUNBZ0lHNWxkMGh2YkdSbGNuTlNhV2RvZENBOUlHbHpRM1Z5Y25rZ1B5QjFibVJsWm1sdVpXUWdPaUJoY21kelNHOXNaR1Z5Y3l4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCaGNuUnBZV3h6SUQwZ2FYTkRkWEp5ZVNBL0lHRnlaM01nT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkUVlYSjBhV0ZzYzFKcFoyaDBJRDBnYVhORGRYSnllU0EvSUhWdVpHVm1hVzVsWkNBNklHRnlaM003WEc1Y2JpQWdJQ0FnSUNBZ1ltbDBiV0Z6YXlCOFBTQW9hWE5EZFhKeWVTQS9JRkJCVWxSSlFVeGZSa3hCUnlBNklGQkJVbFJKUVV4ZlVrbEhTRlJmUmt4QlJ5azdYRzRnSUNBZ0lDQWdJR0pwZEcxaGMyc2dKajBnZmlocGMwTjFjbko1SUQ4Z1VFRlNWRWxCVEY5U1NVZElWRjlHVEVGSElEb2dVRUZTVkVsQlRGOUdURUZIS1R0Y2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVdselEzVnljbmxDYjNWdVpDa2dlMXh1SUNBZ0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaENTVTVFWDBaTVFVY2dmQ0JDU1U1RVgwdEZXVjlHVEVGSEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVjNSR0YwWVNBOUlGdG1kVzVqTENCaWFYUnRZWE5yTENCMGFHbHpRWEpuTENCdVpYZFFZWEowYVdGc2N5d2dibVYzYzBodmJHUmxjbk1zSUc1bGQxQmhjblJwWVd4elVtbG5hSFFzSUc1bGQwaHZiR1JsY25OU2FXZG9kQ3dnYm1WM1FYSm5VRzl6TENCaGNua3NJRzVsZDBGeWFYUjVYU3hjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHTnlaV0YwWlVoNVluSnBaRmR5WVhCd1pYSXVZWEJ3Ykhrb2RXNWtaV1pwYm1Wa0xDQnVaWGRFWVhSaEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb2FYTk1ZWHBwWVdKc1pTaG1kVzVqS1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJSE5sZEVSaGRHRW9jbVZ6ZFd4MExDQnVaWGRFWVhSaEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J5WlhOMWJIUXVjR3hoWTJWb2IyeGtaWElnUFNCd2JHRmpaV2h2YkdSbGNqdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlISmxjM1ZzZER0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdkbUZ5SUhSb2FYTkNhVzVrYVc1bklEMGdhWE5DYVc1a0lEOGdkR2hwYzBGeVp5QTZJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lHWnVJRDBnYVhOQ2FXNWtTMlY1SUQ4Z2RHaHBjMEpwYm1ScGJtZGJablZ1WTEwZ09pQm1kVzVqTzF4dVhHNGdJQ0FnYVdZZ0tHRnlaMUJ2Y3lrZ2UxeHVJQ0FnSUNBZ1lYSm5jeUE5SUhKbGIzSmtaWElvWVhKbmN5d2dZWEpuVUc5ektUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tHbHpRWEo1SUNZbUlHRnllU0E4SUdGeVozTXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQmhjbWR6TG14bGJtZDBhQ0E5SUdGeWVUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIUm9hWE1nSmlZZ2RHaHBjeUFoUFQwZ1oyeHZZbUZzSUNZbUlIUm9hWE1nYVc1emRHRnVZMlZ2WmlCM2NtRndjR1Z5S1NCN1hHNGdJQ0FnSUNCbWJpQTlJRU4wYjNJZ2ZId2dZM0psWVhSbFEzUnZjbGR5WVhCd1pYSW9ablZ1WXlrN1hHNGdJQ0FnZlZ4dUlDQWdJSEpsZEhWeWJpQm1iaTVoY0hCc2VTaDBhR2x6UW1sdVpHbHVaeXdnWVhKbmN5azdYRzRnSUgxY2JpQWdjbVYwZFhKdUlIZHlZWEJ3WlhJN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnWTNKbFlYUmxTSGxpY21sa1YzSmhjSEJsY2p0Y2JpSmRmUT09IiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDE7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AgYW5kIHRoZSBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aG9zZSBwcm92aWRlZCB0b1xuICogdGhlIHdyYXBwZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseSBhcmd1bWVudHMgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVQYXJ0aWFsV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgaXNCaW5kID0gYml0bWFzayAmIEJJTkRfRkxBRyxcbiAgICAgIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIC8vIEF2b2lkIGBhcmd1bWVudHNgIG9iamVjdCB1c2UgZGlzcXVhbGlmeWluZyBvcHRpbWl6YXRpb25zIGJ5XG4gICAgLy8gY29udmVydGluZyBpdCB0byBhbiBhcnJheSBiZWZvcmUgcHJvdmlkaW5nIGl0IGBmdW5jYC5cbiAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKTtcblxuICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgfVxuICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICB9XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUGFydGlhbFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVkJoY25ScFlXeFhjbUZ3Y0dWeUxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElnUFNCeVpYRjFhWEpsS0NjdUwyTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVR0Y2JseHVMeW9xWEc0Z0tpQkRjbVZoZEdWeklHRWdablZ1WTNScGIyNGdkR2hoZENCM2NtRndjeUJnWm5WdVkyQWdZVzVrSUdsdWRtOXJaWE1nYVhRZ2QybDBhQ0IwYUdVZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1JR0IwYUdselFYSm5ZQ0JoYm1RZ2RHaGxJR0J3WVhKMGFXRnNjMkFnY0hKbGNHVnVaR1ZrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdlhHNGdLaUIwYUdVZ2QzSmhjSEJsY2k1Y2JpQXFYRzRnS2lCQWNISnBkbUYwWlZ4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdablZ1WXlCVWFHVWdablZ1WTNScGIyNGdkRzhnY0dGeWRHbGhiR3g1SUdGd2NHeDVJR0Z5WjNWdFpXNTBjeUIwYnk1Y2JpQXFJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQmlhWFJ0WVhOcklGUm9aU0JpYVhSdFlYTnJJRzltSUdac1lXZHpMaUJUWldVZ1lHTnlaV0YwWlZkeVlYQndaWEpnSUdadmNpQnRiM0psSUdSbGRHRnBiSE11WEc0Z0tpQkFjR0Z5WVcwZ2V5cDlJSFJvYVhOQmNtY2dWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUhCaGNuUnBZV3h6SUZSb1pTQmhjbWQxYldWdWRITWdkRzhnY0hKbGNHVnVaQ0IwYnlCMGFHOXpaU0J3Y205MmFXUmxaQ0IwYnlCMGFHVWdibVYzSUdaMWJtTjBhVzl1TGx4dUlDb2dRSEpsZEhWeWJuTWdlMFoxYm1OMGFXOXVmU0JTWlhSMWNtNXpJSFJvWlNCdVpYY2dZbTkxYm1RZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVkJoY25ScFlXeFhjbUZ3Y0dWeUtHWjFibU1zSUdKcGRHMWhjMnNzSUhSb2FYTkJjbWNzSUhCaGNuUnBZV3h6S1NCN1hHNGdJSFpoY2lCcGMwSnBibVFnUFNCaWFYUnRZWE5ySUNZZ1FrbE9SRjlHVEVGSExGeHVJQ0FnSUNBZ1EzUnZjaUE5SUdOeVpXRjBaVU4wYjNKWGNtRndjR1Z5S0daMWJtTXBPMXh1WEc0Z0lHWjFibU4wYVc5dUlIZHlZWEJ3WlhJb0tTQjdYRzRnSUNBZ0x5OGdRWFp2YVdRZ1lHRnlaM1Z0Wlc1MGMyQWdiMkpxWldOMElIVnpaU0JrYVhOeGRXRnNhV1o1YVc1bklHOXdkR2x0YVhwaGRHbHZibk1nWW5sY2JpQWdJQ0F2THlCamIyNTJaWEowYVc1bklHbDBJSFJ2SUdGdUlHRnljbUY1SUdKbFptOXlaU0J3Y205MmFXUnBibWNnYVhRZ1lHWjFibU5nTGx4dUlDQWdJSFpoY2lCaGNtZHpTVzVrWlhnZ1BTQXRNU3hjYmlBZ0lDQWdJQ0FnWVhKbmMweGxibWQwYUNBOUlHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnc1hHNGdJQ0FnSUNBZ0lHeGxablJKYm1SbGVDQTlJQzB4TEZ4dUlDQWdJQ0FnSUNCc1pXWjBUR1Z1WjNSb0lEMGdjR0Z5ZEdsaGJITXViR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWbWRFeGxibWQwYUNBcklHRnlaM05NWlc1bmRHZ3BPMXh1WEc0Z0lDQWdkMmhwYkdVZ0tDc3JiR1ZtZEVsdVpHVjRJRHdnYkdWbWRFeGxibWQwYUNrZ2UxeHVJQ0FnSUNBZ1lYSm5jMXRzWldaMFNXNWtaWGhkSUQwZ2NHRnlkR2xoYkhOYmJHVm1kRWx1WkdWNFhUdGNiaUFnSUNCOVhHNGdJQ0FnZDJocGJHVWdLR0Z5WjNOTVpXNW5kR2d0TFNrZ2UxeHVJQ0FnSUNBZ1lYSm5jMXRzWldaMFNXNWtaWGdySzEwZ1BTQmhjbWQxYldWdWRITmJLeXRoY21kelNXNWtaWGhkTzF4dUlDQWdJSDFjYmlBZ0lDQjJZWElnWm00Z1BTQW9kR2hwY3lBbUppQjBhR2x6SUNFOVBTQm5iRzlpWVd3Z0ppWWdkR2hwY3lCcGJuTjBZVzVqWlc5bUlIZHlZWEJ3WlhJcElEOGdRM1J2Y2lBNklHWjFibU03WEc0Z0lDQWdjbVYwZFhKdUlHWnVMbUZ3Y0d4NUtHbHpRbWx1WkNBL0lIUm9hWE5CY21jZ09pQjBhR2x6TENCaGNtZHpLVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdkM0poY0hCbGNqdGNibjFjYmx4dWJXOWtkV3hsTG1WNGNHOXlkSE1nUFNCamNtVmhkR1ZRWVhKMGFXRnNWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlU2V0RGF0YSA9IHJlcXVpcmUoJy4vYmFzZVNldERhdGEnKSxcbiAgICBjcmVhdGVCaW5kV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQmluZFdyYXBwZXInKSxcbiAgICBjcmVhdGVIeWJyaWRXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVIeWJyaWRXcmFwcGVyJyksXG4gICAgY3JlYXRlUGFydGlhbFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZVBhcnRpYWxXcmFwcGVyJyksXG4gICAgZ2V0RGF0YSA9IHJlcXVpcmUoJy4vZ2V0RGF0YScpLFxuICAgIG1lcmdlRGF0YSA9IHJlcXVpcmUoJy4vbWVyZ2VEYXRhJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQ7XG5cbi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy5cbiAqICBUaGUgYml0bWFzayBtYXkgYmUgY29tcG9zZWQgb2YgdGhlIGZvbGxvd2luZyBmbGFnczpcbiAqICAgICAxIC0gYF8uYmluZGBcbiAqICAgICAyIC0gYF8uYmluZEtleWBcbiAqICAgICA0IC0gYF8uY3VycnlgIG9yIGBfLmN1cnJ5UmlnaHRgIG9mIGEgYm91bmQgZnVuY3Rpb25cbiAqICAgICA4IC0gYF8uY3VycnlgXG4gKiAgICAxNiAtIGBfLmN1cnJ5UmlnaHRgXG4gKiAgICAzMiAtIGBfLnBhcnRpYWxgXG4gKiAgICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAqICAgMTI4IC0gYF8ucmVhcmdgXG4gKiAgIDI1NiAtIGBfLmFyeWBcbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBCSU5EX0tFWV9GTEFHO1xuICBpZiAoIWlzQmluZEtleSAmJiB0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHZhciBsZW5ndGggPSBwYXJ0aWFscyA/IHBhcnRpYWxzLmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgYml0bWFzayAmPSB+KFBBUlRJQUxfRkxBRyB8IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICB9XG4gIGxlbmd0aCAtPSAoaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMCk7XG4gIGlmIChiaXRtYXNrICYgUEFSVElBTF9SSUdIVF9GTEFHKSB7XG4gICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyksXG4gICAgICBuZXdEYXRhID0gW2Z1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eV07XG5cbiAgaWYgKGRhdGEpIHtcbiAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gICAgYXJpdHkgPSBuZXdEYXRhWzldO1xuICB9XG4gIG5ld0RhdGFbOV0gPSBhcml0eSA9PSBudWxsXG4gICAgPyAoaXNCaW5kS2V5ID8gMCA6IGZ1bmMubGVuZ3RoKVxuICAgIDogKG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCkgfHwgMCk7XG5cbiAgaWYgKGJpdG1hc2sgPT0gQklORF9GTEFHKSB7XG4gICAgdmFyIHJlc3VsdCA9IGNyZWF0ZUJpbmRXcmFwcGVyKG5ld0RhdGFbMF0sIG5ld0RhdGFbMl0pO1xuICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFBBUlRJQUxfRkxBRyB8fCBiaXRtYXNrID09IChCSU5EX0ZMQUcgfCBQQVJUSUFMX0ZMQUcpKSAmJiAhbmV3RGF0YVs0XS5sZW5ndGgpIHtcbiAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlci5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfVxuICB2YXIgc2V0dGVyID0gZGF0YSA/IGJhc2VTZXREYXRhIDogc2V0RGF0YTtcbiAgcmV0dXJuIHNldHRlcihyZXN1bHQsIG5ld0RhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVdyYXBwZXI7XG4iLCJ2YXIgYXJyYXlTb21lID0gcmVxdWlyZSgnLi9hcnJheVNvbWUnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtBcnJheX0gb3RoZXIgVGhlIG90aGVyIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgYXJyYXlzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gIGlmIChhcnJMZW5ndGggIT0gb3RoTGVuZ3RoICYmICEoaXNMb29zZSAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBhcnJWYWx1ZSwgaXNMb29zZSA/IGFyclZhbHVlIDogb3RoVmFsdWUsIGluZGV4KSA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoaXNMb29zZSkge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICAgICAgICB9KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghKGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwiLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnKSB7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgIC8vIENvZXJjZSBkYXRlcyBhbmQgYm9vbGVhbnMgdG8gbnVtYmVycywgZGF0ZXMgdG8gbWlsbGlzZWNvbmRzIGFuZCBib29sZWFuc1xuICAgICAgLy8gdG8gYDFgIG9yIGAwYCB0cmVhdGluZyBpbnZhbGlkIGRhdGVzIGNvZXJjZWQgdG8gYE5hTmAgYXMgbm90IGVxdWFsLlxuICAgICAgcmV0dXJuICtvYmplY3QgPT0gK290aGVyO1xuXG4gICAgY2FzZSBlcnJvclRhZzpcbiAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIFRyZWF0IGBOYU5gIHZzLiBgTmFOYCBhcyBlcXVhbC5cbiAgICAgIHJldHVybiAob2JqZWN0ICE9ICtvYmplY3QpXG4gICAgICAgID8gb3RoZXIgIT0gK290aGVyXG4gICAgICAgIDogb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncyBwcmltaXRpdmVzIGFuZCBzdHJpbmdcbiAgICAgIC8vIG9iamVjdHMgYXMgZXF1YWwuIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS4xMC42LjQgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIHJldHVybiBvYmplY3QgPT0gKG90aGVyICsgJycpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBvYmpQcm9wcyA9IGtleXMob2JqZWN0KSxcbiAgICAgIG9iakxlbmd0aCA9IG9ialByb3BzLmxlbmd0aCxcbiAgICAgIG90aFByb3BzID0ga2V5cyhvdGhlciksXG4gICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgaWYgKG9iakxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIWlzTG9vc2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgaWYgKCEoaXNMb29zZSA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHZhciBza2lwQ3RvciA9IGlzTG9vc2U7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV0sXG4gICAgICAgIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKGlzTG9vc2UgPyBvdGhWYWx1ZSA6IG9ialZhbHVlLCBpc0xvb3NlPyBvYmpWYWx1ZSA6IG90aFZhbHVlLCBrZXkpIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBlcXVhbEZ1bmMob2JqVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikgOiByZXN1bHQpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAoIXNraXBDdG9yKSB7XG4gICAgdmFyIG9iakN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgIG90aEN0b3IgPSBvdGhlci5jb25zdHJ1Y3RvcjtcblxuICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLlxuICAgIGlmIChvYmpDdG9yICE9IG90aEN0b3IgJiZcbiAgICAgICAgKCdjb25zdHJ1Y3RvcicgaW4gb2JqZWN0ICYmICdjb25zdHJ1Y3RvcicgaW4gb3RoZXIpICYmXG4gICAgICAgICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJlxuICAgICAgICAgIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsInZhciBtZXRhTWFwID0gcmVxdWlyZSgnLi9tZXRhTWFwJyksXG4gICAgbm9vcCA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvbm9vcCcpO1xuXG4vKipcbiAqIEdldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAqL1xudmFyIGdldERhdGEgPSAhbWV0YU1hcCA/IG5vb3AgOiBmdW5jdGlvbihmdW5jKSB7XG4gIHJldHVybiBtZXRhTWFwLmdldChmdW5jKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RGF0YTtcbiIsInZhciByZWFsTmFtZXMgPSByZXF1aXJlKCcuL3JlYWxOYW1lcycpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hbWUgb2YgYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGdldEZ1bmNOYW1lKGZ1bmMpIHtcbiAgdmFyIHJlc3VsdCA9IChmdW5jLm5hbWUgKyAnJyksXG4gICAgICBhcnJheSA9IHJlYWxOYW1lc1tyZXN1bHRdLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBkYXRhID0gYXJyYXlbbGVuZ3RoXSxcbiAgICAgICAgb3RoZXJGdW5jID0gZGF0YS5mdW5jO1xuICAgIGlmIChvdGhlckZ1bmMgPT0gbnVsbCB8fCBvdGhlckZ1bmMgPT0gZnVuYykge1xuICAgICAgcmV0dXJuIGRhdGEubmFtZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRGdW5jTmFtZTtcbiIsInZhciBiYXNlUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VQcm9wZXJ0eScpO1xuXG4vKipcbiAqIEdldHMgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgdmFsdWUgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBhdm9pZCBhIFtKSVQgYnVnXShodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQyNzkyKVxuICogdGhhdCBhZmZlY3RzIFNhZmFyaSBvbiBhdCBsZWFzdCBpT1MgOC4xLTguMyBBUk02NC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIFwibGVuZ3RoXCIgdmFsdWUuXG4gKi9cbnZhciBnZXRMZW5ndGggPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldExlbmd0aDtcbiIsInZhciBpc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL2lzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIHBhaXJzID0gcmVxdWlyZSgnLi4vb2JqZWN0L3BhaXJzJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgcHJvcGVyeSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBnZXRNYXRjaERhdGEob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBwYWlycyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICByZXN1bHRbbGVuZ3RoXVsyXSA9IGlzU3RyaWN0Q29tcGFyYWJsZShyZXN1bHRbbGVuZ3RoXVsxXSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXRjaERhdGE7XG4iLCJ2YXIgaXNOYXRpdmUgPSByZXF1aXJlKCcuLi9sYW5nL2lzTmF0aXZlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkge1xuICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICByZXR1cm4gaXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TmF0aXZlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgTmFOYCBpcyBmb3VuZCBpbiBgYXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIGBOYU5gLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAwIDogLTEpO1xuXG4gIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgdmFyIG90aGVyID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChvdGhlciAhPT0gb3RoZXIpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2ZOYU47XG4iLCIvKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gIC8vIEFkZCBhcnJheSBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVBcnJheTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBidWZmZXJDbG9uZSA9IHJlcXVpcmUoJy4vYnVmZmVyQ2xvbmUnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgZmxhZ3MgZnJvbSB0aGVpciBjb2VyY2VkIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVGbGFncyA9IC9cXHcqJC87XG5cbi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuXG4vKiogVXNlZCB0byBsb29rdXAgYSB0eXBlIGFycmF5IGNvbnN0cnVjdG9ycyBieSBgdG9TdHJpbmdUYWdgLiAqL1xudmFyIGN0b3JCeVRhZyA9IHt9O1xuY3RvckJ5VGFnW2Zsb2F0MzJUYWddID0gZ2xvYmFsLkZsb2F0MzJBcnJheTtcbmN0b3JCeVRhZ1tmbG9hdDY0VGFnXSA9IGdsb2JhbC5GbG9hdDY0QXJyYXk7XG5jdG9yQnlUYWdbaW50OFRhZ10gPSBnbG9iYWwuSW50OEFycmF5O1xuY3RvckJ5VGFnW2ludDE2VGFnXSA9IGdsb2JhbC5JbnQxNkFycmF5O1xuY3RvckJ5VGFnW2ludDMyVGFnXSA9IGdsb2JhbC5JbnQzMkFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4VGFnXSA9IFVpbnQ4QXJyYXk7XG5jdG9yQnlUYWdbdWludDhDbGFtcGVkVGFnXSA9IGdsb2JhbC5VaW50OENsYW1wZWRBcnJheTtcbmN0b3JCeVRhZ1t1aW50MTZUYWddID0gZ2xvYmFsLlVpbnQxNkFycmF5O1xuY3RvckJ5VGFnW3VpbnQzMlRhZ10gPSBnbG9iYWwuVWludDMyQXJyYXk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICovXG5mdW5jdGlvbiBpbml0Q2xvbmVCeVRhZyhvYmplY3QsIHRhZywgaXNEZWVwKSB7XG4gIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICByZXR1cm4gYnVmZmVyQ2xvbmUob2JqZWN0KTtcblxuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3IoK29iamVjdCk7XG5cbiAgICBjYXNlIGZsb2F0MzJUYWc6IGNhc2UgZmxvYXQ2NFRhZzpcbiAgICBjYXNlIGludDhUYWc6IGNhc2UgaW50MTZUYWc6IGNhc2UgaW50MzJUYWc6XG4gICAgY2FzZSB1aW50OFRhZzogY2FzZSB1aW50OENsYW1wZWRUYWc6IGNhc2UgdWludDE2VGFnOiBjYXNlIHVpbnQzMlRhZzpcbiAgICAgIC8vIFNhZmFyaSA1IG1vYmlsZSBpbmNvcnJlY3RseSBoYXMgYE9iamVjdGAgYXMgdGhlIGNvbnN0cnVjdG9yIG9mIHR5cGVkIGFycmF5cy5cbiAgICAgIGlmIChDdG9yIGluc3RhbmNlb2YgQ3Rvcikge1xuICAgICAgICBDdG9yID0gY3RvckJ5VGFnW3RhZ107XG4gICAgICB9XG4gICAgICB2YXIgYnVmZmVyID0gb2JqZWN0LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgQ3Rvcihpc0RlZXAgPyBidWZmZXJDbG9uZShidWZmZXIpIDogYnVmZmVyLCBvYmplY3QuYnl0ZU9mZnNldCwgb2JqZWN0Lmxlbmd0aCk7XG5cbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIHJldHVybiBuZXcgQ3RvcihvYmplY3QpO1xuXG4gICAgY2FzZSByZWdleHBUYWc6XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IEN0b3Iob2JqZWN0LnNvdXJjZSwgcmVGbGFncy5leGVjKG9iamVjdCkpO1xuICAgICAgcmVzdWx0Lmxhc3RJbmRleCA9IG9iamVjdC5sYXN0SW5kZXg7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVCeVRhZztcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMmx1YVhSRGJHOXVaVUo1VkdGbkxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZblZtWm1WeVEyeHZibVVnUFNCeVpYRjFhWEpsS0NjdUwySjFabVpsY2tOc2IyNWxKeWs3WEc1Y2JpOHFLaUJnVDJKcVpXTjBJM1J2VTNSeWFXNW5ZQ0J5WlhOMWJIUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJpYjI5c1ZHRm5JRDBnSjF0dlltcGxZM1FnUW05dmJHVmhibDBuTEZ4dUlDQWdJR1JoZEdWVVlXY2dQU0FuVzI5aWFtVmpkQ0JFWVhSbFhTY3NYRzRnSUNBZ2JuVnRZbVZ5VkdGbklEMGdKMXR2WW1wbFkzUWdUblZ0WW1WeVhTY3NYRzRnSUNBZ2NtVm5aWGh3VkdGbklEMGdKMXR2WW1wbFkzUWdVbVZuUlhod1hTY3NYRzRnSUNBZ2MzUnlhVzVuVkdGbklEMGdKMXR2WW1wbFkzUWdVM1J5YVc1blhTYzdYRzVjYm5aaGNpQmhjbkpoZVVKMVptWmxjbFJoWnlBOUlDZGJiMkpxWldOMElFRnljbUY1UW5WbVptVnlYU2NzWEc0Z0lDQWdabXh2WVhRek1sUmhaeUE5SUNkYmIySnFaV04wSUVac2IyRjBNekpCY25KaGVWMG5MRnh1SUNBZ0lHWnNiMkYwTmpSVVlXY2dQU0FuVzI5aWFtVmpkQ0JHYkc5aGREWTBRWEp5WVhsZEp5eGNiaUFnSUNCcGJuUTRWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1NXNTBPRUZ5Y21GNVhTY3NYRzRnSUNBZ2FXNTBNVFpVWVdjZ1BTQW5XMjlpYW1WamRDQkpiblF4TmtGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTXpKVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5Rek1rRnljbUY1WFNjc1hHNGdJQ0FnZFdsdWREaFVZV2NnUFNBblcyOWlhbVZqZENCVmFXNTBPRUZ5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1ZXbHVkRGhEYkdGdGNHVmtRWEp5WVhsZEp5eGNiaUFnSUNCMWFXNTBNVFpVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwTVRaQmNuSmhlVjBuTEZ4dUlDQWdJSFZwYm5Rek1sUmhaeUE5SUNkYmIySnFaV04wSUZWcGJuUXpNa0Z5Y21GNVhTYzdYRzVjYmk4cUtpQlZjMlZrSUhSdklHMWhkR05vSUdCU1pXZEZlSEJnSUdac1lXZHpJR1p5YjIwZ2RHaGxhWElnWTI5bGNtTmxaQ0J6ZEhKcGJtY2dkbUZzZFdWekxpQXFMMXh1ZG1GeUlISmxSbXhoWjNNZ1BTQXZYRngzS2lRdk8xeHVYRzR2S2lvZ1RtRjBhWFpsSUcxbGRHaHZaQ0J5WldabGNtVnVZMlZ6TGlBcUwxeHVkbUZ5SUZWcGJuUTRRWEp5WVhrZ1BTQm5iRzlpWVd3dVZXbHVkRGhCY25KaGVUdGNibHh1THlvcUlGVnpaV1FnZEc4Z2JHOXZhM1Z3SUdFZ2RIbHdaU0JoY25KaGVTQmpiMjV6ZEhKMVkzUnZjbk1nWW5rZ1lIUnZVM1J5YVc1blZHRm5ZQzRnS2k5Y2JuWmhjaUJqZEc5eVFubFVZV2NnUFNCN2ZUdGNibU4wYjNKQ2VWUmhaMXRtYkc5aGRETXlWR0ZuWFNBOUlHZHNiMkpoYkM1R2JHOWhkRE15UVhKeVlYazdYRzVqZEc5eVFubFVZV2RiWm14dllYUTJORlJoWjEwZ1BTQm5iRzlpWVd3dVJteHZZWFEyTkVGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzJsdWREaFVZV2RkSUQwZ1oyeHZZbUZzTGtsdWREaEJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF4TmxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0cGJuUXpNbFJoWjEwZ1BTQm5iRzlpWVd3dVNXNTBNekpCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXQxYVc1ME9GUmhaMTBnUFNCVmFXNTBPRUZ5Y21GNU8xeHVZM1J2Y2tKNVZHRm5XM1ZwYm5RNFEyeGhiWEJsWkZSaFoxMGdQU0JuYkc5aVlXd3VWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYazdYRzVqZEc5eVFubFVZV2RiZFdsdWRERTJWR0ZuWFNBOUlHZHNiMkpoYkM1VmFXNTBNVFpCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXQxYVc1ME16SlVZV2RkSUQwZ1oyeHZZbUZzTGxWcGJuUXpNa0Z5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRWx1YVhScFlXeHBlbVZ6SUdGdUlHOWlhbVZqZENCamJHOXVaU0JpWVhObFpDQnZiaUJwZEhNZ1lIUnZVM1J5YVc1blZHRm5ZQzVjYmlBcVhHNGdLaUFxS2s1dmRHVTZLaW9nVkdocGN5Qm1kVzVqZEdsdmJpQnZibXg1SUhOMWNIQnZjblJ6SUdOc2IyNXBibWNnZG1Gc2RXVnpJSGRwZEdnZ2RHRm5jeUJ2Wmx4dUlDb2dZRUp2YjJ4bFlXNWdMQ0JnUkdGMFpXQXNJR0JGY25KdmNtQXNJR0JPZFcxaVpYSmdMQ0JnVW1WblJYaHdZQ3dnYjNJZ1lGTjBjbWx1WjJBdVhHNGdLbHh1SUNvZ1FIQnlhWFpoZEdWY2JpQXFJRUJ3WVhKaGJTQjdUMkpxWldOMGZTQnZZbXBsWTNRZ1ZHaGxJRzlpYW1WamRDQjBieUJqYkc5dVpTNWNiaUFxSUVCd1lYSmhiU0I3YzNSeWFXNW5mU0IwWVdjZ1ZHaGxJR0IwYjFOMGNtbHVaMVJoWjJBZ2IyWWdkR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN1ltOXZiR1ZoYm4wZ1cybHpSR1ZsY0YwZ1UzQmxZMmxtZVNCaElHUmxaWEFnWTJ4dmJtVXVYRzRnS2lCQWNtVjBkWEp1Y3lCN1QySnFaV04wZlNCU1pYUjFjbTV6SUhSb1pTQnBibWwwYVdGc2FYcGxaQ0JqYkc5dVpTNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z2FXNXBkRU5zYjI1bFFubFVZV2NvYjJKcVpXTjBMQ0IwWVdjc0lHbHpSR1ZsY0NrZ2UxeHVJQ0IyWVhJZ1EzUnZjaUE5SUc5aWFtVmpkQzVqYjI1emRISjFZM1J2Y2p0Y2JpQWdjM2RwZEdOb0lDaDBZV2NwSUh0Y2JpQWdJQ0JqWVhObElHRnljbUY1UW5WbVptVnlWR0ZuT2x4dUlDQWdJQ0FnY21WMGRYSnVJR0oxWm1abGNrTnNiMjVsS0c5aWFtVmpkQ2s3WEc1Y2JpQWdJQ0JqWVhObElHSnZiMnhVWVdjNlhHNGdJQ0FnWTJGelpTQmtZWFJsVkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUc1bGR5QkRkRzl5S0N0dlltcGxZM1FwTzF4dVhHNGdJQ0FnWTJGelpTQm1iRzloZERNeVZHRm5PaUJqWVhObElHWnNiMkYwTmpSVVlXYzZYRzRnSUNBZ1kyRnpaU0JwYm5RNFZHRm5PaUJqWVhObElHbHVkREUyVkdGbk9pQmpZWE5sSUdsdWRETXlWR0ZuT2x4dUlDQWdJR05oYzJVZ2RXbHVkRGhVWVdjNklHTmhjMlVnZFdsdWREaERiR0Z0Y0dWa1ZHRm5PaUJqWVhObElIVnBiblF4TmxSaFp6b2dZMkZ6WlNCMWFXNTBNekpVWVdjNlhHNGdJQ0FnSUNBdkx5QlRZV1poY21rZ05TQnRiMkpwYkdVZ2FXNWpiM0p5WldOMGJIa2dhR0Z6SUdCUFltcGxZM1JnSUdGeklIUm9aU0JqYjI1emRISjFZM1J2Y2lCdlppQjBlWEJsWkNCaGNuSmhlWE11WEc0Z0lDQWdJQ0JwWmlBb1EzUnZjaUJwYm5OMFlXNWpaVzltSUVOMGIzSXBJSHRjYmlBZ0lDQWdJQ0FnUTNSdmNpQTlJR04wYjNKQ2VWUmhaMXQwWVdkZE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2RtRnlJR0oxWm1abGNpQTlJRzlpYW1WamRDNWlkV1ptWlhJN1hHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYVhORVpXVndJRDhnWW5WbVptVnlRMnh2Ym1Vb1luVm1abVZ5S1NBNklHSjFabVpsY2l3Z2IySnFaV04wTG1KNWRHVlBabVp6WlhRc0lHOWlhbVZqZEM1c1pXNW5kR2dwTzF4dVhHNGdJQ0FnWTJGelpTQnVkVzFpWlhKVVlXYzZYRzRnSUNBZ1kyRnpaU0J6ZEhKcGJtZFVZV2M2WEc0Z0lDQWdJQ0J5WlhSMWNtNGdibVYzSUVOMGIzSW9iMkpxWldOMEtUdGNibHh1SUNBZ0lHTmhjMlVnY21WblpYaHdWR0ZuT2x4dUlDQWdJQ0FnZG1GeUlISmxjM1ZzZENBOUlHNWxkeUJEZEc5eUtHOWlhbVZqZEM1emIzVnlZMlVzSUhKbFJteGhaM011WlhobFl5aHZZbXBsWTNRcEtUdGNiaUFnSUNBZ0lISmxjM1ZzZEM1c1lYTjBTVzVrWlhnZ1BTQnZZbXBsWTNRdWJHRnpkRWx1WkdWNE8xeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdhVzVwZEVOc2IyNWxRbmxVWVdjN1hHNGlYWDA9IiwiLyoqXG4gKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICovXG5mdW5jdGlvbiBpbml0Q2xvbmVPYmplY3Qob2JqZWN0KSB7XG4gIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoISh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yKSkge1xuICAgIEN0b3IgPSBPYmplY3Q7XG4gIH1cbiAgcmV0dXJuIG5ldyBDdG9yO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluaXRDbG9uZU9iamVjdDtcbiIsInZhciBnZXRMZW5ndGggPSByZXF1aXJlKCcuL2dldExlbmd0aCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aChnZXRMZW5ndGgodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5TGlrZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBob3N0IG9iamVjdCBpbiBJRSA8IDkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBob3N0IG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICovXG52YXIgaXNIb3N0T2JqZWN0ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIE9iamVjdCh7ICd0b1N0cmluZyc6IDAgfSArICcnKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZmFsc2U7IH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gSUUgPCA5IHByZXNlbnRzIG1hbnkgaG9zdCBvYmplY3RzIGFzIGBPYmplY3RgIG9iamVjdHMgdGhhdCBjYW4gY29lcmNlXG4gICAgLy8gdG8gc3RyaW5ncyBkZXNwaXRlIGhhdmluZyBpbXByb3Blcmx5IGRlZmluZWQgYHRvU3RyaW5nYCBtZXRob2RzLlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgKHZhbHVlICsgJycpID09ICdzdHJpbmcnO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0hvc3RPYmplY3Q7XG4iLCIvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICA/IChpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpKVxuICAgICAgOiAodHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpKSB7XG4gICAgdmFyIG90aGVyID0gb2JqZWN0W2luZGV4XTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gKHZhbHVlID09PSBvdGhlcikgOiAob3RoZXIgIT09IG90aGVyKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxuXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgaWYgKCh0eXBlID09ICdzdHJpbmcnICYmIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkpIHx8IHR5cGUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSk7XG4gIHJldHVybiByZXN1bHQgfHwgKG9iamVjdCAhPSBudWxsICYmIHZhbHVlIGluIHRvT2JqZWN0KG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzS2V5O1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9MYXp5V3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBnZXRGdW5jTmFtZSA9IHJlcXVpcmUoJy4vZ2V0RnVuY05hbWUnKSxcbiAgICBsb2Rhc2ggPSByZXF1aXJlKCcuLi9jaGFpbi9sb2Rhc2gnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTGF6aWFibGUoZnVuYykge1xuICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgIG90aGVyID0gbG9kYXNoW2Z1bmNOYW1lXTtcblxuICBpZiAodHlwZW9mIG90aGVyICE9ICdmdW5jdGlvbicgfHwgIShmdW5jTmFtZSBpbiBMYXp5V3JhcHBlci5wcm90b3R5cGUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChmdW5jID09PSBvdGhlcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBkYXRhID0gZ2V0RGF0YShvdGhlcik7XG4gIHJldHVybiAhIWRhdGEgJiYgZnVuYyA9PT0gZGF0YVswXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xhemlhYmxlO1xuIiwiLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgYmFzZWQgb24gW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBBUllfRkxBRyA9IDEyOCxcbiAgICBSRUFSR19GTEFHID0gMjU2O1xuXG4vKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAqXG4gKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyByZXF1aXJlZCB0byBpbnZva2UgYSBmdW5jdGlvbi5cbiAqIFRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtZXRob2RzIGxpa2UgYF8uYmluZGAsIGBfLmN1cnJ5YCwgYW5kIGBfLnBhcnRpYWxgXG4gKiBtYXkgYmUgYXBwbGllZCByZWdhcmRsZXNzIG9mIGV4ZWN1dGlvbiBvcmRlci4gTWV0aG9kcyBsaWtlIGBfLmFyeWAgYW5kIGBfLnJlYXJnYFxuICogYXVnbWVudCBmdW5jdGlvbiBhcmd1bWVudHMsIG1ha2luZyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZXhlY3V0ZWQgaW1wb3J0YW50LFxuICogcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZSBhbiBleGNlcHRpb24gZm9yIGEgc2FmZVxuICogY29tbW9uIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgIGFuZCBvciBgXy5yZWFyZ2AgYXBwbGllZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgZGVzdGluYXRpb24gbWV0YWRhdGEuXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIHNvdXJjZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGF0YWAuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YShkYXRhLCBzb3VyY2UpIHtcbiAgdmFyIGJpdG1hc2sgPSBkYXRhWzFdLFxuICAgICAgc3JjQml0bWFzayA9IHNvdXJjZVsxXSxcbiAgICAgIG5ld0JpdG1hc2sgPSBiaXRtYXNrIHwgc3JjQml0bWFzayxcbiAgICAgIGlzQ29tbW9uID0gbmV3Qml0bWFzayA8IEFSWV9GTEFHO1xuXG4gIHZhciBpc0NvbWJvID1cbiAgICAoc3JjQml0bWFzayA9PSBBUllfRkxBRyAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBSRUFSR19GTEFHICYmIGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgfHxcbiAgICAoc3JjQml0bWFzayA9PSAoQVJZX0ZMQUcgfCBSRUFSR19GTEFHKSAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpO1xuXG4gIC8vIEV4aXQgZWFybHkgaWYgbWV0YWRhdGEgY2FuJ3QgYmUgbWVyZ2VkLlxuICBpZiAoIShpc0NvbW1vbiB8fCBpc0NvbWJvKSkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYHRoaXNBcmdgIGlmIGF2YWlsYWJsZS5cbiAgaWYgKHNyY0JpdG1hc2sgJiBCSU5EX0ZMQUcpIHtcbiAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgbmV3Qml0bWFzayB8PSAoYml0bWFzayAmIEJJTkRfRkxBRykgPyAwIDogQ1VSUllfQk9VTkRfRkxBRztcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICB2YXIgdmFsdWUgPSBzb3VyY2VbM107XG4gIGlmICh2YWx1ZSkge1xuICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgZGF0YVszXSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3MocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNF0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzRdKTtcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgcmlnaHQgYXJndW1lbnRzLlxuICB2YWx1ZSA9IHNvdXJjZVs1XTtcbiAgaWYgKHZhbHVlKSB7XG4gICAgcGFydGlhbHMgPSBkYXRhWzVdO1xuICAgIGRhdGFbNV0gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzUmlnaHQocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNl0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzZdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgdmFsdWUgPSBzb3VyY2VbN107XG4gIGlmICh2YWx1ZSkge1xuICAgIGRhdGFbN10gPSBhcnJheUNvcHkodmFsdWUpO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyeWAgaWYgaXQncyBzbWFsbGVyLlxuICBpZiAoc3JjQml0bWFzayAmIEFSWV9GTEFHKSB7XG4gICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlRGF0YTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL2dldE5hdGl2ZScpO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUoZ2xvYmFsLCAnV2Vha01hcCcpO1xuXG4vKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxubW9kdWxlLmV4cG9ydHMgPSBtZXRhTWFwO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyMWxkR0ZOWVhBdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWjJWMFRtRjBhWFpsSUQwZ2NtVnhkV2x5WlNnbkxpOW5aWFJPWVhScGRtVW5LVHRjYmx4dUx5b3FJRTVoZEdsMlpTQnRaWFJvYjJRZ2NtVm1aWEpsYm1ObGN5NGdLaTljYm5aaGNpQlhaV0ZyVFdGd0lEMGdaMlYwVG1GMGFYWmxLR2RzYjJKaGJDd2dKMWRsWVd0TllYQW5LVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdjM1J2Y21VZ1puVnVZM1JwYjI0Z2JXVjBZV1JoZEdFdUlDb3ZYRzUyWVhJZ2JXVjBZVTFoY0NBOUlGZGxZV3ROWVhBZ0ppWWdibVYzSUZkbFlXdE5ZWEE3WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ2JXVjBZVTFoY0R0Y2JpSmRmUT09IiwiLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG52YXIgcmVhbE5hbWVzID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gcmVhbE5hbWVzO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIFJlb3JkZXIgYGFycmF5YCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBpbmRleGVzIHdoZXJlIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgc2Vjb25kIGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBzZWNvbmQgZWxlbWVudCwgYW5kIHNvIG9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcmVvcmRlci5cbiAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFycmF5IGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gcmVvcmRlcihhcnJheSwgaW5kZXhlcykge1xuICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gbmF0aXZlTWluKGluZGV4ZXMubGVuZ3RoLCBhcnJMZW5ndGgpLFxuICAgICAgb2xkQXJyYXkgPSBhcnJheUNvcHkoYXJyYXkpO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICBhcnJheVtsZW5ndGhdID0gaXNJbmRleChpbmRleCwgYXJyTGVuZ3RoKSA/IG9sZEFycmF5W2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVvcmRlcjtcbiIsIi8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbnZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuLyoqXG4gKiBSZXBsYWNlcyBhbGwgYHBsYWNlaG9sZGVyYCBlbGVtZW50cyBpbiBgYXJyYXlgIHdpdGggYW4gaW50ZXJuYWwgcGxhY2Vob2xkZXJcbiAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byByZXBsYWNlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZUhvbGRlcnMoYXJyYXksIHBsYWNlaG9sZGVyKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gcGxhY2Vob2xkZXIpIHtcbiAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgcmVzdWx0WysrcmVzSW5kZXhdID0gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVwbGFjZUhvbGRlcnM7XG4iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgbm93ID0gcmVxdWlyZSgnLi4vZGF0ZS9ub3cnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHdoZW4gYSBmdW5jdGlvbiBiZWNvbWVzIGhvdC4gKi9cbnZhciBIT1RfQ09VTlQgPSAxNTAsXG4gICAgSE9UX1NQQU4gPSAxNjtcblxuLyoqXG4gKiBTZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogKipOb3RlOioqIElmIHRoaXMgZnVuY3Rpb24gYmVjb21lcyBob3QsIGkuZS4gaXMgaW52b2tlZCBhIGxvdCBpbiBhIHNob3J0XG4gKiBwZXJpb2Qgb2YgdGltZSwgaXQgd2lsbCB0cmlwIGl0cyBicmVha2VyIGFuZCB0cmFuc2l0aW9uIHRvIGFuIGlkZW50aXR5IGZ1bmN0aW9uXG4gKiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWUgW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDcwKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIHNldERhdGEgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBjb3VudCA9IDAsXG4gICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICByZXR1cm4gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhciBzdGFtcCA9IG5vdygpLFxuICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpO1xuXG4gICAgbGFzdENhbGxlZCA9IHN0YW1wO1xuICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICBpZiAoKytjb3VudCA+PSBIT1RfQ09VTlQpIHtcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY291bnQgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZVNldERhdGEoa2V5LCB2YWx1ZSk7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERhdGE7XG4iLCJ2YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBrZXlzSW4gPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5c0luJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgZmFsbGJhY2sgaW1wbGVtZW50YXRpb24gb2YgYE9iamVjdC5rZXlzYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5IG9mIHRoZVxuICogb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIHNoaW1LZXlzKG9iamVjdCkge1xuICB2YXIgcHJvcHMgPSBrZXlzSW4ob2JqZWN0KSxcbiAgICAgIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gcHJvcHNMZW5ndGggJiYgb2JqZWN0Lmxlbmd0aDtcblxuICB2YXIgYWxsb3dJbmRleGVzID0gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIGlmICgoYWxsb3dJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaGltS2V5cztcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gb2JqZWN0IGlmIGl0J3Mgbm90IG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QodmFsdWUpIHtcbiAgaWYgKHN1cHBvcnQudW5pbmRleGVkQ2hhcnMgJiYgaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgcmVzdWx0ID0gT2JqZWN0KHZhbHVlKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gdmFsdWUuY2hhckF0KGluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpID8gdmFsdWUgOiBPYmplY3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvT2JqZWN0O1xuIiwidmFyIGJhc2VUb1N0cmluZyA9IHJlcXVpcmUoJy4vYmFzZVRvU3RyaW5nJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVQcm9wTmFtZSA9IC9bXi5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXG5cXFxcXXxcXFxcLikqPylcXDIpXFxdL2c7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gcHJvcGVydHkgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBiYXNlVG9TdHJpbmcodmFsdWUpLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN0cmluZykge1xuICAgIHJlc3VsdC5wdXNoKHF1b3RlID8gc3RyaW5nLnJlcGxhY2UocmVFc2NhcGVDaGFyLCAnJDEnKSA6IChudW1iZXIgfHwgbWF0Y2gpKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9QYXRoO1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuL0xvZGFzaFdyYXBwZXInKSxcbiAgICBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgd3JhcHBlcmAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSB3cmFwcGVyIFRoZSB3cmFwcGVyIHRvIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gKi9cbmZ1bmN0aW9uIHdyYXBwZXJDbG9uZSh3cmFwcGVyKSB7XG4gIHJldHVybiB3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXJcbiAgICA/IHdyYXBwZXIuY2xvbmUoKVxuICAgIDogbmV3IExvZGFzaFdyYXBwZXIod3JhcHBlci5fX3dyYXBwZWRfXywgd3JhcHBlci5fX2NoYWluX18sIGFycmF5Q29weSh3cmFwcGVyLl9fYWN0aW9uc19fKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHBlckNsb25lO1xuIiwidmFyIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDbG9uZScpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2JpbmRDYWxsYmFjaycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWVwIGNsb25lIG9mIGB2YWx1ZWAuIElmIGBjdXN0b21pemVyYCBpcyBwcm92aWRlZCBpdCdzIGludm9rZWRcbiAqIHRvIHByb2R1Y2UgdGhlIGNsb25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgIGNsb25pbmdcbiAqIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYFxuICogYW5kIGludm9rZWQgd2l0aCB1cCB0byB0aHJlZSBhcmd1bWVudDsgKHZhbHVlIFssIGluZGV4fGtleSwgb2JqZWN0XSkuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L2luZnJhc3RydWN0dXJlLmh0bWwjaW50ZXJuYWwtc3RydWN0dXJlZC1jbG9uaW5nLWFsZ29yaXRobSkuXG4gKiBUaGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBhcmd1bWVudHNgIG9iamVjdHMgYW5kIG9iamVjdHMgY3JlYXRlZCBieVxuICogY29uc3RydWN0b3JzIG90aGVyIHRoYW4gYE9iamVjdGAgYXJlIGNsb25lZCB0byBwbGFpbiBgT2JqZWN0YCBvYmplY3RzLiBBblxuICogZW1wdHkgb2JqZWN0IGlzIHJldHVybmVkIGZvciB1bmNsb25lYWJsZSB2YWx1ZXMgc3VjaCBhcyBmdW5jdGlvbnMsIERPTSBub2RlcyxcbiAqIE1hcHMsIFNldHMsIGFuZCBXZWFrTWFwcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGRlZXAgY2xvbmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgY3VzdG9taXplcmAuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiB2YXIgZGVlcCA9IF8uY2xvbmVEZWVwKHVzZXJzKTtcbiAqIGRlZXBbMF0gPT09IHVzZXJzWzBdO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAqIHZhciBlbCA9IF8uY2xvbmVEZWVwKGRvY3VtZW50LmJvZHksIGZ1bmN0aW9uKHZhbHVlKSB7XG4gKiAgIGlmIChfLmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICogICB9XG4gKiB9KTtcbiAqXG4gKiBlbCA9PT0gZG9jdW1lbnQuYm9keVxuICogLy8gPT4gZmFsc2VcbiAqIGVsLm5vZGVOYW1lXG4gKiAvLyA9PiBCT0RZXG4gKiBlbC5jaGlsZE5vZGVzLmxlbmd0aDtcbiAqIC8vID0+IDIwXG4gKi9cbmZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSwgY3VzdG9taXplciwgdGhpc0FyZykge1xuICByZXR1cm4gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJ1xuICAgID8gYmFzZUNsb25lKHZhbHVlLCB0cnVlLCBiaW5kQ2FsbGJhY2soY3VzdG9taXplciwgdGhpc0FyZywgMykpXG4gICAgOiBiYXNlQ2xvbmUodmFsdWUsIHRydWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGVlcDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpICYmXG4gICAgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVJc0FycmF5ID0gZ2V0TmF0aXZlKEFycmF5LCAnaXNBcnJheScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGFycmF5VGFnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4vaXNGdW5jdGlvbicpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi9pc1N0cmluZycpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGVtcHR5LiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgZW1wdHkgdW5sZXNzIGl0J3MgYW5cbiAqIGBhcmd1bWVudHNgIG9iamVjdCwgYXJyYXksIHN0cmluZywgb3IgalF1ZXJ5LWxpa2UgY29sbGVjdGlvbiB3aXRoIGEgbGVuZ3RoXG4gKiBncmVhdGVyIHRoYW4gYDBgIG9yIGFuIG9iamVjdCB3aXRoIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZW1wdHksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0VtcHR5KG51bGwpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eSh0cnVlKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkoMSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNFbXB0eSh7ICdhJzogMSB9KTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRW1wdHkodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheUxpa2UodmFsdWUpICYmIChpc0FycmF5KHZhbHVlKSB8fCBpc1N0cmluZyh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpIHx8XG4gICAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0Z1bmN0aW9uKHZhbHVlLnNwbGljZSkpKSkge1xuICAgIHJldHVybiAhdmFsdWUubGVuZ3RoO1xuICB9XG4gIHJldHVybiAha2V5cyh2YWx1ZSkubGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRW1wdHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIG9sZGVyIHZlcnNpb25zIG9mIENocm9tZSBhbmQgU2FmYXJpIHdoaWNoIHJldHVybiAnZnVuY3Rpb24nIGZvciByZWdleGVzXG4gIC8vIGFuZCBTYWZhcmkgOCB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMuXG4gIHJldHVybiBpc09iamVjdCh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0Z1bmN0aW9uO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0hvc3RPYmplY3QnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkgPiA1KS4gKi9cbnZhciByZUlzSG9zdEN0b3IgPSAvXlxcW29iamVjdCAuKz9Db25zdHJ1Y3RvclxcXSQvO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZuVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UoL1tcXFxcXiQuKis/KClbXFxde318XS9nLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTmF0aXZlKEFycmF5LnByb3RvdHlwZS5wdXNoKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTmF0aXZlKF8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNOYXRpdmUodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgcmV0dXJuIHJlSXNOYXRpdmUudGVzdChmblRvU3RyaW5nLmNhbGwodmFsdWUpKTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAoaXNIb3N0T2JqZWN0KHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3IpLnRlc3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTmF0aXZlO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUgW2xhbmd1YWdlIHR5cGVdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDgpIG9mIGBPYmplY3RgLlxuICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdCgxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIC8vIEF2b2lkIGEgVjggSklUIGJ1ZyBpbiBDaHJvbWUgMTktMjAuXG4gIC8vIFNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjI5MSBmb3IgbW9yZSBkZXRhaWxzLlxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsInZhciBiYXNlRm9ySW4gPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRm9ySW4nKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0hvc3RPYmplY3QnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGF0IGlzLCBhbiBvYmplY3QgY3JlYXRlZCBieSB0aGVcbiAqIGBPYmplY3RgIGNvbnN0cnVjdG9yIG9yIG9uZSB3aXRoIGEgYFtbUHJvdG90eXBlXV1gIG9mIGBudWxsYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgYXNzdW1lcyBvYmplY3RzIGNyZWF0ZWQgYnkgdGhlIGBPYmplY3RgIGNvbnN0cnVjdG9yXG4gKiBoYXZlIG5vIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqIH1cbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QobmV3IEZvbyk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoeyAneCc6IDAsICd5JzogMCB9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgdmFyIEN0b3I7XG5cbiAgLy8gRXhpdCBlYXJseSBmb3Igbm9uIGBPYmplY3RgIG9iamVjdHMuXG4gIGlmICghKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gb2JqZWN0VGFnICYmICFpc0hvc3RPYmplY3QodmFsdWUpICYmICFpc0FyZ3VtZW50cyh2YWx1ZSkpIHx8XG4gICAgICAoIWhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjb25zdHJ1Y3RvcicpICYmIChDdG9yID0gdmFsdWUuY29uc3RydWN0b3IsIHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgIShDdG9yIGluc3RhbmNlb2YgQ3RvcikpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJRSA8IDkgaXRlcmF0ZXMgaW5oZXJpdGVkIHByb3BlcnRpZXMgYmVmb3JlIG93biBwcm9wZXJ0aWVzLiBJZiB0aGUgZmlyc3RcbiAgLy8gaXRlcmF0ZWQgcHJvcGVydHkgaXMgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnR5IHRoZW4gdGhlcmUgYXJlIG5vIGluaGVyaXRlZFxuICAvLyBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gIHZhciByZXN1bHQ7XG4gIGlmIChzdXBwb3J0Lm93bkxhc3QpIHtcbiAgICBiYXNlRm9ySW4odmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgcmVzdWx0ID0gaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdCAhPT0gZmFsc2U7XG4gIH1cbiAgLy8gSW4gbW9zdCBlbnZpcm9ubWVudHMgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgYXJlIGl0ZXJhdGVkIGJlZm9yZVxuICAvLyBpdHMgaW5oZXJpdGVkIHByb3BlcnRpZXMuIElmIHRoZSBsYXN0IGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzXG4gIC8vIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICBiYXNlRm9ySW4odmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHQgPSBrZXk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgfHwgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgcmVzdWx0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1BsYWluT2JqZWN0O1xuIiwidmFyIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3RyaW5nYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3RyaW5nKCdhYmMnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3RyaW5nKDEpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzdHJpbmdUYWcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3RyaW5nO1xuIiwidmFyIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG52YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPSB0eXBlZEFycmF5VGFnc1tlcnJvclRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPSB0eXBlZEFycmF5VGFnc1ttYXBUYWddID1cbnR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tvYmplY3RUYWddID1cbnR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPSB0eXBlZEFycmF5VGFnc1tzZXRUYWddID1cbnR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPSB0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNUeXBlZEFycmF5KG5ldyBVaW50OEFycmF5KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShbXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29ialRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1R5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVW5kZWZpbmVkO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBzaGltS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3NoaW1LZXlzJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2tleXMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIF8ua2V5cygnaGknKTtcbiAqIC8vID0+IFsnMCcsICcxJ11cbiAqL1xudmFyIGtleXMgPSAhbmF0aXZlS2V5cyA/IHNoaW1LZXlzIDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciBDdG9yID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3QuY29uc3RydWN0b3I7XG4gIGlmICgodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0KSB8fFxuICAgICAgKHR5cGVvZiBvYmplY3QgPT0gJ2Z1bmN0aW9uJyA/IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgOiBpc0FycmF5TGlrZShvYmplY3QpKSkge1xuICAgIHJldHVybiBzaGltS2V5cyhvYmplY3QpO1xuICB9XG4gIHJldHVybiBpc09iamVjdChvYmplY3QpID8gbmF0aXZlS2V5cyhvYmplY3QpIDogW107XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXM7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9sYW5nL2lzRnVuY3Rpb24nKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKiBVc2VkIHRvIGZpeCB0aGUgSlNjcmlwdCBgW1tEb250RW51bV1dYCBidWcuICovXG52YXIgc2hhZG93UHJvcHMgPSBbXG4gICdjb25zdHJ1Y3RvcicsICdoYXNPd25Qcm9wZXJ0eScsICdpc1Byb3RvdHlwZU9mJywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcbiAgJ3RvTG9jYWxlU3RyaW5nJywgJ3RvU3RyaW5nJywgJ3ZhbHVlT2YnXG5dO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGVycm9yUHJvdG8gPSBFcnJvci5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlLFxuICAgIHN0cmluZ1Byb3RvID0gU3RyaW5nLnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gYXZvaWQgaXRlcmF0aW5nIG92ZXIgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbiBJRSA8IDkuICovXG52YXIgbm9uRW51bVByb3BzID0ge307XG5ub25FbnVtUHJvcHNbYXJyYXlUYWddID0gbm9uRW51bVByb3BzW2RhdGVUYWddID0gbm9uRW51bVByb3BzW251bWJlclRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b0xvY2FsZVN0cmluZyc6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Jvb2xUYWddID0gbm9uRW51bVByb3BzW3N0cmluZ1RhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Vycm9yVGFnXSA9IG5vbkVudW1Qcm9wc1tmdW5jVGFnXSA9IG5vbkVudW1Qcm9wc1tyZWdleHBUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlIH07XG5ub25FbnVtUHJvcHNbb2JqZWN0VGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSB9O1xuXG5hcnJheUVhY2goc2hhZG93UHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICBmb3IgKHZhciB0YWcgaW4gbm9uRW51bVByb3BzKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwobm9uRW51bVByb3BzLCB0YWcpKSB7XG4gICAgICB2YXIgcHJvcHMgPSBub25FbnVtUHJvcHNbdGFnXTtcbiAgICAgIHByb3BzW2tleV0gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3BzLCBrZXkpO1xuICAgIH1cbiAgfVxufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzSW4obmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYicsICdjJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xuZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7XG5cbiAgbGVuZ3RoID0gKGxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpIHx8IGlzU3RyaW5nKG9iamVjdCkpICYmIGxlbmd0aCkgfHwgMDtcblxuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgIGluZGV4ID0gLTEsXG4gICAgICBwcm90byA9IChpc0Z1bmN0aW9uKEN0b3IpICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90byxcbiAgICAgIGlzUHJvdG8gPSBwcm90byA9PT0gb2JqZWN0LFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgIHNraXBJbmRleGVzID0gbGVuZ3RoID4gMCxcbiAgICAgIHNraXBFcnJvclByb3BzID0gc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyAmJiAob2JqZWN0ID09PSBlcnJvclByb3RvIHx8IG9iamVjdCBpbnN0YW5jZW9mIEVycm9yKSxcbiAgICAgIHNraXBQcm90byA9IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgJiYgaXNGdW5jdGlvbihvYmplY3QpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IChpbmRleCArICcnKTtcbiAgfVxuICAvLyBsb2Rhc2ggc2tpcHMgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgd2hlbiBpdCBpbmZlcnMgaXQncyBpdGVyYXRpbmdcbiAgLy8gb3ZlciBhIGBwcm90b3R5cGVgIG9iamVjdCBiZWNhdXNlIElFIDwgOSBjYW4ndCBzZXQgdGhlIGBbW0VudW1lcmFibGVdXWBcbiAgLy8gYXR0cmlidXRlIG9mIGFuIGV4aXN0aW5nIHByb3BlcnR5IGFuZCB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBvZiBhXG4gIC8vIHByb3RvdHlwZSBkZWZhdWx0cyB0byBub24tZW51bWVyYWJsZS5cbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmICghKHNraXBQcm90byAmJiBrZXkgPT0gJ3Byb3RvdHlwZScpICYmXG4gICAgICAgICEoc2tpcEVycm9yUHJvcHMgJiYgKGtleSA9PSAnbWVzc2FnZScgfHwga2V5ID09ICduYW1lJykpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgaXNJbmRleChrZXksIGxlbmd0aCkpICYmXG4gICAgICAgICEoa2V5ID09ICdjb25zdHJ1Y3RvcicgJiYgKGlzUHJvdG8gfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIGlmIChzdXBwb3J0Lm5vbkVudW1TaGFkb3dzICYmIG9iamVjdCAhPT0gb2JqZWN0UHJvdG8pIHtcbiAgICB2YXIgdGFnID0gb2JqZWN0ID09PSBzdHJpbmdQcm90byA/IHN0cmluZ1RhZyA6IChvYmplY3QgPT09IGVycm9yUHJvdG8gPyBlcnJvclRhZyA6IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KSksXG4gICAgICAgIG5vbkVudW1zID0gbm9uRW51bVByb3BzW3RhZ10gfHwgbm9uRW51bVByb3BzW29iamVjdFRhZ107XG5cbiAgICBpZiAodGFnID09IG9iamVjdFRhZykge1xuICAgICAgcHJvdG8gPSBvYmplY3RQcm90bztcbiAgICB9XG4gICAgbGVuZ3RoID0gc2hhZG93UHJvcHMubGVuZ3RoO1xuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAga2V5ID0gc2hhZG93UHJvcHNbbGVuZ3RoXTtcbiAgICAgIHZhciBub25FbnVtID0gbm9uRW51bXNba2V5XTtcbiAgICAgIGlmICghKGlzUHJvdG8gJiYgbm9uRW51bSkgJiZcbiAgICAgICAgICAobm9uRW51bSA/IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpIDogb2JqZWN0W2tleV0gIT09IHByb3RvW2tleV0pKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c0luO1xuIiwidmFyIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiB0aGUga2V5LXZhbHVlIHBhaXJzIGZvciBgb2JqZWN0YCxcbiAqIGUuZy4gYFtba2V5MSwgdmFsdWUxXSwgW2tleTIsIHZhbHVlMl1dYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2Yga2V5LXZhbHVlIHBhaXJzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnBhaXJzKHsgJ2Jhcm5leSc6IDM2LCAnZnJlZCc6IDQwIH0pO1xuICogLy8gPT4gW1snYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCA0MF1dIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIHBhaXJzKG9iamVjdCkge1xuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICByZXN1bHRbaW5kZXhdID0gW2tleSwgb2JqZWN0W2tleV1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGFpcnM7XG4iLCJ2YXIgYmFzZVZhbHVlcyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VWYWx1ZXMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgdmFsdWVzIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy52YWx1ZXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLnZhbHVlcygnaGknKTtcbiAqIC8vID0+IFsnaCcsICdpJ11cbiAqL1xuZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICByZXR1cm4gYmFzZVZhbHVlcyhvYmplY3QsIGtleXMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmFsdWVzO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgIGVycm9yUHJvdG8gPSBFcnJvci5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGUsXG4gICAgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2U7XG5cbi8qKlxuICogQW4gb2JqZWN0IGVudmlyb25tZW50IGZlYXR1cmUgZmxhZ3MuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEB0eXBlIE9iamVjdFxuICovXG52YXIgc3VwcG9ydCA9IHt9O1xuXG4oZnVuY3Rpb24oeCkge1xuICB2YXIgQ3RvciA9IGZ1bmN0aW9uKCkgeyB0aGlzLnggPSB4OyB9LFxuICAgICAgb2JqZWN0ID0geyAnMCc6IHgsICdsZW5ndGgnOiB4IH0sXG4gICAgICBwcm9wcyA9IFtdO1xuXG4gIEN0b3IucHJvdG90eXBlID0geyAndmFsdWVPZic6IHgsICd5JzogeCB9O1xuICBmb3IgKHZhciBrZXkgaW4gbmV3IEN0b3IpIHsgcHJvcHMucHVzaChrZXkpOyB9XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgbmFtZWAgb3IgYG1lc3NhZ2VgIHByb3BlcnRpZXMgb2YgYEVycm9yLnByb3RvdHlwZWAgYXJlXG4gICAqIGVudW1lcmFibGUgYnkgZGVmYXVsdCAoSUUgPCA5LCBTYWZhcmkgPCA1LjEpLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bUVycm9yUHJvcHMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGVycm9yUHJvdG8sICdtZXNzYWdlJykgfHxcbiAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGVycm9yUHJvdG8sICduYW1lJyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgcHJvdG90eXBlYCBwcm9wZXJ0aWVzIGFyZSBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQuXG4gICAqXG4gICAqIEZpcmVmb3ggPCAzLjYsIE9wZXJhID4gOS41MCAtIE9wZXJhIDwgMTEuNjAsIGFuZCBTYWZhcmkgPCA1LjFcbiAgICogKGlmIHRoZSBwcm90b3R5cGUgb3IgYSBwcm9wZXJ0eSBvbiB0aGUgcHJvdG90eXBlIGhhcyBiZWVuIHNldClcbiAgICogaW5jb3JyZWN0bHkgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gIHZhbHVlIG9mIGEgZnVuY3Rpb24ncyBgcHJvdG90eXBlYFxuICAgKiBwcm9wZXJ0eSB0byBgdHJ1ZWAuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5lbnVtUHJvdG90eXBlcyA9IHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoQ3RvciwgJ3Byb3RvdHlwZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgcHJvcGVydGllcyBzaGFkb3dpbmcgdGhvc2Ugb24gYE9iamVjdC5wcm90b3R5cGVgIGFyZSBub24tZW51bWVyYWJsZS5cbiAgICpcbiAgICogSW4gSUUgPCA5IGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzLCBzaGFkb3dpbmcgbm9uLWVudW1lcmFibGUgb25lcyxcbiAgICogYXJlIG1hZGUgbm9uLWVudW1lcmFibGUgYXMgd2VsbCAoYS5rLmEgdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0Lm5vbkVudW1TaGFkb3dzID0gIS92YWx1ZU9mLy50ZXN0KHByb3BzKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBhZnRlciBpbmhlcml0ZWQgcHJvcGVydGllcyAoSUUgPCA5KS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0Lm93bkxhc3QgPSBwcm9wc1swXSAhPSAneCc7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgQXJyYXkjc2hpZnRgIGFuZCBgQXJyYXkjc3BsaWNlYCBhdWdtZW50IGFycmF5LWxpa2Ugb2JqZWN0c1xuICAgKiBjb3JyZWN0bHkuXG4gICAqXG4gICAqIEZpcmVmb3ggPCAxMCwgY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LCBhbmQgSUUgPCA5IGhhdmUgYnVnZ3kgQXJyYXlcbiAgICogYHNoaWZ0KClgIGFuZCBgc3BsaWNlKClgIGZ1bmN0aW9ucyB0aGF0IGZhaWwgdG8gcmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQsXG4gICAqIGB2YWx1ZVswXWAsIG9mIGFycmF5LWxpa2Ugb2JqZWN0cyBldmVuIHRob3VnaCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBpc1xuICAgKiBzZXQgdG8gYDBgLiBUaGUgYHNoaWZ0KClgIG1ldGhvZCBpcyBidWdneSBpbiBjb21wYXRpYmlsaXR5IG1vZGVzIG9mIElFIDgsXG4gICAqIHdoaWxlIGBzcGxpY2UoKWAgaXMgYnVnZ3kgcmVnYXJkbGVzcyBvZiBtb2RlIGluIElFIDwgOS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnNwbGljZU9iamVjdHMgPSAoc3BsaWNlLmNhbGwob2JqZWN0LCAwLCAxKSwgIW9iamVjdFswXSk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBsYWNrIG9mIHN1cHBvcnQgZm9yIGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyBieSBpbmRleC5cbiAgICpcbiAgICogSUUgPCA4IGNhbid0IGFjY2VzcyBjaGFyYWN0ZXJzIGJ5IGluZGV4LiBJRSA4IGNhbiBvbmx5IGFjY2VzcyBjaGFyYWN0ZXJzXG4gICAqIGJ5IGluZGV4IG9uIHN0cmluZyBsaXRlcmFscywgbm90IHN0cmluZyBvYmplY3RzLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQudW5pbmRleGVkQ2hhcnMgPSAoJ3gnWzBdICsgT2JqZWN0KCd4JylbMF0pICE9ICd4eCc7XG59KDEsIDApKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzdXBwb3J0O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBwcm92aWRlZCB0byBpdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aXR5O1xuIiwiLyoqXG4gKiBBIG5vLW9wZXJhdGlvbiBmdW5jdGlvbiB0aGF0IHJldHVybnMgYHVuZGVmaW5lZGAgcmVnYXJkbGVzcyBvZiB0aGVcbiAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLm5vb3Aob2JqZWN0KSA9PT0gdW5kZWZpbmVkO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBub29wKCkge1xuICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5vb3A7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZVByb3BlcnR5JyksXG4gICAgYmFzZVByb3BlcnR5RGVlcCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eURlZXAnKSxcbiAgICBpc0tleSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzS2V5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgYXQgYHBhdGhgIG9uIGFcbiAqIGdpdmVuIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbXG4gKiAgIHsgJ2EnOiB7ICdiJzogeyAnYyc6IDIgfSB9IH0sXG4gKiAgIHsgJ2EnOiB7ICdiJzogeyAnYyc6IDEgfSB9IH1cbiAqIF07XG4gKlxuICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iLmMnKSk7XG4gKiAvLyA9PiBbMiwgMV1cbiAqXG4gKiBfLnBsdWNrKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InLCAnYyddKSksICdhLmIuYycpO1xuICogLy8gPT4gWzEsIDJdXG4gKi9cbmZ1bmN0aW9uIHByb3BlcnR5KHBhdGgpIHtcbiAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHBhdGgpIDogYmFzZVByb3BlcnR5RGVlcChwYXRoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwcm9wZXJ0eTtcbiIsIihmdW5jdGlvbiAocHJvY2Vzcyl7XG4vLyB2aW06dHM9NDpzdHM9NDpzdz00OlxuLyohXG4gKlxuICogQ29weXJpZ2h0IDIwMDktMjAxMiBLcmlzIEtvd2FsIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUXG4gKiBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9naXRodWIuY29tL2tyaXNrb3dhbC9xL3Jhdy9tYXN0ZXIvTElDRU5TRVxuICpcbiAqIFdpdGggcGFydHMgYnkgVHlsZXIgQ2xvc2VcbiAqIENvcHlyaWdodCAyMDA3LTIwMDkgVHlsZXIgQ2xvc2UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgWCBsaWNlbnNlIGZvdW5kXG4gKiBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWxcbiAqIEZvcmtlZCBhdCByZWZfc2VuZC5qcyB2ZXJzaW9uOiAyMDA5LTA1LTExXG4gKlxuICogV2l0aCBwYXJ0cyBieSBNYXJrIE1pbGxlclxuICogQ29weXJpZ2h0IChDKSAyMDExIEdvb2dsZSBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbihmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgLy8gVGhpcyBmaWxlIHdpbGwgZnVuY3Rpb24gcHJvcGVybHkgYXMgYSA8c2NyaXB0PiB0YWcsIG9yIGEgbW9kdWxlXG4gICAgLy8gdXNpbmcgQ29tbW9uSlMgYW5kIE5vZGVKUyBvciBSZXF1aXJlSlMgbW9kdWxlIGZvcm1hdHMuICBJblxuICAgIC8vIENvbW1vbi9Ob2RlL1JlcXVpcmVKUywgdGhlIG1vZHVsZSBleHBvcnRzIHRoZSBRIEFQSSBhbmQgd2hlblxuICAgIC8vIGV4ZWN1dGVkIGFzIGEgc2ltcGxlIDxzY3JpcHQ+LCBpdCBjcmVhdGVzIGEgUSBnbG9iYWwgaW5zdGVhZC5cblxuICAgIC8vIE1vbnRhZ2UgUmVxdWlyZVxuICAgIGlmICh0eXBlb2YgYm9vdHN0cmFwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYm9vdHN0cmFwKFwicHJvbWlzZVwiLCBkZWZpbml0aW9uKTtcblxuICAgIC8vIENvbW1vbkpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZGVmaW5pdGlvbigpO1xuXG4gICAgLy8gUmVxdWlyZUpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZGVmaW5pdGlvbik7XG5cbiAgICAvLyBTRVMgKFNlY3VyZSBFY21hU2NyaXB0KVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNlcyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAoIXNlcy5vaygpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXMubWFrZVEgPSBkZWZpbml0aW9uO1xuICAgICAgICB9XG5cbiAgICAvLyA8c2NyaXB0PlxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiB8fCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBQcmVmZXIgd2luZG93IG92ZXIgc2VsZiBmb3IgYWRkLW9uIHNjcmlwdHMuIFVzZSBzZWxmIGZvclxuICAgICAgICAvLyBub24td2luZG93ZWQgY29udGV4dHMuXG4gICAgICAgIHZhciBnbG9iYWwgPSB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogc2VsZjtcblxuICAgICAgICAvLyBHZXQgdGhlIGB3aW5kb3dgIG9iamVjdCwgc2F2ZSB0aGUgcHJldmlvdXMgUSBnbG9iYWxcbiAgICAgICAgLy8gYW5kIGluaXRpYWxpemUgUSBhcyBhIGdsb2JhbC5cbiAgICAgICAgdmFyIHByZXZpb3VzUSA9IGdsb2JhbC5RO1xuICAgICAgICBnbG9iYWwuUSA9IGRlZmluaXRpb24oKTtcblxuICAgICAgICAvLyBBZGQgYSBub0NvbmZsaWN0IGZ1bmN0aW9uIHNvIFEgY2FuIGJlIHJlbW92ZWQgZnJvbSB0aGVcbiAgICAgICAgLy8gZ2xvYmFsIG5hbWVzcGFjZS5cbiAgICAgICAgZ2xvYmFsLlEubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGdsb2JhbC5RID0gcHJldmlvdXNRO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGVudmlyb25tZW50IHdhcyBub3QgYW50aWNpcGF0ZWQgYnkgUS4gUGxlYXNlIGZpbGUgYSBidWcuXCIpO1xuICAgIH1cblxufSkoZnVuY3Rpb24gKCkge1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBoYXNTdGFja3MgPSBmYWxzZTtcbnRyeSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG59IGNhdGNoIChlKSB7XG4gICAgaGFzU3RhY2tzID0gISFlLnN0YWNrO1xufVxuXG4vLyBBbGwgY29kZSBhZnRlciB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMgcmVwb3J0ZWRcbi8vIGJ5IFEuXG52YXIgcVN0YXJ0aW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG52YXIgcUZpbGVOYW1lO1xuXG4vLyBzaGltc1xuXG4vLyB1c2VkIGZvciBmYWxsYmFjayBpbiBcImFsbFJlc29sdmVkXCJcbnZhciBub29wID0gZnVuY3Rpb24gKCkge307XG5cbi8vIFVzZSB0aGUgZmFzdGVzdCBwb3NzaWJsZSBtZWFucyB0byBleGVjdXRlIGEgdGFzayBpbiBhIGZ1dHVyZSB0dXJuXG4vLyBvZiB0aGUgZXZlbnQgbG9vcC5cbnZhciBuZXh0VGljayA9KGZ1bmN0aW9uICgpIHtcbiAgICAvLyBsaW5rZWQgbGlzdCBvZiB0YXNrcyAoc2luZ2xlLCB3aXRoIGhlYWQgbm9kZSlcbiAgICB2YXIgaGVhZCA9IHt0YXNrOiB2b2lkIDAsIG5leHQ6IG51bGx9O1xuICAgIHZhciB0YWlsID0gaGVhZDtcbiAgICB2YXIgZmx1c2hpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVxdWVzdFRpY2sgPSB2b2lkIDA7XG4gICAgdmFyIGlzTm9kZUpTID0gZmFsc2U7XG4gICAgLy8gcXVldWUgZm9yIGxhdGUgdGFza3MsIHVzZWQgYnkgdW5oYW5kbGVkIHJlamVjdGlvbiB0cmFja2luZ1xuICAgIHZhciBsYXRlclF1ZXVlID0gW107XG5cbiAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgLyoganNoaW50IGxvb3BmdW5jOiB0cnVlICovXG4gICAgICAgIHZhciB0YXNrLCBkb21haW47XG5cbiAgICAgICAgd2hpbGUgKGhlYWQubmV4dCkge1xuICAgICAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgICAgICAgIHRhc2sgPSBoZWFkLnRhc2s7XG4gICAgICAgICAgICBoZWFkLnRhc2sgPSB2b2lkIDA7XG4gICAgICAgICAgICBkb21haW4gPSBoZWFkLmRvbWFpbjtcblxuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgIGhlYWQuZG9tYWluID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2ssIGRvbWFpbik7XG5cbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAobGF0ZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRhc2sgPSBsYXRlclF1ZXVlLnBvcCgpO1xuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2spO1xuICAgICAgICB9XG4gICAgICAgIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIC8vIHJ1bnMgYSBzaW5nbGUgZnVuY3Rpb24gaW4gdGhlIGFzeW5jIHF1ZXVlXG4gICAgZnVuY3Rpb24gcnVuU2luZ2xlKHRhc2ssIGRvbWFpbikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGFzaygpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChpc05vZGVKUykge1xuICAgICAgICAgICAgICAgIC8vIEluIG5vZGUsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIGNvbnNpZGVyZWQgZmF0YWwgZXJyb3JzLlxuICAgICAgICAgICAgICAgIC8vIFJlLXRocm93IHRoZW0gc3luY2hyb25vdXNseSB0byBpbnRlcnJ1cHQgZmx1c2hpbmchXG5cbiAgICAgICAgICAgICAgICAvLyBFbnN1cmUgY29udGludWF0aW9uIGlmIHRoZSB1bmNhdWdodCBleGNlcHRpb24gaXMgc3VwcHJlc3NlZFxuICAgICAgICAgICAgICAgIC8vIGxpc3RlbmluZyBcInVuY2F1Z2h0RXhjZXB0aW9uXCIgZXZlbnRzIChhcyBkb21haW5zIGRvZXMpLlxuICAgICAgICAgICAgICAgIC8vIENvbnRpbnVlIGluIG5leHQgZXZlbnQgdG8gYXZvaWQgdGljayByZWN1cnNpb24uXG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IGU7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gYnJvd3NlcnMsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIG5vdCBmYXRhbC5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIGFzeW5jaHJvbm91c2x5IHRvIGF2b2lkIHNsb3ctZG93bnMuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV4dFRpY2sgPSBmdW5jdGlvbiAodGFzaykge1xuICAgICAgICB0YWlsID0gdGFpbC5uZXh0ID0ge1xuICAgICAgICAgICAgdGFzazogdGFzayxcbiAgICAgICAgICAgIGRvbWFpbjogaXNOb2RlSlMgJiYgcHJvY2Vzcy5kb21haW4sXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgcHJvY2Vzcy50b1N0cmluZygpID09PSBcIltvYmplY3QgcHJvY2Vzc11cIiAmJiBwcm9jZXNzLm5leHRUaWNrKSB7XG4gICAgICAgIC8vIEVuc3VyZSBRIGlzIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50LCB3aXRoIGEgYHByb2Nlc3MubmV4dFRpY2tgLlxuICAgICAgICAvLyBUbyBzZWUgdGhyb3VnaCBmYWtlIE5vZGUgZW52aXJvbm1lbnRzOlxuICAgICAgICAvLyAqIE1vY2hhIHRlc3QgcnVubmVyIC0gZXhwb3NlcyBhIGBwcm9jZXNzYCBnbG9iYWwgd2l0aG91dCBhIGBuZXh0VGlja2BcbiAgICAgICAgLy8gKiBCcm93c2VyaWZ5IC0gZXhwb3NlcyBhIGBwcm9jZXNzLm5leFRpY2tgIGZ1bmN0aW9uIHRoYXQgdXNlc1xuICAgICAgICAvLyAgIGBzZXRUaW1lb3V0YC4gSW4gdGhpcyBjYXNlIGBzZXRJbW1lZGlhdGVgIGlzIHByZWZlcnJlZCBiZWNhdXNlXG4gICAgICAgIC8vICAgIGl0IGlzIGZhc3Rlci4gQnJvd3NlcmlmeSdzIGBwcm9jZXNzLnRvU3RyaW5nKClgIHlpZWxkc1xuICAgICAgICAvLyAgIFwiW29iamVjdCBPYmplY3RdXCIsIHdoaWxlIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50XG4gICAgICAgIC8vICAgYHByb2Nlc3MubmV4dFRpY2soKWAgeWllbGRzIFwiW29iamVjdCBwcm9jZXNzXVwiLlxuICAgICAgICBpc05vZGVKUyA9IHRydWU7XG5cbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIC8vIEluIElFMTAsIE5vZGUuanMgMC45Kywgb3IgaHR0cHM6Ly9naXRodWIuY29tL05vYmxlSlMvc2V0SW1tZWRpYXRlXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByZXF1ZXN0VGljayA9IHNldEltbWVkaWF0ZS5iaW5kKHdpbmRvdywgZmx1c2gpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1tZWRpYXRlKGZsdXNoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIC8vIG1vZGVybiBicm93c2Vyc1xuICAgICAgICAvLyBodHRwOi8vd3d3Lm5vbmJsb2NraW5nLmlvLzIwMTEvMDYvd2luZG93bmV4dHRpY2suaHRtbFxuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICAvLyBBdCBsZWFzdCBTYWZhcmkgVmVyc2lvbiA2LjAuNSAoODUzNi4zMC4xKSBpbnRlcm1pdHRlbnRseSBjYW5ub3QgY3JlYXRlXG4gICAgICAgIC8vIHdvcmtpbmcgbWVzc2FnZSBwb3J0cyB0aGUgZmlyc3QgdGltZSBhIHBhZ2UgbG9hZHMuXG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSByZXF1ZXN0UG9ydFRpY2s7XG4gICAgICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZsdXNoO1xuICAgICAgICAgICAgZmx1c2goKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHJlcXVlc3RQb3J0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIE9wZXJhIHJlcXVpcmVzIHVzIHRvIHByb3ZpZGUgYSBtZXNzYWdlIHBheWxvYWQsIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgICAgICAgIC8vIHdoZXRoZXIgd2UgdXNlIGl0LlxuICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgIHJlcXVlc3RQb3J0VGljaygpO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb2xkIGJyb3dzZXJzXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vIHJ1bnMgYSB0YXNrIGFmdGVyIGFsbCBvdGhlciB0YXNrcyBoYXZlIGJlZW4gcnVuXG4gICAgLy8gdGhpcyBpcyB1c2VmdWwgZm9yIHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmcgdGhhdCBuZWVkcyB0byBoYXBwZW5cbiAgICAvLyBhZnRlciBhbGwgYHRoZW5gZCB0YXNrcyBoYXZlIGJlZW4gcnVuLlxuICAgIG5leHRUaWNrLnJ1bkFmdGVyID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgbGF0ZXJRdWV1ZS5wdXNoKHRhc2spO1xuICAgICAgICBpZiAoIWZsdXNoaW5nKSB7XG4gICAgICAgICAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgICAgICAgICByZXF1ZXN0VGljaygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gbmV4dFRpY2s7XG59KSgpO1xuXG4vLyBBdHRlbXB0IHRvIG1ha2UgZ2VuZXJpY3Mgc2FmZSBpbiB0aGUgZmFjZSBvZiBkb3duc3RyZWFtXG4vLyBtb2RpZmljYXRpb25zLlxuLy8gVGhlcmUgaXMgbm8gc2l0dWF0aW9uIHdoZXJlIHRoaXMgaXMgbmVjZXNzYXJ5LlxuLy8gSWYgeW91IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsIHRoZXNlIHByaW1vcmRpYWxzIG5lZWQgdG8gYmVcbi8vIGRlZXBseSBmcm96ZW4gYW55d2F5LCBhbmQgaWYgeW91IGRvbuKAmXQgbmVlZCBhIHNlY3VyaXR5IGd1YXJhbnRlZSxcbi8vIHRoaXMgaXMganVzdCBwbGFpbiBwYXJhbm9pZC5cbi8vIEhvd2V2ZXIsIHRoaXMgKiptaWdodCoqIGhhdmUgdGhlIG5pY2Ugc2lkZS1lZmZlY3Qgb2YgcmVkdWNpbmcgdGhlIHNpemUgb2Zcbi8vIHRoZSBtaW5pZmllZCBjb2RlIGJ5IHJlZHVjaW5nIHguY2FsbCgpIHRvIG1lcmVseSB4KClcbi8vIFNlZSBNYXJrIE1pbGxlcuKAmXMgZXhwbGFuYXRpb24gb2Ygd2hhdCB0aGlzIGRvZXMuXG4vLyBodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1jb252ZW50aW9uczpzYWZlX21ldGFfcHJvZ3JhbW1pbmdcbnZhciBjYWxsID0gRnVuY3Rpb24uY2FsbDtcbmZ1bmN0aW9uIHVuY3VycnlUaGlzKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gY2FsbC5hcHBseShmLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG4vLyBUaGlzIGlzIGVxdWl2YWxlbnQsIGJ1dCBzbG93ZXI6XG4vLyB1bmN1cnJ5VGhpcyA9IEZ1bmN0aW9uX2JpbmQuYmluZChGdW5jdGlvbl9iaW5kLmNhbGwpO1xuLy8gaHR0cDovL2pzcGVyZi5jb20vdW5jdXJyeXRoaXNcblxudmFyIGFycmF5X3NsaWNlID0gdW5jdXJyeVRoaXMoQXJyYXkucHJvdG90eXBlLnNsaWNlKTtcblxudmFyIGFycmF5X3JlZHVjZSA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgfHwgZnVuY3Rpb24gKGNhbGxiYWNrLCBiYXNpcykge1xuICAgICAgICB2YXIgaW5kZXggPSAwLFxuICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIC8vIGNvbmNlcm5pbmcgdGhlIGluaXRpYWwgdmFsdWUsIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIHNlZWsgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBhcnJheSwgYWNjb3VudGluZ1xuICAgICAgICAgICAgLy8gZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGlzIGlzIGEgc3BhcnNlIGFycmF5XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICAgICAgYmFzaXMgPSB0aGlzW2luZGV4KytdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCsraW5kZXggPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlICgxKTtcbiAgICAgICAgfVxuICAgICAgICAvLyByZWR1Y2VcbiAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAvLyBhY2NvdW50IGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgYXJyYXkgaXMgc3BhcnNlXG4gICAgICAgICAgICBpZiAoaW5kZXggaW4gdGhpcykge1xuICAgICAgICAgICAgICAgIGJhc2lzID0gY2FsbGJhY2soYmFzaXMsIHRoaXNbaW5kZXhdLCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2lzO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9pbmRleE9mID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgfHwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5vdCBhIHZlcnkgZ29vZCBzaGltLCBidXQgZ29vZCBlbm91Z2ggZm9yIG91ciBvbmUgdXNlIG9mIGl0XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXNbaV0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9tYXAgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUubWFwIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgdGhpc3ApIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgY29sbGVjdCA9IFtdO1xuICAgICAgICBhcnJheV9yZWR1Y2Uoc2VsZiwgZnVuY3Rpb24gKHVuZGVmaW5lZCwgdmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICBjb2xsZWN0LnB1c2goY2FsbGJhY2suY2FsbCh0aGlzcCwgdmFsdWUsIGluZGV4LCBzZWxmKSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0O1xuICAgIH1cbik7XG5cbnZhciBvYmplY3RfY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiAocHJvdG90eXBlKSB7XG4gICAgZnVuY3Rpb24gVHlwZSgpIHsgfVxuICAgIFR5cGUucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgIHJldHVybiBuZXcgVHlwZSgpO1xufTtcblxudmFyIG9iamVjdF9oYXNPd25Qcm9wZXJ0eSA9IHVuY3VycnlUaGlzKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkpO1xuXG52YXIgb2JqZWN0X2tleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3RfaGFzT3duUHJvcGVydHkob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5cztcbn07XG5cbnZhciBvYmplY3RfdG9TdHJpbmcgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKTtcblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IE9iamVjdCh2YWx1ZSk7XG59XG5cbi8vIGdlbmVyYXRvciByZWxhdGVkIHNoaW1zXG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBmdW5jdGlvbiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG5mdW5jdGlvbiBpc1N0b3BJdGVyYXRpb24oZXhjZXB0aW9uKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgb2JqZWN0X3RvU3RyaW5nKGV4Y2VwdGlvbikgPT09IFwiW29iamVjdCBTdG9wSXRlcmF0aW9uXVwiIHx8XG4gICAgICAgIGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFFSZXR1cm5WYWx1ZVxuICAgICk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBoZWxwZXIgYW5kIFEucmV0dXJuIG9uY2UgRVM2IGdlbmVyYXRvcnMgYXJlIGluXG4vLyBTcGlkZXJNb25rZXkuXG52YXIgUVJldHVyblZhbHVlO1xuaWYgKHR5cGVvZiBSZXR1cm5WYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIFFSZXR1cm5WYWx1ZSA9IFJldHVyblZhbHVlO1xufSBlbHNlIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH07XG59XG5cbi8vIGxvbmcgc3RhY2sgdHJhY2VzXG5cbnZhciBTVEFDS19KVU1QX1NFUEFSQVRPUiA9IFwiRnJvbSBwcmV2aW91cyBldmVudDpcIjtcblxuZnVuY3Rpb24gbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKSB7XG4gICAgLy8gSWYgcG9zc2libGUsIHRyYW5zZm9ybSB0aGUgZXJyb3Igc3RhY2sgdHJhY2UgYnkgcmVtb3ZpbmcgTm9kZSBhbmQgUVxuICAgIC8vIGNydWZ0LCB0aGVuIGNvbmNhdGVuYXRpbmcgd2l0aCB0aGUgc3RhY2sgdHJhY2Ugb2YgYHByb21pc2VgLiBTZWUgIzU3LlxuICAgIGlmIChoYXNTdGFja3MgJiZcbiAgICAgICAgcHJvbWlzZS5zdGFjayAmJlxuICAgICAgICB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgZXJyb3IgIT09IG51bGwgJiZcbiAgICAgICAgZXJyb3Iuc3RhY2sgJiZcbiAgICAgICAgZXJyb3Iuc3RhY2suaW5kZXhPZihTVEFDS19KVU1QX1NFUEFSQVRPUikgPT09IC0xXG4gICAgKSB7XG4gICAgICAgIHZhciBzdGFja3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgcCA9IHByb21pc2U7ICEhcDsgcCA9IHAuc291cmNlKSB7XG4gICAgICAgICAgICBpZiAocC5zdGFjaykge1xuICAgICAgICAgICAgICAgIHN0YWNrcy51bnNoaWZ0KHAuc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YWNrcy51bnNoaWZ0KGVycm9yLnN0YWNrKTtcblxuICAgICAgICB2YXIgY29uY2F0ZWRTdGFja3MgPSBzdGFja3Muam9pbihcIlxcblwiICsgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgKyBcIlxcblwiKTtcbiAgICAgICAgZXJyb3Iuc3RhY2sgPSBmaWx0ZXJTdGFja1N0cmluZyhjb25jYXRlZFN0YWNrcyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaWx0ZXJTdGFja1N0cmluZyhzdGFja1N0cmluZykge1xuICAgIHZhciBsaW5lcyA9IHN0YWNrU3RyaW5nLnNwbGl0KFwiXFxuXCIpO1xuICAgIHZhciBkZXNpcmVkTGluZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZXNbaV07XG5cbiAgICAgICAgaWYgKCFpc0ludGVybmFsRnJhbWUobGluZSkgJiYgIWlzTm9kZUZyYW1lKGxpbmUpICYmIGxpbmUpIHtcbiAgICAgICAgICAgIGRlc2lyZWRMaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXNpcmVkTGluZXMuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaXNOb2RlRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgcmV0dXJuIHN0YWNrTGluZS5pbmRleE9mKFwiKG1vZHVsZS5qczpcIikgIT09IC0xIHx8XG4gICAgICAgICAgIHN0YWNrTGluZS5pbmRleE9mKFwiKG5vZGUuanM6XCIpICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSkge1xuICAgIC8vIE5hbWVkIGZ1bmN0aW9uczogXCJhdCBmdW5jdGlvbk5hbWUgKGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyKVwiXG4gICAgLy8gSW4gSUUxMCBmdW5jdGlvbiBuYW1lIGNhbiBoYXZlIHNwYWNlcyAoXCJBbm9ueW1vdXMgZnVuY3Rpb25cIikgT19vXG4gICAgdmFyIGF0dGVtcHQxID0gL2F0IC4rIFxcKCguKyk6KFxcZCspOig/OlxcZCspXFwpJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0MSkge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQxWzFdLCBOdW1iZXIoYXR0ZW1wdDFbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBBbm9ueW1vdXMgZnVuY3Rpb25zOiBcImF0IGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyXCJcbiAgICB2YXIgYXR0ZW1wdDIgPSAvYXQgKFteIF0rKTooXFxkKyk6KD86XFxkKykkLy5leGVjKHN0YWNrTGluZSk7XG4gICAgaWYgKGF0dGVtcHQyKSB7XG4gICAgICAgIHJldHVybiBbYXR0ZW1wdDJbMV0sIE51bWJlcihhdHRlbXB0MlsyXSldO1xuICAgIH1cblxuICAgIC8vIEZpcmVmb3ggc3R5bGU6IFwiZnVuY3Rpb25AZmlsZW5hbWU6bGluZU51bWJlciBvciBAZmlsZW5hbWU6bGluZU51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQzID0gLy4qQCguKyk6KFxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mykge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQzWzFdLCBOdW1iZXIoYXR0ZW1wdDNbMl0pXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzSW50ZXJuYWxGcmFtZShzdGFja0xpbmUpIHtcbiAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSk7XG5cbiAgICBpZiAoIWZpbGVOYW1lQW5kTGluZU51bWJlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGZpbGVOYW1lID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzBdO1xuICAgIHZhciBsaW5lTnVtYmVyID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzFdO1xuXG4gICAgcmV0dXJuIGZpbGVOYW1lID09PSBxRmlsZU5hbWUgJiZcbiAgICAgICAgbGluZU51bWJlciA+PSBxU3RhcnRpbmdMaW5lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPD0gcUVuZGluZ0xpbmU7XG59XG5cbi8vIGRpc2NvdmVyIG93biBmaWxlIG5hbWUgYW5kIGxpbmUgbnVtYmVyIHJhbmdlIGZvciBmaWx0ZXJpbmcgc3RhY2tcbi8vIHRyYWNlc1xuZnVuY3Rpb24gY2FwdHVyZUxpbmUoKSB7XG4gICAgaWYgKCFoYXNTdGFja3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gZS5zdGFjay5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgdmFyIGZpcnN0TGluZSA9IGxpbmVzWzBdLmluZGV4T2YoXCJAXCIpID4gMCA/IGxpbmVzWzFdIDogbGluZXNbMl07XG4gICAgICAgIHZhciBmaWxlTmFtZUFuZExpbmVOdW1iZXIgPSBnZXRGaWxlTmFtZUFuZExpbmVOdW1iZXIoZmlyc3RMaW5lKTtcbiAgICAgICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHFGaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZShjYWxsYmFjaywgbmFtZSwgYWx0ZXJuYXRpdmUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLndhcm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKG5hbWUgKyBcIiBpcyBkZXByZWNhdGVkLCB1c2UgXCIgKyBhbHRlcm5hdGl2ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgXCIgaW5zdGVhZC5cIiwgbmV3IEVycm9yKFwiXCIpLnN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoY2FsbGJhY2ssIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuLy8gZW5kIG9mIHNoaW1zXG4vLyBiZWdpbm5pbmcgb2YgcmVhbCB3b3JrXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UsIHBhc3NlcyBwcm9taXNlcyB0aHJvdWdoLCBvclxuICogY29lcmNlcyBwcm9taXNlcyBmcm9tIGRpZmZlcmVudCBzeXN0ZW1zLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2Ugb3IgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBRKHZhbHVlKSB7XG4gICAgLy8gSWYgdGhlIG9iamVjdCBpcyBhbHJlYWR5IGEgUHJvbWlzZSwgcmV0dXJuIGl0IGRpcmVjdGx5LiAgVGhpcyBlbmFibGVzXG4gICAgLy8gdGhlIHJlc29sdmUgZnVuY3Rpb24gdG8gYm90aCBiZSB1c2VkIHRvIGNyZWF0ZWQgcmVmZXJlbmNlcyBmcm9tIG9iamVjdHMsXG4gICAgLy8gYnV0IHRvIHRvbGVyYWJseSBjb2VyY2Ugbm9uLXByb21pc2VzIHRvIHByb21pc2VzLlxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8vIGFzc2ltaWxhdGUgdGhlbmFibGVzXG4gICAgaWYgKGlzUHJvbWlzZUFsaWtlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gY29lcmNlKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZnVsZmlsbCh2YWx1ZSk7XG4gICAgfVxufVxuUS5yZXNvbHZlID0gUTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIHRhc2sgaW4gYSBmdXR1cmUgdHVybiBvZiB0aGUgZXZlbnQgbG9vcC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRhc2tcbiAqL1xuUS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4vKipcbiAqIENvbnRyb2xzIHdoZXRoZXIgb3Igbm90IGxvbmcgc3RhY2sgdHJhY2VzIHdpbGwgYmUgb25cbiAqL1xuUS5sb25nU3RhY2tTdXBwb3J0ID0gZmFsc2U7XG5cbi8vIGVuYWJsZSBsb25nIHN0YWNrcyBpZiBRX0RFQlVHIGlzIHNldFxuaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYgJiYgcHJvY2Vzcy5lbnYuUV9ERUJVRykge1xuICAgIFEubG9uZ1N0YWNrU3VwcG9ydCA9IHRydWU7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHtwcm9taXNlLCByZXNvbHZlLCByZWplY3R9IG9iamVjdC5cbiAqXG4gKiBgcmVzb2x2ZWAgaXMgYSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBhIG1vcmUgcmVzb2x2ZWQgdmFsdWUgZm9yIHRoZVxuICogcHJvbWlzZS4gVG8gZnVsZmlsbCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGFueSB2YWx1ZSB0aGF0IGlzXG4gKiBub3QgYSB0aGVuYWJsZS4gVG8gcmVqZWN0IHRoZSBwcm9taXNlLCBpbnZva2UgYHJlc29sdmVgIHdpdGggYSByZWplY3RlZFxuICogdGhlbmFibGUsIG9yIGludm9rZSBgcmVqZWN0YCB3aXRoIHRoZSByZWFzb24gZGlyZWN0bHkuIFRvIHJlc29sdmUgdGhlXG4gKiBwcm9taXNlIHRvIGFub3RoZXIgdGhlbmFibGUsIHRodXMgcHV0dGluZyBpdCBpbiB0aGUgc2FtZSBzdGF0ZSwgaW52b2tlXG4gKiBgcmVzb2x2ZWAgd2l0aCB0aGF0IG90aGVyIHRoZW5hYmxlLlxuICovXG5RLmRlZmVyID0gZGVmZXI7XG5mdW5jdGlvbiBkZWZlcigpIHtcbiAgICAvLyBpZiBcIm1lc3NhZ2VzXCIgaXMgYW4gXCJBcnJheVwiLCB0aGF0IGluZGljYXRlcyB0aGF0IHRoZSBwcm9taXNlIGhhcyBub3QgeWV0XG4gICAgLy8gYmVlbiByZXNvbHZlZC4gIElmIGl0IGlzIFwidW5kZWZpbmVkXCIsIGl0IGhhcyBiZWVuIHJlc29sdmVkLiAgRWFjaFxuICAgIC8vIGVsZW1lbnQgb2YgdGhlIG1lc3NhZ2VzIGFycmF5IGlzIGl0c2VsZiBhbiBhcnJheSBvZiBjb21wbGV0ZSBhcmd1bWVudHMgdG9cbiAgICAvLyBmb3J3YXJkIHRvIHRoZSByZXNvbHZlZCBwcm9taXNlLiAgV2UgY29lcmNlIHRoZSByZXNvbHV0aW9uIHZhbHVlIHRvIGFcbiAgICAvLyBwcm9taXNlIHVzaW5nIHRoZSBgcmVzb2x2ZWAgZnVuY3Rpb24gYmVjYXVzZSBpdCBoYW5kbGVzIGJvdGggZnVsbHlcbiAgICAvLyBub24tdGhlbmFibGUgdmFsdWVzIGFuZCBvdGhlciB0aGVuYWJsZXMgZ3JhY2VmdWxseS5cbiAgICB2YXIgbWVzc2FnZXMgPSBbXSwgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBbXSwgcmVzb2x2ZWRQcm9taXNlO1xuXG4gICAgdmFyIGRlZmVycmVkID0gb2JqZWN0X2NyZWF0ZShkZWZlci5wcm90b3R5cGUpO1xuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgb3BlcmFuZHMpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2VzLnB1c2goYXJncyk7XG4gICAgICAgICAgICBpZiAob3AgPT09IFwid2hlblwiICYmIG9wZXJhbmRzWzFdKSB7IC8vIHByb2dyZXNzIG9wZXJhbmRcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVycy5wdXNoKG9wZXJhbmRzWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkocmVzb2x2ZWRQcm9taXNlLCBhcmdzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkXG4gICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZWFyZXJWYWx1ZSA9IG5lYXJlcihyZXNvbHZlZFByb21pc2UpO1xuICAgICAgICBpZiAoaXNQcm9taXNlKG5lYXJlclZhbHVlKSkge1xuICAgICAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmVhcmVyVmFsdWU7IC8vIHNob3J0ZW4gY2hhaW5cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmVhcmVyVmFsdWU7XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHN0YXRlOiBcInBlbmRpbmdcIiB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNvbHZlZFByb21pc2UuaW5zcGVjdCgpO1xuICAgIH07XG5cbiAgICBpZiAoUS5sb25nU3RhY2tTdXBwb3J0ICYmIGhhc1N0YWNrcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGRvbid0IHRyeSB0byB1c2UgYEVycm9yLmNhcHR1cmVTdGFja1RyYWNlYCBvciB0cmFuc2ZlciB0aGVcbiAgICAgICAgICAgIC8vIGFjY2Vzc29yIGFyb3VuZDsgdGhhdCBjYXVzZXMgbWVtb3J5IGxlYWtzIGFzIHBlciBHSC0xMTEuIEp1c3RcbiAgICAgICAgICAgIC8vIHJlaWZ5IHRoZSBzdGFjayB0cmFjZSBhcyBhIHN0cmluZyBBU0FQLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEF0IHRoZSBzYW1lIHRpbWUsIGN1dCBvZmYgdGhlIGZpcnN0IGxpbmU7IGl0J3MgYWx3YXlzIGp1c3RcbiAgICAgICAgICAgIC8vIFwiW29iamVjdCBQcm9taXNlXVxcblwiLCBhcyBwZXIgdGhlIGB0b1N0cmluZ2AuXG4gICAgICAgICAgICBwcm9taXNlLnN0YWNrID0gZS5zdGFjay5zdWJzdHJpbmcoZS5zdGFjay5pbmRleE9mKFwiXFxuXCIpICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOT1RFOiB3ZSBkbyB0aGUgY2hlY2tzIGZvciBgcmVzb2x2ZWRQcm9taXNlYCBpbiBlYWNoIG1ldGhvZCwgaW5zdGVhZCBvZlxuICAgIC8vIGNvbnNvbGlkYXRpbmcgdGhlbSBpbnRvIGBiZWNvbWVgLCBzaW5jZSBvdGhlcndpc2Ugd2UnZCBjcmVhdGUgbmV3XG4gICAgLy8gcHJvbWlzZXMgd2l0aCB0aGUgbGluZXMgYGJlY29tZSh3aGF0ZXZlcih2YWx1ZSkpYC4gU2VlIGUuZy4gR0gtMjUyLlxuXG4gICAgZnVuY3Rpb24gYmVjb21lKG5ld1Byb21pc2UpIHtcbiAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmV3UHJvbWlzZTtcbiAgICAgICAgcHJvbWlzZS5zb3VyY2UgPSBuZXdQcm9taXNlO1xuXG4gICAgICAgIGFycmF5X3JlZHVjZShtZXNzYWdlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgbWVzc2FnZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbmV3UHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkobmV3UHJvbWlzZSwgbWVzc2FnZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcblxuICAgICAgICBtZXNzYWdlcyA9IHZvaWQgMDtcbiAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSB2b2lkIDA7XG4gICAgfVxuXG4gICAgZGVmZXJyZWQucHJvbWlzZSA9IHByb21pc2U7XG4gICAgZGVmZXJyZWQucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoUSh2YWx1ZSkpO1xuICAgIH07XG5cbiAgICBkZWZlcnJlZC5mdWxmaWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShmdWxmaWxsKHZhbHVlKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShyZWplY3QocmVhc29uKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5ub3RpZnkgPSBmdW5jdGlvbiAocHJvZ3Jlc3MpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJyYXlfcmVkdWNlKHByb2dyZXNzTGlzdGVuZXJzLCBmdW5jdGlvbiAodW5kZWZpbmVkLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHByb2dyZXNzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgIH07XG5cbiAgICByZXR1cm4gZGVmZXJyZWQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIE5vZGUtc3R5bGUgY2FsbGJhY2sgdGhhdCB3aWxsIHJlc29sdmUgb3IgcmVqZWN0IHRoZSBkZWZlcnJlZFxuICogcHJvbWlzZS5cbiAqIEByZXR1cm5zIGEgbm9kZWJhY2tcbiAqL1xuZGVmZXIucHJvdG90eXBlLm1ha2VOb2RlUmVzb2x2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHZhbHVlKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgc2VsZi5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUoYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHJlc29sdmVyIHtGdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgbm90aGluZyBhbmQgYWNjZXB0c1xuICogdGhlIHJlc29sdmUsIHJlamVjdCwgYW5kIG5vdGlmeSBmdW5jdGlvbnMgZm9yIGEgZGVmZXJyZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCBtYXkgYmUgcmVzb2x2ZWQgd2l0aCB0aGUgZ2l2ZW4gcmVzb2x2ZSBhbmQgcmVqZWN0XG4gKiBmdW5jdGlvbnMsIG9yIHJlamVjdGVkIGJ5IGEgdGhyb3duIGV4Y2VwdGlvbiBpbiByZXNvbHZlclxuICovXG5RLlByb21pc2UgPSBwcm9taXNlOyAvLyBFUzZcblEucHJvbWlzZSA9IHByb21pc2U7XG5mdW5jdGlvbiBwcm9taXNlKHJlc29sdmVyKSB7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJyZXNvbHZlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO1xuICAgIH1cbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVyKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICB9IGNhdGNoIChyZWFzb24pIHtcbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlYXNvbik7XG4gICAgfVxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG5wcm9taXNlLnJhY2UgPSByYWNlOyAvLyBFUzZcbnByb21pc2UuYWxsID0gYWxsOyAvLyBFUzZcbnByb21pc2UucmVqZWN0ID0gcmVqZWN0OyAvLyBFUzZcbnByb21pc2UucmVzb2x2ZSA9IFE7IC8vIEVTNlxuXG4vLyBYWFggZXhwZXJpbWVudGFsLiAgVGhpcyBtZXRob2QgaXMgYSB3YXkgdG8gZGVub3RlIHRoYXQgYSBsb2NhbCB2YWx1ZSBpc1xuLy8gc2VyaWFsaXphYmxlIGFuZCBzaG91bGQgYmUgaW1tZWRpYXRlbHkgZGlzcGF0Y2hlZCB0byBhIHJlbW90ZSB1cG9uIHJlcXVlc3QsXG4vLyBpbnN0ZWFkIG9mIHBhc3NpbmcgYSByZWZlcmVuY2UuXG5RLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gb2JqZWN0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUucGFzc0J5Q29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvL2ZyZWV6ZShvYmplY3QpO1xuICAgIC8vcGFzc0J5Q29waWVzLnNldChvYmplY3QsIHRydWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBJZiB0d28gcHJvbWlzZXMgZXZlbnR1YWxseSBmdWxmaWxsIHRvIHRoZSBzYW1lIHZhbHVlLCBwcm9taXNlcyB0aGF0IHZhbHVlLFxuICogYnV0IG90aGVyd2lzZSByZWplY3RzLlxuICogQHBhcmFtIHgge0FueSp9XG4gKiBAcGFyYW0geSB7QW55Kn1cbiAqIEByZXR1cm5zIHtBbnkqfSBhIHByb21pc2UgZm9yIHggYW5kIHkgaWYgdGhleSBhcmUgdGhlIHNhbWUsIGJ1dCBhIHJlamVjdGlvblxuICogb3RoZXJ3aXNlLlxuICpcbiAqL1xuUS5qb2luID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gUSh4KS5qb2luKHkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uICh0aGF0KSB7XG4gICAgcmV0dXJuIFEoW3RoaXMsIHRoYXRdKS5zcHJlYWQoZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgaWYgKHggPT09IHkpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IFwiPT09XCIgc2hvdWxkIGJlIE9iamVjdC5pcyBvciBlcXVpdlxuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBqb2luOiBub3QgdGhlIHNhbWU6IFwiICsgeCArIFwiIFwiICsgeSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBmaXJzdCBvZiBhbiBhcnJheSBvZiBwcm9taXNlcyB0byBiZWNvbWUgc2V0dGxlZC5cbiAqIEBwYXJhbSBhbnN3ZXJzIHtBcnJheVtBbnkqXX0gcHJvbWlzZXMgdG8gcmFjZVxuICogQHJldHVybnMge0FueSp9IHRoZSBmaXJzdCBwcm9taXNlIHRvIGJlIHNldHRsZWRcbiAqL1xuUS5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoYW5zd2VyUHMpIHtcbiAgICByZXR1cm4gcHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIFN3aXRjaCB0byB0aGlzIG9uY2Ugd2UgY2FuIGFzc3VtZSBhdCBsZWFzdCBFUzVcbiAgICAgICAgLy8gYW5zd2VyUHMuZm9yRWFjaChmdW5jdGlvbiAoYW5zd2VyUCkge1xuICAgICAgICAvLyAgICAgUShhbnN3ZXJQKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIC8vIH0pO1xuICAgICAgICAvLyBVc2UgdGhpcyBpbiB0aGUgbWVhbnRpbWVcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFuc3dlclBzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBRKGFuc3dlclBzW2ldKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUucmFjZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKFEucmFjZSk7XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBQcm9taXNlIHdpdGggYSBwcm9taXNlIGRlc2NyaXB0b3Igb2JqZWN0IGFuZCBvcHRpb25hbCBmYWxsYmFja1xuICogZnVuY3Rpb24uICBUaGUgZGVzY3JpcHRvciBjb250YWlucyBtZXRob2RzIGxpa2Ugd2hlbihyZWplY3RlZCksIGdldChuYW1lKSxcbiAqIHNldChuYW1lLCB2YWx1ZSksIHBvc3QobmFtZSwgYXJncyksIGFuZCBkZWxldGUobmFtZSksIHdoaWNoIGFsbFxuICogcmV0dXJuIGVpdGhlciBhIHZhbHVlLCBhIHByb21pc2UgZm9yIGEgdmFsdWUsIG9yIGEgcmVqZWN0aW9uLiAgVGhlIGZhbGxiYWNrXG4gKiBhY2NlcHRzIHRoZSBvcGVyYXRpb24gbmFtZSwgYSByZXNvbHZlciwgYW5kIGFueSBmdXJ0aGVyIGFyZ3VtZW50cyB0aGF0IHdvdWxkXG4gKiBoYXZlIGJlZW4gZm9yd2FyZGVkIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXRob2QgYWJvdmUgaGFkIGEgbWV0aG9kIGJlZW5cbiAqIHByb3ZpZGVkIHdpdGggdGhlIHByb3BlciBuYW1lLiAgVGhlIEFQSSBtYWtlcyBubyBndWFyYW50ZWVzIGFib3V0IHRoZSBuYXR1cmVcbiAqIG9mIHRoZSByZXR1cm5lZCBvYmplY3QsIGFwYXJ0IGZyb20gdGhhdCBpdCBpcyB1c2FibGUgd2hlcmVldmVyIHByb21pc2VzIGFyZVxuICogYm91Z2h0IGFuZCBzb2xkLlxuICovXG5RLm1ha2VQcm9taXNlID0gUHJvbWlzZTtcbmZ1bmN0aW9uIFByb21pc2UoZGVzY3JpcHRvciwgZmFsbGJhY2ssIGluc3BlY3QpIHtcbiAgICBpZiAoZmFsbGJhY2sgPT09IHZvaWQgMCkge1xuICAgICAgICBmYWxsYmFjayA9IGZ1bmN0aW9uIChvcCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJQcm9taXNlIGRvZXMgbm90IHN1cHBvcnQgb3BlcmF0aW9uOiBcIiArIG9wXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGluc3BlY3QgPT09IHZvaWQgMCkge1xuICAgICAgICBpbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZTogXCJ1bmtub3duXCJ9O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgYXJncykge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3Jbb3BdKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZGVzY3JpcHRvcltvcF0uYXBwbHkocHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbGxiYWNrLmNhbGwocHJvbWlzZSwgb3AsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlKSB7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJvbWlzZS5pbnNwZWN0ID0gaW5zcGVjdDtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkIGB2YWx1ZU9mYCBhbmQgYGV4Y2VwdGlvbmAgc3VwcG9ydFxuICAgIGlmIChpbnNwZWN0KSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgICAgcHJvbWlzZS5leGNlcHRpb24gPSBpbnNwZWN0ZWQucmVhc29uO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGluc3BlY3RlZCA9IGluc3BlY3QoKTtcbiAgICAgICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicGVuZGluZ1wiIHx8XG4gICAgICAgICAgICAgICAgaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBcIltvYmplY3QgUHJvbWlzZV1cIjtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbiAoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBkb25lID0gZmFsc2U7ICAgLy8gZW5zdXJlIHRoZSB1bnRydXN0ZWQgcHJvbWlzZSBtYWtlcyBhdCBtb3N0IGFcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpbmdsZSBjYWxsIHRvIG9uZSBvZiB0aGUgY2FsbGJhY2tzXG5cbiAgICBmdW5jdGlvbiBfZnVsZmlsbGVkKHZhbHVlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGZ1bGZpbGxlZCA9PT0gXCJmdW5jdGlvblwiID8gZnVsZmlsbGVkKHZhbHVlKSA6IHZhbHVlO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9yZWplY3RlZChleGNlcHRpb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZWplY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXhjZXB0aW9uLCBzZWxmKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkKGV4Y2VwdGlvbik7XG4gICAgICAgICAgICB9IGNhdGNoIChuZXdFeGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ld0V4Y2VwdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wcm9ncmVzc2VkKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcHJvZ3Jlc3NlZCA9PT0gXCJmdW5jdGlvblwiID8gcHJvZ3Jlc3NlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5wcm9taXNlRGlzcGF0Y2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9mdWxmaWxsZWQodmFsdWUpKTtcbiAgICAgICAgfSwgXCJ3aGVuXCIsIFtmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9yZWplY3RlZChleGNlcHRpb24pKTtcbiAgICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgLy8gUHJvZ3Jlc3MgcHJvcGFnYXRvciBuZWVkIHRvIGJlIGF0dGFjaGVkIGluIHRoZSBjdXJyZW50IHRpY2suXG4gICAgc2VsZi5wcm9taXNlRGlzcGF0Y2godm9pZCAwLCBcIndoZW5cIiwgW3ZvaWQgMCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBuZXdWYWx1ZTtcbiAgICAgICAgdmFyIHRocmV3ID0gZmFsc2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IF9wcm9ncmVzc2VkKHZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyZXcgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhyZXcpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeShuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblEudGFwID0gZnVuY3Rpb24gKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGFwKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogV29ya3MgYWxtb3N0IGxpa2UgXCJmaW5hbGx5XCIsIGJ1dCBub3QgY2FsbGVkIGZvciByZWplY3Rpb25zLlxuICogT3JpZ2luYWwgcmVzb2x1dGlvbiB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCBjYWxsYmFjayB1bmFmZmVjdGVkLlxuICogQ2FsbGJhY2sgbWF5IHJldHVybiBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGF3YWl0ZWQgZm9yLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtRLlByb21pc2V9XG4gKiBAZXhhbXBsZVxuICogZG9Tb21ldGhpbmcoKVxuICogICAudGhlbiguLi4pXG4gKiAgIC50YXAoY29uc29sZS5sb2cpXG4gKiAgIC50aGVuKC4uLik7XG4gKi9cblByb21pc2UucHJvdG90eXBlLnRhcCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG5cbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwodmFsdWUpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIG9ic2VydmVyIG9uIGEgcHJvbWlzZS5cbiAqXG4gKiBHdWFyYW50ZWVzOlxuICpcbiAqIDEuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIGJlIGNhbGxlZCBvbmx5IG9uY2UuXG4gKiAyLiB0aGF0IGVpdGhlciB0aGUgZnVsZmlsbGVkIGNhbGxiYWNrIG9yIHRoZSByZWplY3RlZCBjYWxsYmFjayB3aWxsIGJlXG4gKiAgICBjYWxsZWQsIGJ1dCBub3QgYm90aC5cbiAqIDMuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIG5vdCBiZSBjYWxsZWQgaW4gdGhpcyB0dXJuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAgICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSB0byBvYnNlcnZlXG4gKiBAcGFyYW0gZnVsZmlsbGVkICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgZnVsZmlsbGVkIHZhbHVlXG4gKiBAcGFyYW0gcmVqZWN0ZWQgICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgcmVqZWN0aW9uIGV4Y2VwdGlvblxuICogQHBhcmFtIHByb2dyZXNzZWQgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgaW52b2tlZCBjYWxsYmFja1xuICovXG5RLndoZW4gPSB3aGVuO1xuZnVuY3Rpb24gd2hlbih2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsdWU7IH0pO1xufTtcblxuUS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uIChwcm9taXNlLCB2YWx1ZSkge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAoKSB7IHRocm93IHJlYXNvbjsgfSk7XG59O1xuXG5RLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGhlblJlamVjdChyZWFzb24pO1xufTtcblxuLyoqXG4gKiBJZiBhbiBvYmplY3QgaXMgbm90IGEgcHJvbWlzZSwgaXQgaXMgYXMgXCJuZWFyXCIgYXMgcG9zc2libGUuXG4gKiBJZiBhIHByb21pc2UgaXMgcmVqZWN0ZWQsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlIHRvby5cbiAqIElmIGl04oCZcyBhIGZ1bGZpbGxlZCBwcm9taXNlLCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgaXMgbmVhcmVyLlxuICogSWYgaXTigJlzIGEgZGVmZXJyZWQgcHJvbWlzZSBhbmQgdGhlIGRlZmVycmVkIGhhcyBiZWVuIHJlc29sdmVkLCB0aGVcbiAqIHJlc29sdXRpb24gaXMgXCJuZWFyZXJcIi5cbiAqIEBwYXJhbSBvYmplY3RcbiAqIEByZXR1cm5zIG1vc3QgcmVzb2x2ZWQgKG5lYXJlc3QpIGZvcm0gb2YgdGhlIG9iamVjdFxuICovXG5cbi8vIFhYWCBzaG91bGQgd2UgcmUtZG8gdGhpcz9cblEubmVhcmVyID0gbmVhcmVyO1xuZnVuY3Rpb24gbmVhcmVyKHZhbHVlKSB7XG4gICAgaWYgKGlzUHJvbWlzZSh2YWx1ZSkpIHtcbiAgICAgICAgdmFyIGluc3BlY3RlZCA9IHZhbHVlLmluc3BlY3QoKTtcbiAgICAgICAgaWYgKGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RlZC52YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcHJvbWlzZS5cbiAqIE90aGVyd2lzZSBpdCBpcyBhIGZ1bGZpbGxlZCB2YWx1ZS5cbiAqL1xuUS5pc1Byb21pc2UgPSBpc1Byb21pc2U7XG5mdW5jdGlvbiBpc1Byb21pc2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIFByb21pc2U7XG59XG5cblEuaXNQcm9taXNlQWxpa2UgPSBpc1Byb21pc2VBbGlrZTtcbmZ1bmN0aW9uIGlzUHJvbWlzZUFsaWtlKG9iamVjdCkge1xuICAgIHJldHVybiBpc09iamVjdChvYmplY3QpICYmIHR5cGVvZiBvYmplY3QudGhlbiA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHBlbmRpbmcgcHJvbWlzZSwgbWVhbmluZyBub3RcbiAqIGZ1bGZpbGxlZCBvciByZWplY3RlZC5cbiAqL1xuUS5pc1BlbmRpbmcgPSBpc1BlbmRpbmc7XG5mdW5jdGlvbiBpc1BlbmRpbmcob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicGVuZGluZ1wiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgdmFsdWUgb3IgZnVsZmlsbGVkXG4gKiBwcm9taXNlLlxuICovXG5RLmlzRnVsZmlsbGVkID0gaXNGdWxmaWxsZWQ7XG5mdW5jdGlvbiBpc0Z1bGZpbGxlZChvYmplY3QpIHtcbiAgICByZXR1cm4gIWlzUHJvbWlzZShvYmplY3QpIHx8IG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzRnVsZmlsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcmVqZWN0ZWQgcHJvbWlzZS5cbiAqL1xuUS5pc1JlamVjdGVkID0gaXNSZWplY3RlZDtcbmZ1bmN0aW9uIGlzUmVqZWN0ZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn07XG5cbi8vLy8gQkVHSU4gVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vLyBUaGlzIHByb21pc2UgbGlicmFyeSBjb25zdW1lcyBleGNlcHRpb25zIHRocm93biBpbiBoYW5kbGVycyBzbyB0aGV5IGNhbiBiZVxuLy8gaGFuZGxlZCBieSBhIHN1YnNlcXVlbnQgcHJvbWlzZS4gIFRoZSBleGNlcHRpb25zIGdldCBhZGRlZCB0byB0aGlzIGFycmF5IHdoZW5cbi8vIHRoZXkgYXJlIGNyZWF0ZWQsIGFuZCByZW1vdmVkIHdoZW4gdGhleSBhcmUgaGFuZGxlZC4gIE5vdGUgdGhhdCBpbiBFUzYgb3Jcbi8vIHNoaW1tZWQgZW52aXJvbm1lbnRzLCB0aGlzIHdvdWxkIG5hdHVyYWxseSBiZSBhIGBTZXRgLlxudmFyIHVuaGFuZGxlZFJlYXNvbnMgPSBbXTtcbnZhciB1bmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcblxuZnVuY3Rpb24gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCkge1xuICAgIHVuaGFuZGxlZFJlYXNvbnMubGVuZ3RoID0gMDtcbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLmxlbmd0aCA9IDA7XG5cbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSB0cnVlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdHJhY2tSZWplY3Rpb24ocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5lbWl0KFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsIHJlYXNvbiwgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuaGFuZGxlZFJlamVjdGlvbnMucHVzaChwcm9taXNlKTtcbiAgICBpZiAocmVhc29uICYmIHR5cGVvZiByZWFzb24uc3RhY2sgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKHJlYXNvbi5zdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKFwiKG5vIHN0YWNrKSBcIiArIHJlYXNvbik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1bnRyYWNrUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGF0ID0gYXJyYXlfaW5kZXhPZih1bmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICBpZiAoYXQgIT09IC0xKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvY2Vzcy5lbWl0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhdFJlcG9ydCA9IGFycmF5X2luZGV4T2YocmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICBpZiAoYXRSZXBvcnQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInJlamVjdGlvbkhhbmRsZWRcIiwgdW5oYW5kbGVkUmVhc29uc1thdF0sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMuc3BsaWNlKGF0UmVwb3J0LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdCwgMSk7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMuc3BsaWNlKGF0LCAxKTtcbiAgICB9XG59XG5cblEucmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zID0gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zO1xuXG5RLmdldFVuaGFuZGxlZFJlYXNvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gTWFrZSBhIGNvcHkgc28gdGhhdCBjb25zdW1lcnMgY2FuJ3QgaW50ZXJmZXJlIHdpdGggb3VyIGludGVybmFsIHN0YXRlLlxuICAgIHJldHVybiB1bmhhbmRsZWRSZWFzb25zLnNsaWNlKCk7XG59O1xuXG5RLnN0b3BVbmhhbmRsZWRSZWplY3Rpb25UcmFja2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSBmYWxzZTtcbn07XG5cbnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuXG4vLy8vIEVORCBVTkhBTkRMRUQgUkVKRUNUSU9OIFRSQUNLSU5HXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHJlamVjdGVkIHByb21pc2UuXG4gKiBAcGFyYW0gcmVhc29uIHZhbHVlIGRlc2NyaWJpbmcgdGhlIGZhaWx1cmVcbiAqL1xuUS5yZWplY3QgPSByZWplY3Q7XG5mdW5jdGlvbiByZWplY3QocmVhc29uKSB7XG4gICAgdmFyIHJlamVjdGlvbiA9IFByb21pc2Uoe1xuICAgICAgICBcIndoZW5cIjogZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgICAgICAgICAvLyBub3RlIHRoYXQgdGhlIGVycm9yIGhhcyBiZWVuIGhhbmRsZWRcbiAgICAgICAgICAgIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgICAgICAgIHVudHJhY2tSZWplY3Rpb24odGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0ZWQgPyByZWplY3RlZChyZWFzb24pIDogdGhpcztcbiAgICAgICAgfVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJyZWplY3RlZFwiLCByZWFzb246IHJlYXNvbiB9O1xuICAgIH0pO1xuXG4gICAgLy8gTm90ZSB0aGF0IHRoZSByZWFzb24gaGFzIG5vdCBiZWVuIGhhbmRsZWQuXG4gICAgdHJhY2tSZWplY3Rpb24ocmVqZWN0aW9uLCByZWFzb24pO1xuXG4gICAgcmV0dXJuIHJlamVjdGlvbjtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgZnVsZmlsbGVkIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0gdmFsdWUgaW1tZWRpYXRlIHJlZmVyZW5jZVxuICovXG5RLmZ1bGZpbGwgPSBmdWxmaWxsO1xuZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJnZXRcIjogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJzZXRcIjogZnVuY3Rpb24gKG5hbWUsIHJocykge1xuICAgICAgICAgICAgdmFsdWVbbmFtZV0gPSByaHM7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZGVsZXRlXCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICBkZWxldGUgdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwicG9zdFwiOiBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgICAgICAgICAgLy8gTWFyayBNaWxsZXIgcHJvcG9zZXMgdGhhdCBwb3N0IHdpdGggbm8gbmFtZSBzaG91bGQgYXBwbHkgYVxuICAgICAgICAgICAgLy8gcHJvbWlzZWQgZnVuY3Rpb24uXG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gbnVsbCB8fCBuYW1lID09PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodm9pZCAwLCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlW25hbWVdLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgXCJhcHBseVwiOiBmdW5jdGlvbiAodGhpc3AsIGFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5hcHBseSh0aGlzcCwgYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIFwia2V5c1wiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0X2tleXModmFsdWUpO1xuICAgICAgICB9XG4gICAgfSwgdm9pZCAwLCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJmdWxmaWxsZWRcIiwgdmFsdWU6IHZhbHVlIH07XG4gICAgfSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlbmFibGVzIHRvIFEgcHJvbWlzZXMuXG4gKiBAcGFyYW0gcHJvbWlzZSB0aGVuYWJsZSBwcm9taXNlXG4gKiBAcmV0dXJucyBhIFEgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBjb2VyY2UocHJvbWlzZSkge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oZGVmZXJyZWQucmVzb2x2ZSwgZGVmZXJyZWQucmVqZWN0LCBkZWZlcnJlZC5ub3RpZnkpO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGFuIG9iamVjdCBzdWNoIHRoYXQgaXQgd2lsbCBuZXZlciBiZVxuICogdHJhbnNmZXJyZWQgYXdheSBmcm9tIHRoaXMgcHJvY2VzcyBvdmVyIGFueSBwcm9taXNlXG4gKiBjb21tdW5pY2F0aW9uIGNoYW5uZWwuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBwcm9taXNlIGEgd3JhcHBpbmcgb2YgdGhhdCBvYmplY3QgdGhhdFxuICogYWRkaXRpb25hbGx5IHJlc3BvbmRzIHRvIHRoZSBcImlzRGVmXCIgbWVzc2FnZVxuICogd2l0aG91dCBhIHJlamVjdGlvbi5cbiAqL1xuUS5tYXN0ZXIgPSBtYXN0ZXI7XG5mdW5jdGlvbiBtYXN0ZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2Uoe1xuICAgICAgICBcImlzRGVmXCI6IGZ1bmN0aW9uICgpIHt9XG4gICAgfSwgZnVuY3Rpb24gZmFsbGJhY2sob3AsIGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIGRpc3BhdGNoKG9iamVjdCwgb3AsIGFyZ3MpO1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFEob2JqZWN0KS5pbnNwZWN0KCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogU3ByZWFkcyB0aGUgdmFsdWVzIG9mIGEgcHJvbWlzZWQgYXJyYXkgb2YgYXJndW1lbnRzIGludG8gdGhlXG4gKiBmdWxmaWxsbWVudCBjYWxsYmFjay5cbiAqIEBwYXJhbSBmdWxmaWxsZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB2YXJpYWRpYyBhcmd1bWVudHMgZnJvbSB0aGVcbiAqIHByb21pc2VkIGFycmF5XG4gKiBAcGFyYW0gcmVqZWN0ZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB0aGUgZXhjZXB0aW9uIGlmIHRoZSBwcm9taXNlXG4gKiBpcyByZWplY3RlZC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSBvciB0aHJvd24gZXhjZXB0aW9uIG9mXG4gKiBlaXRoZXIgY2FsbGJhY2suXG4gKi9cblEuc3ByZWFkID0gc3ByZWFkO1xuZnVuY3Rpb24gc3ByZWFkKHZhbHVlLCBmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEodmFsdWUpLnNwcmVhZChmdWxmaWxsZWQsIHJlamVjdGVkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuc3ByZWFkID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoKS50aGVuKGZ1bmN0aW9uIChhcnJheSkge1xuICAgICAgICByZXR1cm4gZnVsZmlsbGVkLmFwcGx5KHZvaWQgMCwgYXJyYXkpO1xuICAgIH0sIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogVGhlIGFzeW5jIGZ1bmN0aW9uIGlzIGEgZGVjb3JhdG9yIGZvciBnZW5lcmF0b3IgZnVuY3Rpb25zLCB0dXJuaW5nXG4gKiB0aGVtIGludG8gYXN5bmNocm9ub3VzIGdlbmVyYXRvcnMuICBBbHRob3VnaCBnZW5lcmF0b3JzIGFyZSBvbmx5IHBhcnRcbiAqIG9mIHRoZSBuZXdlc3QgRUNNQVNjcmlwdCA2IGRyYWZ0cywgdGhpcyBjb2RlIGRvZXMgbm90IGNhdXNlIHN5bnRheFxuICogZXJyb3JzIGluIG9sZGVyIGVuZ2luZXMuICBUaGlzIGNvZGUgc2hvdWxkIGNvbnRpbnVlIHRvIHdvcmsgYW5kIHdpbGxcbiAqIGluIGZhY3QgaW1wcm92ZSBvdmVyIHRpbWUgYXMgdGhlIGxhbmd1YWdlIGltcHJvdmVzLlxuICpcbiAqIEVTNiBnZW5lcmF0b3JzIGFyZSBjdXJyZW50bHkgcGFydCBvZiBWOCB2ZXJzaW9uIDMuMTkgd2l0aCB0aGVcbiAqIC0taGFybW9ueS1nZW5lcmF0b3JzIHJ1bnRpbWUgZmxhZyBlbmFibGVkLiAgU3BpZGVyTW9ua2V5IGhhcyBoYWQgdGhlbVxuICogZm9yIGxvbmdlciwgYnV0IHVuZGVyIGFuIG9sZGVyIFB5dGhvbi1pbnNwaXJlZCBmb3JtLiAgVGhpcyBmdW5jdGlvblxuICogd29ya3Mgb24gYm90aCBraW5kcyBvZiBnZW5lcmF0b3JzLlxuICpcbiAqIERlY29yYXRlcyBhIGdlbmVyYXRvciBmdW5jdGlvbiBzdWNoIHRoYXQ6XG4gKiAgLSBpdCBtYXkgeWllbGQgcHJvbWlzZXNcbiAqICAtIGV4ZWN1dGlvbiB3aWxsIGNvbnRpbnVlIHdoZW4gdGhhdCBwcm9taXNlIGlzIGZ1bGZpbGxlZFxuICogIC0gdGhlIHZhbHVlIG9mIHRoZSB5aWVsZCBleHByZXNzaW9uIHdpbGwgYmUgdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogIC0gaXQgcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgKHdoZW4gdGhlIGdlbmVyYXRvclxuICogICAgc3RvcHMgaXRlcmF0aW5nKVxuICogIC0gdGhlIGRlY29yYXRlZCBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICogICAgb2YgdGhlIGdlbmVyYXRvciBvciB0aGUgZmlyc3QgcmVqZWN0ZWQgcHJvbWlzZSBhbW9uZyB0aG9zZVxuICogICAgeWllbGRlZC5cbiAqICAtIGlmIGFuIGVycm9yIGlzIHRocm93biBpbiB0aGUgZ2VuZXJhdG9yLCBpdCBwcm9wYWdhdGVzIHRocm91Z2hcbiAqICAgIGV2ZXJ5IGZvbGxvd2luZyB5aWVsZCB1bnRpbCBpdCBpcyBjYXVnaHQsIG9yIHVudGlsIGl0IGVzY2FwZXNcbiAqICAgIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gYWx0b2dldGhlciwgYW5kIGlzIHRyYW5zbGF0ZWQgaW50byBhXG4gKiAgICByZWplY3Rpb24gZm9yIHRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkZWNvcmF0ZWQgZ2VuZXJhdG9yLlxuICovXG5RLmFzeW5jID0gYXN5bmM7XG5mdW5jdGlvbiBhc3luYyhtYWtlR2VuZXJhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwic2VuZFwiLCBhcmcgaXMgYSB2YWx1ZVxuICAgICAgICAvLyB3aGVuIHZlcmIgaXMgXCJ0aHJvd1wiLCBhcmcgaXMgYW4gZXhjZXB0aW9uXG4gICAgICAgIGZ1bmN0aW9uIGNvbnRpbnVlcih2ZXJiLCBhcmcpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgICAgICAgIC8vIFVudGlsIFY4IDMuMTkgLyBDaHJvbWl1bSAyOSBpcyByZWxlYXNlZCwgU3BpZGVyTW9ua2V5IGlzIHRoZSBvbmx5XG4gICAgICAgICAgICAvLyBlbmdpbmUgdGhhdCBoYXMgYSBkZXBsb3llZCBiYXNlIG9mIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgLy8gSG93ZXZlciwgU00ncyBnZW5lcmF0b3JzIHVzZSB0aGUgUHl0aG9uLWluc3BpcmVkIHNlbWFudGljcyBvZlxuICAgICAgICAgICAgLy8gb3V0ZGF0ZWQgRVM2IGRyYWZ0cy4gIFdlIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBFUzYsIGJ1dCB3ZSdkIGFsc29cbiAgICAgICAgICAgIC8vIGxpa2UgdG8gbWFrZSBpdCBwb3NzaWJsZSB0byB1c2UgZ2VuZXJhdG9ycyBpbiBkZXBsb3llZCBicm93c2Vycywgc29cbiAgICAgICAgICAgIC8vIHdlIGFsc28gc3VwcG9ydCBQeXRob24tc3R5bGUgZ2VuZXJhdG9ycy4gIEF0IHNvbWUgcG9pbnQgd2UgY2FuIHJlbW92ZVxuICAgICAgICAgICAgLy8gdGhpcyBibG9jay5cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTdG9wSXRlcmF0aW9uID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgLy8gRVM2IEdlbmVyYXRvcnNcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFEocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2hlbihyZXN1bHQudmFsdWUsIGNhbGxiYWNrLCBlcnJiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNwaWRlck1vbmtleSBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgLy8gRklYTUU6IFJlbW92ZSB0aGlzIGNhc2Ugd2hlbiBTTSBkb2VzIEVTNiBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdlbmVyYXRvclt2ZXJiXShhcmcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBRKGV4Y2VwdGlvbi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdlbmVyYXRvciA9IG1ha2VHZW5lcmF0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcIm5leHRcIik7XG4gICAgICAgIHZhciBlcnJiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcInRocm93XCIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIFRoZSBzcGF3biBmdW5jdGlvbiBpcyBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kIGFzeW5jIHRoYXQgaW1tZWRpYXRlbHlcbiAqIGNhbGxzIHRoZSBnZW5lcmF0b3IgYW5kIGFsc28gZW5kcyB0aGUgcHJvbWlzZSBjaGFpbiwgc28gdGhhdCBhbnlcbiAqIHVuaGFuZGxlZCBlcnJvcnMgYXJlIHRocm93biBpbnN0ZWFkIG9mIGZvcndhcmRlZCB0byB0aGUgZXJyb3JcbiAqIGhhbmRsZXIuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgaXQncyBleHRyZW1lbHkgY29tbW9uIHRvIHJ1blxuICogZ2VuZXJhdG9ycyBhdCB0aGUgdG9wLWxldmVsIHRvIHdvcmsgd2l0aCBsaWJyYXJpZXMuXG4gKi9cblEuc3Bhd24gPSBzcGF3bjtcbmZ1bmN0aW9uIHNwYXduKG1ha2VHZW5lcmF0b3IpIHtcbiAgICBRLmRvbmUoUS5hc3luYyhtYWtlR2VuZXJhdG9yKSgpKTtcbn1cblxuLy8gRklYTUU6IFJlbW92ZSB0aGlzIGludGVyZmFjZSBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG4vKipcbiAqIFRocm93cyBhIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB0byBzdG9wIGFuIGFzeW5jaHJvbm91cyBnZW5lcmF0b3IuXG4gKlxuICogVGhpcyBpbnRlcmZhY2UgaXMgYSBzdG9wLWdhcCBtZWFzdXJlIHRvIHN1cHBvcnQgZ2VuZXJhdG9yIHJldHVyblxuICogdmFsdWVzIGluIG9sZGVyIEZpcmVmb3gvU3BpZGVyTW9ua2V5LiAgSW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEVTNlxuICogZ2VuZXJhdG9ycyBsaWtlIENocm9taXVtIDI5LCBqdXN0IHVzZSBcInJldHVyblwiIGluIHlvdXIgZ2VuZXJhdG9yXG4gKiBmdW5jdGlvbnMuXG4gKlxuICogQHBhcmFtIHZhbHVlIHRoZSByZXR1cm4gdmFsdWUgZm9yIHRoZSBzdXJyb3VuZGluZyBnZW5lcmF0b3JcbiAqIEB0aHJvd3MgUmV0dXJuVmFsdWUgZXhjZXB0aW9uIHdpdGggdGhlIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIC8vIEVTNiBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiogKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICByZXR1cm4gZm9vICsgYmFyO1xuICogfSlcbiAqIC8vIE9sZGVyIFNwaWRlck1vbmtleSBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiAoKSB7XG4gKiAgICAgIHZhciBmb28gPSB5aWVsZCBnZXRGb29Qcm9taXNlKCk7XG4gKiAgICAgIHZhciBiYXIgPSB5aWVsZCBnZXRCYXJQcm9taXNlKCk7XG4gKiAgICAgIFEucmV0dXJuKGZvbyArIGJhcik7XG4gKiB9KVxuICovXG5RW1wicmV0dXJuXCJdID0gX3JldHVybjtcbmZ1bmN0aW9uIF9yZXR1cm4odmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgUVJldHVyblZhbHVlKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUaGUgcHJvbWlzZWQgZnVuY3Rpb24gZGVjb3JhdG9yIGVuc3VyZXMgdGhhdCBhbnkgcHJvbWlzZSBhcmd1bWVudHNcbiAqIGFyZSBzZXR0bGVkIGFuZCBwYXNzZWQgYXMgdmFsdWVzIChgdGhpc2AgaXMgYWxzbyBzZXR0bGVkIGFuZCBwYXNzZWRcbiAqIGFzIGEgdmFsdWUpLiAgSXQgd2lsbCBhbHNvIGVuc3VyZSB0aGF0IHRoZSByZXN1bHQgb2YgYSBmdW5jdGlvbiBpc1xuICogYWx3YXlzIGEgcHJvbWlzZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGFkZCA9IFEucHJvbWlzZWQoZnVuY3Rpb24gKGEsIGIpIHtcbiAqICAgICByZXR1cm4gYSArIGI7XG4gKiB9KTtcbiAqIGFkZChRKGEpLCBRKEIpKTtcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gZGVjb3JhdGVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IGhhcyBiZWVuIGRlY29yYXRlZC5cbiAqL1xuUS5wcm9taXNlZCA9IHByb21pc2VkO1xuZnVuY3Rpb24gcHJvbWlzZWQoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc3ByZWFkKFt0aGlzLCBhbGwoYXJndW1lbnRzKV0sIGZ1bmN0aW9uIChzZWxmLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8qKlxuICogc2VuZHMgYSBtZXNzYWdlIHRvIGEgdmFsdWUgaW4gYSBmdXR1cmUgdHVyblxuICogQHBhcmFtIG9iamVjdCogdGhlIHJlY2lwaWVudFxuICogQHBhcmFtIG9wIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIG9wZXJhdGlvbiwgZS5nLiwgXCJ3aGVuXCIsXG4gKiBAcGFyYW0gYXJncyBmdXJ0aGVyIGFyZ3VtZW50cyB0byBiZSBmb3J3YXJkZWQgdG8gdGhlIG9wZXJhdGlvblxuICogQHJldHVybnMgcmVzdWx0IHtQcm9taXNlfSBhIHByb21pc2UgZm9yIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvblxuICovXG5RLmRpc3BhdGNoID0gZGlzcGF0Y2g7XG5mdW5jdGlvbiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChvcCwgYXJncyk7XG59XG5cblByb21pc2UucHJvdG90eXBlLmRpc3BhdGNoID0gZnVuY3Rpb24gKG9wLCBhcmdzKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGRlZmVycmVkLnJlc29sdmUsIG9wLCBhcmdzKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBnZXRcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHByb3BlcnR5IHZhbHVlXG4gKi9cblEuZ2V0ID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImdldFwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3Igb2JqZWN0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIHByb3BlcnR5IHRvIHNldFxuICogQHBhcmFtIHZhbHVlICAgICBuZXcgdmFsdWUgb2YgcHJvcGVydHlcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG4vKipcbiAqIERlbGV0ZXMgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBkZWxldGVcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLmRlbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJkZWxldGVcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBrZXkpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogSW52b2tlcyBhIG1ldGhvZCBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBtZXRob2QgdG8gaW52b2tlXG4gKiBAcGFyYW0gdmFsdWUgICAgIGEgdmFsdWUgdG8gcG9zdCwgdHlwaWNhbGx5IGFuIGFycmF5IG9mXG4gKiAgICAgICAgICAgICAgICAgIGludm9jYXRpb24gYXJndW1lbnRzIGZvciBwcm9taXNlcyB0aGF0XG4gKiAgICAgICAgICAgICAgICAgIGFyZSB1bHRpbWF0ZWx5IGJhY2tlZCB3aXRoIGByZXNvbHZlYCB2YWx1ZXMsXG4gKiAgICAgICAgICAgICAgICAgIGFzIG9wcG9zZWQgdG8gdGhvc2UgYmFja2VkIHdpdGggVVJMc1xuICogICAgICAgICAgICAgICAgICB3aGVyZWluIHRoZSBwb3N0ZWQgdmFsdWUgY2FuIGJlIGFueVxuICogICAgICAgICAgICAgICAgICBKU09OIHNlcmlhbGl6YWJsZSBvYmplY3QuXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuLy8gYm91bmQgbG9jYWxseSBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgb3RoZXIgbWV0aG9kc1xuUS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUS5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUucG9zdCA9IGZ1bmN0aW9uIChuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBpbnZvY2F0aW9uIGFyZ3VtZW50c1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cblEuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5RLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEuaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDIpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZW5kID0gLy8gWFhYIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgcGFybGFuY2VcblByb21pc2UucHJvdG90eXBlLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gYXJncyAgICAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZhcHBseSA9IGZ1bmN0aW9uIChvYmplY3QsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cbi8qKlxuICogQ2FsbHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RW1widHJ5XCJdID1cblEuZmNhbGwgPSBmdW5jdGlvbiAob2JqZWN0IC8qIC4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5mY2FsbCA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzKV0pO1xufTtcblxuLyoqXG4gKiBCaW5kcyB0aGUgcHJvbWlzZWQgZnVuY3Rpb24sIHRyYW5zZm9ybWluZyByZXR1cm4gdmFsdWVzIGludG8gYSBmdWxmaWxsZWRcbiAqIHByb21pc2UgYW5kIHRocm93biBlcnJvcnMgaW50byBhIHJlamVjdGVkIG9uZS5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgZnVuY3Rpb25cbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgYXBwbGljYXRpb24gYXJndW1lbnRzXG4gKi9cblEuZmJpbmQgPSBmdW5jdGlvbiAob2JqZWN0IC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSBRKG9iamVjdCk7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuUHJvbWlzZS5wcm90b3R5cGUuZmJpbmQgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuXG4vKipcbiAqIFJlcXVlc3RzIHRoZSBuYW1lcyBvZiB0aGUgb3duZWQgcHJvcGVydGllcyBvZiBhIHByb21pc2VkXG4gKiBvYmplY3QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBrZXlzIG9mIHRoZSBldmVudHVhbGx5IHNldHRsZWQgb2JqZWN0XG4gKi9cblEua2V5cyA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG4vKipcbiAqIFR1cm5zIGFuIGFycmF5IG9mIHByb21pc2VzIGludG8gYSBwcm9taXNlIGZvciBhbiBhcnJheS4gIElmIGFueSBvZlxuICogdGhlIHByb21pc2VzIGdldHMgcmVqZWN0ZWQsIHRoZSB3aG9sZSBhcnJheSBpcyByZWplY3RlZCBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QXJyYXkqfSBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlc1xuICovXG4vLyBCeSBNYXJrIE1pbGxlclxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9c3RyYXdtYW46Y29uY3VycmVuY3kmcmV2PTEzMDg3NzY1MjEjYWxsZnVsZmlsbGVkXG5RLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgdmFyIHBlbmRpbmdDb3VudCA9IDA7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvbWlzZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBzbmFwc2hvdDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBpc1Byb21pc2UocHJvbWlzZSkgJiZcbiAgICAgICAgICAgICAgICAoc25hcHNob3QgPSBwcm9taXNlLmluc3BlY3QoKSkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHNuYXBzaG90LnZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICArK3BlbmRpbmdDb3VudDtcbiAgICAgICAgICAgICAgICB3aGVuKFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC0tcGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShwcm9taXNlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkoeyBpbmRleDogaW5kZXgsIHZhbHVlOiBwcm9ncmVzcyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIGlmIChwZW5kaW5nQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSBvZiBhbiBhcnJheS4gUHJpb3IgcmVqZWN0ZWQgcHJvbWlzZXMgYXJlXG4gKiBpZ25vcmVkLiAgUmVqZWN0cyBvbmx5IGlmIGFsbCBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgY29udGFpbmluZyB2YWx1ZXMgb3IgcHJvbWlzZXMgZm9yIHZhbHVlc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZ1bGZpbGxlZCB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSxcbiAqIG9yIGEgcmVqZWN0ZWQgcHJvbWlzZSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICovXG5RLmFueSA9IGFueTtcblxuZnVuY3Rpb24gYW55KHByb21pc2VzKSB7XG4gICAgaWYgKHByb21pc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gUS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgdmFyIGRlZmVycmVkID0gUS5kZWZlcigpO1xuICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHByZXYsIGN1cnJlbnQsIGluZGV4KSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gcHJvbWlzZXNbaW5kZXhdO1xuXG4gICAgICAgIHBlbmRpbmdDb3VudCsrO1xuXG4gICAgICAgIHdoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MpO1xuICAgICAgICBmdW5jdGlvbiBvbkZ1bGZpbGxlZChyZXN1bHQpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBvblJlamVjdGVkKCkge1xuICAgICAgICAgICAgcGVuZGluZ0NvdW50LS07XG4gICAgICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJDYW4ndCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgZnJvbSBhbnkgcHJvbWlzZSwgYWxsIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJwcm9taXNlcyB3ZXJlIHJlamVjdGVkLlwiXG4gICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHtcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHByb2dyZXNzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sIHVuZGVmaW5lZCk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbnkodGhpcyk7XG59O1xuXG4vKipcbiAqIFdhaXRzIGZvciBhbGwgcHJvbWlzZXMgdG8gYmUgc2V0dGxlZCwgZWl0aGVyIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQuICBUaGlzIGlzIGRpc3RpbmN0IGZyb20gYGFsbGAgc2luY2UgdGhhdCB3b3VsZCBzdG9wXG4gKiB3YWl0aW5nIGF0IHRoZSBmaXJzdCByZWplY3Rpb24uICBUaGUgcHJvbWlzZSByZXR1cm5lZCBieVxuICogYGFsbFJlc29sdmVkYCB3aWxsIG5ldmVyIGJlIHJlamVjdGVkLlxuICogQHBhcmFtIHByb21pc2VzIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgKG9yIGFuIGFycmF5KSBvZiBwcm9taXNlc1xuICogKG9yIHZhbHVlcylcbiAqIEByZXR1cm4gYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiBwcm9taXNlc1xuICovXG5RLmFsbFJlc29sdmVkID0gZGVwcmVjYXRlKGFsbFJlc29sdmVkLCBcImFsbFJlc29sdmVkXCIsIFwiYWxsU2V0dGxlZFwiKTtcbmZ1bmN0aW9uIGFsbFJlc29sdmVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHdoZW4ocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICBwcm9taXNlcyA9IGFycmF5X21hcChwcm9taXNlcywgUSk7XG4gICAgICAgIHJldHVybiB3aGVuKGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gd2hlbihwcm9taXNlLCBub29wLCBub29wKTtcbiAgICAgICAgfSkpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZXM7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGxSZXNvbHZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWxsUmVzb2x2ZWQodGhpcyk7XG59O1xuXG4vKipcbiAqIEBzZWUgUHJvbWlzZSNhbGxTZXR0bGVkXG4gKi9cblEuYWxsU2V0dGxlZCA9IGFsbFNldHRsZWQ7XG5mdW5jdGlvbiBhbGxTZXR0bGVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZXMpLmFsbFNldHRsZWQoKTtcbn1cblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgdGhlaXIgc3RhdGVzIChhc1xuICogcmV0dXJuZWQgYnkgYGluc3BlY3RgKSB3aGVuIHRoZXkgaGF2ZSBhbGwgc2V0dGxlZC5cbiAqIEBwYXJhbSB7QXJyYXlbQW55Kl19IHZhbHVlcyBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyB7QXJyYXlbU3RhdGVdfSBhbiBhcnJheSBvZiBzdGF0ZXMgZm9yIHRoZSByZXNwZWN0aXZlIHZhbHVlcy5cbiAqL1xuUHJvbWlzZS5wcm90b3R5cGUuYWxsU2V0dGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICByZXR1cm4gYWxsKGFycmF5X21hcChwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgICAgIHByb21pc2UgPSBRKHByb21pc2UpO1xuICAgICAgICAgICAgZnVuY3Rpb24gcmVnYXJkbGVzcygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZS5pbnNwZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKHJlZ2FyZGxlc3MsIHJlZ2FyZGxlc3MpO1xuICAgICAgICB9KSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIENhcHR1cmVzIHRoZSBmYWlsdXJlIG9mIGEgcHJvbWlzZSwgZ2l2aW5nIGFuIG9wb3J0dW5pdHkgdG8gcmVjb3ZlclxuICogd2l0aCBhIGNhbGxiYWNrLiAgSWYgdGhlIGdpdmVuIHByb21pc2UgaXMgZnVsZmlsbGVkLCB0aGUgcmV0dXJuZWRcbiAqIHByb21pc2UgaXMgZnVsZmlsbGVkLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGZvciBzb21ldGhpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIGZ1bGZpbGwgdGhlIHJldHVybmVkIHByb21pc2UgaWYgdGhlXG4gKiBnaXZlbiBwcm9taXNlIGlzIHJlamVjdGVkXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrXG4gKi9cblEuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuLyoqXG4gKiBBdHRhY2hlcyBhIGxpc3RlbmVyIHRoYXQgY2FuIHJlc3BvbmQgdG8gcHJvZ3Jlc3Mgbm90aWZpY2F0aW9ucyBmcm9tIGFcbiAqIHByb21pc2UncyBvcmlnaW5hdGluZyBkZWZlcnJlZC4gVGhpcyBsaXN0ZW5lciByZWNlaXZlcyB0aGUgZXhhY3QgYXJndW1lbnRzXG4gKiBwYXNzZWQgdG8gYGBkZWZlcnJlZC5ub3RpZnlgYC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byByZWNlaXZlIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJucyB0aGUgZ2l2ZW4gcHJvbWlzZSwgdW5jaGFuZ2VkXG4gKi9cblEucHJvZ3Jlc3MgPSBwcm9ncmVzcztcbmZ1bmN0aW9uIHByb2dyZXNzKG9iamVjdCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnByb2dyZXNzID0gZnVuY3Rpb24gKHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgdm9pZCAwLCBwcm9ncmVzc2VkKTtcbn07XG5cbi8qKlxuICogUHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gb2JzZXJ2ZSB0aGUgc2V0dGxpbmcgb2YgYSBwcm9taXNlLFxuICogcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBwcm9taXNlIGlzIGZ1bGZpbGxlZCBvciByZWplY3RlZC4gIEZvcndhcmRzXG4gKiB0aGUgcmVzb2x1dGlvbiB0byB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aGVuIHRoZSBjYWxsYmFjayBpcyBkb25lLlxuICogVGhlIGNhbGxiYWNrIGNhbiByZXR1cm4gYSBwcm9taXNlIHRvIGRlZmVyIGNvbXBsZXRpb24uXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIG9ic2VydmUgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuXG4gKiBwcm9taXNlLCB0YWtlcyBubyBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIHdoZW5cbiAqIGBgZmluYGAgaXMgZG9uZS5cbiAqL1xuUS5maW4gPSAvLyBYWFggbGVnYWN5XG5RW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KVtcImZpbmFsbHlcIl0oY2FsbGJhY2spO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmluID0gLy8gWFhYIGxlZ2FjeVxuUHJvbWlzZS5wcm90b3R5cGVbXCJmaW5hbGx5XCJdID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBRKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAvLyBUT0RPIGF0dGVtcHQgdG8gcmVjeWNsZSB0aGUgcmVqZWN0aW9uIHdpdGggXCJ0aGlzXCIuXG4gICAgICAgIHJldHVybiBjYWxsYmFjay5mY2FsbCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhyb3cgcmVhc29uO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogVGVybWluYXRlcyBhIGNoYWluIG9mIHByb21pc2VzLCBmb3JjaW5nIHJlamVjdGlvbnMgdG8gYmVcbiAqIHRocm93biBhcyBleGNlcHRpb25zLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGF0IHRoZSBlbmQgb2YgYSBjaGFpbiBvZiBwcm9taXNlc1xuICogQHJldHVybnMgbm90aGluZ1xuICovXG5RLmRvbmUgPSBmdW5jdGlvbiAob2JqZWN0LCBmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZG9uZShmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kb25lID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSB7XG4gICAgdmFyIG9uVW5oYW5kbGVkRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgLy8gZm9yd2FyZCB0byBhIGZ1dHVyZSB0dXJuIHNvIHRoYXQgYGB3aGVuYGBcbiAgICAgICAgLy8gZG9lcyBub3QgY2F0Y2ggaXQgYW5kIHR1cm4gaXQgaW50byBhIHJlamVjdGlvbi5cbiAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXJyb3IsIHByb21pc2UpO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gQXZvaWQgdW5uZWNlc3NhcnkgYG5leHRUaWNrYGluZyB2aWEgYW4gdW5uZWNlc3NhcnkgYHdoZW5gLlxuICAgIHZhciBwcm9taXNlID0gZnVsZmlsbGVkIHx8IHJlamVjdGVkIHx8IHByb2dyZXNzID9cbiAgICAgICAgdGhpcy50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSA6XG4gICAgICAgIHRoaXM7XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyAmJiBwcm9jZXNzLmRvbWFpbikge1xuICAgICAgICBvblVuaGFuZGxlZEVycm9yID0gcHJvY2Vzcy5kb21haW4uYmluZChvblVuaGFuZGxlZEVycm9yKTtcbiAgICB9XG5cbiAgICBwcm9taXNlLnRoZW4odm9pZCAwLCBvblVuaGFuZGxlZEVycm9yKTtcbn07XG5cbi8qKlxuICogQ2F1c2VzIGEgcHJvbWlzZSB0byBiZSByZWplY3RlZCBpZiBpdCBkb2VzIG5vdCBnZXQgZnVsZmlsbGVkIGJlZm9yZVxuICogc29tZSBtaWxsaXNlY29uZHMgdGltZSBvdXQuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7TnVtYmVyfSBtaWxsaXNlY29uZHMgdGltZW91dFxuICogQHBhcmFtIHtBbnkqfSBjdXN0b20gZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3QgKG9wdGlvbmFsKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBpZiBpdCBpc1xuICogZnVsZmlsbGVkIGJlZm9yZSB0aGUgdGltZW91dCwgb3RoZXJ3aXNlIHJlamVjdGVkLlxuICovXG5RLnRpbWVvdXQgPSBmdW5jdGlvbiAob2JqZWN0LCBtcywgZXJyb3IpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRpbWVvdXQobXMsIGVycm9yKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAobXMsIGVycm9yKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgXCJzdHJpbmdcIiA9PT0gdHlwZW9mIGVycm9yKSB7XG4gICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihlcnJvciB8fCBcIlRpbWVkIG91dCBhZnRlciBcIiArIG1zICsgXCIgbXNcIik7XG4gICAgICAgICAgICBlcnJvci5jb2RlID0gXCJFVElNRURPVVRcIjtcbiAgICAgICAgfVxuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXJyb3IpO1xuICAgIH0sIG1zKTtcblxuICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChleGNlcHRpb24pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgIH0sIGRlZmVycmVkLm5vdGlmeSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBnaXZlbiB2YWx1ZSAob3IgcHJvbWlzZWQgdmFsdWUpLCBzb21lXG4gKiBtaWxsaXNlY29uZHMgYWZ0ZXIgaXQgcmVzb2x2ZWQuIFBhc3NlcyByZWplY3Rpb25zIGltbWVkaWF0ZWx5LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIGFmdGVyIG1pbGxpc2Vjb25kc1xuICogdGltZSBoYXMgZWxhcHNlZCBzaW5jZSB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZS5cbiAqIElmIHRoZSBnaXZlbiBwcm9taXNlIHJlamVjdHMsIHRoYXQgaXMgcGFzc2VkIGltbWVkaWF0ZWx5LlxuICovXG5RLmRlbGF5ID0gZnVuY3Rpb24gKG9iamVjdCwgdGltZW91dCkge1xuICAgIGlmICh0aW1lb3V0ID09PSB2b2lkIDApIHtcbiAgICAgICAgdGltZW91dCA9IG9iamVjdDtcbiAgICAgICAgb2JqZWN0ID0gdm9pZCAwO1xuICAgIH1cbiAgICByZXR1cm4gUShvYmplY3QpLmRlbGF5KHRpbWVvdXQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAodGltZW91dCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgYXMgYW4gYXJyYXksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqXG4gKiAgICAgIFEubmZhcHBseShGUy5yZWFkRmlsZSwgW19fZmlsZW5hbWVdKVxuICogICAgICAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogICAgICB9KVxuICpcbiAqL1xuUS5uZmFwcGx5ID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBQYXNzZXMgYSBjb250aW51YXRpb24gdG8gYSBOb2RlIGZ1bmN0aW9uLCB3aGljaCBpcyBjYWxsZWQgd2l0aCB0aGUgZ2l2ZW5cbiAqIGFyZ3VtZW50cyBwcm92aWRlZCBpbmRpdmlkdWFsbHksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mY2FsbChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSlcbiAqIC50aGVuKGZ1bmN0aW9uIChjb250ZW50KSB7XG4gKiB9KVxuICpcbiAqL1xuUS5uZmNhbGwgPSBmdW5jdGlvbiAoY2FsbGJhY2sgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFdyYXBzIGEgTm9kZUpTIGNvbnRpbnVhdGlvbiBwYXNzaW5nIGZ1bmN0aW9uIGFuZCByZXR1cm5zIGFuIGVxdWl2YWxlbnRcbiAqIHZlcnNpb24gdGhhdCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mYmluZChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSkoXCJ1dGYtOFwiKVxuICogLnRoZW4oY29uc29sZS5sb2cpXG4gKiAuZG9uZSgpXG4gKi9cblEubmZiaW5kID1cblEuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgUShjYWxsYmFjaykuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmJpbmQgPVxuUHJvbWlzZS5wcm90b3R5cGUuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5kZW5vZGVpZnkuYXBwbHkodm9pZCAwLCBhcmdzKTtcbn07XG5cblEubmJpbmQgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgZnVuY3Rpb24gYm91bmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpc3AsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgUShib3VuZCkuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uYmluZCA9IGZ1bmN0aW9uICgvKnRoaXNwLCAuLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMCk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMpO1xuICAgIHJldHVybiBRLm5iaW5kLmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2sgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkIGNhbGxiYWNrLlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIHtBcnJheX0gYXJncyBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kOyB0aGUgY2FsbGJhY2tcbiAqIHdpbGwgYmUgcHJvdmlkZWQgYnkgUSBhbmQgYXBwZW5kZWQgdG8gdGhlc2UgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgdmFsdWUgb3IgZXJyb3JcbiAqL1xuUS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEubnBvc3QgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5ucG9zdChuYW1lLCBhcmdzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUubnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MgfHwgW10pO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogQ2FsbHMgYSBtZXRob2Qgb2YgYSBOb2RlLXN0eWxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBOb2RlLXN0eWxlXG4gKiBjYWxsYmFjaywgZm9yd2FyZGluZyB0aGUgZ2l2ZW4gdmFyaWFkaWMgYXJndW1lbnRzLCBwbHVzIGEgcHJvdmlkZWRcbiAqIGNhbGxiYWNrIGFyZ3VtZW50LlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIC4uLmFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrIHdpbGxcbiAqIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubnNlbmQgPSAvLyBYWFggQmFzZWQgb24gTWFyayBNaWxsZXIncyBwcm9wb3NlZCBcInNlbmRcIlxuUS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5RLm5pbnZva2UgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblByb21pc2UucHJvdG90eXBlLm5tY2FsbCA9IC8vIFhYWCBCYXNlZCBvbiBcIlJlZHNhbmRybydzXCIgcHJvcG9zYWxcblByb21pc2UucHJvdG90eXBlLm5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIG5vZGVBcmdzXSkuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBJZiBhIGZ1bmN0aW9uIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBib3RoIE5vZGUgY29udGludWF0aW9uLXBhc3Npbmctc3R5bGUgYW5kXG4gKiBwcm9taXNlLXJldHVybmluZy1zdHlsZSwgaXQgY2FuIGVuZCBpdHMgaW50ZXJuYWwgcHJvbWlzZSBjaGFpbiB3aXRoXG4gKiBgbm9kZWlmeShub2RlYmFjaylgLCBmb3J3YXJkaW5nIHRoZSBvcHRpb25hbCBub2RlYmFjayBhcmd1bWVudC4gIElmIHRoZSB1c2VyXG4gKiBlbGVjdHMgdG8gdXNlIGEgbm9kZWJhY2ssIHRoZSByZXN1bHQgd2lsbCBiZSBzZW50IHRoZXJlLiAgSWYgdGhleSBkbyBub3RcbiAqIHBhc3MgYSBub2RlYmFjaywgdGhleSB3aWxsIHJlY2VpdmUgdGhlIHJlc3VsdCBwcm9taXNlLlxuICogQHBhcmFtIG9iamVjdCBhIHJlc3VsdCAob3IgYSBwcm9taXNlIGZvciBhIHJlc3VsdClcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG5vZGViYWNrIGEgTm9kZS5qcy1zdHlsZSBjYWxsYmFja1xuICogQHJldHVybnMgZWl0aGVyIHRoZSBwcm9taXNlIG9yIG5vdGhpbmdcbiAqL1xuUS5ub2RlaWZ5ID0gbm9kZWlmeTtcbmZ1bmN0aW9uIG5vZGVpZnkob2JqZWN0LCBub2RlYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdCkubm9kZWlmeShub2RlYmFjayk7XG59XG5cblByb21pc2UucHJvdG90eXBlLm5vZGVpZnkgPSBmdW5jdGlvbiAobm9kZWJhY2spIHtcbiAgICBpZiAobm9kZWJhY2spIHtcbiAgICAgICAgdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2sobnVsbCwgdmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn07XG5cblEubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlEubm9Db25mbGljdCBvbmx5IHdvcmtzIHdoZW4gUSBpcyB1c2VkIGFzIGEgZ2xvYmFsXCIpO1xufTtcblxuLy8gQWxsIGNvZGUgYmVmb3JlIHRoaXMgcG9pbnQgd2lsbCBiZSBmaWx0ZXJlZCBmcm9tIHN0YWNrIHRyYWNlcy5cbnZhciBxRW5kaW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG5cbnJldHVybiBRO1xuXG59KTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5eEwzRXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lMeThnZG1sdE9uUnpQVFE2YzNSelBUUTZjM2M5TkRwY2JpOHFJVnh1SUNwY2JpQXFJRU52Y0hseWFXZG9kQ0F5TURBNUxUSXdNVElnUzNKcGN5QkxiM2RoYkNCMWJtUmxjaUIwYUdVZ2RHVnliWE1nYjJZZ2RHaGxJRTFKVkZ4dUlDb2diR2xqWlc1elpTQm1iM1Z1WkNCaGRDQm9kSFJ3T2k4dloybDBhSFZpTG1OdmJTOXJjbWx6YTI5M1lXd3ZjUzl5WVhjdmJXRnpkR1Z5TDB4SlEwVk9VMFZjYmlBcVhHNGdLaUJYYVhSb0lIQmhjblJ6SUdKNUlGUjViR1Z5SUVOc2IzTmxYRzRnS2lCRGIzQjVjbWxuYUhRZ01qQXdOeTB5TURBNUlGUjViR1Z5SUVOc2IzTmxJSFZ1WkdWeUlIUm9aU0IwWlhKdGN5QnZaaUIwYUdVZ1RVbFVJRmdnYkdsalpXNXpaU0JtYjNWdVpGeHVJQ29nWVhRZ2FIUjBjRG92TDNkM2R5NXZjR1Z1YzI5MWNtTmxMbTl5Wnk5c2FXTmxibk5sY3k5dGFYUXRiR2xqWlc1elpTNW9kRzFzWEc0Z0tpQkdiM0pyWldRZ1lYUWdjbVZtWDNObGJtUXVhbk1nZG1WeWMybHZiam9nTWpBd09TMHdOUzB4TVZ4dUlDcGNiaUFxSUZkcGRHZ2djR0Z5ZEhNZ1lua2dUV0Z5YXlCTmFXeHNaWEpjYmlBcUlFTnZjSGx5YVdkb2RDQW9ReWtnTWpBeE1TQkhiMjluYkdVZ1NXNWpMbHh1SUNwY2JpQXFJRXhwWTJWdWMyVmtJSFZ1WkdWeUlIUm9aU0JCY0dGamFHVWdUR2xqWlc1elpTd2dWbVZ5YzJsdmJpQXlMakFnS0hSb1pTQmNJa3hwWTJWdWMyVmNJaWs3WEc0Z0tpQjViM1VnYldGNUlHNXZkQ0IxYzJVZ2RHaHBjeUJtYVd4bElHVjRZMlZ3ZENCcGJpQmpiMjF3YkdsaGJtTmxJSGRwZEdnZ2RHaGxJRXhwWTJWdWMyVXVYRzRnS2lCWmIzVWdiV0Y1SUc5aWRHRnBiaUJoSUdOdmNIa2diMllnZEdobElFeHBZMlZ1YzJVZ1lYUmNiaUFxWEc0Z0tpQm9kSFJ3T2k4dmQzZDNMbUZ3WVdOb1pTNXZjbWN2YkdsalpXNXpaWE12VEVsRFJVNVRSUzB5TGpCY2JpQXFYRzRnS2lCVmJteGxjM01nY21WeGRXbHlaV1FnWW5rZ1lYQndiR2xqWVdKc1pTQnNZWGNnYjNJZ1lXZHlaV1ZrSUhSdklHbHVJSGR5YVhScGJtY3NJSE52Wm5SM1lYSmxYRzRnS2lCa2FYTjBjbWxpZFhSbFpDQjFibVJsY2lCMGFHVWdUR2xqWlc1elpTQnBjeUJrYVhOMGNtbGlkWFJsWkNCdmJpQmhiaUJjSWtGVElFbFRYQ0lnUWtGVFNWTXNYRzRnS2lCWFNWUklUMVZVSUZkQlVsSkJUbFJKUlZNZ1QxSWdRMDlPUkVsVVNVOU9VeUJQUmlCQlRsa2dTMGxPUkN3Z1pXbDBhR1Z5SUdWNGNISmxjM01nYjNJZ2FXMXdiR2xsWkM1Y2JpQXFJRk5sWlNCMGFHVWdUR2xqWlc1elpTQm1iM0lnZEdobElITndaV05wWm1saklHeGhibWQxWVdkbElHZHZkbVZ5Ym1sdVp5QndaWEp0YVhOemFXOXVjeUJoYm1SY2JpQXFJR3hwYldsMFlYUnBiMjV6SUhWdVpHVnlJSFJvWlNCTWFXTmxibk5sTGx4dUlDcGNiaUFxTDF4dVhHNG9ablZ1WTNScGIyNGdLR1JsWm1sdWFYUnBiMjRwSUh0Y2JpQWdJQ0JjSW5WelpTQnpkSEpwWTNSY0lqdGNibHh1SUNBZ0lDOHZJRlJvYVhNZ1ptbHNaU0IzYVd4c0lHWjFibU4wYVc5dUlIQnliM0JsY214NUlHRnpJR0VnUEhOamNtbHdkRDRnZEdGbkxDQnZjaUJoSUcxdlpIVnNaVnh1SUNBZ0lDOHZJSFZ6YVc1bklFTnZiVzF2YmtwVElHRnVaQ0JPYjJSbFNsTWdiM0lnVW1WeGRXbHlaVXBUSUcxdlpIVnNaU0JtYjNKdFlYUnpMaUFnU1c1Y2JpQWdJQ0F2THlCRGIyMXRiMjR2VG05a1pTOVNaWEYxYVhKbFNsTXNJSFJvWlNCdGIyUjFiR1VnWlhod2IzSjBjeUIwYUdVZ1VTQkJVRWtnWVc1a0lIZG9aVzVjYmlBZ0lDQXZMeUJsZUdWamRYUmxaQ0JoY3lCaElITnBiWEJzWlNBOGMyTnlhWEIwUGl3Z2FYUWdZM0psWVhSbGN5QmhJRkVnWjJ4dlltRnNJR2x1YzNSbFlXUXVYRzVjYmlBZ0lDQXZMeUJOYjI1MFlXZGxJRkpsY1hWcGNtVmNiaUFnSUNCcFppQW9kSGx3Wlc5bUlHSnZiM1J6ZEhKaGNDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJR0p2YjNSemRISmhjQ2hjSW5CeWIyMXBjMlZjSWl3Z1pHVm1hVzVwZEdsdmJpazdYRzVjYmlBZ0lDQXZMeUJEYjIxdGIyNUtVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHVjRjRzl5ZEhNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUcxdlpIVnNaU0E5UFQwZ1hDSnZZbXBsWTNSY0lpa2dlMXh1SUNBZ0lDQWdJQ0J0YjJSMWJHVXVaWGh3YjNKMGN5QTlJR1JsWm1sdWFYUnBiMjRvS1R0Y2JseHVJQ0FnSUM4dklGSmxjWFZwY21WS1UxeHVJQ0FnSUgwZ1pXeHpaU0JwWmlBb2RIbHdaVzltSUdSbFptbHVaU0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lJQ1ltSUdSbFptbHVaUzVoYldRcElIdGNiaUFnSUNBZ0lDQWdaR1ZtYVc1bEtHUmxabWx1YVhScGIyNHBPMXh1WEc0Z0lDQWdMeThnVTBWVElDaFRaV04xY21VZ1JXTnRZVk5qY21sd2RDbGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCelpYTWdJVDA5SUZ3aWRXNWtaV1pwYm1Wa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRnpaWE11YjJzb0tTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZ6TG0xaGEyVlJJRDBnWkdWbWFXNXBkR2x2Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0x5OGdQSE5qY21sd2RENWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCM2FXNWtiM2NnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lnZkh3Z2RIbHdaVzltSUhObGJHWWdJVDA5SUZ3aWRXNWtaV1pwYm1Wa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1VISmxabVZ5SUhkcGJtUnZkeUJ2ZG1WeUlITmxiR1lnWm05eUlHRmtaQzF2YmlCelkzSnBjSFJ6TGlCVmMyVWdjMlZzWmlCbWIzSmNiaUFnSUNBZ0lDQWdMeThnYm05dUxYZHBibVJ2ZDJWa0lHTnZiblJsZUhSekxseHVJQ0FnSUNBZ0lDQjJZWElnWjJ4dlltRnNJRDBnZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnWENKMWJtUmxabWx1WldSY0lpQS9JSGRwYm1SdmR5QTZJSE5sYkdZN1hHNWNiaUFnSUNBZ0lDQWdMeThnUjJWMElIUm9aU0JnZDJsdVpHOTNZQ0J2WW1wbFkzUXNJSE5oZG1VZ2RHaGxJSEJ5WlhacGIzVnpJRkVnWjJ4dlltRnNYRzRnSUNBZ0lDQWdJQzh2SUdGdVpDQnBibWwwYVdGc2FYcGxJRkVnWVhNZ1lTQm5iRzlpWVd3dVhHNGdJQ0FnSUNBZ0lIWmhjaUJ3Y21WMmFXOTFjMUVnUFNCbmJHOWlZV3d1VVR0Y2JpQWdJQ0FnSUNBZ1oyeHZZbUZzTGxFZ1BTQmtaV1pwYm1sMGFXOXVLQ2s3WEc1Y2JpQWdJQ0FnSUNBZ0x5OGdRV1JrSUdFZ2JtOURiMjVtYkdsamRDQm1kVzVqZEdsdmJpQnpieUJSSUdOaGJpQmlaU0J5WlcxdmRtVmtJR1p5YjIwZ2RHaGxYRzRnSUNBZ0lDQWdJQzh2SUdkc2IySmhiQ0J1WVcxbGMzQmhZMlV1WEc0Z0lDQWdJQ0FnSUdkc2IySmhiQzVSTG01dlEyOXVabXhwWTNRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQm5iRzlpWVd3dVVTQTlJSEJ5WlhacGIzVnpVVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnZEdoeWIzY2dibVYzSUVWeWNtOXlLRndpVkdocGN5QmxiblpwY205dWJXVnVkQ0IzWVhNZ2JtOTBJR0Z1ZEdsamFYQmhkR1ZrSUdKNUlGRXVJRkJzWldGelpTQm1hV3hsSUdFZ1luVm5MbHdpS1R0Y2JpQWdJQ0I5WEc1Y2JuMHBLR1oxYm1OMGFXOXVJQ2dwSUh0Y2Jsd2lkWE5sSUhOMGNtbGpkRndpTzF4dVhHNTJZWElnYUdGelUzUmhZMnR6SUQwZ1ptRnNjMlU3WEc1MGNua2dlMXh1SUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVmU0JqWVhSamFDQW9aU2tnZTF4dUlDQWdJR2hoYzFOMFlXTnJjeUE5SUNFaFpTNXpkR0ZqYXp0Y2JuMWNibHh1THk4Z1FXeHNJR052WkdVZ1lXWjBaWElnZEdocGN5QndiMmx1ZENCM2FXeHNJR0psSUdacGJIUmxjbVZrSUdaeWIyMGdjM1JoWTJzZ2RISmhZMlZ6SUhKbGNHOXlkR1ZrWEc0dkx5QmllU0JSTGx4dWRtRnlJSEZUZEdGeWRHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dWRtRnlJSEZHYVd4bFRtRnRaVHRjYmx4dUx5OGdjMmhwYlhOY2JseHVMeThnZFhObFpDQm1iM0lnWm1Gc2JHSmhZMnNnYVc0Z1hDSmhiR3hTWlhOdmJIWmxaRndpWEc1MllYSWdibTl2Y0NBOUlHWjFibU4wYVc5dUlDZ3BJSHQ5TzF4dVhHNHZMeUJWYzJVZ2RHaGxJR1poYzNSbGMzUWdjRzl6YzJsaWJHVWdiV1ZoYm5NZ2RHOGdaWGhsWTNWMFpTQmhJSFJoYzJzZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymx4dUx5OGdiMllnZEdobElHVjJaVzUwSUd4dmIzQXVYRzUyWVhJZ2JtVjRkRlJwWTJzZ1BTaG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdMeThnYkdsdWEyVmtJR3hwYzNRZ2IyWWdkR0Z6YTNNZ0tITnBibWRzWlN3Z2QybDBhQ0JvWldGa0lHNXZaR1VwWEc0Z0lDQWdkbUZ5SUdobFlXUWdQU0I3ZEdGemF6b2dkbTlwWkNBd0xDQnVaWGgwT2lCdWRXeHNmVHRjYmlBZ0lDQjJZWElnZEdGcGJDQTlJR2hsWVdRN1hHNGdJQ0FnZG1GeUlHWnNkWE5vYVc1bklEMGdabUZzYzJVN1hHNGdJQ0FnZG1GeUlISmxjWFZsYzNSVWFXTnJJRDBnZG05cFpDQXdPMXh1SUNBZ0lIWmhjaUJwYzA1dlpHVktVeUE5SUdaaGJITmxPMXh1SUNBZ0lDOHZJSEYxWlhWbElHWnZjaUJzWVhSbElIUmhjMnR6TENCMWMyVmtJR0o1SUhWdWFHRnVaR3hsWkNCeVpXcGxZM1JwYjI0Z2RISmhZMnRwYm1kY2JpQWdJQ0IyWVhJZ2JHRjBaWEpSZFdWMVpTQTlJRnRkTzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWm14MWMyZ29LU0I3WEc0Z0lDQWdJQ0FnSUM4cUlHcHphR2x1ZENCc2IyOXdablZ1WXpvZ2RISjFaU0FxTDF4dUlDQWdJQ0FnSUNCMllYSWdkR0Z6YXl3Z1pHOXRZV2x1TzF4dVhHNGdJQ0FnSUNBZ0lIZG9hV3hsSUNob1pXRmtMbTVsZUhRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdobFlXUWdQU0JvWldGa0xtNWxlSFE3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2FHVmhaQzUwWVhOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYUdWaFpDNTBZWE5ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJQ0FnSUNBZ0lDQWdaRzl0WVdsdUlEMGdhR1ZoWkM1a2IyMWhhVzQ3WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoa2IyMWhhVzRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCb1pXRmtMbVJ2YldGcGJpQTlJSFp2YVdRZ01EdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmtiMjFoYVc0dVpXNTBaWElvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNBZ0lISjFibE5wYm1kc1pTaDBZWE5yTENCa2IyMWhhVzRwTzF4dVhHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkMmhwYkdVZ0tHeGhkR1Z5VVhWbGRXVXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMFlYTnJJRDBnYkdGMFpYSlJkV1YxWlM1d2IzQW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISjFibE5wYm1kc1pTaDBZWE5yS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQm1iSFZ6YUdsdVp5QTlJR1poYkhObE8xeHVJQ0FnSUgxY2JpQWdJQ0F2THlCeWRXNXpJR0VnYzJsdVoyeGxJR1oxYm1OMGFXOXVJR2x1SUhSb1pTQmhjM2x1WXlCeGRXVjFaVnh1SUNBZ0lHWjFibU4wYVc5dUlISjFibE5wYm1kc1pTaDBZWE5yTENCa2IyMWhhVzRwSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnNvS1R0Y2JseHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnBaaUFvYVhOT2IyUmxTbE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QkpiaUJ1YjJSbExDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCamIyNXphV1JsY21Wa0lHWmhkR0ZzSUdWeWNtOXljeTVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCU1pTMTBhSEp2ZHlCMGFHVnRJSE41Ym1Ob2NtOXViM1Z6YkhrZ2RHOGdhVzUwWlhKeWRYQjBJR1pzZFhOb2FXNW5JVnh1WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1JXNXpkWEpsSUdOdmJuUnBiblZoZEdsdmJpQnBaaUIwYUdVZ2RXNWpZWFZuYUhRZ1pYaGpaWEIwYVc5dUlHbHpJSE4xY0hCeVpYTnpaV1JjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCc2FYTjBaVzVwYm1jZ1hDSjFibU5oZFdkb2RFVjRZMlZ3ZEdsdmJsd2lJR1YyWlc1MGN5QW9ZWE1nWkc5dFlXbHVjeUJrYjJWektTNWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJEYjI1MGFXNTFaU0JwYmlCdVpYaDBJR1YyWlc1MElIUnZJR0YyYjJsa0lIUnBZMnNnY21WamRYSnphVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5QmxPMXh1WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRWx1SUdKeWIzZHpaWEp6TENCMWJtTmhkV2RvZENCbGVHTmxjSFJwYjI1eklHRnlaU0J1YjNRZ1ptRjBZV3d1WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1VtVXRkR2h5YjNjZ2RHaGxiU0JoYzNsdVkyaHliMjV2ZFhOc2VTQjBieUJoZG05cFpDQnpiRzkzTFdSdmQyNXpMbHh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSE5sZEZScGJXVnZkWFFvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5QmxPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSDBzSURBcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lDQWdhV1lnS0dSdmJXRnBiaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaRzl0WVdsdUxtVjRhWFFvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JseHVJQ0FnSUc1bGVIUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tIUmhjMnNwSUh0Y2JpQWdJQ0FnSUNBZ2RHRnBiQ0E5SUhSaGFXd3VibVY0ZENBOUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSaGMyczZJSFJoYzJzc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNDZJR2x6VG05a1pVcFRJQ1ltSUhCeWIyTmxjM011Wkc5dFlXbHVMRnh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjRkRG9nYm5Wc2JGeHVJQ0FnSUNBZ0lDQjlPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habXgxYzJocGJtY3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWnNkWE5vYVc1bklEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05yS0NrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOU8xeHVYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lIQnliMk5sYzNNdWRHOVRkSEpwYm1jb0tTQTlQVDBnWENKYmIySnFaV04wSUhCeWIyTmxjM05kWENJZ0ppWWdjSEp2WTJWemN5NXVaWGgwVkdsamF5a2dlMXh1SUNBZ0lDQWdJQ0F2THlCRmJuTjFjbVVnVVNCcGN5QnBiaUJoSUhKbFlXd2dUbTlrWlNCbGJuWnBjbTl1YldWdWRDd2dkMmwwYUNCaElHQndjbTlqWlhOekxtNWxlSFJVYVdOcllDNWNiaUFnSUNBZ0lDQWdMeThnVkc4Z2MyVmxJSFJvY205MVoyZ2dabUZyWlNCT2IyUmxJR1Z1ZG1seWIyNXRaVzUwY3pwY2JpQWdJQ0FnSUNBZ0x5OGdLaUJOYjJOb1lTQjBaWE4wSUhKMWJtNWxjaUF0SUdWNGNHOXpaWE1nWVNCZ2NISnZZMlZ6YzJBZ1oyeHZZbUZzSUhkcGRHaHZkWFFnWVNCZ2JtVjRkRlJwWTJ0Z1hHNGdJQ0FnSUNBZ0lDOHZJQ29nUW5KdmQzTmxjbWxtZVNBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemN5NXVaWGhVYVdOcllDQm1kVzVqZEdsdmJpQjBhR0YwSUhWelpYTmNiaUFnSUNBZ0lDQWdMeThnSUNCZ2MyVjBWR2x0Wlc5MWRHQXVJRWx1SUhSb2FYTWdZMkZ6WlNCZ2MyVjBTVzF0WldScFlYUmxZQ0JwY3lCd2NtVm1aWEp5WldRZ1ltVmpZWFZ6WlZ4dUlDQWdJQ0FnSUNBdkx5QWdJQ0JwZENCcGN5Qm1ZWE4wWlhJdUlFSnliM2R6WlhKcFpua25jeUJnY0hKdlkyVnpjeTUwYjFOMGNtbHVaeWdwWUNCNWFXVnNaSE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmNJbHR2WW1wbFkzUWdUMkpxWldOMFhWd2lMQ0IzYUdsc1pTQnBiaUJoSUhKbFlXd2dUbTlrWlNCbGJuWnBjbTl1YldWdWRGeHVJQ0FnSUNBZ0lDQXZMeUFnSUdCd2NtOWpaWE56TG01bGVIUlVhV05yS0NsZ0lIbHBaV3hrY3lCY0lsdHZZbXBsWTNRZ2NISnZZMlZ6YzExY0lpNWNiaUFnSUNBZ0lDQWdhWE5PYjJSbFNsTWdQU0IwY25WbE8xeHVYRzRnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NISnZZMlZ6Y3k1dVpYaDBWR2xqYXlobWJIVnphQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCelpYUkpiVzFsWkdsaGRHVWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0F2THlCSmJpQkpSVEV3TENCT2IyUmxMbXB6SURBdU9Tc3NJRzl5SUdoMGRIQnpPaTh2WjJsMGFIVmlMbU52YlM5T2IySnNaVXBUTDNObGRFbHRiV1ZrYVdGMFpWeHVJQ0FnSUNBZ0lDQnBaaUFvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnhkV1Z6ZEZScFkyc2dQU0J6WlhSSmJXMWxaR2xoZEdVdVltbHVaQ2gzYVc1a2IzY3NJR1pzZFhOb0tUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRFbHRiV1ZrYVdGMFpTaG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5TzF4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCTlpYTnpZV2RsUTJoaGJtNWxiQ0FoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QnRiMlJsY200Z1luSnZkM05sY25OY2JpQWdJQ0FnSUNBZ0x5OGdhSFIwY0RvdkwzZDNkeTV1YjI1aWJHOWphMmx1Wnk1cGJ5OHlNREV4THpBMkwzZHBibVJ2ZDI1bGVIUjBhV05yTG1oMGJXeGNiaUFnSUNBZ0lDQWdkbUZ5SUdOb1lXNXVaV3dnUFNCdVpYY2dUV1Z6YzJGblpVTm9ZVzV1Wld3b0tUdGNiaUFnSUNBZ0lDQWdMeThnUVhRZ2JHVmhjM1FnVTJGbVlYSnBJRlpsY25OcGIyNGdOaTR3TGpVZ0tEZzFNell1TXpBdU1Ta2dhVzUwWlhKdGFYUjBaVzUwYkhrZ1kyRnVibTkwSUdOeVpXRjBaVnh1SUNBZ0lDQWdJQ0F2THlCM2IzSnJhVzVuSUcxbGMzTmhaMlVnY0c5eWRITWdkR2hsSUdacGNuTjBJSFJwYldVZ1lTQndZV2RsSUd4dllXUnpMbHh1SUNBZ0lDQWdJQ0JqYUdGdWJtVnNMbkJ2Y25ReExtOXViV1Z6YzJGblpTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ2NtVnhkV1Z6ZEZCdmNuUlVhV05yTzF4dUlDQWdJQ0FnSUNBZ0lDQWdZMmhoYm01bGJDNXdiM0owTVM1dmJtMWxjM05oWjJVZ1BTQm1iSFZ6YUR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb0tDazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhaaGNpQnlaWEYxWlhOMFVHOXlkRlJwWTJzZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJQY0dWeVlTQnlaWEYxYVhKbGN5QjFjeUIwYnlCd2NtOTJhV1JsSUdFZ2JXVnpjMkZuWlNCd1lYbHNiMkZrTENCeVpXZGhjbVJzWlhOeklHOW1YRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QjNhR1YwYUdWeUlIZGxJSFZ6WlNCcGRDNWNiaUFnSUNBZ0lDQWdJQ0FnSUdOb1lXNXVaV3d1Y0c5eWRESXVjRzl6ZEUxbGMzTmhaMlVvTUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2MyVjBWR2x0Wlc5MWRDaG1iSFZ6YUN3Z01DazdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYRjFaWE4wVUc5eWRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZUdGNibHh1SUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDOHZJRzlzWkNCaWNtOTNjMlZ5YzF4dUlDQWdJQ0FnSUNCeVpYRjFaWE4wVkdsamF5QTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSE5sZEZScGJXVnZkWFFvWm14MWMyZ3NJREFwTzF4dUlDQWdJQ0FnSUNCOU8xeHVJQ0FnSUgxY2JpQWdJQ0F2THlCeWRXNXpJR0VnZEdGemF5QmhablJsY2lCaGJHd2diM1JvWlhJZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJseHVJQ0FnSUM4dklIUm9hWE1nYVhNZ2RYTmxablZzSUdadmNpQjFibWhoYm1Sc1pXUWdjbVZxWldOMGFXOXVJSFJ5WVdOcmFXNW5JSFJvWVhRZ2JtVmxaSE1nZEc4Z2FHRndjR1Z1WEc0Z0lDQWdMeThnWVdaMFpYSWdZV3hzSUdCMGFHVnVZR1FnZEdGemEzTWdhR0YyWlNCaVpXVnVJSEoxYmk1Y2JpQWdJQ0J1WlhoMFZHbGpheTV5ZFc1QlpuUmxjaUE5SUdaMWJtTjBhVzl1SUNoMFlYTnJLU0I3WEc0Z0lDQWdJQ0FnSUd4aGRHVnlVWFZsZFdVdWNIVnphQ2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdhV1lnS0NGbWJIVnphR2x1WnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWm14MWMyaHBibWNnUFNCMGNuVmxPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnhkV1Z6ZEZScFkyc29LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc0Z0lDQWdjbVYwZFhKdUlHNWxlSFJVYVdOck8xeHVmU2tvS1R0Y2JseHVMeThnUVhSMFpXMXdkQ0IwYnlCdFlXdGxJR2RsYm1WeWFXTnpJSE5oWm1VZ2FXNGdkR2hsSUdaaFkyVWdiMllnWkc5M2JuTjBjbVZoYlZ4dUx5OGdiVzlrYVdacFkyRjBhVzl1Y3k1Y2JpOHZJRlJvWlhKbElHbHpJRzV2SUhOcGRIVmhkR2x2YmlCM2FHVnlaU0IwYUdseklHbHpJRzVsWTJWemMyRnllUzVjYmk4dklFbG1JSGx2ZFNCdVpXVmtJR0VnYzJWamRYSnBkSGtnWjNWaGNtRnVkR1ZsTENCMGFHVnpaU0J3Y21sdGIzSmthV0ZzY3lCdVpXVmtJSFJ2SUdKbFhHNHZMeUJrWldWd2JIa2dabkp2ZW1WdUlHRnVlWGRoZVN3Z1lXNWtJR2xtSUhsdmRTQmtiMjdpZ0psMElHNWxaV1FnWVNCelpXTjFjbWwwZVNCbmRXRnlZVzUwWldVc1hHNHZMeUIwYUdseklHbHpJR3AxYzNRZ2NHeGhhVzRnY0dGeVlXNXZhV1F1WEc0dkx5QkliM2RsZG1WeUxDQjBhR2x6SUNvcWJXbG5hSFFxS2lCb1lYWmxJSFJvWlNCdWFXTmxJSE5wWkdVdFpXWm1aV04wSUc5bUlISmxaSFZqYVc1bklIUm9aU0J6YVhwbElHOW1YRzR2THlCMGFHVWdiV2x1YVdacFpXUWdZMjlrWlNCaWVTQnlaV1IxWTJsdVp5QjRMbU5oYkd3b0tTQjBieUJ0WlhKbGJIa2dlQ2dwWEc0dkx5QlRaV1VnVFdGeWF5Qk5hV3hzWlhMaWdKbHpJR1Y0Y0d4aGJtRjBhVzl1SUc5bUlIZG9ZWFFnZEdocGN5QmtiMlZ6TGx4dUx5OGdhSFIwY0RvdkwzZHBhMmt1WldOdFlYTmpjbWx3ZEM1dmNtY3ZaRzlyZFM1d2FIQS9hV1E5WTI5dWRtVnVkR2x2Ym5NNmMyRm1aVjl0WlhSaFgzQnliMmR5WVcxdGFXNW5YRzUyWVhJZ1kyRnNiQ0E5SUVaMWJtTjBhVzl1TG1OaGJHdzdYRzVtZFc1amRHbHZiaUIxYm1OMWNuSjVWR2hwY3lobUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3d1WVhCd2JIa29aaXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0I5TzF4dWZWeHVMeThnVkdocGN5QnBjeUJsY1hWcGRtRnNaVzUwTENCaWRYUWdjMnh2ZDJWeU9seHVMeThnZFc1amRYSnllVlJvYVhNZ1BTQkdkVzVqZEdsdmJsOWlhVzVrTG1KcGJtUW9SblZ1WTNScGIyNWZZbWx1WkM1allXeHNLVHRjYmk4dklHaDBkSEE2THk5cWMzQmxjbVl1WTI5dEwzVnVZM1Z5Y25sMGFHbHpYRzVjYm5aaGNpQmhjbkpoZVY5emJHbGpaU0E5SUhWdVkzVnljbmxVYUdsektFRnljbUY1TG5CeWIzUnZkSGx3WlM1emJHbGpaU2s3WEc1Y2JuWmhjaUJoY25KaGVWOXlaV1IxWTJVZ1BTQjFibU4xY25KNVZHaHBjeWhjYmlBZ0lDQkJjbkpoZVM1d2NtOTBiM1I1Y0dVdWNtVmtkV05sSUh4OElHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5d2dZbUZ6YVhNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUdsdVpHVjRJRDBnTUN4Y2JpQWdJQ0FnSUNBZ0lDQWdJR3hsYm1kMGFDQTlJSFJvYVhNdWJHVnVaM1JvTzF4dUlDQWdJQ0FnSUNBdkx5QmpiMjVqWlhKdWFXNW5JSFJvWlNCcGJtbDBhV0ZzSUhaaGJIVmxMQ0JwWmlCdmJtVWdhWE1nYm05MElIQnliM1pwWkdWa1hHNGdJQ0FnSUNBZ0lHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDA5UFNBeEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnpaV1ZySUhSdklIUm9aU0JtYVhKemRDQjJZV3gxWlNCcGJpQjBhR1VnWVhKeVlYa3NJR0ZqWTI5MWJuUnBibWRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJR1p2Y2lCMGFHVWdjRzl6YzJsaWFXeHBkSGtnZEdoaGRDQnBjeUJwY3lCaElITndZWEp6WlNCaGNuSmhlVnh1SUNBZ0lDQWdJQ0FnSUNBZ1pHOGdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUNocGJtUmxlQ0JwYmlCMGFHbHpLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHSmhjMmx6SUQwZ2RHaHBjMXRwYm1SbGVDc3JYVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDZ3JLMmx1WkdWNElENDlJR3hsYm1kMGFDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1ZIbHdaVVZ5Y205eUtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQjNhR2xzWlNBb01TazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnTHk4Z2NtVmtkV05sWEc0Z0lDQWdJQ0FnSUdadmNpQW9PeUJwYm1SbGVDQThJR3hsYm1kMGFEc2dhVzVrWlhnckt5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdZV05qYjNWdWRDQm1iM0lnZEdobElIQnZjM05wWW1sc2FYUjVJSFJvWVhRZ2RHaGxJR0Z5Y21GNUlHbHpJSE53WVhKelpWeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUdsdUlIUm9hWE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCaVlYTnBjeUE5SUdOaGJHeGlZV05yS0dKaGMybHpMQ0IwYUdselcybHVaR1Y0WFN3Z2FXNWtaWGdwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJpWVhOcGN6dGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmFXNWtaWGhQWmlBOUlIVnVZM1Z5Y25sVWFHbHpLRnh1SUNBZ0lFRnljbUY1TG5CeWIzUnZkSGx3WlM1cGJtUmxlRTltSUh4OElHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ1YjNRZ1lTQjJaWEo1SUdkdmIyUWdjMmhwYlN3Z1luVjBJR2R2YjJRZ1pXNXZkV2RvSUdadmNpQnZkWElnYjI1bElIVnpaU0J2WmlCcGRGeHVJQ0FnSUNBZ0lDQm1iM0lnS0haaGNpQnBJRDBnTURzZ2FTQThJSFJvYVhNdWJHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2gwYUdselcybGRJRDA5UFNCMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUF0TVR0Y2JpQWdJQ0I5WEc0cE8xeHVYRzUyWVhJZ1lYSnlZWGxmYldGd0lEMGdkVzVqZFhKeWVWUm9hWE1vWEc0Z0lDQWdRWEp5WVhrdWNISnZkRzkwZVhCbExtMWhjQ0I4ZkNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzc0lIUm9hWE53S1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ykd4bFkzUWdQU0JiWFR0Y2JpQWdJQ0FnSUNBZ1lYSnlZWGxmY21Wa2RXTmxLSE5sYkdZc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSFpoYkhWbExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWTI5c2JHVmpkQzV3ZFhOb0tHTmhiR3hpWVdOckxtTmhiR3dvZEdocGMzQXNJSFpoYkhWbExDQnBibVJsZUN3Z2MyVnNaaWtwTzF4dUlDQWdJQ0FnSUNCOUxDQjJiMmxrSURBcE8xeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1kyOXNiR1ZqZER0Y2JpQWdJQ0I5WEc0cE8xeHVYRzUyWVhJZ2IySnFaV04wWDJOeVpXRjBaU0E5SUU5aWFtVmpkQzVqY21WaGRHVWdmSHdnWm5WdVkzUnBiMjRnS0hCeWIzUnZkSGx3WlNrZ2UxeHVJQ0FnSUdaMWJtTjBhVzl1SUZSNWNHVW9LU0I3SUgxY2JpQWdJQ0JVZVhCbExuQnliM1J2ZEhsd1pTQTlJSEJ5YjNSdmRIbHdaVHRjYmlBZ0lDQnlaWFIxY200Z2JtVjNJRlI1Y0dVb0tUdGNibjA3WEc1Y2JuWmhjaUJ2WW1wbFkzUmZhR0Z6VDNkdVVISnZjR1Z5ZEhrZ1BTQjFibU4xY25KNVZHaHBjeWhQWW1wbFkzUXVjSEp2ZEc5MGVYQmxMbWhoYzA5M2JsQnliM0JsY25SNUtUdGNibHh1ZG1GeUlHOWlhbVZqZEY5clpYbHpJRDBnVDJKcVpXTjBMbXRsZVhNZ2ZId2dablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lIWmhjaUJyWlhseklEMGdXMTA3WEc0Z0lDQWdabTl5SUNoMllYSWdhMlY1SUdsdUlHOWlhbVZqZENrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvYjJKcVpXTjBYMmhoYzA5M2JsQnliM0JsY25SNUtHOWlhbVZqZEN3Z2EyVjVLU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhMlY1Y3k1d2RYTm9LR3RsZVNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJR3RsZVhNN1hHNTlPMXh1WEc1MllYSWdiMkpxWldOMFgzUnZVM1J5YVc1bklEMGdkVzVqZFhKeWVWUm9hWE1vVDJKcVpXTjBMbkJ5YjNSdmRIbHdaUzUwYjFOMGNtbHVaeWs3WEc1Y2JtWjFibU4wYVc5dUlHbHpUMkpxWldOMEtIWmhiSFZsS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFpoYkhWbElEMDlQU0JQWW1wbFkzUW9kbUZzZFdVcE8xeHVmVnh1WEc0dkx5Qm5aVzVsY21GMGIzSWdjbVZzWVhSbFpDQnphR2x0YzF4dVhHNHZMeUJHU1ZoTlJUb2dVbVZ0YjNabElIUm9hWE1nWm5WdVkzUnBiMjRnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVablZ1WTNScGIyNGdhWE5UZEc5d1NYUmxjbUYwYVc5dUtHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlBb1hHNGdJQ0FnSUNBZ0lHOWlhbVZqZEY5MGIxTjBjbWx1WnlobGVHTmxjSFJwYjI0cElEMDlQU0JjSWx0dlltcGxZM1FnVTNSdmNFbDBaWEpoZEdsdmJsMWNJaUI4ZkZ4dUlDQWdJQ0FnSUNCbGVHTmxjSFJwYjI0Z2FXNXpkR0Z1WTJWdlppQlJVbVYwZFhKdVZtRnNkV1ZjYmlBZ0lDQXBPMXh1ZlZ4dVhHNHZMeUJHU1ZoTlJUb2dVbVZ0YjNabElIUm9hWE1nYUdWc2NHVnlJR0Z1WkNCUkxuSmxkSFZ5YmlCdmJtTmxJRVZUTmlCblpXNWxjbUYwYjNKeklHRnlaU0JwYmx4dUx5OGdVM0JwWkdWeVRXOXVhMlY1TGx4dWRtRnlJRkZTWlhSMWNtNVdZV3gxWlR0Y2JtbG1JQ2gwZVhCbGIyWWdVbVYwZFhKdVZtRnNkV1VnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0JSVW1WMGRYSnVWbUZzZFdVZ1BTQlNaWFIxY201V1lXeDFaVHRjYm4wZ1pXeHpaU0I3WEc0Z0lDQWdVVkpsZEhWeWJsWmhiSFZsSUQwZ1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IyWVd4MVpUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dkx5QnNiMjVuSUhOMFlXTnJJSFJ5WVdObGMxeHVYRzUyWVhJZ1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSWdQU0JjSWtaeWIyMGdjSEpsZG1sdmRYTWdaWFpsYm5RNlhDSTdYRzVjYm1aMWJtTjBhVzl1SUcxaGEyVlRkR0ZqYTFSeVlXTmxURzl1WnlobGNuSnZjaXdnY0hKdmJXbHpaU2tnZTF4dUlDQWdJQzh2SUVsbUlIQnZjM05wWW14bExDQjBjbUZ1YzJadmNtMGdkR2hsSUdWeWNtOXlJSE4wWVdOcklIUnlZV05sSUdKNUlISmxiVzkyYVc1bklFNXZaR1VnWVc1a0lGRmNiaUFnSUNBdkx5QmpjblZtZEN3Z2RHaGxiaUJqYjI1allYUmxibUYwYVc1bklIZHBkR2dnZEdobElITjBZV05ySUhSeVlXTmxJRzltSUdCd2NtOXRhWE5sWUM0Z1UyVmxJQ00xTnk1Y2JpQWdJQ0JwWmlBb2FHRnpVM1JoWTJ0eklDWW1YRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVjM1JoWTJzZ0ppWmNiaUFnSUNBZ0lDQWdkSGx3Wlc5bUlHVnljbTl5SUQwOVBTQmNJbTlpYW1WamRGd2lJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlJQ0U5UFNCdWRXeHNJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOcklDWW1YRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05yTG1sdVpHVjRUMllvVTFSQlEwdGZTbFZOVUY5VFJWQkJVa0ZVVDFJcElEMDlQU0F0TVZ4dUlDQWdJQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdjM1JoWTJ0eklEMGdXMTA3WEc0Z0lDQWdJQ0FnSUdadmNpQW9kbUZ5SUhBZ1BTQndjbTl0YVhObE95QWhJWEE3SUhBZ1BTQndMbk52ZFhKalpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEF1YzNSaFkyc3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaHdMbk4wWVdOcktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnpkR0ZqYTNNdWRXNXphR2xtZENobGNuSnZjaTV6ZEdGamF5azdYRzVjYmlBZ0lDQWdJQ0FnZG1GeUlHTnZibU5oZEdWa1UzUmhZMnR6SUQwZ2MzUmhZMnR6TG1wdmFXNG9YQ0pjWEc1Y0lpQXJJRk5VUVVOTFgwcFZUVkJmVTBWUVFWSkJWRTlTSUNzZ1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJRDBnWm1sc2RHVnlVM1JoWTJ0VGRISnBibWNvWTI5dVkyRjBaV1JUZEdGamEzTXBPMXh1SUNBZ0lIMWNibjFjYmx4dVpuVnVZM1JwYjI0Z1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb2MzUmhZMnRUZEhKcGJtY3BJSHRjYmlBZ0lDQjJZWElnYkdsdVpYTWdQU0J6ZEdGamExTjBjbWx1Wnk1emNHeHBkQ2hjSWx4Y2Jsd2lLVHRjYmlBZ0lDQjJZWElnWkdWemFYSmxaRXhwYm1WeklEMGdXMTA3WEc0Z0lDQWdabTl5SUNoMllYSWdhU0E5SURBN0lHa2dQQ0JzYVc1bGN5NXNaVzVuZEdnN0lDc3JhU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdiR2x1WlNBOUlHeHBibVZ6VzJsZE8xeHVYRzRnSUNBZ0lDQWdJR2xtSUNnaGFYTkpiblJsY201aGJFWnlZVzFsS0d4cGJtVXBJQ1ltSUNGcGMwNXZaR1ZHY21GdFpTaHNhVzVsS1NBbUppQnNhVzVsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWlhOcGNtVmtUR2x1WlhNdWNIVnphQ2hzYVc1bEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnSUNCeVpYUjFjbTRnWkdWemFYSmxaRXhwYm1WekxtcHZhVzRvWENKY1hHNWNJaWs3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2x6VG05a1pVWnlZVzFsS0hOMFlXTnJUR2x1WlNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ6ZEdGamEweHBibVV1YVc1a1pYaFBaaWhjSWlodGIyUjFiR1V1YW5NNlhDSXBJQ0U5UFNBdE1TQjhmRnh1SUNBZ0lDQWdJQ0FnSUNCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHViMlJsTG1wek9sd2lLU0FoUFQwZ0xURTdYRzU5WEc1Y2JtWjFibU4wYVc5dUlHZGxkRVpwYkdWT1lXMWxRVzVrVEdsdVpVNTFiV0psY2loemRHRmphMHhwYm1VcElIdGNiaUFnSUNBdkx5Qk9ZVzFsWkNCbWRXNWpkR2x2Ym5NNklGd2lZWFFnWm5WdVkzUnBiMjVPWVcxbElDaG1hV3hsYm1GdFpUcHNhVzVsVG5WdFltVnlPbU52YkhWdGJrNTFiV0psY2lsY0lseHVJQ0FnSUM4dklFbHVJRWxGTVRBZ1puVnVZM1JwYjI0Z2JtRnRaU0JqWVc0Z2FHRjJaU0J6Y0dGalpYTWdLRndpUVc1dmJubHRiM1Z6SUdaMWJtTjBhVzl1WENJcElFOWZiMXh1SUNBZ0lIWmhjaUJoZEhSbGJYQjBNU0E5SUM5aGRDQXVLeUJjWENnb0xpc3BPaWhjWEdRcktUb29QenBjWEdRcktWeGNLU1F2TG1WNFpXTW9jM1JoWTJ0TWFXNWxLVHRjYmlBZ0lDQnBaaUFvWVhSMFpXMXdkREVwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUZ0aGRIUmxiWEIwTVZzeFhTd2dUblZ0WW1WeUtHRjBkR1Z0Y0hReFd6SmRLVjA3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnUVc1dmJubHRiM1Z6SUdaMWJtTjBhVzl1Y3pvZ1hDSmhkQ0JtYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNsd2lYRzRnSUNBZ2RtRnlJR0YwZEdWdGNIUXlJRDBnTDJGMElDaGJYaUJkS3lrNktGeGNaQ3NwT2lnL09seGNaQ3NwSkM4dVpYaGxZeWh6ZEdGamEweHBibVVwTzF4dUlDQWdJR2xtSUNoaGRIUmxiWEIwTWlrZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1cyRjBkR1Z0Y0hReVd6RmRMQ0JPZFcxaVpYSW9ZWFIwWlcxd2RESmJNbDBwWFR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0F2THlCR2FYSmxabTk0SUhOMGVXeGxPaUJjSW1aMWJtTjBhVzl1UUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhJZ2IzSWdRR1pwYkdWdVlXMWxPbXhwYm1WT2RXMWlaWEpjSWx4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTXlBOUlDOHVLa0FvTGlzcE9paGNYR1FyS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERNcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME0xc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXpXekpkS1YwN1hHNGdJQ0FnZlZ4dWZWeHVYRzVtZFc1amRHbHZiaUJwYzBsdWRHVnlibUZzUm5KaGJXVW9jM1JoWTJ0TWFXNWxLU0I3WEc0Z0lDQWdkbUZ5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpQTlJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBPMXh1WEc0Z0lDQWdhV1lnS0NGbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1poYkhObE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhaaGNpQm1hV3hsVG1GdFpTQTlJR1pwYkdWT1lXMWxRVzVrVEdsdVpVNTFiV0psY2xzd1hUdGNiaUFnSUNCMllYSWdiR2x1WlU1MWJXSmxjaUE5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3hYVHRjYmx4dUlDQWdJSEpsZEhWeWJpQm1hV3hsVG1GdFpTQTlQVDBnY1VacGJHVk9ZVzFsSUNZbVhHNGdJQ0FnSUNBZ0lHeHBibVZPZFcxaVpYSWdQajBnY1ZOMFlYSjBhVzVuVEdsdVpTQW1KbHh1SUNBZ0lDQWdJQ0JzYVc1bFRuVnRZbVZ5SUR3OUlIRkZibVJwYm1kTWFXNWxPMXh1ZlZ4dVhHNHZMeUJrYVhOamIzWmxjaUJ2ZDI0Z1ptbHNaU0J1WVcxbElHRnVaQ0JzYVc1bElHNTFiV0psY2lCeVlXNW5aU0JtYjNJZ1ptbHNkR1Z5YVc1bklITjBZV05yWEc0dkx5QjBjbUZqWlhOY2JtWjFibU4wYVc5dUlHTmhjSFIxY21WTWFXNWxLQ2tnZTF4dUlDQWdJR2xtSUNnaGFHRnpVM1JoWTJ0ektTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9LVHRjYmlBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQnNhVzVsY3lBOUlHVXVjM1JoWTJzdWMzQnNhWFFvWENKY1hHNWNJaWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQm1hWEp6ZEV4cGJtVWdQU0JzYVc1bGMxc3dYUzVwYm1SbGVFOW1LRndpUUZ3aUtTQStJREFnUHlCc2FXNWxjMXN4WFNBNklHeHBibVZ6V3pKZE8xeHVJQ0FnSUNBZ0lDQjJZWElnWm1sc1pVNWhiV1ZCYm1STWFXNWxUblZ0WW1WeUlEMGdaMlYwUm1sc1pVNWhiV1ZCYm1STWFXNWxUblZ0WW1WeUtHWnBjbk4wVEdsdVpTazdYRzRnSUNBZ0lDQWdJR2xtSUNnaFptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lIMWNibHh1SUNBZ0lDQWdJQ0J4Um1sc1pVNWhiV1VnUFNCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNRjA3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaVUZ1WkV4cGJtVk9kVzFpWlhKYk1WMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCa1pYQnlaV05oZEdVb1kyRnNiR0poWTJzc0lHNWhiV1VzSUdGc2RHVnlibUYwYVhabEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdhV1lnS0hSNWNHVnZaaUJqYjI1emIyeGxJQ0U5UFNCY0luVnVaR1ZtYVc1bFpGd2lJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQjBlWEJsYjJZZ1kyOXVjMjlzWlM1M1lYSnVJRDA5UFNCY0ltWjFibU4wYVc5dVhDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHTnZibk52YkdVdWQyRnliaWh1WVcxbElDc2dYQ0lnYVhNZ1pHVndjbVZqWVhSbFpDd2dkWE5sSUZ3aUlDc2dZV3gwWlhKdVlYUnBkbVVnSzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aUlHbHVjM1JsWVdRdVhDSXNJRzVsZHlCRmNuSnZjaWhjSWx3aUtTNXpkR0ZqYXlrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtRndjR3g1S0dOaGJHeGlZV05yTENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUgwN1hHNTlYRzVjYmk4dklHVnVaQ0J2WmlCemFHbHRjMXh1THk4Z1ltVm5hVzV1YVc1bklHOW1JSEpsWVd3Z2QyOXlhMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObExDQndZWE56WlhNZ2NISnZiV2x6WlhNZ2RHaHliM1ZuYUN3Z2IzSmNiaUFxSUdOdlpYSmpaWE1nY0hKdmJXbHpaWE1nWm5KdmJTQmthV1ptWlhKbGJuUWdjM2x6ZEdWdGN5NWNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJRzl5SUhCeWIyMXBjMlZjYmlBcUwxeHVablZ1WTNScGIyNGdVU2gyWVd4MVpTa2dlMXh1SUNBZ0lDOHZJRWxtSUhSb1pTQnZZbXBsWTNRZ2FYTWdZV3h5WldGa2VTQmhJRkJ5YjIxcGMyVXNJSEpsZEhWeWJpQnBkQ0JrYVhKbFkzUnNlUzRnSUZSb2FYTWdaVzVoWW14bGMxeHVJQ0FnSUM4dklIUm9aU0J5WlhOdmJIWmxJR1oxYm1OMGFXOXVJSFJ2SUdKdmRHZ2dZbVVnZFhObFpDQjBieUJqY21WaGRHVmtJSEpsWm1WeVpXNWpaWE1nWm5KdmJTQnZZbXBsWTNSekxGeHVJQ0FnSUM4dklHSjFkQ0IwYnlCMGIyeGxjbUZpYkhrZ1kyOWxjbU5sSUc1dmJpMXdjbTl0YVhObGN5QjBieUJ3Y205dGFYTmxjeTVjYmlBZ0lDQnBaaUFvZG1Gc2RXVWdhVzV6ZEdGdVkyVnZaaUJRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QmhjM05wYldsc1lYUmxJSFJvWlc1aFlteGxjMXh1SUNBZ0lHbG1JQ2hwYzFCeWIyMXBjMlZCYkdsclpTaDJZV3gxWlNrcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTnZaWEpqWlNoMllXeDFaU2s3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWjFiR1pwYkd3b2RtRnNkV1VwTzF4dUlDQWdJSDFjYm4xY2JsRXVjbVZ6YjJ4MlpTQTlJRkU3WEc1Y2JpOHFLbHh1SUNvZ1VHVnlabTl5YlhNZ1lTQjBZWE5ySUdsdUlHRWdablYwZFhKbElIUjFjbTRnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQjBZWE5yWEc0Z0tpOWNibEV1Ym1WNGRGUnBZMnNnUFNCdVpYaDBWR2xqYXp0Y2JseHVMeW9xWEc0Z0tpQkRiMjUwY205c2N5QjNhR1YwYUdWeUlHOXlJRzV2ZENCc2IyNW5JSE4wWVdOcklIUnlZV05sY3lCM2FXeHNJR0psSUc5dVhHNGdLaTljYmxFdWJHOXVaMU4wWVdOclUzVndjRzl5ZENBOUlHWmhiSE5sTzF4dVhHNHZMeUJsYm1GaWJHVWdiRzl1WnlCemRHRmphM01nYVdZZ1VWOUVSVUpWUnlCcGN5QnpaWFJjYm1sbUlDaDBlWEJsYjJZZ2NISnZZMlZ6Y3lBOVBUMGdYQ0p2WW1wbFkzUmNJaUFtSmlCd2NtOWpaWE56SUNZbUlIQnliMk5sYzNNdVpXNTJJQ1ltSUhCeWIyTmxjM011Wlc1MkxsRmZSRVZDVlVjcElIdGNiaUFnSUNCUkxteHZibWRUZEdGamExTjFjSEJ2Y25RZ1BTQjBjblZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU52Ym5OMGNuVmpkSE1nWVNCN2NISnZiV2x6WlN3Z2NtVnpiMngyWlN3Z2NtVnFaV04wZlNCdlltcGxZM1F1WEc0Z0tseHVJQ29nWUhKbGMyOXNkbVZnSUdseklHRWdZMkZzYkdKaFkyc2dkRzhnYVc1MmIydGxJSGRwZEdnZ1lTQnRiM0psSUhKbGMyOXNkbVZrSUhaaGJIVmxJR1p2Y2lCMGFHVmNiaUFxSUhCeWIyMXBjMlV1SUZSdklHWjFiR1pwYkd3Z2RHaGxJSEJ5YjIxcGMyVXNJR2x1ZG05clpTQmdjbVZ6YjJ4MlpXQWdkMmwwYUNCaGJua2dkbUZzZFdVZ2RHaGhkQ0JwYzF4dUlDb2dibTkwSUdFZ2RHaGxibUZpYkdVdUlGUnZJSEpsYW1WamRDQjBhR1VnY0hKdmJXbHpaU3dnYVc1MmIydGxJR0J5WlhOdmJIWmxZQ0IzYVhSb0lHRWdjbVZxWldOMFpXUmNiaUFxSUhSb1pXNWhZbXhsTENCdmNpQnBiblp2YTJVZ1lISmxhbVZqZEdBZ2QybDBhQ0IwYUdVZ2NtVmhjMjl1SUdScGNtVmpkR3g1TGlCVWJ5QnlaWE52YkhabElIUm9aVnh1SUNvZ2NISnZiV2x6WlNCMGJ5QmhibTkwYUdWeUlIUm9aVzVoWW14bExDQjBhSFZ6SUhCMWRIUnBibWNnYVhRZ2FXNGdkR2hsSUhOaGJXVWdjM1JoZEdVc0lHbHVkbTlyWlZ4dUlDb2dZSEpsYzI5c2RtVmdJSGRwZEdnZ2RHaGhkQ0J2ZEdobGNpQjBhR1Z1WVdKc1pTNWNiaUFxTDF4dVVTNWtaV1psY2lBOUlHUmxabVZ5TzF4dVpuVnVZM1JwYjI0Z1pHVm1aWElvS1NCN1hHNGdJQ0FnTHk4Z2FXWWdYQ0p0WlhOellXZGxjMXdpSUdseklHRnVJRndpUVhKeVlYbGNJaXdnZEdoaGRDQnBibVJwWTJGMFpYTWdkR2hoZENCMGFHVWdjSEp2YldselpTQm9ZWE1nYm05MElIbGxkRnh1SUNBZ0lDOHZJR0psWlc0Z2NtVnpiMngyWldRdUlDQkpaaUJwZENCcGN5QmNJblZ1WkdWbWFXNWxaRndpTENCcGRDQm9ZWE1nWW1WbGJpQnlaWE52YkhabFpDNGdJRVZoWTJoY2JpQWdJQ0F2THlCbGJHVnRaVzUwSUc5bUlIUm9aU0J0WlhOellXZGxjeUJoY25KaGVTQnBjeUJwZEhObGJHWWdZVzRnWVhKeVlYa2diMllnWTI5dGNHeGxkR1VnWVhKbmRXMWxiblJ6SUhSdlhHNGdJQ0FnTHk4Z1ptOXlkMkZ5WkNCMGJ5QjBhR1VnY21WemIyeDJaV1FnY0hKdmJXbHpaUzRnSUZkbElHTnZaWEpqWlNCMGFHVWdjbVZ6YjJ4MWRHbHZiaUIyWVd4MVpTQjBieUJoWEc0Z0lDQWdMeThnY0hKdmJXbHpaU0IxYzJsdVp5QjBhR1VnWUhKbGMyOXNkbVZnSUdaMWJtTjBhVzl1SUdKbFkyRjFjMlVnYVhRZ2FHRnVaR3hsY3lCaWIzUm9JR1oxYkd4NVhHNGdJQ0FnTHk4Z2JtOXVMWFJvWlc1aFlteGxJSFpoYkhWbGN5QmhibVFnYjNSb1pYSWdkR2hsYm1GaWJHVnpJR2R5WVdObFpuVnNiSGt1WEc0Z0lDQWdkbUZ5SUcxbGMzTmhaMlZ6SUQwZ1cxMHNJSEJ5YjJkeVpYTnpUR2x6ZEdWdVpYSnpJRDBnVzEwc0lISmxjMjlzZG1Wa1VISnZiV2x6WlR0Y2JseHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJRzlpYW1WamRGOWpjbVZoZEdVb1pHVm1aWEl1Y0hKdmRHOTBlWEJsS1R0Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHOWlhbVZqZEY5amNtVmhkR1VvVUhKdmJXbHpaUzV3Y205MGIzUjVjR1VwTzF4dVhHNGdJQ0FnY0hKdmJXbHpaUzV3Y205dGFYTmxSR2x6Y0dGMFkyZ2dQU0JtZFc1amRHbHZiaUFvY21WemIyeDJaU3dnYjNBc0lHOXdaWEpoYm1SektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNBZ0lDQWdhV1lnS0cxbGMzTmhaMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J0WlhOellXZGxjeTV3ZFhOb0tHRnlaM01wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c5d0lEMDlQU0JjSW5kb1pXNWNJaUFtSmlCdmNHVnlZVzVrYzFzeFhTa2dleUF2THlCd2NtOW5jbVZ6Y3lCdmNHVnlZVzVrWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY0hKdlozSmxjM05NYVhOMFpXNWxjbk11Y0hWemFDaHZjR1Z5WVc1a2Mxc3hYU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOcktHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOdmJIWmxaRkJ5YjIxcGMyVXVjSEp2YldselpVUnBjM0JoZEdOb0xtRndjR3g1S0hKbGMyOXNkbVZrVUhKdmJXbHpaU3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQXZMeUJZV0ZnZ1pHVndjbVZqWVhSbFpGeHVJQ0FnSUhCeWIyMXBjMlV1ZG1Gc2RXVlBaaUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdhV1lnS0cxbGMzTmhaMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVmhjbVZ5Vm1Gc2RXVWdQU0J1WldGeVpYSW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdhV1lnS0dselVISnZiV2x6WlNodVpXRnlaWEpXWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjMjlzZG1Wa1VISnZiV2x6WlNBOUlHNWxZWEpsY2xaaGJIVmxPeUF2THlCemFHOXlkR1Z1SUdOb1lXbHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzVsWVhKbGNsWmhiSFZsTzF4dUlDQWdJSDA3WEc1Y2JpQWdJQ0J3Y205dGFYTmxMbWx1YzNCbFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2doY21WemIyeDJaV1JRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2V5QnpkR0YwWlRvZ1hDSndaVzVrYVc1blhDSWdmVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY21WemIyeDJaV1JRY205dGFYTmxMbWx1YzNCbFkzUW9LVHRjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0ZFdWJHOXVaMU4wWVdOclUzVndjRzl5ZENBbUppQm9ZWE5UZEdGamEzTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJRzVsZHlCRmNuSnZjaWdwTzF4dUlDQWdJQ0FnSUNCOUlHTmhkR05vSUNobEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5Qk9UMVJGT2lCa2IyNG5kQ0IwY25rZ2RHOGdkWE5sSUdCRmNuSnZjaTVqWVhCMGRYSmxVM1JoWTJ0VWNtRmpaV0FnYjNJZ2RISmhibk5tWlhJZ2RHaGxYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QmhZMk5sYzNOdmNpQmhjbTkxYm1RN0lIUm9ZWFFnWTJGMWMyVnpJRzFsYlc5eWVTQnNaV0ZyY3lCaGN5QndaWElnUjBndE1URXhMaUJLZFhOMFhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCeVpXbG1lU0IwYUdVZ2MzUmhZMnNnZEhKaFkyVWdZWE1nWVNCemRISnBibWNnUVZOQlVDNWNiaUFnSUNBZ0lDQWdJQ0FnSUM4dlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCQmRDQjBhR1VnYzJGdFpTQjBhVzFsTENCamRYUWdiMlptSUhSb1pTQm1hWEp6ZENCc2FXNWxPeUJwZENkeklHRnNkMkY1Y3lCcWRYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QmNJbHR2WW1wbFkzUWdVSEp2YldselpWMWNYRzVjSWl3Z1lYTWdjR1Z5SUhSb1pTQmdkRzlUZEhKcGJtZGdMbHh1SUNBZ0lDQWdJQ0FnSUNBZ2NISnZiV2x6WlM1emRHRmpheUE5SUdVdWMzUmhZMnN1YzNWaWMzUnlhVzVuS0dVdWMzUmhZMnN1YVc1a1pYaFBaaWhjSWx4Y2Jsd2lLU0FySURFcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVYRzRnSUNBZ0x5OGdUazlVUlRvZ2QyVWdaRzhnZEdobElHTm9aV05yY3lCbWIzSWdZSEpsYzI5c2RtVmtVSEp2YldselpXQWdhVzRnWldGamFDQnRaWFJvYjJRc0lHbHVjM1JsWVdRZ2IyWmNiaUFnSUNBdkx5QmpiMjV6YjJ4cFpHRjBhVzVuSUhSb1pXMGdhVzUwYnlCZ1ltVmpiMjFsWUN3Z2MybHVZMlVnYjNSb1pYSjNhWE5sSUhkbEoyUWdZM0psWVhSbElHNWxkMXh1SUNBZ0lDOHZJSEJ5YjIxcGMyVnpJSGRwZEdnZ2RHaGxJR3hwYm1WeklHQmlaV052YldVb2QyaGhkR1YyWlhJb2RtRnNkV1VwS1dBdUlGTmxaU0JsTG1jdUlFZElMVEkxTWk1Y2JseHVJQ0FnSUdaMWJtTjBhVzl1SUdKbFkyOXRaU2h1WlhkUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxjMjlzZG1Wa1VISnZiV2x6WlNBOUlHNWxkMUJ5YjIxcGMyVTdYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVjMjkxY21ObElEMGdibVYzVUhKdmJXbHpaVHRjYmx4dUlDQWdJQ0FnSUNCaGNuSmhlVjl5WldSMVkyVW9iV1Z6YzJGblpYTXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUcxbGMzTmhaMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNWxkMUJ5YjIxcGMyVXVjSEp2YldselpVUnBjM0JoZEdOb0xtRndjR3g1S0c1bGQxQnliMjFwYzJVc0lHMWxjM05oWjJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMHNJSFp2YVdRZ01DazdYRzVjYmlBZ0lDQWdJQ0FnYldWemMyRm5aWE1nUFNCMmIybGtJREE3WEc0Z0lDQWdJQ0FnSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSDFjYmx4dUlDQWdJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVWdQU0J3Y205dGFYTmxPMXh1SUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdhV1lnS0hKbGMyOXNkbVZrVUhKdmJXbHpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnWW1WamIyMWxLRkVvZG1Gc2RXVXBLVHRjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdaR1ZtWlhKeVpXUXVablZzWm1sc2JDQTlJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvWm5Wc1ptbHNiQ2gyWVd4MVpTa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tISmxZWE52YmlrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaV1JRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lIMWNibHh1SUNBZ0lDQWdJQ0JpWldOdmJXVW9jbVZxWldOMEtISmxZWE52YmlrcE8xeHVJQ0FnSUgwN1hHNGdJQ0FnWkdWbVpYSnlaV1F1Ym05MGFXWjVJRDBnWm5WdVkzUnBiMjRnS0hCeWIyZHlaWE56S1NCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2h5WlhOdmJIWmxaRkJ5YjIxcGMyVXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJR0Z5Y21GNVgzSmxaSFZqWlNod2NtOW5jbVZ6YzB4cGMzUmxibVZ5Y3l3Z1puVnVZM1JwYjI0Z0tIVnVaR1ZtYVc1bFpDd2djSEp2WjNKbGMzTk1hWE4wWlc1bGNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1VTNXVaWGgwVkdsamF5aG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY0hKdlozSmxjM05NYVhOMFpXNWxjaWh3Y205bmNtVnpjeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlN3Z2RtOXBaQ0F3S1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFTnlaV0YwWlhNZ1lTQk9iMlJsTFhOMGVXeGxJR05oYkd4aVlXTnJJSFJvWVhRZ2QybHNiQ0J5WlhOdmJIWmxJRzl5SUhKbGFtVmpkQ0IwYUdVZ1pHVm1aWEp5WldSY2JpQXFJSEJ5YjIxcGMyVXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElHNXZaR1ZpWVdOclhHNGdLaTljYm1SbFptVnlMbkJ5YjNSdmRIbHdaUzV0WVd0bFRtOWtaVkpsYzI5c2RtVnlJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUhaaGNpQnpaV3htSUQwZ2RHaHBjenRjYmlBZ0lDQnlaWFIxY200Z1puVnVZM1JwYjI0Z0tHVnljbTl5TENCMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGJHWXVjbVZxWldOMEtHVnljbTl5S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUdsbUlDaGhjbWQxYldWdWRITXViR1Z1WjNSb0lENGdNaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZzWmk1eVpYTnZiSFpsS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNU2twTzF4dUlDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZzWmk1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRUJ3WVhKaGJTQnlaWE52YkhabGNpQjdSblZ1WTNScGIyNTlJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQnlaWFIxY201eklHNXZkR2hwYm1jZ1lXNWtJR0ZqWTJWd2RITmNiaUFxSUhSb1pTQnlaWE52YkhabExDQnlaV3BsWTNRc0lHRnVaQ0J1YjNScFpua2dablZ1WTNScGIyNXpJR1p2Y2lCaElHUmxabVZ5Y21Wa0xseHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUhSb1lYUWdiV0Y1SUdKbElISmxjMjlzZG1Wa0lIZHBkR2dnZEdobElHZHBkbVZ1SUhKbGMyOXNkbVVnWVc1a0lISmxhbVZqZEZ4dUlDb2dablZ1WTNScGIyNXpMQ0J2Y2lCeVpXcGxZM1JsWkNCaWVTQmhJSFJvY205M2JpQmxlR05sY0hScGIyNGdhVzRnY21WemIyeDJaWEpjYmlBcUwxeHVVUzVRY205dGFYTmxJRDBnY0hKdmJXbHpaVHNnTHk4Z1JWTTJYRzVSTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dVpuVnVZM1JwYjI0Z2NISnZiV2x6WlNoeVpYTnZiSFpsY2lrZ2UxeHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnpiMngyWlhJZ0lUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLRndpY21WemIyeDJaWElnYlhWemRDQmlaU0JoSUdaMWJtTjBhVzl1TGx3aUtUdGNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0J5WlhOdmJIWmxjaWhrWldabGNuSmxaQzV5WlhOdmJIWmxMQ0JrWldabGNuSmxaQzV5WldwbFkzUXNJR1JsWm1WeWNtVmtMbTV2ZEdsbWVTazdYRzRnSUNBZ2ZTQmpZWFJqYUNBb2NtVmhjMjl1S1NCN1hHNGdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxhbVZqZENoeVpXRnpiMjRwTzF4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMWNibHh1Y0hKdmJXbHpaUzV5WVdObElEMGdjbUZqWlRzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG1Gc2JDQTlJR0ZzYkRzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGFtVmpkQ0E5SUhKbGFtVmpkRHNnTHk4Z1JWTTJYRzV3Y205dGFYTmxMbkpsYzI5c2RtVWdQU0JST3lBdkx5QkZVelpjYmx4dUx5OGdXRmhZSUdWNGNHVnlhVzFsYm5SaGJDNGdJRlJvYVhNZ2JXVjBhRzlrSUdseklHRWdkMkY1SUhSdklHUmxibTkwWlNCMGFHRjBJR0VnYkc5allXd2dkbUZzZFdVZ2FYTmNiaTh2SUhObGNtbGhiR2w2WVdKc1pTQmhibVFnYzJodmRXeGtJR0psSUdsdGJXVmthV0YwWld4NUlHUnBjM0JoZEdOb1pXUWdkRzhnWVNCeVpXMXZkR1VnZFhCdmJpQnlaWEYxWlhOMExGeHVMeThnYVc1emRHVmhaQ0J2WmlCd1lYTnphVzVuSUdFZ2NtVm1aWEpsYm1ObExseHVVUzV3WVhOelFubERiM0I1SUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZENrZ2UxeHVJQ0FnSUM4dlpuSmxaWHBsS0c5aWFtVmpkQ2s3WEc0Z0lDQWdMeTl3WVhOelFubERiM0JwWlhNdWMyVjBLRzlpYW1WamRDd2dkSEoxWlNrN1hHNGdJQ0FnY21WMGRYSnVJRzlpYW1WamREdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExuQmhjM05DZVVOdmNIa2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk5bWNtVmxlbVVvYjJKcVpXTjBLVHRjYmlBZ0lDQXZMM0JoYzNOQ2VVTnZjR2xsY3k1elpYUW9iMkpxWldOMExDQjBjblZsS1R0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3p0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ2RIZHZJSEJ5YjIxcGMyVnpJR1YyWlc1MGRXRnNiSGtnWm5Wc1ptbHNiQ0IwYnlCMGFHVWdjMkZ0WlNCMllXeDFaU3dnY0hKdmJXbHpaWE1nZEdoaGRDQjJZV3gxWlN4Y2JpQXFJR0oxZENCdmRHaGxjbmRwYzJVZ2NtVnFaV04wY3k1Y2JpQXFJRUJ3WVhKaGJTQjRJSHRCYm5rcWZWeHVJQ29nUUhCaGNtRnRJSGtnZTBGdWVTcDlYRzRnS2lCQWNtVjBkWEp1Y3lCN1FXNTVLbjBnWVNCd2NtOXRhWE5sSUdadmNpQjRJR0Z1WkNCNUlHbG1JSFJvWlhrZ1lYSmxJSFJvWlNCellXMWxMQ0JpZFhRZ1lTQnlaV3BsWTNScGIyNWNiaUFxSUc5MGFHVnlkMmx6WlM1Y2JpQXFYRzRnS2k5Y2JsRXVhbTlwYmlBOUlHWjFibU4wYVc5dUlDaDRMQ0I1S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvZUNrdWFtOXBiaWg1S1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1wdmFXNGdQU0JtZFc1amRHbHZiaUFvZEdoaGRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktGdDBhR2x6TENCMGFHRjBYU2t1YzNCeVpXRmtLR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoNElEMDlQU0I1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCVVQwUlBPaUJjSWowOVBWd2lJSE5vYjNWc1pDQmlaU0JQWW1wbFkzUXVhWE1nYjNJZ1pYRjFhWFpjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCNE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnZEdoeWIzY2dibVYzSUVWeWNtOXlLRndpUTJGdUozUWdhbTlwYmpvZ2JtOTBJSFJvWlNCellXMWxPaUJjSWlBcklIZ2dLeUJjSWlCY0lpQXJJSGtwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnWm1seWMzUWdiMllnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2RHOGdZbVZqYjIxbElITmxkSFJzWldRdVhHNGdLaUJBY0dGeVlXMGdZVzV6ZDJWeWN5QjdRWEp5WVhsYlFXNTVLbDE5SUhCeWIyMXBjMlZ6SUhSdklISmhZMlZjYmlBcUlFQnlaWFIxY201eklIdEJibmtxZlNCMGFHVWdabWx5YzNRZ2NISnZiV2x6WlNCMGJ5QmlaU0J6WlhSMGJHVmtYRzRnS2k5Y2JsRXVjbUZqWlNBOUlISmhZMlU3WEc1bWRXNWpkR2x2YmlCeVlXTmxLR0Z1YzNkbGNsQnpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVb1puVnVZM1JwYjI0Z0tISmxjMjlzZG1Vc0lISmxhbVZqZENrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJUZDJsMFkyZ2dkRzhnZEdocGN5QnZibU5sSUhkbElHTmhiaUJoYzNOMWJXVWdZWFFnYkdWaGMzUWdSVk0xWEc0Z0lDQWdJQ0FnSUM4dklHRnVjM2RsY2xCekxtWnZja1ZoWTJnb1puVnVZM1JwYjI0Z0tHRnVjM2RsY2xBcElIdGNiaUFnSUNBZ0lDQWdMeThnSUNBZ0lGRW9ZVzV6ZDJWeVVDa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNBdkx5QjlLVHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZYTmxJSFJvYVhNZ2FXNGdkR2hsSUcxbFlXNTBhVzFsWEc0Z0lDQWdJQ0FnSUdadmNpQW9kbUZ5SUdrZ1BTQXdMQ0JzWlc0Z1BTQmhibk4zWlhKUWN5NXNaVzVuZEdnN0lHa2dQQ0JzWlc0N0lHa3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVU2hoYm5OM1pYSlFjMXRwWFNrdWRHaGxiaWh5WlhOdmJIWmxMQ0J5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmU2s3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkpoWTJVZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaFJMbkpoWTJVcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRGIyNXpkSEoxWTNSeklHRWdVSEp2YldselpTQjNhWFJvSUdFZ2NISnZiV2x6WlNCa1pYTmpjbWx3ZEc5eUlHOWlhbVZqZENCaGJtUWdiM0IwYVc5dVlXd2dabUZzYkdKaFkydGNiaUFxSUdaMWJtTjBhVzl1TGlBZ1ZHaGxJR1JsYzJOeWFYQjBiM0lnWTI5dWRHRnBibk1nYldWMGFHOWtjeUJzYVd0bElIZG9aVzRvY21WcVpXTjBaV1FwTENCblpYUW9ibUZ0WlNrc1hHNGdLaUJ6WlhRb2JtRnRaU3dnZG1Gc2RXVXBMQ0J3YjNOMEtHNWhiV1VzSUdGeVozTXBMQ0JoYm1RZ1pHVnNaWFJsS0c1aGJXVXBMQ0IzYUdsamFDQmhiR3hjYmlBcUlISmxkSFZ5YmlCbGFYUm9aWElnWVNCMllXeDFaU3dnWVNCd2NtOXRhWE5sSUdadmNpQmhJSFpoYkhWbExDQnZjaUJoSUhKbGFtVmpkR2x2Ymk0Z0lGUm9aU0JtWVd4c1ltRmphMXh1SUNvZ1lXTmpaWEIwY3lCMGFHVWdiM0JsY21GMGFXOXVJRzVoYldVc0lHRWdjbVZ6YjJ4MlpYSXNJR0Z1WkNCaGJua2dablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkR2hoZENCM2IzVnNaRnh1SUNvZ2FHRjJaU0JpWldWdUlHWnZjbmRoY21SbFpDQjBieUIwYUdVZ1lYQndjbTl3Y21saGRHVWdiV1YwYUc5a0lHRmliM1psSUdoaFpDQmhJRzFsZEdodlpDQmlaV1Z1WEc0Z0tpQndjbTkyYVdSbFpDQjNhWFJvSUhSb1pTQndjbTl3WlhJZ2JtRnRaUzRnSUZSb1pTQkJVRWtnYldGclpYTWdibThnWjNWaGNtRnVkR1ZsY3lCaFltOTFkQ0IwYUdVZ2JtRjBkWEpsWEc0Z0tpQnZaaUIwYUdVZ2NtVjBkWEp1WldRZ2IySnFaV04wTENCaGNHRnlkQ0JtY205dElIUm9ZWFFnYVhRZ2FYTWdkWE5oWW14bElIZG9aWEpsWlhabGNpQndjbTl0YVhObGN5QmhjbVZjYmlBcUlHSnZkV2RvZENCaGJtUWdjMjlzWkM1Y2JpQXFMMXh1VVM1dFlXdGxVSEp2YldselpTQTlJRkJ5YjIxcGMyVTdYRzVtZFc1amRHbHZiaUJRY205dGFYTmxLR1JsYzJOeWFYQjBiM0lzSUdaaGJHeGlZV05yTENCcGJuTndaV04wS1NCN1hHNGdJQ0FnYVdZZ0tHWmhiR3hpWVdOcklEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnWm1Gc2JHSmhZMnNnUFNCbWRXNWpkR2x2YmlBb2IzQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvYm1WM0lFVnljbTl5S0Z4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aVVISnZiV2x6WlNCa2IyVnpJRzV2ZENCemRYQndiM0owSUc5d1pYSmhkR2x2YmpvZ1hDSWdLeUJ2Y0Z4dUlDQWdJQ0FnSUNBZ0lDQWdLU2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnZlZ4dUlDQWdJR2xtSUNocGJuTndaV04wSUQwOVBTQjJiMmxrSURBcElIdGNiaUFnSUNBZ0lDQWdhVzV6Y0dWamRDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjdjM1JoZEdVNklGd2lkVzVyYm05M2Jsd2lmVHRjYmlBZ0lDQWdJQ0FnZlR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHOWlhbVZqZEY5amNtVmhkR1VvVUhKdmJXbHpaUzV3Y205MGIzUjVjR1VwTzF4dVhHNGdJQ0FnY0hKdmJXbHpaUzV3Y205dGFYTmxSR2x6Y0dGMFkyZ2dQU0JtZFc1amRHbHZiaUFvY21WemIyeDJaU3dnYjNBc0lHRnlaM01wSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJSEpsYzNWc2REdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoa1pYTmpjbWx3ZEc5eVcyOXdYU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGMzVnNkQ0E5SUdSbGMyTnlhWEIwYjNKYmIzQmRMbUZ3Y0d4NUtIQnliMjFwYzJVc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm1ZV3hzWW1GamF5NWpZV3hzS0hCeWIyMXBjMlVzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0J5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnpiMngyWlNoeVpYTjFiSFFwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlR0Y2JseHVJQ0FnSUhCeWIyMXBjMlV1YVc1emNHVmpkQ0E5SUdsdWMzQmxZM1E3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaQ0JnZG1Gc2RXVlBabUFnWVc1a0lHQmxlR05sY0hScGIyNWdJSE4xY0hCdmNuUmNiaUFnSUNCcFppQW9hVzV6Y0dWamRDa2dlMXh1SUNBZ0lDQWdJQ0IyWVhJZ2FXNXpjR1ZqZEdWa0lEMGdhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0JwWmlBb2FXNXpjR1ZqZEdWa0xuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVaWGhqWlhCMGFXOXVJRDBnYVc1emNHVmpkR1ZrTG5KbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhjaUJwYm5Od1pXTjBaV1FnUFNCcGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FXNXpjR1ZqZEdWa0xuTjBZWFJsSUQwOVBTQmNJbkJsYm1ScGJtZGNJaUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsdWMzQmxZM1JsWkM1emRHRjBaU0E5UFQwZ1hDSnlaV3BsWTNSbFpGd2lLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVTdYRzRnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdhVzV6Y0dWamRHVmtMblpoYkhWbE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNibHh1SUNBZ0lISmxkSFZ5YmlCd2NtOXRhWE5sTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYjFOMGNtbHVaeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnWENKYmIySnFaV04wSUZCeWIyMXBjMlZkWENJN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVJRDBnWm5WdVkzUnBiMjRnS0daMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQjJZWElnYzJWc1ppQTlJSFJvYVhNN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdaRzl1WlNBOUlHWmhiSE5sT3lBZ0lDOHZJR1Z1YzNWeVpTQjBhR1VnZFc1MGNuVnpkR1ZrSUhCeWIyMXBjMlVnYldGclpYTWdZWFFnYlc5emRDQmhYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6YVc1bmJHVWdZMkZzYkNCMGJ5QnZibVVnYjJZZ2RHaGxJR05oYkd4aVlXTnJjMXh1WEc0Z0lDQWdablZ1WTNScGIyNGdYMloxYkdacGJHeGxaQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFI1Y0dWdlppQm1kV3htYVd4c1pXUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpQS9JR1oxYkdacGJHeGxaQ2gyWVd4MVpTa2dPaUIyWVd4MVpUdGNiaUFnSUNBZ0lDQWdmU0JqWVhSamFDQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnFaV04wS0dWNFkyVndkR2x2YmlrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOVhHNWNiaUFnSUNCbWRXNWpkR2x2YmlCZmNtVnFaV04wWldRb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnY21WcVpXTjBaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Y0WTJWd2RHbHZiaXdnYzJWc1ppazdYRzRnSUNBZ0lDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNSbFpDaGxlR05sY0hScGIyNHBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb2JtVjNSWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRDaHVaWGRGZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkSGx3Wlc5bUlIQnliMmR5WlhOelpXUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpQS9JSEJ5YjJkeVpYTnpaV1FvZG1Gc2RXVXBJRG9nZG1Gc2RXVTdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ1VTNXVaWGgwVkdsamF5aG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZibVVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyNWxJRDBnZEhKMVpUdGNibHh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnpiMngyWlNoZlpuVnNabWxzYkdWa0tIWmhiSFZsS1NrN1hHNGdJQ0FnSUNBZ0lIMHNJRndpZDJobGJsd2lMQ0JiWm5WdVkzUnBiMjRnS0dWNFkyVndkR2x2YmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZibVVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyNWxJRDBnZEhKMVpUdGNibHh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnpiMngyWlNoZmNtVnFaV04wWldRb1pYaGpaWEIwYVc5dUtTazdYRzRnSUNBZ0lDQWdJSDFkS1R0Y2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUM4dklGQnliMmR5WlhOeklIQnliM0JoWjJGMGIzSWdibVZsWkNCMGJ5QmlaU0JoZEhSaFkyaGxaQ0JwYmlCMGFHVWdZM1Z5Y21WdWRDQjBhV05yTGx4dUlDQWdJSE5sYkdZdWNISnZiV2x6WlVScGMzQmhkR05vS0hadmFXUWdNQ3dnWENKM2FHVnVYQ0lzSUZ0MmIybGtJREFzSUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzVm1Gc2RXVTdYRzRnSUNBZ0lDQWdJSFpoY2lCMGFISmxkeUE5SUdaaGJITmxPMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYm1WM1ZtRnNkV1VnUFNCZmNISnZaM0psYzNObFpDaDJZV3gxWlNrN1hHNGdJQ0FnSUNBZ0lIMGdZMkYwWTJnZ0tHVXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbVYzSUQwZ2RISjFaVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hSTG05dVpYSnliM0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCUkxtOXVaWEp5YjNJb1pTazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJR1U3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCcFppQW9JWFJvY21WM0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1dWIzUnBabmtvYm1WM1ZtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlYwcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzVSTG5SaGNDQTlJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxMQ0JqWVd4c1ltRmpheWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVXBMblJoY0NoallXeHNZbUZqYXlrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZkdmNtdHpJR0ZzYlc5emRDQnNhV3RsSUZ3aVptbHVZV3hzZVZ3aUxDQmlkWFFnYm05MElHTmhiR3hsWkNCbWIzSWdjbVZxWldOMGFXOXVjeTVjYmlBcUlFOXlhV2RwYm1Gc0lISmxjMjlzZFhScGIyNGdkbUZzZFdVZ2FYTWdjR0Z6YzJWa0lIUm9jbTkxWjJnZ1kyRnNiR0poWTJzZ2RXNWhabVpsWTNSbFpDNWNiaUFxSUVOaGJHeGlZV05ySUcxaGVTQnlaWFIxY200Z1lTQndjbTl0YVhObElIUm9ZWFFnZDJsc2JDQmlaU0JoZDJGcGRHVmtJR1p2Y2k1Y2JpQXFJRUJ3WVhKaGJTQjdSblZ1WTNScGIyNTlJR05oYkd4aVlXTnJYRzRnS2lCQWNtVjBkWEp1Y3lCN1VTNVFjbTl0YVhObGZWeHVJQ29nUUdWNFlXMXdiR1ZjYmlBcUlHUnZVMjl0WlhSb2FXNW5LQ2xjYmlBcUlDQWdMblJvWlc0b0xpNHVLVnh1SUNvZ0lDQXVkR0Z3S0dOdmJuTnZiR1V1Ykc5bktWeHVJQ29nSUNBdWRHaGxiaWd1TGk0cE8xeHVJQ292WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MFlYQWdQU0JtZFc1amRHbHZiaUFvWTJGc2JHSmhZMnNwSUh0Y2JpQWdJQ0JqWVd4c1ltRmpheUE5SUZFb1kyRnNiR0poWTJzcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1aallXeHNLSFpoYkhWbEtTNTBhR1Z1VW1WemIyeDJaU2gyWVd4MVpTazdYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxaMmx6ZEdWeWN5QmhiaUJ2WW5ObGNuWmxjaUJ2YmlCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ1IzVmhjbUZ1ZEdWbGN6cGNiaUFxWEc0Z0tpQXhMaUIwYUdGMElHWjFiR1pwYkd4bFpDQmhibVFnY21WcVpXTjBaV1FnZDJsc2JDQmlaU0JqWVd4c1pXUWdiMjVzZVNCdmJtTmxMbHh1SUNvZ01pNGdkR2hoZENCbGFYUm9aWElnZEdobElHWjFiR1pwYkd4bFpDQmpZV3hzWW1GamF5QnZjaUIwYUdVZ2NtVnFaV04wWldRZ1kyRnNiR0poWTJzZ2QybHNiQ0JpWlZ4dUlDb2dJQ0FnWTJGc2JHVmtMQ0JpZFhRZ2JtOTBJR0p2ZEdndVhHNGdLaUF6TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0J1YjNRZ1ltVWdZMkZzYkdWa0lHbHVJSFJvYVhNZ2RIVnliaTVjYmlBcVhHNGdLaUJBY0dGeVlXMGdkbUZzZFdVZ0lDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ2RHOGdiMkp6WlhKMlpWeHVJQ29nUUhCaGNtRnRJR1oxYkdacGJHeGxaQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElHWjFiR1pwYkd4bFpDQjJZV3gxWlZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lDQWdablZ1WTNScGIyNGdkRzhnWW1VZ1kyRnNiR1ZrSUhkcGRHZ2dkR2hsSUhKbGFtVmpkR2x2YmlCbGVHTmxjSFJwYjI1Y2JpQXFJRUJ3WVhKaGJTQndjbTluY21WemMyVmtJR1oxYm1OMGFXOXVJSFJ2SUdKbElHTmhiR3hsWkNCdmJpQmhibmtnY0hKdlozSmxjM01nYm05MGFXWnBZMkYwYVc5dWMxeHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUdaeWIyMGdkR2hsSUdsdWRtOXJaV1FnWTJGc2JHSmhZMnRjYmlBcUwxeHVVUzUzYUdWdUlEMGdkMmhsYmp0Y2JtWjFibU4wYVc5dUlIZG9aVzRvZG1Gc2RXVXNJR1oxYkdacGJHeGxaQ3dnY21WcVpXTjBaV1FzSUhCeWIyZHlaWE56WldRcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNoMllXeDFaU2t1ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjMlZrS1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTBhR1Z1S0daMWJtTjBhVzl1SUNncElIc2djbVYwZFhKdUlIWmhiSFZsT3lCOUtUdGNibjA3WEc1Y2JsRXVkR2hsYmxKbGMyOXNkbVVnUFNCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h3Y205dGFYTmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxuUm9aVzRvWm5WdVkzUnBiMjRnS0NrZ2V5QjBhSEp2ZHlCeVpXRnpiMjQ3SUgwcE8xeHVmVHRjYmx4dVVTNTBhR1Z1VW1WcVpXTjBJRDBnWm5WdVkzUnBiMjRnS0hCeWIyMXBjMlVzSUhKbFlYTnZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVXBMblJvWlc1U1pXcGxZM1FvY21WaGMyOXVLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dTV1lnWVc0Z2IySnFaV04wSUdseklHNXZkQ0JoSUhCeWIyMXBjMlVzSUdsMElHbHpJR0Z6SUZ3aWJtVmhjbHdpSUdGeklIQnZjM05wWW14bExseHVJQ29nU1dZZ1lTQndjbTl0YVhObElHbHpJSEpsYW1WamRHVmtMQ0JwZENCcGN5QmhjeUJjSW01bFlYSmNJaUJoY3lCd2IzTnphV0pzWlNCMGIyOHVYRzRnS2lCSlppQnBkT0tBbVhNZ1lTQm1kV3htYVd4c1pXUWdjSEp2YldselpTd2dkR2hsSUdaMWJHWnBiR3h0Wlc1MElIWmhiSFZsSUdseklHNWxZWEpsY2k1Y2JpQXFJRWxtSUdsMDRvQ1pjeUJoSUdSbFptVnljbVZrSUhCeWIyMXBjMlVnWVc1a0lIUm9aU0JrWldabGNuSmxaQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQ3dnZEdobFhHNGdLaUJ5WlhOdmJIVjBhVzl1SUdseklGd2libVZoY21WeVhDSXVYRzRnS2lCQWNHRnlZVzBnYjJKcVpXTjBYRzRnS2lCQWNtVjBkWEp1Y3lCdGIzTjBJSEpsYzI5c2RtVmtJQ2h1WldGeVpYTjBLU0JtYjNKdElHOW1JSFJvWlNCdlltcGxZM1JjYmlBcUwxeHVYRzR2THlCWVdGZ2djMmh2ZFd4a0lIZGxJSEpsTFdSdklIUm9hWE0vWEc1UkxtNWxZWEpsY2lBOUlHNWxZWEpsY2p0Y2JtWjFibU4wYVc5dUlHNWxZWEpsY2loMllXeDFaU2tnZTF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJVb2RtRnNkV1VwS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJwYm5Od1pXTjBaV1FnUFNCMllXeDFaUzVwYm5Od1pXTjBLQ2s3WEc0Z0lDQWdJQ0FnSUdsbUlDaHBibk53WldOMFpXUXVjM1JoZEdVZ1BUMDlJRndpWm5Wc1ptbHNiR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJwYm5Od1pXTjBaV1F1ZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCUGRHaGxjbmRwYzJVZ2FYUWdhWE1nWVNCbWRXeG1hV3hzWldRZ2RtRnNkV1V1WEc0Z0tpOWNibEV1YVhOUWNtOXRhWE5sSUQwZ2FYTlFjbTl0YVhObE8xeHVablZ1WTNScGIyNGdhWE5RY205dGFYTmxLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCdlltcGxZM1FnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sTzF4dWZWeHVYRzVSTG1selVISnZiV2x6WlVGc2FXdGxJRDBnYVhOUWNtOXRhWE5sUVd4cGEyVTdYRzVtZFc1amRHbHZiaUJwYzFCeWIyMXBjMlZCYkdsclpTaHZZbXBsWTNRcElIdGNiaUFnSUNCeVpYUjFjbTRnYVhOUFltcGxZM1FvYjJKcVpXTjBLU0FtSmlCMGVYQmxiMllnYjJKcVpXTjBMblJvWlc0Z1BUMDlJRndpWm5WdVkzUnBiMjVjSWp0Y2JuMWNibHh1THlvcVhHNGdLaUJBY21WMGRYSnVjeUIzYUdWMGFHVnlJSFJvWlNCbmFYWmxiaUJ2WW1wbFkzUWdhWE1nWVNCd1pXNWthVzVuSUhCeWIyMXBjMlVzSUcxbFlXNXBibWNnYm05MFhHNGdLaUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdVhHNGdLaTljYmxFdWFYTlFaVzVrYVc1bklEMGdhWE5RWlc1a2FXNW5PMXh1Wm5WdVkzUnBiMjRnYVhOUVpXNWthVzVuS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnBjMUJ5YjIxcGMyVW9iMkpxWldOMEtTQW1KaUJ2WW1wbFkzUXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWp0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YVhOUVpXNWthVzVuSUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbWx1YzNCbFkzUW9LUzV6ZEdGMFpTQTlQVDBnWENKd1pXNWthVzVuWENJN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCeVpYUjFjbTV6SUhkb1pYUm9aWElnZEdobElHZHBkbVZ1SUc5aWFtVmpkQ0JwY3lCaElIWmhiSFZsSUc5eUlHWjFiR1pwYkd4bFpGeHVJQ29nY0hKdmJXbHpaUzVjYmlBcUwxeHVVUzVwYzBaMWJHWnBiR3hsWkNBOUlHbHpSblZzWm1sc2JHVmtPMXh1Wm5WdVkzUnBiMjRnYVhOR2RXeG1hV3hzWldRb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJQ0ZwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0I4ZkNCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0ltWjFiR1pwYkd4bFpGd2lPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXBjMFoxYkdacGJHeGxaQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NXBibk53WldOMEtDa3VjM1JoZEdVZ1BUMDlJRndpWm5Wc1ptbHNiR1ZrWENJN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCeVpYUjFjbTV6SUhkb1pYUm9aWElnZEdobElHZHBkbVZ1SUc5aWFtVmpkQ0JwY3lCaElISmxhbVZqZEdWa0lIQnliMjFwYzJVdVhHNGdLaTljYmxFdWFYTlNaV3BsWTNSbFpDQTlJR2x6VW1WcVpXTjBaV1E3WEc1bWRXNWpkR2x2YmlCcGMxSmxhbVZqZEdWa0tHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luSmxhbVZqZEdWa1hDSTdYRzU5WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtbHpVbVZxWldOMFpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OU8xeHVYRzR2THk4dklFSkZSMGxPSUZWT1NFRk9SRXhGUkNCU1JVcEZRMVJKVDA0Z1ZGSkJRMHRKVGtkY2JseHVMeThnVkdocGN5QndjbTl0YVhObElHeHBZbkpoY25rZ1kyOXVjM1Z0WlhNZ1pYaGpaWEIwYVc5dWN5QjBhSEp2ZDI0Z2FXNGdhR0Z1Wkd4bGNuTWdjMjhnZEdobGVTQmpZVzRnWW1WY2JpOHZJR2hoYm1Sc1pXUWdZbmtnWVNCemRXSnpaWEYxWlc1MElIQnliMjFwYzJVdUlDQlVhR1VnWlhoalpYQjBhVzl1Y3lCblpYUWdZV1JrWldRZ2RHOGdkR2hwY3lCaGNuSmhlU0IzYUdWdVhHNHZMeUIwYUdWNUlHRnlaU0JqY21WaGRHVmtMQ0JoYm1RZ2NtVnRiM1psWkNCM2FHVnVJSFJvWlhrZ1lYSmxJR2hoYm1Sc1pXUXVJQ0JPYjNSbElIUm9ZWFFnYVc0Z1JWTTJJRzl5WEc0dkx5QnphR2x0YldWa0lHVnVkbWx5YjI1dFpXNTBjeXdnZEdocGN5QjNiM1ZzWkNCdVlYUjFjbUZzYkhrZ1ltVWdZU0JnVTJWMFlDNWNiblpoY2lCMWJtaGhibVJzWldSU1pXRnpiMjV6SUQwZ1cxMDdYRzUyWVhJZ2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJRnRkTzF4dWRtRnlJSEpsY0c5eWRHVmtWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhSeVlXTnJWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUhSeWRXVTdYRzVjYm1aMWJtTjBhVzl1SUhKbGMyVjBWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeWdwSUh0Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldGemIyNXpMbXhsYm1kMGFDQTlJREE3WEc0Z0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTVzWlc1bmRHZ2dQU0F3TzF4dVhHNGdJQ0FnYVdZZ0tDRjBjbUZqYTFWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5NcElIdGNiaUFnSUNBZ0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdkSEoxWlR0Y2JpQWdJQ0I5WEc1OVhHNWNibVoxYm1OMGFXOXVJSFJ5WVdOclVtVnFaV04wYVc5dUtIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUdsbUlDZ2hkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1ektTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCd2NtOWpaWE56SUQwOVBTQmNJbTlpYW1WamRGd2lJQ1ltSUhSNWNHVnZaaUJ3Y205alpYTnpMbVZ0YVhRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJMbkoxYmtGbWRHVnlLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoaGNuSmhlVjlwYm1SbGVFOW1LSFZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1zSUhCeWIyMXBjMlVwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhCeWIyTmxjM011WlcxcGRDaGNJblZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibHdpTENCeVpXRnpiMjRzSUhCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1d2RYTm9LSEJ5YjIxcGMyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjFibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpMbkIxYzJnb2NISnZiV2x6WlNrN1hHNGdJQ0FnYVdZZ0tISmxZWE52YmlBbUppQjBlWEJsYjJZZ2NtVmhjMjl1TG5OMFlXTnJJQ0U5UFNCY0luVnVaR1ZtYVc1bFpGd2lLU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaHlaV0Z6YjI0dWMzUmhZMnNwTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJSFZ1YUdGdVpHeGxaRkpsWVhOdmJuTXVjSFZ6YUNoY0lpaHVieUJ6ZEdGamF5a2dYQ0lnS3lCeVpXRnpiMjRwTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdkVzUwY21GamExSmxhbVZqZEdsdmJpaHdjbTl0YVhObEtTQjdYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJoZENBOUlHRnljbUY1WDJsdVpHVjRUMllvZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnYVdZZ0tHRjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhCeWIyTmxjM01nUFQwOUlGd2liMkpxWldOMFhDSWdKaVlnZEhsd1pXOW1JSEJ5YjJObGMzTXVaVzFwZENBOVBUMGdYQ0ptZFc1amRHbHZibHdpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjJZWElnWVhSU1pYQnZjblFnUFNCaGNuSmhlVjlwYm1SbGVFOW1LSEpsY0c5eWRHVmtWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeXdnY0hKdmJXbHpaU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHRjBVbVZ3YjNKMElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205alpYTnpMbVZ0YVhRb1hDSnlaV3BsWTNScGIyNUlZVzVrYkdWa1hDSXNJSFZ1YUdGdVpHeGxaRkpsWVhOdmJuTmJZWFJkTENCd2NtOXRhWE5sS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ3YjNKMFpXUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpMbk53YkdsalpTaGhkRkpsY0c5eWRDd2dNU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXpjR3hwWTJVb1lYUXNJREVwTzF4dUlDQWdJQ0FnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG5Od2JHbGpaU2hoZEN3Z01TazdYRzRnSUNBZ2ZWeHVmVnh1WEc1UkxuSmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3p0Y2JseHVVUzVuWlhSVmJtaGhibVJzWldSU1pXRnpiMjV6SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDOHZJRTFoYTJVZ1lTQmpiM0I1SUhOdklIUm9ZWFFnWTI5dWMzVnRaWEp6SUdOaGJpZDBJR2x1ZEdWeVptVnlaU0IzYVhSb0lHOTFjaUJwYm5SbGNtNWhiQ0J6ZEdGMFpTNWNiaUFnSUNCeVpYUjFjbTRnZFc1b1lXNWtiR1ZrVW1WaGMyOXVjeTV6YkdsalpTZ3BPMXh1ZlR0Y2JseHVVUzV6ZEc5d1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dVZISmhZMnRwYm1jZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVZ6WlhSVmJtaGhibVJzWldSU1pXcGxZM1JwYjI1ektDazdYRzRnSUNBZ2RISmhZMnRWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6SUQwZ1ptRnNjMlU3WEc1OU8xeHVYRzV5WlhObGRGVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTW9LVHRjYmx4dUx5OHZMeUJGVGtRZ1ZVNUlRVTVFVEVWRUlGSkZTa1ZEVkVsUFRpQlVVa0ZEUzBsT1IxeHVYRzR2S2lwY2JpQXFJRU52Ym5OMGNuVmpkSE1nWVNCeVpXcGxZM1JsWkNCd2NtOXRhWE5sTGx4dUlDb2dRSEJoY21GdElISmxZWE52YmlCMllXeDFaU0JrWlhOamNtbGlhVzVuSUhSb1pTQm1ZV2xzZFhKbFhHNGdLaTljYmxFdWNtVnFaV04wSUQwZ2NtVnFaV04wTzF4dVpuVnVZM1JwYjI0Z2NtVnFaV04wS0hKbFlYTnZiaWtnZTF4dUlDQWdJSFpoY2lCeVpXcGxZM1JwYjI0Z1BTQlFjbTl0YVhObEtIdGNiaUFnSUNBZ0lDQWdYQ0ozYUdWdVhDSTZJR1oxYm1OMGFXOXVJQ2h5WldwbFkzUmxaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnYm05MFpTQjBhR0YwSUhSb1pTQmxjbkp2Y2lCb1lYTWdZbVZsYmlCb1lXNWtiR1ZrWEc0Z0lDQWdJQ0FnSUNBZ0lDQnBaaUFvY21WcVpXTjBaV1FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMWJuUnlZV05yVW1WcVpXTjBhVzl1S0hSb2FYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRHVmtJRDhnY21WcVpXTjBaV1FvY21WaGMyOXVLU0E2SUhSb2FYTTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUJtWVd4c1ltRmpheWdwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUNBZ2ZTd2dablZ1WTNScGIyNGdhVzV6Y0dWamRDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSHNnYzNSaGRHVTZJRndpY21WcVpXTjBaV1JjSWl3Z2NtVmhjMjl1T2lCeVpXRnpiMjRnZlR0Y2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUM4dklFNXZkR1VnZEdoaGRDQjBhR1VnY21WaGMyOXVJR2hoY3lCdWIzUWdZbVZsYmlCb1lXNWtiR1ZrTGx4dUlDQWdJSFJ5WVdOclVtVnFaV04wYVc5dUtISmxhbVZqZEdsdmJpd2djbVZoYzI5dUtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1JwYjI0N1hHNTlYRzVjYmk4cUtseHVJQ29nUTI5dWMzUnlkV04wY3lCaElHWjFiR1pwYkd4bFpDQndjbTl0YVhObElHWnZjaUJoYmlCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObExseHVJQ29nUUhCaGNtRnRJSFpoYkhWbElHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVmNiaUFxTDF4dVVTNW1kV3htYVd4c0lEMGdablZzWm1sc2JEdGNibVoxYm1OMGFXOXVJR1oxYkdacGJHd29kbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVUhKdmJXbHpaU2g3WEc0Z0lDQWdJQ0FnSUZ3aWQyaGxibHdpT2lCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aVoyVjBYQ0k2SUdaMWJtTjBhVzl1SUNodVlXMWxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1ZiYm1GdFpWMDdYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aWMyVjBYQ0k2SUdaMWJtTjBhVzl1SUNodVlXMWxMQ0J5YUhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhaaGJIVmxXMjVoYldWZElEMGdjbWh6TzF4dUlDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQmNJbVJsYkdWMFpWd2lPaUJtZFc1amRHbHZiaUFvYm1GdFpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVnNaWFJsSUhaaGJIVmxXMjVoYldWZE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW5CdmMzUmNJam9nWm5WdVkzUnBiMjRnS0c1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklFMWhjbXNnVFdsc2JHVnlJSEJ5YjNCdmMyVnpJSFJvWVhRZ2NHOXpkQ0IzYVhSb0lHNXZJRzVoYldVZ2MyaHZkV3hrSUdGd2NHeDVJR0ZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMbHh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLRzVoYldVZ1BUMDlJRzUxYkd3Z2ZId2dibUZ0WlNBOVBUMGdkbTlwWkNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIWmhiSFZsTG1Gd2NHeDVLSFp2YVdRZ01Dd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjJZV3gxWlZ0dVlXMWxYUzVoY0hCc2VTaDJZV3gxWlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aVlYQndiSGxjSWpvZ1puVnVZM1JwYjI0Z0tIUm9hWE53TENCaGNtZHpLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1V1WVhCd2JIa29kR2hwYzNBc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQmNJbXRsZVhOY0lqb2dablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlHOWlhbVZqZEY5clpYbHpLSFpoYkhWbEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMHNJSFp2YVdRZ01Dd2dablZ1WTNScGIyNGdhVzV6Y0dWamRDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSHNnYzNSaGRHVTZJRndpWm5Wc1ptbHNiR1ZrWENJc0lIWmhiSFZsT2lCMllXeDFaU0I5TzF4dUlDQWdJSDBwTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU52Ym5abGNuUnpJSFJvWlc1aFlteGxjeUIwYnlCUklIQnliMjFwYzJWekxseHVJQ29nUUhCaGNtRnRJSEJ5YjIxcGMyVWdkR2hsYm1GaWJHVWdjSEp2YldselpWeHVJQ29nUUhKbGRIVnlibk1nWVNCUklIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnWTI5bGNtTmxLSEJ5YjIxcGMyVXBJSHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNTBhR1Z1S0dSbFptVnljbVZrTG5KbGMyOXNkbVVzSUdSbFptVnljbVZrTG5KbGFtVmpkQ3dnWkdWbVpYSnlaV1F1Ym05MGFXWjVLVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBwTzF4dUlDQWdJSEpsZEhWeWJpQmtaV1psY25KbFpDNXdjbTl0YVhObE8xeHVmVnh1WEc0dktpcGNiaUFxSUVGdWJtOTBZWFJsY3lCaGJpQnZZbXBsWTNRZ2MzVmphQ0IwYUdGMElHbDBJSGRwYkd3Z2JtVjJaWElnWW1WY2JpQXFJSFJ5WVc1elptVnljbVZrSUdGM1lYa2dabkp2YlNCMGFHbHpJSEJ5YjJObGMzTWdiM1psY2lCaGJua2djSEp2YldselpWeHVJQ29nWTI5dGJYVnVhV05oZEdsdmJpQmphR0Z1Ym1Wc0xseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRGeHVJQ29nUUhKbGRIVnlibk1nY0hKdmJXbHpaU0JoSUhkeVlYQndhVzVuSUc5bUlIUm9ZWFFnYjJKcVpXTjBJSFJvWVhSY2JpQXFJR0ZrWkdsMGFXOXVZV3hzZVNCeVpYTndiMjVrY3lCMGJ5QjBhR1VnWENKcGMwUmxabHdpSUcxbGMzTmhaMlZjYmlBcUlIZHBkR2h2ZFhRZ1lTQnlaV3BsWTNScGIyNHVYRzRnS2k5Y2JsRXViV0Z6ZEdWeUlEMGdiV0Z6ZEdWeU8xeHVablZ1WTNScGIyNGdiV0Z6ZEdWeUtHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKcGMwUmxabHdpT2lCbWRXNWpkR2x2YmlBb0tTQjdmVnh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJR1poYkd4aVlXTnJLRzl3TENCaGNtZHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJrYVhOd1lYUmphQ2h2WW1wbFkzUXNJRzl3TENCaGNtZHpLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWFXNXpjR1ZqZENncE8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUZOd2NtVmhaSE1nZEdobElIWmhiSFZsY3lCdlppQmhJSEJ5YjIxcGMyVmtJR0Z5Y21GNUlHOW1JR0Z5WjNWdFpXNTBjeUJwYm5SdklIUm9aVnh1SUNvZ1puVnNabWxzYkcxbGJuUWdZMkZzYkdKaFkyc3VYRzRnS2lCQWNHRnlZVzBnWm5Wc1ptbHNiR1ZrSUdOaGJHeGlZV05ySUhSb1lYUWdjbVZqWldsMlpYTWdkbUZ5YVdGa2FXTWdZWEpuZFcxbGJuUnpJR1p5YjIwZ2RHaGxYRzRnS2lCd2NtOXRhWE5sWkNCaGNuSmhlVnh1SUNvZ1FIQmhjbUZ0SUhKbGFtVmpkR1ZrSUdOaGJHeGlZV05ySUhSb1lYUWdjbVZqWldsMlpYTWdkR2hsSUdWNFkyVndkR2x2YmlCcFppQjBhR1VnY0hKdmJXbHpaVnh1SUNvZ2FYTWdjbVZxWldOMFpXUXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVWdiM0lnZEdoeWIzZHVJR1Y0WTJWd2RHbHZiaUJ2Wmx4dUlDb2daV2wwYUdWeUlHTmhiR3hpWVdOckxseHVJQ292WEc1UkxuTndjbVZoWkNBOUlITndjbVZoWkR0Y2JtWjFibU4wYVc5dUlITndjbVZoWkNoMllXeDFaU3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0haaGJIVmxLUzV6Y0hKbFlXUW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ2s3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbk53Y21WaFpDQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVlXeHNLQ2t1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZWEp5WVhrcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWjFiR1pwYkd4bFpDNWhjSEJzZVNoMmIybGtJREFzSUdGeWNtRjVLVHRjYmlBZ0lDQjlMQ0J5WldwbFkzUmxaQ2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRlJvWlNCaGMzbHVZeUJtZFc1amRHbHZiaUJwY3lCaElHUmxZMjl5WVhSdmNpQm1iM0lnWjJWdVpYSmhkRzl5SUdaMWJtTjBhVzl1Y3l3Z2RIVnlibWx1WjF4dUlDb2dkR2hsYlNCcGJuUnZJR0Z6ZVc1amFISnZibTkxY3lCblpXNWxjbUYwYjNKekxpQWdRV3gwYUc5MVoyZ2daMlZ1WlhKaGRHOXljeUJoY21VZ2IyNXNlU0J3WVhKMFhHNGdLaUJ2WmlCMGFHVWdibVYzWlhOMElFVkRUVUZUWTNKcGNIUWdOaUJrY21GbWRITXNJSFJvYVhNZ1kyOWtaU0JrYjJWeklHNXZkQ0JqWVhWelpTQnplVzUwWVhoY2JpQXFJR1Z5Y205eWN5QnBiaUJ2YkdSbGNpQmxibWRwYm1WekxpQWdWR2hwY3lCamIyUmxJSE5vYjNWc1pDQmpiMjUwYVc1MVpTQjBieUIzYjNKcklHRnVaQ0IzYVd4c1hHNGdLaUJwYmlCbVlXTjBJR2x0Y0hKdmRtVWdiM1psY2lCMGFXMWxJR0Z6SUhSb1pTQnNZVzVuZFdGblpTQnBiWEJ5YjNabGN5NWNiaUFxWEc0Z0tpQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdZM1Z5Y21WdWRHeDVJSEJoY25RZ2IyWWdWamdnZG1WeWMybHZiaUF6TGpFNUlIZHBkR2dnZEdobFhHNGdLaUF0TFdoaGNtMXZibmt0WjJWdVpYSmhkRzl5Y3lCeWRXNTBhVzFsSUdac1lXY2daVzVoWW14bFpDNGdJRk53YVdSbGNrMXZibXRsZVNCb1lYTWdhR0ZrSUhSb1pXMWNiaUFxSUdadmNpQnNiMjVuWlhJc0lHSjFkQ0IxYm1SbGNpQmhiaUJ2YkdSbGNpQlFlWFJvYjI0dGFXNXpjR2x5WldRZ1ptOXliUzRnSUZSb2FYTWdablZ1WTNScGIyNWNiaUFxSUhkdmNtdHpJRzl1SUdKdmRHZ2dhMmx1WkhNZ2IyWWdaMlZ1WlhKaGRHOXljeTVjYmlBcVhHNGdLaUJFWldOdmNtRjBaWE1nWVNCblpXNWxjbUYwYjNJZ1puVnVZM1JwYjI0Z2MzVmphQ0IwYUdGME9seHVJQ29nSUMwZ2FYUWdiV0Y1SUhscFpXeGtJSEJ5YjIxcGMyVnpYRzRnS2lBZ0xTQmxlR1ZqZFhScGIyNGdkMmxzYkNCamIyNTBhVzUxWlNCM2FHVnVJSFJvWVhRZ2NISnZiV2x6WlNCcGN5Qm1kV3htYVd4c1pXUmNiaUFxSUNBdElIUm9aU0IyWVd4MVpTQnZaaUIwYUdVZ2VXbGxiR1FnWlhod2NtVnpjMmx2YmlCM2FXeHNJR0psSUhSb1pTQm1kV3htYVd4c1pXUWdkbUZzZFdWY2JpQXFJQ0F0SUdsMElISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJQ2gzYUdWdUlIUm9aU0JuWlc1bGNtRjBiM0pjYmlBcUlDQWdJSE4wYjNCeklHbDBaWEpoZEdsdVp5bGNiaUFxSUNBdElIUm9aU0JrWldOdmNtRjBaV1FnWm5WdVkzUnBiMjRnY21WMGRYSnVjeUJoSUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFJQ0FnSUc5bUlIUm9aU0JuWlc1bGNtRjBiM0lnYjNJZ2RHaGxJR1pwY25OMElISmxhbVZqZEdWa0lIQnliMjFwYzJVZ1lXMXZibWNnZEdodmMyVmNiaUFxSUNBZ0lIbHBaV3hrWldRdVhHNGdLaUFnTFNCcFppQmhiaUJsY25KdmNpQnBjeUIwYUhKdmQyNGdhVzRnZEdobElHZGxibVZ5WVhSdmNpd2dhWFFnY0hKdmNHRm5ZWFJsY3lCMGFISnZkV2RvWEc0Z0tpQWdJQ0JsZG1WeWVTQm1iMnhzYjNkcGJtY2dlV2xsYkdRZ2RXNTBhV3dnYVhRZ2FYTWdZMkYxWjJoMExDQnZjaUIxYm5ScGJDQnBkQ0JsYzJOaGNHVnpYRzRnS2lBZ0lDQjBhR1VnWjJWdVpYSmhkRzl5SUdaMWJtTjBhVzl1SUdGc2RHOW5aWFJvWlhJc0lHRnVaQ0JwY3lCMGNtRnVjMnhoZEdWa0lHbHVkRzhnWVZ4dUlDb2dJQ0FnY21WcVpXTjBhVzl1SUdadmNpQjBhR1VnY0hKdmJXbHpaU0J5WlhSMWNtNWxaQ0JpZVNCMGFHVWdaR1ZqYjNKaGRHVmtJR2RsYm1WeVlYUnZjaTVjYmlBcUwxeHVVUzVoYzNsdVl5QTlJR0Z6ZVc1ak8xeHVablZ1WTNScGIyNGdZWE41Ym1Nb2JXRnJaVWRsYm1WeVlYUnZjaWtnZTF4dUlDQWdJSEpsZEhWeWJpQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUM4dklIZG9aVzRnZG1WeVlpQnBjeUJjSW5ObGJtUmNJaXdnWVhKbklHbHpJR0VnZG1Gc2RXVmNiaUFnSUNBZ0lDQWdMeThnZDJobGJpQjJaWEppSUdseklGd2lkR2h5YjNkY0lpd2dZWEpuSUdseklHRnVJR1Y0WTJWd2RHbHZibHh1SUNBZ0lDQWdJQ0JtZFc1amRHbHZiaUJqYjI1MGFXNTFaWElvZG1WeVlpd2dZWEpuS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ2NtVnpkV3gwTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCVmJuUnBiQ0JXT0NBekxqRTVJQzhnUTJoeWIyMXBkVzBnTWprZ2FYTWdjbVZzWldGelpXUXNJRk53YVdSbGNrMXZibXRsZVNCcGN5QjBhR1VnYjI1c2VWeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1pXNW5hVzVsSUhSb1lYUWdhR0Z6SUdFZ1pHVndiRzk1WldRZ1ltRnpaU0J2WmlCaWNtOTNjMlZ5Y3lCMGFHRjBJSE4xY0hCdmNuUWdaMlZ1WlhKaGRHOXljeTVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRWh2ZDJWMlpYSXNJRk5OSjNNZ1oyVnVaWEpoZEc5eWN5QjFjMlVnZEdobElGQjVkR2h2YmkxcGJuTndhWEpsWkNCelpXMWhiblJwWTNNZ2IyWmNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklHOTFkR1JoZEdWa0lFVlROaUJrY21GbWRITXVJQ0JYWlNCM2IzVnNaQ0JzYVd0bElIUnZJSE4xY0hCdmNuUWdSVk0yTENCaWRYUWdkMlVuWkNCaGJITnZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhV3RsSUhSdklHMWhhMlVnYVhRZ2NHOXpjMmxpYkdVZ2RHOGdkWE5sSUdkbGJtVnlZWFJ2Y25NZ2FXNGdaR1Z3Ykc5NVpXUWdZbkp2ZDNObGNuTXNJSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzWlNCaGJITnZJSE4xY0hCdmNuUWdVSGwwYUc5dUxYTjBlV3hsSUdkbGJtVnlZWFJ2Y25NdUlDQkJkQ0J6YjIxbElIQnZhVzUwSUhkbElHTmhiaUJ5WlcxdmRtVmNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklIUm9hWE1nWW14dlkyc3VYRzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2gwZVhCbGIyWWdVM1J2Y0VsMFpYSmhkR2x2YmlBOVBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVZUTmlCSFpXNWxjbUYwYjNKelhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVnpkV3gwSUQwZ1oyVnVaWEpoZEc5eVczWmxjbUpkS0dGeVp5azdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEpsYzNWc2RDNWtiMjVsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLSEpsYzNWc2RDNTJZV3gxWlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIZG9aVzRvY21WemRXeDBMblpoYkhWbExDQmpZV3hzWW1GamF5d2daWEp5WW1GamF5azdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlRjR2xrWlhKTmIyNXJaWGtnUjJWdVpYSmhkRzl5YzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUM4dklFWkpXRTFGT2lCU1pXMXZkbVVnZEdocGN5QmpZWE5sSUhkb1pXNGdVMDBnWkc5bGN5QkZVellnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCblpXNWxjbUYwYjNKYmRtVnlZbDBvWVhKbktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxlR05sY0hScGIyNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x6VTNSdmNFbDBaWEpoZEdsdmJpaGxlR05sY0hScGIyNHBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdVU2hsZUdObGNIUnBiMjR1ZG1Gc2RXVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRDaGxlR05sY0hScGIyNHBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEpsYzNWc2RDd2dZMkZzYkdKaFkyc3NJR1Z5Y21KaFkyc3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSFpoY2lCblpXNWxjbUYwYjNJZ1BTQnRZV3RsUjJWdVpYSmhkRzl5TG1Gd2NHeDVLSFJvYVhNc0lHRnlaM1Z0Wlc1MGN5azdYRzRnSUNBZ0lDQWdJSFpoY2lCallXeHNZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSnVaWGgwWENJcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWlhKeVltRmpheUE5SUdOdmJuUnBiblZsY2k1aWFXNWtLR052Ym5ScGJuVmxjaXdnWENKMGFISnZkMXdpS1R0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yS0NrN1hHNGdJQ0FnZlR0Y2JuMWNibHh1THlvcVhHNGdLaUJVYUdVZ2MzQmhkMjRnWm5WdVkzUnBiMjRnYVhNZ1lTQnpiV0ZzYkNCM2NtRndjR1Z5SUdGeWIzVnVaQ0JoYzNsdVl5QjBhR0YwSUdsdGJXVmthV0YwWld4NVhHNGdLaUJqWVd4c2N5QjBhR1VnWjJWdVpYSmhkRzl5SUdGdVpDQmhiSE52SUdWdVpITWdkR2hsSUhCeWIyMXBjMlVnWTJoaGFXNHNJSE52SUhSb1lYUWdZVzU1WEc0Z0tpQjFibWhoYm1Sc1pXUWdaWEp5YjNKeklHRnlaU0IwYUhKdmQyNGdhVzV6ZEdWaFpDQnZaaUJtYjNKM1lYSmtaV1FnZEc4Z2RHaGxJR1Z5Y205eVhHNGdLaUJvWVc1a2JHVnlMaUJVYUdseklHbHpJSFZ6WldaMWJDQmlaV05oZFhObElHbDBKM01nWlhoMGNtVnRaV3g1SUdOdmJXMXZiaUIwYnlCeWRXNWNiaUFxSUdkbGJtVnlZWFJ2Y25NZ1lYUWdkR2hsSUhSdmNDMXNaWFpsYkNCMGJ5QjNiM0pySUhkcGRHZ2diR2xpY21GeWFXVnpMbHh1SUNvdlhHNVJMbk53WVhkdUlEMGdjM0JoZDI0N1hHNW1kVzVqZEdsdmJpQnpjR0YzYmlodFlXdGxSMlZ1WlhKaGRHOXlLU0I3WEc0Z0lDQWdVUzVrYjI1bEtGRXVZWE41Ym1Nb2JXRnJaVWRsYm1WeVlYUnZjaWtvS1NrN1hHNTlYRzVjYmk4dklFWkpXRTFGT2lCU1pXMXZkbVVnZEdocGN5QnBiblJsY21aaFkyVWdiMjVqWlNCRlV6WWdaMlZ1WlhKaGRHOXljeUJoY21VZ2FXNGdVM0JwWkdWeVRXOXVhMlY1TGx4dUx5b3FYRzRnS2lCVWFISnZkM01nWVNCU1pYUjFjbTVXWVd4MVpTQmxlR05sY0hScGIyNGdkRzhnYzNSdmNDQmhiaUJoYzNsdVkyaHliMjV2ZFhNZ1oyVnVaWEpoZEc5eUxseHVJQ3BjYmlBcUlGUm9hWE1nYVc1MFpYSm1ZV05sSUdseklHRWdjM1J2Y0MxbllYQWdiV1ZoYzNWeVpTQjBieUJ6ZFhCd2IzSjBJR2RsYm1WeVlYUnZjaUJ5WlhSMWNtNWNiaUFxSUhaaGJIVmxjeUJwYmlCdmJHUmxjaUJHYVhKbFptOTRMMU53YVdSbGNrMXZibXRsZVM0Z0lFbHVJR0p5YjNkelpYSnpJSFJvWVhRZ2MzVndjRzl5ZENCRlV6WmNiaUFxSUdkbGJtVnlZWFJ2Y25NZ2JHbHJaU0JEYUhKdmJXbDFiU0F5T1N3Z2FuVnpkQ0IxYzJVZ1hDSnlaWFIxY201Y0lpQnBiaUI1YjNWeUlHZGxibVZ5WVhSdmNseHVJQ29nWm5WdVkzUnBiMjV6TGx4dUlDcGNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnZjaUIwYUdVZ2MzVnljbTkxYm1ScGJtY2daMlZ1WlhKaGRHOXlYRzRnS2lCQWRHaHliM2R6SUZKbGRIVnlibFpoYkhWbElHVjRZMlZ3ZEdsdmJpQjNhWFJvSUhSb1pTQjJZV3gxWlM1Y2JpQXFJRUJsZUdGdGNHeGxYRzRnS2lBdkx5QkZVellnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRxSUNncElIdGNiaUFxSUNBZ0lDQWdkbUZ5SUdadmJ5QTlJSGxwWld4a0lHZGxkRVp2YjFCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2RtRnlJR0poY2lBOUlIbHBaV3hrSUdkbGRFSmhjbEJ5YjIxcGMyVW9LVHRjYmlBcUlDQWdJQ0FnY21WMGRYSnVJR1p2YnlBcklHSmhjanRjYmlBcUlIMHBYRzRnS2lBdkx5QlBiR1JsY2lCVGNHbGtaWEpOYjI1clpYa2djM1I1YkdWY2JpQXFJRkV1WVhONWJtTW9ablZ1WTNScGIyNGdLQ2tnZTF4dUlDb2dJQ0FnSUNCMllYSWdabTl2SUQwZ2VXbGxiR1FnWjJWMFJtOXZVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0IyWVhJZ1ltRnlJRDBnZVdsbGJHUWdaMlYwUW1GeVVISnZiV2x6WlNncE8xeHVJQ29nSUNBZ0lDQlJMbkpsZEhWeWJpaG1iMjhnS3lCaVlYSXBPMXh1SUNvZ2ZTbGNiaUFxTDF4dVVWdGNJbkpsZEhWeWJsd2lYU0E5SUY5eVpYUjFjbTQ3WEc1bWRXNWpkR2x2YmlCZmNtVjBkWEp1S0haaGJIVmxLU0I3WEc0Z0lDQWdkR2h5YjNjZ2JtVjNJRkZTWlhSMWNtNVdZV3gxWlNoMllXeDFaU2s3WEc1OVhHNWNiaThxS2x4dUlDb2dWR2hsSUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1SUdSbFkyOXlZWFJ2Y2lCbGJuTjFjbVZ6SUhSb1lYUWdZVzU1SUhCeWIyMXBjMlVnWVhKbmRXMWxiblJ6WEc0Z0tpQmhjbVVnYzJWMGRHeGxaQ0JoYm1RZ2NHRnpjMlZrSUdGeklIWmhiSFZsY3lBb1lIUm9hWE5nSUdseklHRnNjMjhnYzJWMGRHeGxaQ0JoYm1RZ2NHRnpjMlZrWEc0Z0tpQmhjeUJoSUhaaGJIVmxLUzRnSUVsMElIZHBiR3dnWVd4emJ5Qmxibk4xY21VZ2RHaGhkQ0IwYUdVZ2NtVnpkV3gwSUc5bUlHRWdablZ1WTNScGIyNGdhWE5jYmlBcUlHRnNkMkY1Y3lCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJSFpoY2lCaFpHUWdQU0JSTG5CeWIyMXBjMlZrS0daMWJtTjBhVzl1SUNoaExDQmlLU0I3WEc0Z0tpQWdJQ0FnY21WMGRYSnVJR0VnS3lCaU8xeHVJQ29nZlNrN1hHNGdLaUJoWkdRb1VTaGhLU3dnVVNoQ0tTazdYRzRnS2x4dUlDb2dRSEJoY21GdElIdG1kVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dWR2hsSUdaMWJtTjBhVzl1SUhSdklHUmxZMjl5WVhSbFhHNGdLaUJBY21WMGRYSnVjeUI3Wm5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0JvWVhNZ1ltVmxiaUJrWldOdmNtRjBaV1F1WEc0Z0tpOWNibEV1Y0hKdmJXbHpaV1FnUFNCd2NtOXRhWE5sWkR0Y2JtWjFibU4wYVc5dUlIQnliMjFwYzJWa0tHTmhiR3hpWVdOcktTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlITndjbVZoWkNoYmRHaHBjeXdnWVd4c0tHRnlaM1Z0Wlc1MGN5bGRMQ0JtZFc1amRHbHZiaUFvYzJWc1ppd2dZWEpuY3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtITmxiR1lzSUdGeVozTXBPMXh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5TzF4dWZWeHVYRzR2S2lwY2JpQXFJSE5sYm1SeklHRWdiV1Z6YzJGblpTQjBieUJoSUhaaGJIVmxJR2x1SUdFZ1puVjBkWEpsSUhSMWNtNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUXFJSFJvWlNCeVpXTnBjR2xsYm5SY2JpQXFJRUJ3WVhKaGJTQnZjQ0IwYUdVZ2JtRnRaU0J2WmlCMGFHVWdiV1Z6YzJGblpTQnZjR1Z5WVhScGIyNHNJR1V1Wnk0c0lGd2lkMmhsYmx3aUxGeHVJQ29nUUhCaGNtRnRJR0Z5WjNNZ1puVnlkR2hsY2lCaGNtZDFiV1Z1ZEhNZ2RHOGdZbVVnWm05eWQyRnlaR1ZrSUhSdklIUm9aU0J2Y0dWeVlYUnBiMjVjYmlBcUlFQnlaWFIxY201eklISmxjM1ZzZENCN1VISnZiV2x6WlgwZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVnpkV3gwSUc5bUlIUm9aU0J2Y0dWeVlYUnBiMjVjYmlBcUwxeHVVUzVrYVhOd1lYUmphQ0E5SUdScGMzQmhkR05vTzF4dVpuVnVZM1JwYjI0Z1pHbHpjR0YwWTJnb2IySnFaV04wTENCdmNDd2dZWEpuY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvYjNBc0lHRnlaM01wTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVrYVhOd1lYUmphQ0E5SUdaMWJtTjBhVzl1SUNodmNDd2dZWEpuY3lrZ2UxeHVJQ0FnSUhaaGNpQnpaV3htSUQwZ2RHaHBjenRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQnpaV3htTG5CeWIyMXBjMlZFYVhOd1lYUmphQ2hrWldabGNuSmxaQzV5WlhOdmJIWmxMQ0J2Y0N3Z1lYSm5jeWs3WEc0Z0lDQWdmU2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVkbGRITWdkR2hsSUhaaGJIVmxJRzltSUdFZ2NISnZjR1Z5ZEhrZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymk1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ0lDQWdjSEp2YldselpTQnZjaUJwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUdadmNpQjBZWEpuWlhRZ2IySnFaV04wWEc0Z0tpQkFjR0Z5WVcwZ2JtRnRaU0FnSUNBZ0lHNWhiV1VnYjJZZ2NISnZjR1Z5ZEhrZ2RHOGdaMlYwWEc0Z0tpQkFjbVYwZFhKdUlIQnliMjFwYzJVZ1ptOXlJSFJvWlNCd2NtOXdaWEowZVNCMllXeDFaVnh1SUNvdlhHNVJMbWRsZENBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VaR2x6Y0dGMFkyZ29YQ0puWlhSY0lpd2dXMnRsZVYwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVoyVjBJRDBnWm5WdVkzUnBiMjRnS0d0bGVTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpWjJWMFhDSXNJRnRyWlhsZEtUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1UyVjBjeUIwYUdVZ2RtRnNkV1VnYjJZZ1lTQndjbTl3WlhKMGVTQnBiaUJoSUdaMWRIVnlaU0IwZFhKdUxseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ1ptOXlJRzlpYW1WamRDQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQnVZVzFsSUNBZ0lDQWdibUZ0WlNCdlppQndjbTl3WlhKMGVTQjBieUJ6WlhSY2JpQXFJRUJ3WVhKaGJTQjJZV3gxWlNBZ0lDQWdibVYzSUhaaGJIVmxJRzltSUhCeWIzQmxjblI1WEc0Z0tpQkFjbVYwZFhKdUlIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxTDF4dVVTNXpaWFFnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCclpYa3NJSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU3dnZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW5ObGRGd2lMQ0JiYTJWNUxDQjJZV3gxWlYwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRVpXeGxkR1Z6SUdFZ2NISnZjR1Z5ZEhrZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymk1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ0lDQWdjSEp2YldselpTQnZjaUJwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUdadmNpQjBZWEpuWlhRZ2IySnFaV04wWEc0Z0tpQkFjR0Z5WVcwZ2JtRnRaU0FnSUNBZ0lHNWhiV1VnYjJZZ2NISnZjR1Z5ZEhrZ2RHOGdaR1ZzWlhSbFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzVrWld3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1Ulcxd2laR1ZzWlhSbFhDSmRJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYTJWNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pWdGNJbVJsYkdWMFpWd2lYU0E5SUdaMWJtTjBhVzl1SUNoclpYa3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1SbGJHVjBaVndpTENCYmEyVjVYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRWx1ZG05clpYTWdZU0J0WlhSb2IyUWdhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdiV1YwYUc5a0lIUnZJR2x1ZG05clpWeHVJQ29nUUhCaGNtRnRJSFpoYkhWbElDQWdJQ0JoSUhaaGJIVmxJSFJ2SUhCdmMzUXNJSFI1Y0dsallXeHNlU0JoYmlCaGNuSmhlU0J2Wmx4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnBiblp2WTJGMGFXOXVJR0Z5WjNWdFpXNTBjeUJtYjNJZ2NISnZiV2x6WlhNZ2RHaGhkRnh1SUNvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCaGNtVWdkV3gwYVcxaGRHVnNlU0JpWVdOclpXUWdkMmwwYUNCZ2NtVnpiMngyWldBZ2RtRnNkV1Z6TEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjeUJ2Y0hCdmMyVmtJSFJ2SUhSb2IzTmxJR0poWTJ0bFpDQjNhWFJvSUZWU1RITmNiaUFxSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZDJobGNtVnBiaUIwYUdVZ2NHOXpkR1ZrSUhaaGJIVmxJR05oYmlCaVpTQmhibmxjYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1NsTlBUaUJ6WlhKcFlXeHBlbUZpYkdVZ2IySnFaV04wTGx4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxYRzRnS2k5Y2JpOHZJR0p2ZFc1a0lHeHZZMkZzYkhrZ1ltVmpZWFZ6WlNCcGRDQnBjeUIxYzJWa0lHSjVJRzkwYUdWeUlHMWxkR2h2WkhOY2JsRXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEV1Y0c5emRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEpuYzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJXRndjR3g1SUQwZ0x5OGdXRmhZSUVGeklIQnliM0J2YzJWa0lHSjVJRndpVW1Wa2MyRnVaSEp2WENKY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExuQnZjM1FnUFNCbWRXNWpkR2x2YmlBb2JtRnRaU3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEpuYzEwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCSmJuWnZhMlZ6SUdFZ2JXVjBhRzlrSUdsdUlHRWdablYwZFhKbElIUjFjbTR1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUc5aWFtVmpkRnh1SUNvZ1FIQmhjbUZ0SUc1aGJXVWdJQ0FnSUNCdVlXMWxJRzltSUcxbGRHaHZaQ0IwYnlCcGJuWnZhMlZjYmlBcUlFQndZWEpoYlNBdUxpNWhjbWR6SUNBZ1lYSnlZWGtnYjJZZ2FXNTJiMk5oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxSUVCeVpYUjFjbTRnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSEpsZEhWeWJpQjJZV3gxWlZ4dUlDb3ZYRzVSTG5ObGJtUWdQU0F2THlCWVdGZ2dUV0Z5YXlCTmFXeHNaWEluY3lCd2NtOXdiM05sWkNCd1lYSnNZVzVqWlZ4dVVTNXRZMkZzYkNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbWx1ZG05clpTQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJRzVoYldVZ0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F5S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWMyVnVaQ0E5SUM4dklGaFlXQ0JOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lIQmhjbXhoYm1ObFhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXRZMkZzYkNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXBiblp2YTJVZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkJjSEJzYVdWeklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdJQ0FnSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVTNW1ZWEJ3YkhrZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQmhjbWR6S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeVozTmRLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoY0hCc2VTQTlJR1oxYm1OMGFXOXVJQ2hoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0poY0hCc2VWd2lMQ0JiZG05cFpDQXdMQ0JoY21kelhTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFTmhiR3h6SUhSb1pTQndjbTl0YVhObFpDQm1kVzVqZEdsdmJpQnBiaUJoSUdaMWRIVnlaU0IwZFhKdUxseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ1ptOXlJSFJoY21kbGRDQm1kVzVqZEdsdmJseHVJQ29nUUhCaGNtRnRJQzR1TG1GeVozTWdJQ0JoY25KaGVTQnZaaUJoY0hCc2FXTmhkR2x2YmlCaGNtZDFiV1Z1ZEhOY2JpQXFMMXh1VVZ0Y0luUnllVndpWFNBOVhHNVJMbVpqWVd4c0lEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDQXZLaUF1TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpWVhCd2JIbGNJaXdnVzNadmFXUWdNQ3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wm1OaGJHd2dQU0JtZFc1amRHbHZiaUFvTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnQyYjJsa0lEQXNJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lsZEtUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FtbHVaSE1nZEdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUxDQjBjbUZ1YzJadmNtMXBibWNnY21WMGRYSnVJSFpoYkhWbGN5QnBiblJ2SUdFZ1puVnNabWxzYkdWa1hHNGdLaUJ3Y205dGFYTmxJR0Z1WkNCMGFISnZkMjRnWlhKeWIzSnpJR2x1ZEc4Z1lTQnlaV3BsWTNSbFpDQnZibVV1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUdaMWJtTjBhVzl1WEc0Z0tpQkFjR0Z5WVcwZ0xpNHVZWEpuY3lBZ0lHRnljbUY1SUc5bUlHRndjR3hwWTJGMGFXOXVJR0Z5WjNWdFpXNTBjMXh1SUNvdlhHNVJMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCd2NtOXRhWE5sSUQwZ1VTaHZZbXBsWTNRcE8xeHVJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1R0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdabUp2ZFc1a0tDa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpTNWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE1zWEc0Z0lDQWdJQ0FnSUNBZ0lDQmhjbWR6TG1OdmJtTmhkQ2hoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNcEtWeHVJQ0FnSUNBZ0lDQmRLVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWmlhVzVrSUQwZ1puVnVZM1JwYjI0Z0tDOHFMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUhCeWIyMXBjMlVnUFNCMGFHbHpPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdabUp2ZFc1a0tDa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpTNWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE1zWEc0Z0lDQWdJQ0FnSUNBZ0lDQmhjbWR6TG1OdmJtTmhkQ2hoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNcEtWeHVJQ0FnSUNBZ0lDQmRLVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlNaWEYxWlhOMGN5QjBhR1VnYm1GdFpYTWdiMllnZEdobElHOTNibVZrSUhCeWIzQmxjblJwWlhNZ2IyWWdZU0J3Y205dGFYTmxaRnh1SUNvZ2IySnFaV04wSUdsdUlHRWdablYwZFhKbElIUjFjbTR1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnYTJWNWN5QnZaaUIwYUdVZ1pYWmxiblIxWVd4c2VTQnpaWFIwYkdWa0lHOWlhbVZqZEZ4dUlDb3ZYRzVSTG10bGVYTWdQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YTJWNWN5QTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltdGxlWE5jSWl3Z1cxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlVkWEp1Y3lCaGJpQmhjbkpoZVNCdlppQndjbTl0YVhObGN5QnBiblJ2SUdFZ2NISnZiV2x6WlNCbWIzSWdZVzRnWVhKeVlYa3VJQ0JKWmlCaGJua2diMlpjYmlBcUlIUm9aU0J3Y205dGFYTmxjeUJuWlhSeklISmxhbVZqZEdWa0xDQjBhR1VnZDJodmJHVWdZWEp5WVhrZ2FYTWdjbVZxWldOMFpXUWdhVzF0WldScFlYUmxiSGt1WEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1S24wZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQmhiaUJoY25KaGVTQnZaaUIwYUdVZ1kyOXljbVZ6Y0c5dVpHbHVaeUIyWVd4MVpYTmNiaUFxTDF4dUx5OGdRbmtnVFdGeWF5Qk5hV3hzWlhKY2JpOHZJR2gwZEhBNkx5OTNhV3RwTG1WamJXRnpZM0pwY0hRdWIzSm5MMlJ2YTNVdWNHaHdQMmxrUFhOMGNtRjNiV0Z1T21OdmJtTjFjbkpsYm1ONUpuSmxkajB4TXpBNE56YzJOVEl4STJGc2JHWjFiR1pwYkd4bFpGeHVVUzVoYkd3Z1BTQmhiR3c3WEc1bWRXNWpkR2x2YmlCaGJHd29jSEp2YldselpYTXBJSHRjYmlBZ0lDQnlaWFIxY200Z2QyaGxiaWh3Y205dGFYTmxjeXdnWm5WdVkzUnBiMjRnS0hCeWIyMXBjMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ3Wlc1a2FXNW5RMjkxYm5RZ1BTQXdPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvY0hKdmJXbHpaWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lIQnliMjFwYzJVc0lHbHVaR1Y0S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ2MyNWhjSE5vYjNRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FYTlFjbTl0YVhObEtIQnliMjFwYzJVcElDWW1YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdLSE51WVhCemFHOTBJRDBnY0hKdmJXbHpaUzVwYm5Od1pXTjBLQ2twTG5OMFlYUmxJRDA5UFNCY0ltWjFiR1pwYkd4bFpGd2lYRzRnSUNBZ0lDQWdJQ0FnSUNBcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObGMxdHBibVJsZUYwZ1BTQnpibUZ3YzJodmRDNTJZV3gxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdLeXR3Wlc1a2FXNW5RMjkxYm5RN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxiaWhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZiV2x6WlN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObGMxdHBibVJsZUYwZ1BTQjJZV3gxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDZ3RMWEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2NISnZiV2x6WlhNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXlaV3BsWTNRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1oxYm1OMGFXOXVJQ2h3Y205bmNtVnpjeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWkdWbVpYSnlaV1F1Ym05MGFXWjVLSHNnYVc1a1pYZzZJR2x1WkdWNExDQjJZV3gxWlRvZ2NISnZaM0psYzNNZ2ZTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOUxDQjJiMmxrSURBcE8xeHVJQ0FnSUNBZ0lDQnBaaUFvY0dWdVpHbHVaME52ZFc1MElEMDlQU0F3S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEJ5YjIxcGMyVnpLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlLVHRjYm4xY2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVZV3hzSUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCaGJHd29kR2hwY3lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nZEdobElHWnBjbk4wSUhKbGMyOXNkbVZrSUhCeWIyMXBjMlVnYjJZZ1lXNGdZWEp5WVhrdUlGQnlhVzl5SUhKbGFtVmpkR1ZrSUhCeWIyMXBjMlZ6SUdGeVpWeHVJQ29nYVdkdWIzSmxaQzRnSUZKbGFtVmpkSE1nYjI1c2VTQnBaaUJoYkd3Z2NISnZiV2x6WlhNZ1lYSmxJSEpsYW1WamRHVmtMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlU3A5SUdGdUlHRnljbUY1SUdOdmJuUmhhVzVwYm1jZ2RtRnNkV1Z6SUc5eUlIQnliMjFwYzJWeklHWnZjaUIyWVd4MVpYTmNiaUFxSUVCeVpYUjFjbTV6SUdFZ2NISnZiV2x6WlNCbWRXeG1hV3hzWldRZ2QybDBhQ0IwYUdVZ2RtRnNkV1VnYjJZZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVc1hHNGdLaUJ2Y2lCaElISmxhbVZqZEdWa0lIQnliMjFwYzJVZ2FXWWdZV3hzSUhCeWIyMXBjMlZ6SUdGeVpTQnlaV3BsWTNSbFpDNWNiaUFxTDF4dVVTNWhibmtnUFNCaGJuazdYRzVjYm1aMWJtTjBhVzl1SUdGdWVTaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lHbG1JQ2h3Y205dGFYTmxjeTVzWlc1bmRHZ2dQVDA5SURBcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGRXVjbVZ6YjJ4MlpTZ3BPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUZFdVpHVm1aWElvS1R0Y2JpQWdJQ0IyWVhJZ2NHVnVaR2x1WjBOdmRXNTBJRDBnTUR0Y2JpQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaHdjbVYyTENCamRYSnlaVzUwTENCcGJtUmxlQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdjSEp2YldselpTQTlJSEJ5YjIxcGMyVnpXMmx1WkdWNFhUdGNibHh1SUNBZ0lDQWdJQ0J3Wlc1a2FXNW5RMjkxYm5Rckt6dGNibHh1SUNBZ0lDQWdJQ0IzYUdWdUtIQnliMjFwYzJVc0lHOXVSblZzWm1sc2JHVmtMQ0J2YmxKbGFtVmpkR1ZrTENCdmJsQnliMmR5WlhOektUdGNiaUFnSUNBZ0lDQWdablZ1WTNScGIyNGdiMjVHZFd4bWFXeHNaV1FvY21WemRXeDBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXlaWE52YkhabEtISmxjM1ZzZENrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdablZ1WTNScGIyNGdiMjVTWldwbFkzUmxaQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEJsYm1ScGJtZERiM1Z1ZEMwdE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tIQmxibVJwYm1kRGIzVnVkQ0E5UFQwZ01Da2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHVaWGNnUlhKeWIzSW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aVEyRnVKM1FnWjJWMElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHWnliMjBnWVc1NUlIQnliMjFwYzJVc0lHRnNiQ0JjSWlBclhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRndpY0hKdmJXbHpaWE1nZDJWeVpTQnlaV3BsWTNSbFpDNWNJbHh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ2twTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUc5dVVISnZaM0psYzNNb2NISnZaM0psYzNNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG01dmRHbG1lU2g3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVc1a1pYZzZJR2x1WkdWNExGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsT2lCd2NtOW5jbVZ6YzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCMWJtUmxabWx1WldRcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbUZ1ZVNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1lXNTVLSFJvYVhNcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCWFlXbDBjeUJtYjNJZ1lXeHNJSEJ5YjIxcGMyVnpJSFJ2SUdKbElITmxkSFJzWldRc0lHVnBkR2hsY2lCbWRXeG1hV3hzWldRZ2IzSmNiaUFxSUhKbGFtVmpkR1ZrTGlBZ1ZHaHBjeUJwY3lCa2FYTjBhVzVqZENCbWNtOXRJR0JoYkd4Z0lITnBibU5sSUhSb1lYUWdkMjkxYkdRZ2MzUnZjRnh1SUNvZ2QyRnBkR2x1WnlCaGRDQjBhR1VnWm1seWMzUWdjbVZxWldOMGFXOXVMaUFnVkdobElIQnliMjFwYzJVZ2NtVjBkWEp1WldRZ1lubGNiaUFxSUdCaGJHeFNaWE52YkhabFpHQWdkMmxzYkNCdVpYWmxjaUJpWlNCeVpXcGxZM1JsWkM1Y2JpQXFJRUJ3WVhKaGJTQndjbTl0YVhObGN5QmhJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1SUNodmNpQmhiaUJoY25KaGVTa2diMllnY0hKdmJXbHpaWE5jYmlBcUlDaHZjaUIyWVd4MVpYTXBYRzRnS2lCQWNtVjBkWEp1SUdFZ2NISnZiV2x6WlNCbWIzSWdZVzRnWVhKeVlYa2diMllnY0hKdmJXbHpaWE5jYmlBcUwxeHVVUzVoYkd4U1pYTnZiSFpsWkNBOUlHUmxjSEpsWTJGMFpTaGhiR3hTWlhOdmJIWmxaQ3dnWENKaGJHeFNaWE52YkhabFpGd2lMQ0JjSW1Gc2JGTmxkSFJzWldSY0lpazdYRzVtZFc1amRHbHZiaUJoYkd4U1pYTnZiSFpsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUIzYUdWdUtIQnliMjFwYzJWekxDQm1kVzVqZEdsdmJpQW9jSEp2YldselpYTXBJSHRjYmlBZ0lDQWdJQ0FnY0hKdmJXbHpaWE1nUFNCaGNuSmhlVjl0WVhBb2NISnZiV2x6WlhNc0lGRXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkMmhsYmloaGJHd29ZWEp5WVhsZmJXRndLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIZG9aVzRvY0hKdmJXbHpaU3dnYm05dmNDd2dibTl2Y0NrN1hHNGdJQ0FnSUNBZ0lIMHBLU3dnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVnpPMXh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c1VtVnpiMngyWldRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHRnNiRkpsYzI5c2RtVmtLSFJvYVhNcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCQWMyVmxJRkJ5YjIxcGMyVWpZV3hzVTJWMGRHeGxaRnh1SUNvdlhHNVJMbUZzYkZObGRIUnNaV1FnUFNCaGJHeFRaWFIwYkdWa08xeHVablZ1WTNScGIyNGdZV3hzVTJWMGRHeGxaQ2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVnpLUzVoYkd4VFpYUjBiR1ZrS0NrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkhWeWJuTWdZVzRnWVhKeVlYa2diMllnY0hKdmJXbHpaWE1nYVc1MGJ5QmhJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1SUc5bUlIUm9aV2x5SUhOMFlYUmxjeUFvWVhOY2JpQXFJSEpsZEhWeWJtVmtJR0o1SUdCcGJuTndaV04wWUNrZ2QyaGxiaUIwYUdWNUlHaGhkbVVnWVd4c0lITmxkSFJzWldRdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVcwRnVlU3BkZlNCMllXeDFaWE1nWVc0Z1lYSnlZWGtnS0c5eUlIQnliMjFwYzJVZ1ptOXlJR0Z1SUdGeWNtRjVLU0J2WmlCMllXeDFaWE1nS0c5eVhHNGdLaUJ3Y205dGFYTmxjeUJtYjNJZ2RtRnNkV1Z6S1Z4dUlDb2dRSEpsZEhWeWJuTWdlMEZ5Y21GNVcxTjBZWFJsWFgwZ1lXNGdZWEp5WVhrZ2IyWWdjM1JoZEdWeklHWnZjaUIwYUdVZ2NtVnpjR1ZqZEdsMlpTQjJZV3gxWlhNdVhHNGdLaTljYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1Gc2JGTmxkSFJzWldRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9jSEp2YldselpYTXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR0ZzYkNoaGNuSmhlVjl0WVhBb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaHdjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCd2NtOXRhWE5sSUQwZ1VTaHdjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUhKbFoyRnlaR3hsYzNNb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVdWFXNXpjR1ZqZENncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVdWRHaGxiaWh5WldkaGNtUnNaWE56TENCeVpXZGhjbVJzWlhOektUdGNiaUFnSUNBZ0lDQWdmU2twTzF4dUlDQWdJSDBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVhCMGRYSmxjeUIwYUdVZ1ptRnBiSFZ5WlNCdlppQmhJSEJ5YjIxcGMyVXNJR2RwZG1sdVp5QmhiaUJ2Y0c5eWRIVnVhWFI1SUhSdklISmxZMjkyWlhKY2JpQXFJSGRwZEdnZ1lTQmpZV3hzWW1GamF5NGdJRWxtSUhSb1pTQm5hWFpsYmlCd2NtOXRhWE5sSUdseklHWjFiR1pwYkd4bFpDd2dkR2hsSUhKbGRIVnlibVZrWEc0Z0tpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaU0JtYjNJZ2MyOXRaWFJvYVc1blhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0JqWVd4c1ltRmpheUIwYnlCbWRXeG1hV3hzSUhSb1pTQnlaWFIxY201bFpDQndjbTl0YVhObElHbG1JSFJvWlZ4dUlDb2daMmwyWlc0Z2NISnZiV2x6WlNCcGN5QnlaV3BsWTNSbFpGeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHOW1JSFJvWlNCallXeHNZbUZqYTF4dUlDb3ZYRzVSTG1aaGFXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWTJGMFkyaGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1OaGRHTm9YQ0pkSUQwZ1puVnVZM1JwYjI0Z0tISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmloMmIybGtJREFzSUhKbGFtVmpkR1ZrS1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nUVhSMFlXTm9aWE1nWVNCc2FYTjBaVzVsY2lCMGFHRjBJR05oYmlCeVpYTndiMjVrSUhSdklIQnliMmR5WlhOeklHNXZkR2xtYVdOaGRHbHZibk1nWm5KdmJTQmhYRzRnS2lCd2NtOXRhWE5sSjNNZ2IzSnBaMmx1WVhScGJtY2daR1ZtWlhKeVpXUXVJRlJvYVhNZ2JHbHpkR1Z1WlhJZ2NtVmpaV2wyWlhNZ2RHaGxJR1Y0WVdOMElHRnlaM1Z0Wlc1MGMxeHVJQ29nY0dGemMyVmtJSFJ2SUdCZ1pHVm1aWEp5WldRdWJtOTBhV1o1WUdBdVhHNGdLaUJBY0dGeVlXMGdlMEZ1ZVNwOUlIQnliMjFwYzJVZ1ptOXlJSE52YldWMGFHbHVaMXh1SUNvZ1FIQmhjbUZ0SUh0R2RXNWpkR2x2Ym4wZ1kyRnNiR0poWTJzZ2RHOGdjbVZqWldsMlpTQmhibmtnY0hKdlozSmxjM01nYm05MGFXWnBZMkYwYVc5dWMxeHVJQ29nUUhKbGRIVnlibk1nZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVzSUhWdVkyaGhibWRsWkZ4dUlDb3ZYRzVSTG5CeWIyZHlaWE56SUQwZ2NISnZaM0psYzNNN1hHNW1kVzVqZEdsdmJpQndjbTluY21WemN5aHZZbXBsWTNRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExuUm9aVzRvZG05cFpDQXdMQ0IyYjJsa0lEQXNJSEJ5YjJkeVpYTnpaV1FwTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV3Y205bmNtVnpjeUE5SUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6YzJWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmloMmIybGtJREFzSUhadmFXUWdNQ3dnY0hKdlozSmxjM05sWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCeWIzWnBaR1Z6SUdGdUlHOXdjRzl5ZEhWdWFYUjVJSFJ2SUc5aWMyVnlkbVVnZEdobElITmxkSFJzYVc1bklHOW1JR0VnY0hKdmJXbHpaU3hjYmlBcUlISmxaMkZ5Wkd4bGMzTWdiMllnZDJobGRHaGxjaUIwYUdVZ2NISnZiV2x6WlNCcGN5Qm1kV3htYVd4c1pXUWdiM0lnY21WcVpXTjBaV1F1SUNCR2IzSjNZWEprYzF4dUlDb2dkR2hsSUhKbGMyOXNkWFJwYjI0Z2RHOGdkR2hsSUhKbGRIVnlibVZrSUhCeWIyMXBjMlVnZDJobGJpQjBhR1VnWTJGc2JHSmhZMnNnYVhNZ1pHOXVaUzVjYmlBcUlGUm9aU0JqWVd4c1ltRmpheUJqWVc0Z2NtVjBkWEp1SUdFZ2NISnZiV2x6WlNCMGJ5QmtaV1psY2lCamIyMXdiR1YwYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCYm5rcWZTQndjbTl0YVhObFhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0JqWVd4c1ltRmpheUIwYnlCdlluTmxjblpsSUhSb1pTQnlaWE52YkhWMGFXOXVJRzltSUhSb1pTQm5hWFpsYmx4dUlDb2djSEp2YldselpTd2dkR0ZyWlhNZ2JtOGdZWEpuZFcxbGJuUnpMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVnpiMngxZEdsdmJpQnZaaUIwYUdVZ1oybDJaVzRnY0hKdmJXbHpaU0IzYUdWdVhHNGdLaUJnWUdacGJtQmdJR2x6SUdSdmJtVXVYRzRnS2k5Y2JsRXVabWx1SUQwZ0x5OGdXRmhZSUd4bFoyRmplVnh1VVZ0Y0ltWnBibUZzYkhsY0lsMGdQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JqWVd4c1ltRmpheWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDbGJYQ0ptYVc1aGJHeDVYQ0pkS0dOaGJHeGlZV05yS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1acGJpQTlJQzh2SUZoWVdDQnNaV2RoWTNsY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbFcxd2labWx1WVd4c2VWd2lYU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUdOaGJHeGlZV05ySUQwZ1VTaGpZV3hzWW1GamF5azdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1aallXeHNLQ2t1ZEdobGJpaG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUgwc0lHWjFibU4wYVc5dUlDaHlaV0Z6YjI0cElIdGNiaUFnSUNBZ0lDQWdMeThnVkU5RVR5QmhkSFJsYlhCMElIUnZJSEpsWTNsamJHVWdkR2hsSUhKbGFtVmpkR2x2YmlCM2FYUm9JRndpZEdocGMxd2lMbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMkZzYkdKaFkyc3VabU5oYkd3b0tTNTBhR1Z1S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJSEpsWVhOdmJqdGNiaUFnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRlJsY20xcGJtRjBaWE1nWVNCamFHRnBiaUJ2WmlCd2NtOXRhWE5sY3l3Z1ptOXlZMmx1WnlCeVpXcGxZM1JwYjI1eklIUnZJR0psWEc0Z0tpQjBhSEp2ZDI0Z1lYTWdaWGhqWlhCMGFXOXVjeTVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaU0JoZENCMGFHVWdaVzVrSUc5bUlHRWdZMmhoYVc0Z2IyWWdjSEp2YldselpYTmNiaUFxSUVCeVpYUjFjbTV6SUc1dmRHaHBibWRjYmlBcUwxeHVVUzVrYjI1bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJ2Ym1Vb1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDd2djSEp2WjNKbGMzTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaRzl1WlNBOUlHWjFibU4wYVc5dUlDaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnZTF4dUlDQWdJSFpoY2lCdmJsVnVhR0Z1Wkd4bFpFVnljbTl5SUQwZ1puVnVZM1JwYjI0Z0tHVnljbTl5S1NCN1hHNGdJQ0FnSUNBZ0lDOHZJR1p2Y25kaGNtUWdkRzhnWVNCbWRYUjFjbVVnZEhWeWJpQnpieUIwYUdGMElHQmdkMmhsYm1CZ1hHNGdJQ0FnSUNBZ0lDOHZJR1J2WlhNZ2JtOTBJR05oZEdOb0lHbDBJR0Z1WkNCMGRYSnVJR2wwSUdsdWRHOGdZU0J5WldwbFkzUnBiMjR1WEc0Z0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JXRnJaVk4wWVdOclZISmhZMlZNYjI1bktHVnljbTl5TENCd2NtOXRhWE5sS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aWEp5YjNJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5Qmxjbkp2Y2p0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlR0Y2JseHVJQ0FnSUM4dklFRjJiMmxrSUhWdWJtVmpaWE56WVhKNUlHQnVaWGgwVkdsamEyQnBibWNnZG1saElHRnVJSFZ1Ym1WalpYTnpZWEo1SUdCM2FHVnVZQzVjYmlBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUdaMWJHWnBiR3hsWkNCOGZDQnlaV3BsWTNSbFpDQjhmQ0J3Y205bmNtVnpjeUEvWEc0Z0lDQWdJQ0FnSUhSb2FYTXVkR2hsYmlobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0xDQndjbTluY21WemN5a2dPbHh1SUNBZ0lDQWdJQ0IwYUdsek8xeHVYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIQnliMk5sYzNNZ0ppWWdjSEp2WTJWemN5NWtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdiMjVWYm1oaGJtUnNaV1JGY25KdmNpQTlJSEJ5YjJObGMzTXVaRzl0WVdsdUxtSnBibVFvYjI1VmJtaGhibVJzWldSRmNuSnZjaWs3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdjSEp2YldselpTNTBhR1Z1S0hadmFXUWdNQ3dnYjI1VmJtaGhibVJzWldSRmNuSnZjaWs3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oZFhObGN5QmhJSEJ5YjIxcGMyVWdkRzhnWW1VZ2NtVnFaV04wWldRZ2FXWWdhWFFnWkc5bGN5QnViM1FnWjJWMElHWjFiR1pwYkd4bFpDQmlaV1p2Y21WY2JpQXFJSE52YldVZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldVZ2IzVjBMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTA1MWJXSmxjbjBnYldsc2JHbHpaV052Ym1SeklIUnBiV1Z2ZFhSY2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ1kzVnpkRzl0SUdWeWNtOXlJRzFsYzNOaFoyVWdiM0lnUlhKeWIzSWdiMkpxWldOMElDaHZjSFJwYjI1aGJDbGNiaUFxSUVCeVpYUjFjbTV6SUdFZ2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVWdhV1lnYVhRZ2FYTmNiaUFxSUdaMWJHWnBiR3hsWkNCaVpXWnZjbVVnZEdobElIUnBiV1Z2ZFhRc0lHOTBhR1Z5ZDJselpTQnlaV3BsWTNSbFpDNWNiaUFxTDF4dVVTNTBhVzFsYjNWMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2diWE1zSUdWeWNtOXlLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNTBhVzFsYjNWMEtHMXpMQ0JsY25KdmNpazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhVzFsYjNWMElEMGdablZ1WTNScGIyNGdLRzF6TENCbGNuSnZjaWtnZTF4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlHUmxabVZ5S0NrN1hHNGdJQ0FnZG1GeUlIUnBiV1Z2ZFhSSlpDQTlJSE5sZEZScGJXVnZkWFFvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvSVdWeWNtOXlJSHg4SUZ3aWMzUnlhVzVuWENJZ1BUMDlJSFI1Y0dWdlppQmxjbkp2Y2lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSWdQU0J1WlhjZ1JYSnliM0lvWlhKeWIzSWdmSHdnWENKVWFXMWxaQ0J2ZFhRZ1lXWjBaWElnWENJZ0t5QnRjeUFySUZ3aUlHMXpYQ0lwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdaWEp5YjNJdVkyOWtaU0E5SUZ3aVJWUkpUVVZFVDFWVVhDSTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWkdWbVpYSnlaV1F1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNCOUxDQnRjeWs3WEc1Y2JpQWdJQ0IwYUdsekxuUm9aVzRvWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUdOc1pXRnlWR2x0Wlc5MWRDaDBhVzFsYjNWMFNXUXBPMXh1SUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSFpoYkhWbEtUdGNiaUFnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdOc1pXRnlWR2x0Wlc5MWRDaDBhVzFsYjNWMFNXUXBPMXh1SUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQjlMQ0JrWldabGNuSmxaQzV1YjNScFpua3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnWjJsMlpXNGdkbUZzZFdVZ0tHOXlJSEJ5YjIxcGMyVmtJSFpoYkhWbEtTd2djMjl0WlZ4dUlDb2diV2xzYkdselpXTnZibVJ6SUdGbWRHVnlJR2wwSUhKbGMyOXNkbVZrTGlCUVlYTnpaWE1nY21WcVpXTjBhVzl1Y3lCcGJXMWxaR2xoZEdWc2VTNWNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdjSEp2YldselpWeHVJQ29nUUhCaGNtRnRJSHRPZFcxaVpYSjlJRzFwYkd4cGMyVmpiMjVrYzF4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCaFpuUmxjaUJ0YVd4c2FYTmxZMjl1WkhOY2JpQXFJSFJwYldVZ2FHRnpJR1ZzWVhCelpXUWdjMmx1WTJVZ2RHaGxJSEpsYzI5c2RYUnBiMjRnYjJZZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVdVhHNGdLaUJKWmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCeVpXcGxZM1J6TENCMGFHRjBJR2x6SUhCaGMzTmxaQ0JwYlcxbFpHbGhkR1ZzZVM1Y2JpQXFMMXh1VVM1a1pXeGhlU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUhScGJXVnZkWFFwSUh0Y2JpQWdJQ0JwWmlBb2RHbHRaVzkxZENBOVBUMGdkbTlwWkNBd0tTQjdYRzRnSUNBZ0lDQWdJSFJwYldWdmRYUWdQU0J2WW1wbFkzUTdYRzRnSUNBZ0lDQWdJRzlpYW1WamRDQTlJSFp2YVdRZ01EdGNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrWld4aGVTaDBhVzFsYjNWMEtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtUmxiR0Y1SUQwZ1puVnVZM1JwYjI0Z0tIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTBhR1Z1S0daMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0J6WlhSVWFXMWxiM1YwS0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGMyOXNkbVVvZG1Gc2RXVXBPMXh1SUNBZ0lDQWdJQ0I5TENCMGFXMWxiM1YwS1R0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkJoYzNObGN5QmhJR052Ym5ScGJuVmhkR2x2YmlCMGJ5QmhJRTV2WkdVZ1puVnVZM1JwYjI0c0lIZG9hV05vSUdseklHTmhiR3hsWkNCM2FYUm9JSFJvWlNCbmFYWmxibHh1SUNvZ1lYSm5kVzFsYm5SeklIQnliM1pwWkdWa0lHRnpJR0Z1SUdGeWNtRjVMQ0JoYm1RZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ0lDQWdJQ0JSTG01bVlYQndiSGtvUmxNdWNtVmhaRVpwYkdVc0lGdGZYMlpwYkdWdVlXMWxYU2xjYmlBcUlDQWdJQ0FnTG5Sb1pXNG9ablZ1WTNScGIyNGdLR052Ym5SbGJuUXBJSHRjYmlBcUlDQWdJQ0FnZlNsY2JpQXFYRzRnS2k5Y2JsRXVibVpoY0hCc2VTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHTmhiR3hpWVdOcktTNXVabUZ3Y0d4NUtHRnlaM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kektUdGNiaUFnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdkR2hwY3k1bVlYQndiSGtvYm05a1pVRnlaM01wTG1aaGFXd29aR1ZtWlhKeVpXUXVjbVZxWldOMEtUdGNiaUFnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVR0Z6YzJWeklHRWdZMjl1ZEdsdWRXRjBhVzl1SUhSdklHRWdUbTlrWlNCbWRXNWpkR2x2Yml3Z2QyaHBZMmdnYVhNZ1kyRnNiR1ZrSUhkcGRHZ2dkR2hsSUdkcGRtVnVYRzRnS2lCaGNtZDFiV1Z1ZEhNZ2NISnZkbWxrWldRZ2FXNWthWFpwWkhWaGJHeDVMQ0JoYm1RZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabU5oYkd3b1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwWEc0Z0tpQXVkR2hsYmlobWRXNWpkR2x2YmlBb1kyOXVkR1Z1ZENrZ2UxeHVJQ29nZlNsY2JpQXFYRzRnS2k5Y2JsRXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLR05oYkd4aVlXTnJJQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHRnlaM01nUFNCaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXNJREVwTzF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmpZV3hzSUQwZ1puVnVZM1JwYjI0Z0tDOHFMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRzV2WkdWQmNtZHpMbkIxYzJnb1pHVm1aWEp5WldRdWJXRnJaVTV2WkdWU1pYTnZiSFpsY2lncEtUdGNiaUFnSUNCMGFHbHpMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJSEpsZEhWeWJpQmtaV1psY25KbFpDNXdjbTl0YVhObE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCWGNtRndjeUJoSUU1dlpHVktVeUJqYjI1MGFXNTFZWFJwYjI0Z2NHRnpjMmx1WnlCbWRXNWpkR2x2YmlCaGJtUWdjbVYwZFhKdWN5QmhiaUJsY1hWcGRtRnNaVzUwWEc0Z0tpQjJaWEp6YVc5dUlIUm9ZWFFnY21WMGRYSnVjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQkFaWGhoYlhCc1pWeHVJQ29nVVM1dVptSnBibVFvUmxNdWNtVmhaRVpwYkdVc0lGOWZabWxzWlc1aGJXVXBLRndpZFhSbUxUaGNJaWxjYmlBcUlDNTBhR1Z1S0dOdmJuTnZiR1V1Ykc5bktWeHVJQ29nTG1SdmJtVW9LVnh1SUNvdlhHNVJMbTVtWW1sdVpDQTlYRzVSTG1SbGJtOWtaV2xtZVNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5QXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCaVlYTmxRWEpuY3lBOUlHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrN1hHNGdJQ0FnY21WMGRYSnVJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJRzV2WkdWQmNtZHpJRDBnWW1GelpVRnlaM011WTI5dVkyRjBLR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lrcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdJQ0FnSUZFb1kyRnNiR0poWTJzcExtWmhjSEJzZVNodWIyUmxRWEpuY3lrdVptRnBiQ2hrWldabGNuSmxaQzV5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNiaUFnSUNCOU8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmlhVzVrSUQxY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2d2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQmhjbWR6TG5WdWMyaHBablFvZEdocGN5azdYRzRnSUNBZ2NtVjBkWEp1SUZFdVpHVnViMlJsYVdaNUxtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzU5TzF4dVhHNVJMbTVpYVc1a0lEMGdablZ1WTNScGIyNGdLR05oYkd4aVlXTnJMQ0IwYUdsemNDQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCaVlYTmxRWEpuY3lBOUlHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTWlrN1hHNGdJQ0FnY21WMGRYSnVJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJRzV2WkdWQmNtZHpJRDBnWW1GelpVRnlaM011WTI5dVkyRjBLR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lrcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUdKdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtRndjR3g1S0hSb2FYTndMQ0JoY21kMWJXVnVkSE1wTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lGRW9ZbTkxYm1RcExtWmhjSEJzZVNodWIyUmxRWEpuY3lrdVptRnBiQ2hrWldabGNuSmxaQzV5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNiaUFnSUNCOU8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtSnBibVFnUFNCbWRXNWpkR2x2YmlBb0x5cDBhR2x6Y0N3Z0xpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURBcE8xeHVJQ0FnSUdGeVozTXVkVzV6YUdsbWRDaDBhR2x6S1R0Y2JpQWdJQ0J5WlhSMWNtNGdVUzV1WW1sdVpDNWhjSEJzZVNoMmIybGtJREFzSUdGeVozTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRZV3hzY3lCaElHMWxkR2h2WkNCdlppQmhJRTV2WkdVdGMzUjViR1VnYjJKcVpXTjBJSFJvWVhRZ1lXTmpaWEIwY3lCaElFNXZaR1V0YzNSNWJHVmNiaUFxSUdOaGJHeGlZV05ySUhkcGRHZ2dZU0JuYVhabGJpQmhjbkpoZVNCdlppQmhjbWQxYldWdWRITXNJSEJzZFhNZ1lTQndjbTkyYVdSbFpDQmpZV3hzWW1GamF5NWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdZVzRnYjJKcVpXTjBJSFJvWVhRZ2FHRnpJSFJvWlNCdVlXMWxaQ0J0WlhSb2IyUmNiaUFxSUVCd1lYSmhiU0I3VTNSeWFXNW5mU0J1WVcxbElHNWhiV1VnYjJZZ2RHaGxJRzFsZEdodlpDQnZaaUJ2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJR0Z5WjNNZ1lYSm5kVzFsYm5SeklIUnZJSEJoYzNNZ2RHOGdkR2hsSUcxbGRHaHZaRHNnZEdobElHTmhiR3hpWVdOclhHNGdLaUIzYVd4c0lHSmxJSEJ5YjNacFpHVmtJR0o1SUZFZ1lXNWtJR0Z3Y0dWdVpHVmtJSFJ2SUhSb1pYTmxJR0Z5WjNWdFpXNTBjeTVjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElIWmhiSFZsSUc5eUlHVnljbTl5WEc0Z0tpOWNibEV1Ym0xaGNIQnNlU0E5SUM4dklGaFlXQ0JCY3lCd2NtOXdiM05sWkNCaWVTQmNJbEpsWkhOaGJtUnliMXdpWEc1UkxtNXdiM04wSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2JtRnRaU3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWJuQnZjM1FvYm1GdFpTd2dZWEpuY3lrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWJXRndjR3g1SUQwZ0x5OGdXRmhZSUVGeklIQnliM0J2YzJWa0lHSjVJRndpVW1Wa2MyRnVaSEp2WENKY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtNXdiM04wSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQjJZWElnYm05a1pVRnlaM01nUFNCaGNuSmhlVjl6YkdsalpTaGhjbWR6SUh4OElGdGRLVHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRzV2WkdWQmNtZHpMbkIxYzJnb1pHVm1aWEp5WldRdWJXRnJaVTV2WkdWU1pYTnZiSFpsY2lncEtUdGNiaUFnSUNCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dibTlrWlVGeVozTmRLUzVtWVdsc0tHUmxabVZ5Y21Wa0xuSmxhbVZqZENrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFTmhiR3h6SUdFZ2JXVjBhRzlrSUc5bUlHRWdUbTlrWlMxemRIbHNaU0J2WW1wbFkzUWdkR2hoZENCaFkyTmxjSFJ6SUdFZ1RtOWtaUzF6ZEhsc1pWeHVJQ29nWTJGc2JHSmhZMnNzSUdadmNuZGhjbVJwYm1jZ2RHaGxJR2RwZG1WdUlIWmhjbWxoWkdsaklHRnlaM1Z0Wlc1MGN5d2djR3gxY3lCaElIQnliM1pwWkdWa1hHNGdLaUJqWVd4c1ltRmpheUJoY21kMWJXVnVkQzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNBdUxpNWhjbWR6SUdGeVozVnRaVzUwY3lCMGJ5QndZWE56SUhSdklIUm9aU0J0WlhSb2IyUTdJSFJvWlNCallXeHNZbUZqYXlCM2FXeHNYRzRnS2lCaVpTQndjbTkyYVdSbFpDQmllU0JSSUdGdVpDQmhjSEJsYm1SbFpDQjBieUIwYUdWelpTQmhjbWQxYldWdWRITXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCMllXeDFaU0J2Y2lCbGNuSnZjbHh1SUNvdlhHNVJMbTV6Wlc1a0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlFMWhjbXNnVFdsc2JHVnlKM01nY0hKdmNHOXpaV1FnWENKelpXNWtYQ0pjYmxFdWJtMWpZV3hzSUQwZ0x5OGdXRmhZSUVKaGMyVmtJRzl1SUZ3aVVtVmtjMkZ1WkhKdkozTmNJaUJ3Y205d2IzTmhiRnh1VVM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2JtRnRaU0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQnViMlJsUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV1YzJWdVpDQTlJQzh2SUZoWVdDQkNZWE5sWkNCdmJpQk5ZWEpySUUxcGJHeGxjaWR6SUhCeWIzQnZjMlZrSUZ3aWMyVnVaRndpWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWJXTmhiR3dnUFNBdkx5QllXRmdnUW1GelpXUWdiMjRnWENKU1pXUnpZVzVrY204bmMxd2lJSEJ5YjNCdmMyRnNYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV1YVc1MmIydGxJRDBnWm5WdVkzUnBiMjRnS0c1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2JtOWtaVUZ5WjNNdWNIVnphQ2hrWldabGNuSmxaQzV0WVd0bFRtOWtaVkpsYzI5c2RtVnlLQ2twTzF4dUlDQWdJSFJvYVhNdVpHbHpjR0YwWTJnb1hDSndiM04wWENJc0lGdHVZVzFsTENCdWIyUmxRWEpuYzEwcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lTQm1kVzVqZEdsdmJpQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnWW05MGFDQk9iMlJsSUdOdmJuUnBiblZoZEdsdmJpMXdZWE56YVc1bkxYTjBlV3hsSUdGdVpGeHVJQ29nY0hKdmJXbHpaUzF5WlhSMWNtNXBibWN0YzNSNWJHVXNJR2wwSUdOaGJpQmxibVFnYVhSeklHbHVkR1Z5Ym1Gc0lIQnliMjFwYzJVZ1kyaGhhVzRnZDJsMGFGeHVJQ29nWUc1dlpHVnBabmtvYm05a1pXSmhZMnNwWUN3Z1ptOXlkMkZ5WkdsdVp5QjBhR1VnYjNCMGFXOXVZV3dnYm05a1pXSmhZMnNnWVhKbmRXMWxiblF1SUNCSlppQjBhR1VnZFhObGNseHVJQ29nWld4bFkzUnpJSFJ2SUhWelpTQmhJRzV2WkdWaVlXTnJMQ0IwYUdVZ2NtVnpkV3gwSUhkcGJHd2dZbVVnYzJWdWRDQjBhR1Z5WlM0Z0lFbG1JSFJvWlhrZ1pHOGdibTkwWEc0Z0tpQndZWE56SUdFZ2JtOWtaV0poWTJzc0lIUm9aWGtnZDJsc2JDQnlaV05sYVhabElIUm9aU0J5WlhOMWJIUWdjSEp2YldselpTNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdZU0J5WlhOMWJIUWdLRzl5SUdFZ2NISnZiV2x6WlNCbWIzSWdZU0J5WlhOMWJIUXBYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCdWIyUmxZbUZqYXlCaElFNXZaR1V1YW5NdGMzUjViR1VnWTJGc2JHSmhZMnRjYmlBcUlFQnlaWFIxY201eklHVnBkR2hsY2lCMGFHVWdjSEp2YldselpTQnZjaUJ1YjNSb2FXNW5YRzRnS2k5Y2JsRXVibTlrWldsbWVTQTlJRzV2WkdWcFpuazdYRzVtZFc1amRHbHZiaUJ1YjJSbGFXWjVLRzlpYW1WamRDd2dibTlrWldKaFkyc3BJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExtNXZaR1ZwWm5rb2JtOWtaV0poWTJzcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWIyUmxhV1o1SUQwZ1puVnVZM1JwYjI0Z0tHNXZaR1ZpWVdOcktTQjdYRzRnSUNBZ2FXWWdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNXZaR1ZpWVdOcktHNTFiR3dzSUhaaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lDQWdJQ0I5TENCbWRXNWpkR2x2YmlBb1pYSnliM0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNXZaR1ZpWVdOcktHVnljbTl5S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnSUNCOVhHNTlPMXh1WEc1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9YQ0pSTG01dlEyOXVabXhwWTNRZ2IyNXNlU0IzYjNKcmN5QjNhR1Z1SUZFZ2FYTWdkWE5sWkNCaGN5QmhJR2RzYjJKaGJGd2lLVHRjYm4wN1hHNWNiaTh2SUVGc2JDQmpiMlJsSUdKbFptOXlaU0IwYUdseklIQnZhVzUwSUhkcGJHd2dZbVVnWm1sc2RHVnlaV1FnWm5KdmJTQnpkR0ZqYXlCMGNtRmpaWE11WEc1MllYSWdjVVZ1WkdsdVoweHBibVVnUFNCallYQjBkWEpsVEdsdVpTZ3BPMXh1WEc1eVpYUjFjbTRnVVR0Y2JseHVmU2s3WEc0aVhYMD0iLCIvKipcbiAqIFJvb3QgcmVmZXJlbmNlIGZvciBpZnJhbWVzLlxuICovXG5cbnZhciByb290O1xuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7IC8vIEJyb3dzZXIgd2luZG93XG4gIHJvb3QgPSB3aW5kb3c7XG59IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykgeyAvLyBXZWIgV29ya2VyXG4gIHJvb3QgPSBzZWxmO1xufSBlbHNlIHsgLy8gT3RoZXIgZW52aXJvbm1lbnRzXG4gIGNvbnNvbGUud2FybihcIlVzaW5nIGJyb3dzZXItb25seSB2ZXJzaW9uIG9mIHN1cGVyYWdlbnQgaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRcIik7XG4gIHJvb3QgPSB0aGlzO1xufVxuXG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2VtaXR0ZXInKTtcbnZhciByZXF1ZXN0QmFzZSA9IHJlcXVpcmUoJy4vcmVxdWVzdC1iYXNlJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gbm9vcCgpe307XG5cbi8qKlxuICogRXhwb3NlIGByZXF1ZXN0YC5cbiAqL1xuXG52YXIgcmVxdWVzdCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZXF1ZXN0JykuYmluZChudWxsLCBSZXF1ZXN0KTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgWEhSLlxuICovXG5cbnJlcXVlc3QuZ2V0WEhSID0gZnVuY3Rpb24gKCkge1xuICBpZiAocm9vdC5YTUxIdHRwUmVxdWVzdFxuICAgICAgJiYgKCFyb290LmxvY2F0aW9uIHx8ICdmaWxlOicgIT0gcm9vdC5sb2NhdGlvbi5wcm90b2NvbFxuICAgICAgICAgIHx8ICFyb290LkFjdGl2ZVhPYmplY3QpKSB7XG4gICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdDtcbiAgfSBlbHNlIHtcbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQLjYuMCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC4zLjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAnKTsgfSBjYXRjaChlKSB7fVxuICB9XG4gIHRocm93IEVycm9yKFwiQnJvd3Nlci1vbmx5IHZlcmlzb24gb2Ygc3VwZXJhZ2VudCBjb3VsZCBub3QgZmluZCBYSFJcIik7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgb2JqW2tleV0pO1xuICB9XG4gIHJldHVybiBwYWlycy5qb2luKCcmJyk7XG59XG5cbi8qKlxuICogSGVscHMgJ3NlcmlhbGl6ZScgd2l0aCBzZXJpYWxpemluZyBhcnJheXMuXG4gKiBNdXRhdGVzIHRoZSBwYWlycyBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWlyc1xuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gKi9cblxuZnVuY3Rpb24gcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdmFsKSB7XG4gIGlmICh2YWwgIT0gbnVsbCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgIHZhbC5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdik7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbCkpIHtcbiAgICAgIGZvcih2YXIgc3Via2V5IGluIHZhbCkge1xuICAgICAgICBwdXNoRW5jb2RlZEtleVZhbHVlUGFpcihwYWlycywga2V5ICsgJ1snICsgc3Via2V5ICsgJ10nLCB2YWxbc3Via2V5XSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICAgICAgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkpO1xuICB9XG59XG5cbi8qKlxuICogRXhwb3NlIHNlcmlhbGl6YXRpb24gbWV0aG9kLlxuICovXG5cbiByZXF1ZXN0LnNlcmlhbGl6ZU9iamVjdCA9IHNlcmlhbGl6ZTtcblxuIC8qKlxuICAqIFBhcnNlIHRoZSBnaXZlbiB4LXd3dy1mb3JtLXVybGVuY29kZWQgYHN0cmAuXG4gICpcbiAgKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gICogQHJldHVybiB7T2JqZWN0fVxuICAqIEBhcGkgcHJpdmF0ZVxuICAqL1xuXG5mdW5jdGlvbiBwYXJzZVN0cmluZyhzdHIpIHtcbiAgdmFyIG9iaiA9IHt9O1xuICB2YXIgcGFpcnMgPSBzdHIuc3BsaXQoJyYnKTtcbiAgdmFyIHBhaXI7XG4gIHZhciBwb3M7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBhaXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgcGFpciA9IHBhaXJzW2ldO1xuICAgIHBvcyA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChwb3MgPT0gLTEpIHtcbiAgICAgIG9ialtkZWNvZGVVUklDb21wb25lbnQocGFpcildID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ialtkZWNvZGVVUklDb21wb25lbnQocGFpci5zbGljZSgwLCBwb3MpKV0gPVxuICAgICAgICBkZWNvZGVVUklDb21wb25lbnQocGFpci5zbGljZShwb3MgKyAxKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICByZXR1cm4gL1tcXC8rXWpzb25cXGIvLnRlc3QobWltZSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtaW1lIHR5cGUgZm9yIHRoZSBnaXZlbiBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiB0eXBlKHN0cil7XG4gIHJldHVybiBzdHIuc3BsaXQoLyAqOyAqLykuc2hpZnQoKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhlYWRlciBmaWVsZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcmFtcyhzdHIpe1xuICByZXR1cm4gc3RyLnNwbGl0KC8gKjsgKi8pLnJlZHVjZShmdW5jdGlvbihvYmosIHN0cil7XG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KC8gKj0gKi8pLFxuICAgICAgICBrZXkgPSBwYXJ0cy5zaGlmdCgpLFxuICAgICAgICB2YWwgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgaWYgKGtleSAmJiB2YWwpIG9ialtrZXldID0gdmFsO1xuICAgIHJldHVybiBvYmo7XG4gIH0sIHt9KTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVzcG9uc2VgIHdpdGggdGhlIGdpdmVuIGB4aHJgLlxuICpcbiAqICAtIHNldCBmbGFncyAoLm9rLCAuZXJyb3IsIGV0YylcbiAqICAtIHBhcnNlIGhlYWRlclxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICBBbGlhc2luZyBgc3VwZXJhZ2VudGAgYXMgYHJlcXVlc3RgIGlzIG5pY2U6XG4gKlxuICogICAgICByZXF1ZXN0ID0gc3VwZXJhZ2VudDtcbiAqXG4gKiAgV2UgY2FuIHVzZSB0aGUgcHJvbWlzZS1saWtlIEFQSSwgb3IgcGFzcyBjYWxsYmFja3M6XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnLycpLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICogICAgICByZXF1ZXN0LmdldCgnLycsIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIFNlbmRpbmcgZGF0YSBjYW4gYmUgY2hhaW5lZDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAuc2VuZCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5wb3N0KClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBPciBmdXJ0aGVyIHJlZHVjZWQgdG8gYSBzaW5nbGUgY2FsbCBmb3Igc2ltcGxlIGNhc2VzOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIEBwYXJhbSB7WE1MSFRUUFJlcXVlc3R9IHhoclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIFJlc3BvbnNlKHJlcSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5yZXEgPSByZXE7XG4gIHRoaXMueGhyID0gdGhpcy5yZXEueGhyO1xuICAvLyByZXNwb25zZVRleHQgaXMgYWNjZXNzaWJsZSBvbmx5IGlmIHJlc3BvbnNlVHlwZSBpcyAnJyBvciAndGV4dCcgYW5kIG9uIG9sZGVyIGJyb3dzZXJzXG4gIHRoaXMudGV4dCA9ICgodGhpcy5yZXEubWV0aG9kICE9J0hFQUQnICYmICh0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICcnIHx8IHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnKSkgfHwgdHlwZW9mIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgID8gdGhpcy54aHIucmVzcG9uc2VUZXh0XG4gICAgIDogbnVsbDtcbiAgdGhpcy5zdGF0dXNUZXh0ID0gdGhpcy5yZXEueGhyLnN0YXR1c1RleHQ7XG4gIHRoaXMuX3NldFN0YXR1c1Byb3BlcnRpZXModGhpcy54aHIuc3RhdHVzKTtcbiAgdGhpcy5oZWFkZXIgPSB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcih0aGlzLnhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gIC8vIGdldEFsbFJlc3BvbnNlSGVhZGVycyBzb21ldGltZXMgZmFsc2VseSByZXR1cm5zIFwiXCIgZm9yIENPUlMgcmVxdWVzdHMsIGJ1dFxuICAvLyBnZXRSZXNwb25zZUhlYWRlciBzdGlsbCB3b3Jrcy4gc28gd2UgZ2V0IGNvbnRlbnQtdHlwZSBldmVuIGlmIGdldHRpbmdcbiAgLy8gb3RoZXIgaGVhZGVycyBmYWlscy5cbiAgdGhpcy5oZWFkZXJbJ2NvbnRlbnQtdHlwZSddID0gdGhpcy54aHIuZ2V0UmVzcG9uc2VIZWFkZXIoJ2NvbnRlbnQtdHlwZScpO1xuICB0aGlzLl9zZXRIZWFkZXJQcm9wZXJ0aWVzKHRoaXMuaGVhZGVyKTtcbiAgdGhpcy5ib2R5ID0gdGhpcy5yZXEubWV0aG9kICE9ICdIRUFEJ1xuICAgID8gdGhpcy5fcGFyc2VCb2R5KHRoaXMudGV4dCA/IHRoaXMudGV4dCA6IHRoaXMueGhyLnJlc3BvbnNlKVxuICAgIDogbnVsbDtcbn1cblxuLyoqXG4gKiBHZXQgY2FzZS1pbnNlbnNpdGl2ZSBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgcmVsYXRlZCBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBgLnR5cGVgIHRoZSBjb250ZW50IHR5cGUgd2l0aG91dCBwYXJhbXNcbiAqXG4gKiBBIHJlc3BvbnNlIG9mIFwiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04XCJcbiAqIHdpbGwgcHJvdmlkZSB5b3Ugd2l0aCBhIGAudHlwZWAgb2YgXCJ0ZXh0L3BsYWluXCIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGhlYWRlclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9zZXRIZWFkZXJQcm9wZXJ0aWVzID0gZnVuY3Rpb24oaGVhZGVyKXtcbiAgLy8gY29udGVudC10eXBlXG4gIHZhciBjdCA9IHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSB8fCAnJztcbiAgdGhpcy50eXBlID0gdHlwZShjdCk7XG5cbiAgLy8gcGFyYW1zXG4gIHZhciBvYmogPSBwYXJhbXMoY3QpO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB0aGlzW2tleV0gPSBvYmpba2V5XTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGJvZHkgYHN0cmAuXG4gKlxuICogVXNlZCBmb3IgYXV0by1wYXJzaW5nIG9mIGJvZGllcy4gUGFyc2Vyc1xuICogYXJlIGRlZmluZWQgb24gdGhlIGBzdXBlcmFnZW50LnBhcnNlYCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuX3BhcnNlQm9keSA9IGZ1bmN0aW9uKHN0cil7XG4gIHZhciBwYXJzZSA9IHJlcXVlc3QucGFyc2VbdGhpcy50eXBlXTtcbiAgaWYgKCFwYXJzZSAmJiBpc0pTT04odGhpcy50eXBlKSkge1xuICAgIHBhcnNlID0gcmVxdWVzdC5wYXJzZVsnYXBwbGljYXRpb24vanNvbiddO1xuICB9XG4gIHJldHVybiBwYXJzZSAmJiBzdHIgJiYgKHN0ci5sZW5ndGggfHwgc3RyIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgID8gcGFyc2Uoc3RyKVxuICAgIDogbnVsbDtcbn07XG5cbi8qKlxuICogU2V0IGZsYWdzIHN1Y2ggYXMgYC5va2AgYmFzZWQgb24gYHN0YXR1c2AuXG4gKlxuICogRm9yIGV4YW1wbGUgYSAyeHggcmVzcG9uc2Ugd2lsbCBnaXZlIHlvdSBhIGAub2tgIG9mIF9fdHJ1ZV9fXG4gKiB3aGVyZWFzIDV4eCB3aWxsIGJlIF9fZmFsc2VfXyBhbmQgYC5lcnJvcmAgd2lsbCBiZSBfX3RydWVfXy4gVGhlXG4gKiBgLmNsaWVudEVycm9yYCBhbmQgYC5zZXJ2ZXJFcnJvcmAgYXJlIGFsc28gYXZhaWxhYmxlIHRvIGJlIG1vcmVcbiAqIHNwZWNpZmljLCBhbmQgYC5zdGF0dXNUeXBlYCBpcyB0aGUgY2xhc3Mgb2YgZXJyb3IgcmFuZ2luZyBmcm9tIDEuLjVcbiAqIHNvbWV0aW1lcyB1c2VmdWwgZm9yIG1hcHBpbmcgcmVzcG9uZCBjb2xvcnMgZXRjLlxuICpcbiAqIFwic3VnYXJcIiBwcm9wZXJ0aWVzIGFyZSBhbHNvIGRlZmluZWQgZm9yIGNvbW1vbiBjYXNlcy4gQ3VycmVudGx5IHByb3ZpZGluZzpcbiAqXG4gKiAgIC0gLm5vQ29udGVudFxuICogICAtIC5iYWRSZXF1ZXN0XG4gKiAgIC0gLnVuYXV0aG9yaXplZFxuICogICAtIC5ub3RBY2NlcHRhYmxlXG4gKiAgIC0gLm5vdEZvdW5kXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXR1c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9zZXRTdGF0dXNQcm9wZXJ0aWVzID0gZnVuY3Rpb24oc3RhdHVzKXtcbiAgLy8gaGFuZGxlIElFOSBidWc6IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTAwNDY5NzIvbXNpZS1yZXR1cm5zLXN0YXR1cy1jb2RlLW9mLTEyMjMtZm9yLWFqYXgtcmVxdWVzdFxuICBpZiAoc3RhdHVzID09PSAxMjIzKSB7XG4gICAgc3RhdHVzID0gMjA0O1xuICB9XG5cbiAgdmFyIHR5cGUgPSBzdGF0dXMgLyAxMDAgfCAwO1xuXG4gIC8vIHN0YXR1cyAvIGNsYXNzXG4gIHRoaXMuc3RhdHVzID0gdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzO1xuICB0aGlzLnN0YXR1c1R5cGUgPSB0eXBlO1xuXG4gIC8vIGJhc2ljc1xuICB0aGlzLmluZm8gPSAxID09IHR5cGU7XG4gIHRoaXMub2sgPSAyID09IHR5cGU7XG4gIHRoaXMuY2xpZW50RXJyb3IgPSA0ID09IHR5cGU7XG4gIHRoaXMuc2VydmVyRXJyb3IgPSA1ID09IHR5cGU7XG4gIHRoaXMuZXJyb3IgPSAoNCA9PSB0eXBlIHx8IDUgPT0gdHlwZSlcbiAgICA/IHRoaXMudG9FcnJvcigpXG4gICAgOiBmYWxzZTtcblxuICAvLyBzdWdhclxuICB0aGlzLmFjY2VwdGVkID0gMjAyID09IHN0YXR1cztcbiAgdGhpcy5ub0NvbnRlbnQgPSAyMDQgPT0gc3RhdHVzO1xuICB0aGlzLmJhZFJlcXVlc3QgPSA0MDAgPT0gc3RhdHVzO1xuICB0aGlzLnVuYXV0aG9yaXplZCA9IDQwMSA9PSBzdGF0dXM7XG4gIHRoaXMubm90QWNjZXB0YWJsZSA9IDQwNiA9PSBzdGF0dXM7XG4gIHRoaXMubm90Rm91bmQgPSA0MDQgPT0gc3RhdHVzO1xuICB0aGlzLmZvcmJpZGRlbiA9IDQwMyA9PSBzdGF0dXM7XG59O1xuXG4vKipcbiAqIFJldHVybiBhbiBgRXJyb3JgIHJlcHJlc2VudGF0aXZlIG9mIHRoaXMgcmVzcG9uc2UuXG4gKlxuICogQHJldHVybiB7RXJyb3J9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS50b0Vycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIHJlcSA9IHRoaXMucmVxO1xuICB2YXIgbWV0aG9kID0gcmVxLm1ldGhvZDtcbiAgdmFyIHVybCA9IHJlcS51cmw7XG5cbiAgdmFyIG1zZyA9ICdjYW5ub3QgJyArIG1ldGhvZCArICcgJyArIHVybCArICcgKCcgKyB0aGlzLnN0YXR1cyArICcpJztcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIuc3RhdHVzID0gdGhpcy5zdGF0dXM7XG4gIGVyci5tZXRob2QgPSBtZXRob2Q7XG4gIGVyci51cmwgPSB1cmw7XG5cbiAgcmV0dXJuIGVycjtcbn07XG5cbi8qKlxuICogRXhwb3NlIGBSZXNwb25zZWAuXG4gKi9cblxucmVxdWVzdC5SZXNwb25zZSA9IFJlc3BvbnNlO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlcXVlc3RgIHdpdGggdGhlIGdpdmVuIGBtZXRob2RgIGFuZCBgdXJsYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFJlcXVlc3QobWV0aG9kLCB1cmwpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9xdWVyeSA9IHRoaXMuX3F1ZXJ5IHx8IFtdO1xuICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgdGhpcy51cmwgPSB1cmw7XG4gIHRoaXMuaGVhZGVyID0ge307IC8vIHByZXNlcnZlcyBoZWFkZXIgbmFtZSBjYXNlXG4gIHRoaXMuX2hlYWRlciA9IHt9OyAvLyBjb2VyY2VzIGhlYWRlciBuYW1lcyB0byBsb3dlcmNhc2VcbiAgdGhpcy5vbignZW5kJywgZnVuY3Rpb24oKXtcbiAgICB2YXIgZXJyID0gbnVsbDtcbiAgICB2YXIgcmVzID0gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICByZXMgPSBuZXcgUmVzcG9uc2Uoc2VsZik7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBlcnIgPSBuZXcgRXJyb3IoJ1BhcnNlciBpcyB1bmFibGUgdG8gcGFyc2UgdGhlIHJlc3BvbnNlJyk7XG4gICAgICBlcnIucGFyc2UgPSB0cnVlO1xuICAgICAgZXJyLm9yaWdpbmFsID0gZTtcbiAgICAgIC8vIGlzc3VlICM2NzU6IHJldHVybiB0aGUgcmF3IHJlc3BvbnNlIGlmIHRoZSByZXNwb25zZSBwYXJzaW5nIGZhaWxzXG4gICAgICBlcnIucmF3UmVzcG9uc2UgPSBzZWxmLnhociAmJiBzZWxmLnhoci5yZXNwb25zZVRleHQgPyBzZWxmLnhoci5yZXNwb25zZVRleHQgOiBudWxsO1xuICAgICAgLy8gaXNzdWUgIzg3NjogcmV0dXJuIHRoZSBodHRwIHN0YXR1cyBjb2RlIGlmIHRoZSByZXNwb25zZSBwYXJzaW5nIGZhaWxzXG4gICAgICBlcnIuc3RhdHVzQ29kZSA9IHNlbGYueGhyICYmIHNlbGYueGhyLnN0YXR1cyA/IHNlbGYueGhyLnN0YXR1cyA6IG51bGw7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIpO1xuICAgIH1cblxuICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXMpO1xuXG4gICAgdmFyIG5ld19lcnI7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChyZXMuc3RhdHVzIDwgMjAwIHx8IHJlcy5zdGF0dXMgPj0gMzAwKSB7XG4gICAgICAgIG5ld19lcnIgPSBuZXcgRXJyb3IocmVzLnN0YXR1c1RleHQgfHwgJ1Vuc3VjY2Vzc2Z1bCBIVFRQIHJlc3BvbnNlJyk7XG4gICAgICAgIG5ld19lcnIub3JpZ2luYWwgPSBlcnI7XG4gICAgICAgIG5ld19lcnIucmVzcG9uc2UgPSByZXM7XG4gICAgICAgIG5ld19lcnIuc3RhdHVzID0gcmVzLnN0YXR1cztcbiAgICAgIH1cbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIG5ld19lcnIgPSBlOyAvLyAjOTg1IHRvdWNoaW5nIHJlcyBtYXkgY2F1c2UgSU5WQUxJRF9TVEFURV9FUlIgb24gb2xkIEFuZHJvaWRcbiAgICB9XG5cbiAgICAvLyAjMTAwMCBkb24ndCBjYXRjaCBlcnJvcnMgZnJvbSB0aGUgY2FsbGJhY2sgdG8gYXZvaWQgZG91YmxlIGNhbGxpbmcgaXRcbiAgICBpZiAobmV3X2Vycikge1xuICAgICAgc2VsZi5jYWxsYmFjayhuZXdfZXJyLCByZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLmNhbGxiYWNrKG51bGwsIHJlcyk7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBNaXhpbiBgRW1pdHRlcmAgYW5kIGByZXF1ZXN0QmFzZWAuXG4gKi9cblxuRW1pdHRlcihSZXF1ZXN0LnByb3RvdHlwZSk7XG5mb3IgKHZhciBrZXkgaW4gcmVxdWVzdEJhc2UpIHtcbiAgUmVxdWVzdC5wcm90b3R5cGVba2V5XSA9IHJlcXVlc3RCYXNlW2tleV07XG59XG5cbi8qKlxuICogU2V0IENvbnRlbnQtVHlwZSB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy54bWwgPSAnYXBwbGljYXRpb24veG1sJztcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ3htbCcpXG4gKiAgICAgICAgLnNlbmQoeG1sc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgnYXBwbGljYXRpb24veG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50eXBlID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdDb250ZW50LVR5cGUnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHJlc3BvbnNlVHlwZSB0byBgdmFsYC4gUHJlc2VudGx5IHZhbGlkIHJlc3BvbnNlVHlwZXMgYXJlICdibG9iJyBhbmRcbiAqICdhcnJheWJ1ZmZlcicuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAucmVzcG9uc2VUeXBlKCdibG9iJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUucmVzcG9uc2VUeXBlID0gZnVuY3Rpb24odmFsKXtcbiAgdGhpcy5fcmVzcG9uc2VUeXBlID0gdmFsO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEFjY2VwdCB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy5qc29uID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXB0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdBY2NlcHQnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEF1dGhvcml6YXRpb24gZmllbGQgdmFsdWUgd2l0aCBgdXNlcmAgYW5kIGBwYXNzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXNlclxuICogQHBhcmFtIHtTdHJpbmd9IHBhc3NcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHdpdGggJ3R5cGUnIHByb3BlcnR5ICdhdXRvJyBvciAnYmFzaWMnIChkZWZhdWx0ICdiYXNpYycpXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYXV0aCA9IGZ1bmN0aW9uKHVzZXIsIHBhc3MsIG9wdGlvbnMpe1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgdHlwZTogJ2Jhc2ljJ1xuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnYmFzaWMnOlxuICAgICAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICAgICAgdGhpcy5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmFzaWMgJyArIHN0cik7XG4gICAgYnJlYWs7XG5cbiAgICBjYXNlICdhdXRvJzpcbiAgICAgIHRoaXMudXNlcm5hbWUgPSB1c2VyO1xuICAgICAgdGhpcy5wYXNzd29yZCA9IHBhc3M7XG4gICAgYnJlYWs7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaCgnY29udGVudCcsIG5ldyBCbG9iKFsnPGEgaWQ9XCJhXCI+PGIgaWQ9XCJiXCI+aGV5ITwvYj48L2E+J10sIHsgdHlwZTogXCJ0ZXh0L2h0bWxcIn0pKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHBhcmFtIHtCbG9ifEZpbGV9IGZpbGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlbmFtZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF0dGFjaCA9IGZ1bmN0aW9uKGZpZWxkLCBmaWxlLCBmaWxlbmFtZSl7XG4gIHRoaXMuX2dldEZvcm1EYXRhKCkuYXBwZW5kKGZpZWxkLCBmaWxlLCBmaWxlbmFtZSB8fCBmaWxlLm5hbWUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLl9nZXRGb3JtRGF0YSA9IGZ1bmN0aW9uKCl7XG4gIGlmICghdGhpcy5fZm9ybURhdGEpIHtcbiAgICB0aGlzLl9mb3JtRGF0YSA9IG5ldyByb290LkZvcm1EYXRhKCk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2Zvcm1EYXRhO1xufTtcblxuLyoqXG4gKiBJbnZva2UgdGhlIGNhbGxiYWNrIHdpdGggYGVycmAgYW5kIGByZXNgXG4gKiBhbmQgaGFuZGxlIGFyaXR5IGNoZWNrLlxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVyclxuICogQHBhcmFtIHtSZXNwb25zZX0gcmVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jYWxsYmFjayA9IGZ1bmN0aW9uKGVyciwgcmVzKXtcbiAgdmFyIGZuID0gdGhpcy5fY2FsbGJhY2s7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIGZuKGVyciwgcmVzKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggeC1kb21haW4gZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY3Jvc3NEb21haW5FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIGJlZW4gdGVybWluYXRlZFxcblBvc3NpYmxlIGNhdXNlczogdGhlIG5ldHdvcmsgaXMgb2ZmbGluZSwgT3JpZ2luIGlzIG5vdCBhbGxvd2VkIGJ5IEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbiwgdGhlIHBhZ2UgaXMgYmVpbmcgdW5sb2FkZWQsIGV0Yy4nKTtcbiAgZXJyLmNyb3NzRG9tYWluID0gdHJ1ZTtcblxuICBlcnIuc3RhdHVzID0gdGhpcy5zdGF0dXM7XG4gIGVyci5tZXRob2QgPSB0aGlzLm1ldGhvZDtcbiAgZXJyLnVybCA9IHRoaXMudXJsO1xuXG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggdGltZW91dCBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fdGltZW91dEVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZXJyID0gbmV3IEVycm9yKCd0aW1lb3V0IG9mICcgKyB0aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyk7XG4gIGVyci50aW1lb3V0ID0gdGltZW91dDtcbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBDb21wb3NlIHF1ZXJ5c3RyaW5nIHRvIGFwcGVuZCB0byByZXEudXJsXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX2FwcGVuZFF1ZXJ5U3RyaW5nID0gZnVuY3Rpb24oKXtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICBpZiAocXVlcnkpIHtcbiAgICB0aGlzLnVybCArPSB+dGhpcy51cmwuaW5kZXhPZignPycpXG4gICAgICA/ICcmJyArIHF1ZXJ5XG4gICAgICA6ICc/JyArIHF1ZXJ5O1xuICB9XG59O1xuXG4vKipcbiAqIEluaXRpYXRlIHJlcXVlc3QsIGludm9raW5nIGNhbGxiYWNrIGBmbihyZXMpYFxuICogd2l0aCBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihmbil7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHhociA9IHRoaXMueGhyID0gcmVxdWVzdC5nZXRYSFIoKTtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZGF0YSA9IHRoaXMuX2Zvcm1EYXRhIHx8IHRoaXMuX2RhdGE7XG5cbiAgLy8gc3RvcmUgY2FsbGJhY2tcbiAgdGhpcy5fY2FsbGJhY2sgPSBmbiB8fCBub29wO1xuXG4gIC8vIHN0YXRlIGNoYW5nZVxuICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKXtcbiAgICBpZiAoNCAhPSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuXG4gICAgLy8gSW4gSUU5LCByZWFkcyB0byBhbnkgcHJvcGVydHkgKGUuZy4gc3RhdHVzKSBvZmYgb2YgYW4gYWJvcnRlZCBYSFIgd2lsbFxuICAgIC8vIHJlc3VsdCBpbiB0aGUgZXJyb3IgXCJDb3VsZCBub3QgY29tcGxldGUgdGhlIG9wZXJhdGlvbiBkdWUgdG8gZXJyb3IgYzAwYzAyM2ZcIlxuICAgIHZhciBzdGF0dXM7XG4gICAgdHJ5IHsgc3RhdHVzID0geGhyLnN0YXR1cyB9IGNhdGNoKGUpIHsgc3RhdHVzID0gMDsgfVxuXG4gICAgaWYgKDAgPT0gc3RhdHVzKSB7XG4gICAgICBpZiAoc2VsZi50aW1lZG91dCkgcmV0dXJuIHNlbGYuX3RpbWVvdXRFcnJvcigpO1xuICAgICAgaWYgKHNlbGYuX2Fib3J0ZWQpIHJldHVybjtcbiAgICAgIHJldHVybiBzZWxmLmNyb3NzRG9tYWluRXJyb3IoKTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdlbmQnKTtcbiAgfTtcblxuICAvLyBwcm9ncmVzc1xuICB2YXIgaGFuZGxlUHJvZ3Jlc3MgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS50b3RhbCA+IDApIHtcbiAgICAgIGUucGVyY2VudCA9IGUubG9hZGVkIC8gZS50b3RhbCAqIDEwMDtcbiAgICB9XG4gICAgZS5kaXJlY3Rpb24gPSAnZG93bmxvYWQnO1xuICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCBlKTtcbiAgfTtcbiAgaWYgKHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgfVxuICB0cnkge1xuICAgIGlmICh4aHIudXBsb2FkICYmIHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge1xuICAgIC8vIEFjY2Vzc2luZyB4aHIudXBsb2FkIGZhaWxzIGluIElFIGZyb20gYSB3ZWIgd29ya2VyLCBzbyBqdXN0IHByZXRlbmQgaXQgZG9lc24ndCBleGlzdC5cbiAgICAvLyBSZXBvcnRlZCBoZXJlOlxuICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODM3MjQ1L3htbGh0dHByZXF1ZXN0LXVwbG9hZC10aHJvd3MtaW52YWxpZC1hcmd1bWVudC13aGVuLXVzZWQtZnJvbS13ZWItd29ya2VyLWNvbnRleHRcbiAgfVxuXG4gIC8vIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgJiYgIXRoaXMuX3RpbWVyKSB7XG4gICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLnRpbWVkb3V0ID0gdHJ1ZTtcbiAgICAgIHNlbGYuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIHF1ZXJ5c3RyaW5nXG4gIHRoaXMuX2FwcGVuZFF1ZXJ5U3RyaW5nKCk7XG5cbiAgLy8gaW5pdGlhdGUgcmVxdWVzdFxuICBpZiAodGhpcy51c2VybmFtZSAmJiB0aGlzLnBhc3N3b3JkKSB7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJsLCB0cnVlLCB0aGlzLnVzZXJuYW1lLCB0aGlzLnBhc3N3b3JkKTtcbiAgfSBlbHNlIHtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHRydWUpO1xuICB9XG5cbiAgLy8gQ09SU1xuICBpZiAodGhpcy5fd2l0aENyZWRlbnRpYWxzKSB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblxuICAvLyBib2R5XG4gIGlmICgnR0VUJyAhPSB0aGlzLm1ldGhvZCAmJiAnSEVBRCcgIT0gdGhpcy5tZXRob2QgJiYgJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgJiYgIXRoaXMuX2lzSG9zdChkYXRhKSkge1xuICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgdmFyIHNlcmlhbGl6ZSA9IHRoaXMuX3NlcmlhbGl6ZXIgfHwgcmVxdWVzdC5zZXJpYWxpemVbY29udGVudFR5cGUgPyBjb250ZW50VHlwZS5zcGxpdCgnOycpWzBdIDogJyddO1xuICAgIGlmICghc2VyaWFsaXplICYmIGlzSlNPTihjb250ZW50VHlwZSkpIHNlcmlhbGl6ZSA9IHJlcXVlc3Quc2VyaWFsaXplWydhcHBsaWNhdGlvbi9qc29uJ107XG4gICAgaWYgKHNlcmlhbGl6ZSkgZGF0YSA9IHNlcmlhbGl6ZShkYXRhKTtcbiAgfVxuXG4gIC8vIHNldCBoZWFkZXIgZmllbGRzXG4gIGZvciAodmFyIGZpZWxkIGluIHRoaXMuaGVhZGVyKSB7XG4gICAgaWYgKG51bGwgPT0gdGhpcy5oZWFkZXJbZmllbGRdKSBjb250aW51ZTtcbiAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihmaWVsZCwgdGhpcy5oZWFkZXJbZmllbGRdKTtcbiAgfVxuXG4gIGlmICh0aGlzLl9yZXNwb25zZVR5cGUpIHtcbiAgICB4aHIucmVzcG9uc2VUeXBlID0gdGhpcy5fcmVzcG9uc2VUeXBlO1xuICB9XG5cbiAgLy8gc2VuZCBzdHVmZlxuICB0aGlzLmVtaXQoJ3JlcXVlc3QnLCB0aGlzKTtcblxuICAvLyBJRTExIHhoci5zZW5kKHVuZGVmaW5lZCkgc2VuZHMgJ3VuZGVmaW5lZCcgc3RyaW5nIGFzIFBPU1QgcGF5bG9hZCAoaW5zdGVhZCBvZiBub3RoaW5nKVxuICAvLyBXZSBuZWVkIG51bGwgaGVyZSBpZiBkYXRhIGlzIHVuZGVmaW5lZFxuICB4aHIuc2VuZCh0eXBlb2YgZGF0YSAhPT0gJ3VuZGVmaW5lZCcgPyBkYXRhIDogbnVsbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIEV4cG9zZSBgUmVxdWVzdGAuXG4gKi9cblxucmVxdWVzdC5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBHRVQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gW2RhdGFdIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gW2RhdGFdIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmhlYWQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0hFQUQnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBPUFRJT05TIHF1ZXJ5IHRvIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5vcHRpb25zID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdPUFRJT05TJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogREVMRVRFIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlbCh1cmwsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0RFTEVURScsIHVybCk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG5yZXF1ZXN0WydkZWwnXSA9IGRlbDtcbnJlcXVlc3RbJ2RlbGV0ZSddID0gZGVsO1xuXG4vKipcbiAqIFBBVENIIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gW2RhdGFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBhdGNoID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdQQVRDSCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBPU1QgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfSBbZGF0YV1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucG9zdCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUE9TVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBVVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wdXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BVVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuIiwiLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICByZXR1cm4gbnVsbCAhPT0gb2JqICYmICdvYmplY3QnID09PSB0eXBlb2Ygb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuIiwiLyoqXG4gKiBNb2R1bGUgb2YgbWl4ZWQtaW4gZnVuY3Rpb25zIHNoYXJlZCBiZXR3ZWVuIG5vZGUgYW5kIGNsaWVudCBjb2RlXG4gKi9cbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXMtb2JqZWN0Jyk7XG5cbi8qKlxuICogQ2xlYXIgcHJldmlvdXMgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbiBfY2xlYXJUaW1lb3V0KCl7XG4gIHRoaXMuX3RpbWVvdXQgPSAwO1xuICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgZGVmYXVsdCByZXNwb25zZSBib2R5IHBhcnNlclxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgdG8gY29udmVydCBpbmNvbWluZyBkYXRhIGludG8gcmVxdWVzdC5ib2R5XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBPdmVycmlkZSBkZWZhdWx0IHJlcXVlc3QgYm9keSBzZXJpYWxpemVyXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB0byBjb252ZXJ0IGRhdGEgc2V0IHZpYSAuc2VuZCBvciAuYXR0YWNoIGludG8gcGF5bG9hZCB0byBzZW5kXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5zZXJpYWxpemUgPSBmdW5jdGlvbiBzZXJpYWxpemUoZm4pe1xuICB0aGlzLl9zZXJpYWxpemVyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGltZW91dCB0byBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudGltZW91dCA9IGZ1bmN0aW9uIHRpbWVvdXQobXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBQcm9taXNlIHN1cHBvcnRcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZXNvbHZlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKi9cblxuZXhwb3J0cy50aGVuID0gZnVuY3Rpb24gdGhlbihyZXNvbHZlLCByZWplY3QpIHtcbiAgaWYgKCF0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKGlubmVyUmVzb2x2ZSwgaW5uZXJSZWplY3Qpe1xuICAgICAgc2VsZi5lbmQoZnVuY3Rpb24oZXJyLCByZXMpe1xuICAgICAgICBpZiAoZXJyKSBpbm5lclJlamVjdChlcnIpOyBlbHNlIGlubmVyUmVzb2x2ZShyZXMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2Z1bGxmaWxsZWRQcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbn1cblxuLyoqXG4gKiBBbGxvdyBmb3IgZXh0ZW5zaW9uXG4gKi9cblxuZXhwb3J0cy51c2UgPSBmdW5jdGlvbiB1c2UoZm4pIHtcbiAgZm4odGhpcyk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogR2V0IHJlcXVlc3QgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmdldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgcmV0dXJuIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgaGVhZGVyIGBmaWVsZGAgdmFsdWUuXG4gKiBUaGlzIGlzIGEgZGVwcmVjYXRlZCBpbnRlcm5hbCBBUEkuIFVzZSBgLmdldChmaWVsZClgIGluc3RlYWQuXG4gKlxuICogKGdldEhlYWRlciBpcyBubyBsb25nZXIgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBzdXBlcmFnZW50IGNvZGUgYmFzZSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICogQGRlcHJlY2F0ZWRcbiAqL1xuXG5leHBvcnRzLmdldEhlYWRlciA9IGV4cG9ydHMuZ2V0O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgYGZpZWxkYCB0byBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLnNldCgnWC1BUEktS2V5JywgJ2Zvb2JhcicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAuc2V0KHsgQWNjZXB0OiAnYXBwbGljYXRpb24vanNvbicsICdYLUFQSS1LZXknOiAnZm9vYmFyJyB9KVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZmllbGRcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnNldCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWwpe1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGZpZWxkKSB7XG4gICAgICB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC51bnNldCgnVXNlci1BZ2VudCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKi9cbmV4cG9ydHMudW5zZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIGRlbGV0ZSB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG4gIGRlbGV0ZSB0aGlzLmhlYWRlcltmaWVsZF07XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJcbiAqIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd8QmxvYnxGaWxlfEJ1ZmZlcnxmcy5SZWFkU3RyZWFtfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuZXhwb3J0cy5maWVsZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbCkge1xuICB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChuYW1lLCB2YWwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWJvcnQgdGhlIHJlcXVlc3QsIGFuZCBjbGVhciBwb3RlbnRpYWwgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZXhwb3J0cy5hYm9ydCA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0aGlzLl9hYm9ydGVkKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdGhpcy5fYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMueGhyICYmIHRoaXMueGhyLmFib3J0KCk7IC8vIGJyb3dzZXJcbiAgdGhpcy5yZXEgJiYgdGhpcy5yZXEuYWJvcnQoKTsgLy8gbm9kZVxuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICB0aGlzLmVtaXQoJ2Fib3J0Jyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbmFibGUgdHJhbnNtaXNzaW9uIG9mIGNvb2tpZXMgd2l0aCB4LWRvbWFpbiByZXF1ZXN0cy5cbiAqXG4gKiBOb3RlIHRoYXQgZm9yIHRoaXMgdG8gd29yayB0aGUgb3JpZ2luIG11c3Qgbm90IGJlXG4gKiB1c2luZyBcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiIHdpdGggYSB3aWxkY2FyZCxcbiAqIGFuZCBhbHNvIG11c3Qgc2V0IFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHNcIlxuICogdG8gXCJ0cnVlXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLndpdGhDcmVkZW50aWFscyA9IGZ1bmN0aW9uKCl7XG4gIC8vIFRoaXMgaXMgYnJvd3Nlci1vbmx5IGZ1bmN0aW9uYWxpdHkuIE5vZGUgc2lkZSBpcyBuby1vcC5cbiAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgbWF4IHJlZGlyZWN0cyB0byBgbmAuIERvZXMgbm90aW5nIGluIGJyb3dzZXIgWEhSIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5yZWRpcmVjdHMgPSBmdW5jdGlvbihuKXtcbiAgdGhpcy5fbWF4UmVkaXJlY3RzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENvbnZlcnQgdG8gYSBwbGFpbiBqYXZhc2NyaXB0IG9iamVjdCAobm90IEpTT04gc3RyaW5nKSBvZiBzY2FsYXIgcHJvcGVydGllcy5cbiAqIE5vdGUgYXMgdGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gcmV0dXJuIGEgdXNlZnVsIG5vbi10aGlzIHZhbHVlLFxuICogaXQgY2Fubm90IGJlIGNoYWluZWQuXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBkZXNjcmliaW5nIG1ldGhvZCwgdXJsLCBhbmQgZGF0YSBvZiB0aGlzIHJlcXVlc3RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50b0pTT04gPSBmdW5jdGlvbigpe1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogdGhpcy5tZXRob2QsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBkYXRhOiB0aGlzLl9kYXRhLFxuICAgIGhlYWRlcnM6IHRoaXMuX2hlYWRlclxuICB9O1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLl9pc0hvc3QgPSBmdW5jdGlvbiBfaXNIb3N0KG9iaikge1xuICB2YXIgc3RyID0ge30udG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIHN3aXRjaCAoc3RyKSB7XG4gICAgY2FzZSAnW29iamVjdCBGaWxlXSc6XG4gICAgY2FzZSAnW29iamVjdCBCbG9iXSc6XG4gICAgY2FzZSAnW29iamVjdCBGb3JtRGF0YV0nOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbmQgYGRhdGFgIGFzIHRoZSByZXF1ZXN0IGJvZHksIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gbWFudWFsIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnanNvbicpXG4gKiAgICAgICAgIC5zZW5kKCd7XCJuYW1lXCI6XCJ0alwifScpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoJ25hbWU9dG9iaScpXG4gKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZGF0YVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuc2VuZCA9IGZ1bmN0aW9uKGRhdGEpe1xuICB2YXIgb2JqID0gaXNPYmplY3QoZGF0YSk7XG4gIHZhciB0eXBlID0gdGhpcy5faGVhZGVyWydjb250ZW50LXR5cGUnXTtcblxuICAvLyBtZXJnZVxuICBpZiAob2JqICYmIGlzT2JqZWN0KHRoaXMuX2RhdGEpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgIHRoaXMuX2RhdGFba2V5XSA9IGRhdGFba2V5XTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIGRhdGEpIHtcbiAgICAvLyBkZWZhdWx0IHRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICAgIGlmICghdHlwZSkgdGhpcy50eXBlKCdmb3JtJyk7XG4gICAgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgaWYgKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnID09IHR5cGUpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB0aGlzLl9kYXRhXG4gICAgICAgID8gdGhpcy5fZGF0YSArICcmJyArIGRhdGFcbiAgICAgICAgOiBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRhID0gKHRoaXMuX2RhdGEgfHwgJycpICsgZGF0YTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gIH1cblxuICBpZiAoIW9iaiB8fCB0aGlzLl9pc0hvc3QoZGF0YSkpIHJldHVybiB0aGlzO1xuXG4gIC8vIGRlZmF1bHQgdG8ganNvblxuICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnanNvbicpO1xuICByZXR1cm4gdGhpcztcbn07XG4iLCIvLyBUaGUgbm9kZSBhbmQgYnJvd3NlciBtb2R1bGVzIGV4cG9zZSB2ZXJzaW9ucyBvZiB0aGlzIHdpdGggdGhlXG4vLyBhcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBib3VuZCBhcyBmaXJzdCBhcmd1bWVudFxuLyoqXG4gKiBJc3N1ZSBhIHJlcXVlc3Q6XG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgcmVxdWVzdCgnR0VUJywgJy91c2VycycpLmVuZChjYWxsYmFjaylcbiAqICAgIHJlcXVlc3QoJy91c2VycycpLmVuZChjYWxsYmFjaylcbiAqICAgIHJlcXVlc3QoJy91c2VycycsIGNhbGxiYWNrKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSB1cmwgb3IgY2FsbGJhY2tcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHJlcXVlc3QoUmVxdWVzdENvbnN0cnVjdG9yLCBtZXRob2QsIHVybCkge1xuICAvLyBjYWxsYmFja1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXJsKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0Q29uc3RydWN0b3IoJ0dFVCcsIG1ldGhvZCkuZW5kKHVybCk7XG4gIH1cblxuICAvLyB1cmwgZmlyc3RcbiAgaWYgKDIgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKCdHRVQnLCBtZXRob2QpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0Q29uc3RydWN0b3IobWV0aG9kLCB1cmwpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG4iLCJcclxuLyoqXHJcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXHJcbiAqL1xyXG5cclxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xyXG59XHJcblxyXG4vKipcclxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXHJcbiAqXHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcclxuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBNaXhpbiB0aGUgZW1pdHRlciBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXHJcbiAqIEByZXR1cm4ge09iamVjdH1cclxuICogQGFwaSBwcml2YXRlXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XHJcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XHJcbiAgICBvYmpba2V5XSA9IEVtaXR0ZXIucHJvdG90eXBlW2tleV07XHJcbiAgfVxyXG4gIHJldHVybiBvYmo7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICAodGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW10pXHJcbiAgICAucHVzaChmbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAqIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIGZ1bmN0aW9uIG9uKCkge1xyXG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcclxuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgfVxyXG5cclxuICBvbi5mbiA9IGZuO1xyXG4gIHRoaXMub24oZXZlbnQsIG9uKTtcclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxyXG4gKiByZWdpc3RlcmVkIGNhbGxiYWNrcy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcblxyXG4gIC8vIGFsbFxyXG4gIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyBzcGVjaWZpYyBldmVudFxyXG4gIHZhciBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxyXG4gIHZhciBjYjtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xyXG4gICAgY2IgPSBjYWxsYmFja3NbaV07XHJcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xyXG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge01peGVkfSAuLi5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxyXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG5cclxuICBpZiAoY2FsbGJhY2tzKSB7XHJcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XHJcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY2FsbGJhY2tzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhcnJheSBvZiBjYWxsYmFja3MgZm9yIGBldmVudGAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtBcnJheX1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG4gIHJldHVybiB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHJldHVybiAhISB0aGlzLmxpc3RlbmVycyhldmVudCkubGVuZ3RoO1xyXG59O1xyXG4iLCIgLypnbG9iYWwgSlNPTkVkaXRvciovXG4ndXNlIHN0cmljdCc7XG5cbndpbmRvdy5Td2FnZ2VyVWkgPSBCYWNrYm9uZS5Sb3V0ZXIuZXh0ZW5kKHtcblxuICBkb21faWQ6ICdzd2FnZ2VyX3VpJyxcblxuICAvLyBBdHRyaWJ1dGVzXG4gIG9wdGlvbnM6IG51bGwsXG4gIGFwaTogbnVsbCxcbiAgaGVhZGVyVmlldzogbnVsbCxcbiAgbWFpblZpZXc6IG51bGwsXG5cbiAgLy8gU3dhZ2dlclVpIGFjY2VwdHMgYWxsIHRoZSBzYW1lIG9wdGlvbnMgYXMgU3dhZ2dlckFwaVxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAob3B0aW9ucy5kZWZhdWx0TW9kZWxSZW5kZXJpbmcgIT09ICdtb2RlbCcpIHtcbiAgICAgIG9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nID0gJ3NjaGVtYSc7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQpIHtcbiAgICAgIG9wdGlvbnMuaGlnaGxpZ2h0U2l6ZVRocmVzaG9sZCA9IDEwMDAwMDtcbiAgICB9XG5cbiAgICAvLyBBbGxvdyBkb21faWQgdG8gYmUgb3ZlcnJpZGRlblxuICAgIGlmIChvcHRpb25zLmRvbV9pZCkge1xuICAgICAgdGhpcy5kb21faWQgPSBvcHRpb25zLmRvbV9pZDtcbiAgICAgIGRlbGV0ZSBvcHRpb25zLmRvbV9pZDtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyl7XG4gICAgICBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBbXG4gICAgICAgICdnZXQnLFxuICAgICAgICAncHV0JyxcbiAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAnZGVsZXRlJyxcbiAgICAgICAgJ2hlYWQnLFxuICAgICAgICAnb3B0aW9ucycsXG4gICAgICAgICdwYXRjaCdcbiAgICAgIF07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLm9hdXRoMlJlZGlyZWN0VXJsID09PSAnc3RyaW5nJykge1xuICAgICAgd2luZG93Lm9BdXRoUmVkaXJlY3RVcmwgPSBvcHRpb25zLm9hdXRoMlJlZGlyZWN0VXJsO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhbiBlbXB0eSBkaXYgd2hpY2ggY29udGFpbnMgdGhlIGRvbV9pZFxuICAgIGlmICghICQoJyMnICsgdGhpcy5kb21faWQpLmxlbmd0aCl7XG4gICAgICAkKCdib2R5JykuYXBwZW5kKCc8ZGl2IGlkPVwiJyArIHRoaXMuZG9tX2lkICsgJ1wiPjwvZGl2PicpIDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgLy8gc2V0IG1hcmtlZCBvcHRpb25zXG4gICAgbWFya2VkLnNldE9wdGlvbnMoe2dmbTogdHJ1ZX0pO1xuXG4gICAgLy8gU2V0IHRoZSBjYWxsYmFja3NcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgdGhpcy5vcHRpb25zLnN1Y2Nlc3MgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoYXQucmVuZGVyKCk7IH07XG4gICAgdGhpcy5vcHRpb25zLnByb2dyZXNzID0gZnVuY3Rpb24oZCkgeyByZXR1cm4gdGhhdC5zaG93TWVzc2FnZShkKTsgfTtcbiAgICB0aGlzLm9wdGlvbnMuZmFpbHVyZSA9IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRoYXQub25Mb2FkRmFpbHVyZShkKTsgfTtcblxuICAgIC8vIENyZWF0ZSB2aWV3IHRvIGhhbmRsZSB0aGUgaGVhZGVyIGlucHV0c1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuSGVhZGVyVmlldyh7ZWw6ICQoJyNoZWFkZXInKX0pO1xuXG4gICAgLy8gRXZlbnQgaGFuZGxlciBmb3Igd2hlbiB0aGUgYmFzZVVybC9hcGlLZXkgaXMgZW50ZXJlZCBieSB1c2VyXG4gICAgdGhpcy5oZWFkZXJWaWV3Lm9uKCd1cGRhdGUtc3dhZ2dlci11aScsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiB0aGF0LnVwZGF0ZVN3YWdnZXJVaShkYXRhKTtcbiAgICB9KTtcblxuICAgIC8vIEpTb24gRWRpdG9yIGN1c3RvbSB0aGVtaW5nXG4gICAgIEpTT05FZGl0b3IuZGVmYXVsdHMuaWNvbmxpYnMuc3dhZ2dlciA9IEpTT05FZGl0b3IuQWJzdHJhY3RJY29uTGliLmV4dGVuZCh7XG4gICAgICBtYXBwaW5nOiB7XG4gICAgICAgIGNvbGxhcHNlOiAnY29sbGFwc2UnLFxuICAgICAgICBleHBhbmQ6ICdleHBhbmQnXG4gICAgICAgIH0sXG4gICAgICBpY29uX3ByZWZpeDogJ3N3YWdnZXItJ1xuICAgICAgfSk7XG5cbiAgfSxcblxuICAvLyBTZXQgYW4gb3B0aW9uIGFmdGVyIGluaXRpYWxpemluZ1xuICBzZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbiwgdmFsdWUpIHtcbiAgICB0aGlzLm9wdGlvbnNbb3B0aW9uXSA9IHZhbHVlO1xuICB9LFxuXG4gIC8vIEdldCB0aGUgdmFsdWUgb2YgYSBwcmV2aW91c2x5IHNldCBvcHRpb25cbiAgZ2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zW29wdGlvbl07XG4gIH0sXG5cbiAgLy8gRXZlbnQgaGFuZGxlciBmb3Igd2hlbiB1cmwva2V5IGlzIHJlY2VpdmVkIGZyb20gdXNlclxuICB1cGRhdGVTd2FnZ2VyVWk6IGZ1bmN0aW9uKGRhdGEpe1xuICAgIHRoaXMub3B0aW9ucy51cmwgPSBkYXRhLnVybDtcbiAgICB0aGlzLmxvYWQoKTtcbiAgfSxcblxuICAvLyBDcmVhdGUgYW4gYXBpIGFuZCByZW5kZXJcbiAgbG9hZDogZnVuY3Rpb24oKXtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBBUEkgb2JqZWN0XG4gICAgaWYgKHRoaXMubWFpblZpZXcpIHtcbiAgICAgIHRoaXMubWFpblZpZXcuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdXRoVmlldykge1xuICAgICAgdGhpcy5hdXRoVmlldy5yZW1vdmUoKTtcbiAgICB9XG4gICAgdmFyIHVybCA9IHRoaXMub3B0aW9ucy51cmw7XG4gICAgaWYgKHVybCAmJiB1cmwuaW5kZXhPZignaHR0cCcpICE9PSAwKSB7XG4gICAgICB1cmwgPSB0aGlzLmJ1aWxkVXJsKHdpbmRvdy5sb2NhdGlvbi5ocmVmLnRvU3RyaW5nKCksIHVybCk7XG4gICAgfVxuICAgIGlmKHRoaXMuYXBpKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuYXV0aG9yaXphdGlvbnMgPSB0aGlzLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hdXRoejtcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zLnVybCA9IHVybDtcbiAgICB0aGlzLmhlYWRlclZpZXcudXBkYXRlKHVybCk7XG5cbiAgICB0aGlzLmFwaSA9IG5ldyBTd2FnZ2VyQ2xpZW50KHRoaXMub3B0aW9ucyk7XG4gIH0sXG5cbiAgLy8gY29sbGFwc2UgYWxsIHNlY3Rpb25zXG4gIGNvbGxhcHNlQWxsOiBmdW5jdGlvbigpe1xuICAgIERvY3MuY29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gbGlzdCBvcGVyYXRpb25zIGZvciBhbGwgc2VjdGlvbnNcbiAgbGlzdEFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmNvbGxhcHNlT3BlcmF0aW9uc0ZvclJlc291cmNlKCcnKTtcbiAgfSxcblxuICAvLyBleHBhbmQgb3BlcmF0aW9ucyBmb3IgYWxsIHNlY3Rpb25zXG4gIGV4cGFuZEFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmV4cGFuZE9wZXJhdGlvbnNGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gVGhpcyBpcyBib3VuZCB0byBzdWNjZXNzIGhhbmRsZXIgZm9yIFN3YWdnZXJBcGlcbiAgLy8gIHNvIGl0IGdldHMgY2FsbGVkIHdoZW4gU3dhZ2dlckFwaSBjb21wbGV0ZXMgbG9hZGluZ1xuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIGF1dGhzTW9kZWw7XG4gICAgdGhpcy5zaG93TWVzc2FnZSgnRmluaXNoZWQgTG9hZGluZyBSZXNvdXJjZSBJbmZvcm1hdGlvbi4gUmVuZGVyaW5nIFN3YWdnZXIgVUkuLi4nKTtcbiAgICB0aGlzLm1haW5WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5NYWluVmlldyh7XG4gICAgICBtb2RlbDogdGhpcy5hcGksXG4gICAgICBlbDogJCgnIycgKyB0aGlzLmRvbV9pZCksXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgcm91dGVyOiB0aGlzXG4gICAgfSkucmVuZGVyKCk7XG4gICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcGkuc2VjdXJpdHlEZWZpbml0aW9ucykpe1xuICAgICAgYXV0aHNNb2RlbCA9IF8ubWFwKHRoaXMuYXBpLnNlY3VyaXR5RGVmaW5pdGlvbnMsIGZ1bmN0aW9uIChhdXRoLCBuYW1lKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgICAgcmVzdWx0W25hbWVdID0gYXV0aDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aEJ1dHRvblZpZXcoe1xuICAgICAgICBkYXRhOiBTd2FnZ2VyVWkudXRpbHMucGFyc2VTZWN1cml0eURlZmluaXRpb25zKGF1dGhzTW9kZWwpLFxuICAgICAgICByb3V0ZXI6IHRoaXNcbiAgICAgIH0pO1xuICAgICAgJCgnI2F1dGhfY29udGFpbmVyJykuYXBwZW5kKHRoaXMuYXV0aFZpZXcucmVuZGVyKCkuZWwpO1xuICAgIH1cbiAgICB0aGlzLnNob3dNZXNzYWdlKCk7XG4gICAgc3dpdGNoICh0aGlzLm9wdGlvbnMuZG9jRXhwYW5zaW9uKSB7XG4gICAgICBjYXNlICdmdWxsJzpcbiAgICAgICAgdGhpcy5leHBhbmRBbGwoKTsgYnJlYWs7XG4gICAgICBjYXNlICdsaXN0JzpcbiAgICAgICAgdGhpcy5saXN0QWxsKCk7IGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMucmVuZGVyR0ZNKCk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9uQ29tcGxldGUpe1xuICAgICAgdGhpcy5vcHRpb25zLm9uQ29tcGxldGUodGhpcy5hcGksIHRoaXMpO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoRG9jcy5zaGViYW5nLmJpbmQodGhpcyksIDEwMCk7XG4gIH0sXG5cbiAgYnVpbGRVcmw6IGZ1bmN0aW9uKGJhc2UsIHVybCl7XG4gICAgaWYgKHVybC5pbmRleE9mKCcvJykgPT09IDApIHtcbiAgICAgIHZhciBwYXJ0cyA9IGJhc2Uuc3BsaXQoJy8nKTtcbiAgICAgIGJhc2UgPSBwYXJ0c1swXSArICcvLycgKyBwYXJ0c1syXTtcbiAgICAgIHJldHVybiBiYXNlICsgdXJsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZW5kT2ZQYXRoID0gYmFzZS5sZW5ndGg7XG5cbiAgICAgIGlmIChiYXNlLmluZGV4T2YoJz8nKSA+IC0xKXtcbiAgICAgICAgZW5kT2ZQYXRoID0gTWF0aC5taW4oZW5kT2ZQYXRoLCBiYXNlLmluZGV4T2YoJz8nKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChiYXNlLmluZGV4T2YoJyMnKSA+IC0xKXtcbiAgICAgICAgZW5kT2ZQYXRoID0gTWF0aC5taW4oZW5kT2ZQYXRoLCBiYXNlLmluZGV4T2YoJyMnKSk7XG4gICAgICB9XG5cbiAgICAgIGJhc2UgPSBiYXNlLnN1YnN0cmluZygwLCBlbmRPZlBhdGgpO1xuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCcvJywgYmFzZS5sZW5ndGggLSAxICkgIT09IC0xKXtcbiAgICAgICAgcmV0dXJuIGJhc2UgKyB1cmw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiYXNlICsgJy8nICsgdXJsO1xuICAgIH1cbiAgfSxcblxuICAvLyBTaG93cyBtZXNzYWdlIG9uIHRvcGJhciBvZiB0aGUgdWlcbiAgc2hvd01lc3NhZ2U6IGZ1bmN0aW9uKGRhdGEpe1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRhdGEgPSAnJztcbiAgICB9XG4gICAgdmFyICRtc2diYXIgPSAkKCcjbWVzc2FnZS1iYXInKTtcbiAgICAkbXNnYmFyLnJlbW92ZUNsYXNzKCdtZXNzYWdlLWZhaWwnKTtcbiAgICAkbXNnYmFyLmFkZENsYXNzKCdtZXNzYWdlLXN1Y2Nlc3MnKTtcbiAgICAkbXNnYmFyLnRleHQoZGF0YSk7XG4gICAgaWYod2luZG93LlN3YWdnZXJUcmFuc2xhdG9yKSB7XG4gICAgICB3aW5kb3cuU3dhZ2dlclRyYW5zbGF0b3IudHJhbnNsYXRlKCRtc2diYXIpO1xuICAgIH1cbiAgfSxcblxuICAvLyBzaG93cyBtZXNzYWdlIGluIHJlZFxuICBvbkxvYWRGYWlsdXJlOiBmdW5jdGlvbihkYXRhKXtcbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBkYXRhID0gJyc7XG4gICAgfVxuICAgICQoJyNtZXNzYWdlLWJhcicpLnJlbW92ZUNsYXNzKCdtZXNzYWdlLXN1Y2Nlc3MnKTtcbiAgICAkKCcjbWVzc2FnZS1iYXInKS5hZGRDbGFzcygnbWVzc2FnZS1mYWlsJyk7XG5cbiAgICB2YXIgdmFsID0gJCgnI21lc3NhZ2UtYmFyJykudGV4dChkYXRhKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMub25GYWlsdXJlKSB7XG4gICAgICB0aGlzLm9wdGlvbnMub25GYWlsdXJlKGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWw7XG4gIH0sXG5cbiAgLy8gUmVuZGVycyBHRk0gZm9yIGVsZW1lbnRzIHdpdGggJ21hcmtkb3duJyBjbGFzc1xuICByZW5kZXJHRk06IGZ1bmN0aW9uKCl7XG4gICAgJCgnLm1hcmtkb3duJykuZWFjaChmdW5jdGlvbigpe1xuICAgICAgJCh0aGlzKS5odG1sKG1hcmtlZCgkKHRoaXMpLmh0bWwoKSkpO1xuICAgIH0pO1xuXG4gICAgJCgnLnByb3BEZXNjJywgJy5tb2RlbC1zaWduYXR1cmUgLmRlc2NyaXB0aW9uJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAkKHRoaXMpLmh0bWwobWFya2VkKCQodGhpcykuaHRtbCgpKSkuYWRkQ2xhc3MoJ21hcmtkb3duJyk7XG4gICAgfSk7XG4gIH1cblxufSk7XG5cbndpbmRvdy5Td2FnZ2VyVWkuVmlld3MgPSB7fTtcbndpbmRvdy5Td2FnZ2VyVWkuTW9kZWxzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLkNvbGxlY3Rpb25zID0ge307XG53aW5kb3cuU3dhZ2dlclVpLnBhcnRpYWxzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLnV0aWxzID0ge307XG5cbi8vIGRvbid0IGJyZWFrIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBwcmV2aW91cyB2ZXJzaW9ucyBhbmQgd2FybiB1c2VycyB0byB1cGdyYWRlIHRoZWlyIGNvZGVcbihmdW5jdGlvbigpe1xuICB3aW5kb3cuYXV0aG9yaXphdGlvbnMgPSB7XG4gICAgYWRkOiBmdW5jdGlvbigpIHtcbiAgICAgIHdhcm4oJ1VzaW5nIHdpbmRvdy5hdXRob3JpemF0aW9ucyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKCkuJyk7XG5cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93LnN3YWdnZXJVaSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignd2luZG93LnN3YWdnZXJVaSBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAod2luZG93LnN3YWdnZXJVaSBpbnN0YW5jZW9mIFN3YWdnZXJVaSkge1xuICAgICAgICB3aW5kb3cuc3dhZ2dlclVpLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQuYXBwbHkod2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdpbmRvdy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgd2Fybignd2luZG93LkFwaUtleUF1dGhvcml6YXRpb24gaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24uJyk7XG4gICAgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uLmFwcGx5KHdpbmRvdywgYXJndW1lbnRzKTtcbiAgfTtcblxuICB3aW5kb3cuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgd2Fybignd2luZG93LlBhc3N3b3JkQXV0aG9yaXphdGlvbiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uLicpO1xuICAgIFN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uLmFwcGx5KHdpbmRvdywgYXJndW1lbnRzKTtcbiAgfTtcblxuICBmdW5jdGlvbiB3YXJuKG1lc3NhZ2UpIHtcbiAgICBpZiAoJ2NvbnNvbGUnIGluIHdpbmRvdyAmJiB0eXBlb2Ygd2luZG93LmNvbnNvbGUud2FybiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc29sZS53YXJuKG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufSkoKTtcblxuXG4vLyBVTURcbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuICAgICAgICBkZWZpbmUoWydiJ10sIGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICByZXR1cm4gKHJvb3QuU3dhZ2dlclVpID0gZmFjdG9yeShiKSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIC8vIE5vZGUuIERvZXMgbm90IHdvcmsgd2l0aCBzdHJpY3QgQ29tbW9uSlMsIGJ1dFxuICAgICAgICAvLyBvbmx5IENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHRoYXQgc3VwcG9ydCBtb2R1bGUuZXhwb3J0cyxcbiAgICAgICAgLy8gbGlrZSBOb2RlLlxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSgnYicpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBCcm93c2VyIGdsb2JhbHNcbiAgICAgICAgcm9vdC5Td2FnZ2VyVWkgPSBmYWN0b3J5KHJvb3QuYik7XG4gICAgfVxufSh0aGlzLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFN3YWdnZXJVaTtcbn0pKTtcbiIsIid1c2Ugc3RyaWN0Jztcblxud2luZG93LlN3YWdnZXJVaS51dGlscyA9IHtcbiAgICBwYXJzZVNlY3VyaXR5RGVmaW5pdGlvbnM6IGZ1bmN0aW9uIChzZWN1cml0eSwgc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgICAgICB2YXIgYXV0aHMgPSBPYmplY3QuYXNzaWduKHt9LCBzZWN1cml0eURlZmluaXRpb25zKTtcbiAgICAgICAgdmFyIG9hdXRoMkFyciA9IFtdO1xuICAgICAgICB2YXIgYXV0aHNBcnIgPSBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IFtdO1xuICAgICAgICB2YXIgdXRpbHMgPSB3aW5kb3cuU3dhZ2dlclVpLnV0aWxzO1xuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWN1cml0eSkpIHsgcmV0dXJuIG51bGw7IH1cblxuICAgICAgICBzZWN1cml0eS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgc2luZ2xlU2VjdXJpdHkgPSB7fTtcbiAgICAgICAgICAgIHZhciBzaW5nbGVPYXV0aDJTZWN1cml0eSA9IHt9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gaXRlbSkge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW1ba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhdXRoc1trZXldKSB7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICAgIGF1dGhzW2tleV0gPSBhdXRoc1trZXldIHx8IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXV0aHNba2V5XS50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGF1dGhzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XS5pbmRleE9mKGkpIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSB1dGlscy5wYXJzZU9hdXRoMlNjb3BlcyhzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXMgPSBfLm1lcmdlKHNjb3Blcywgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGF1dGhzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XS50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGl0ZW1ba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3BlcyA9IHV0aWxzLnBhcnNlT2F1dGgyU2NvcGVzKHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlcyA9IF8ubWVyZ2Uoc2NvcGVzLCBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVTZWN1cml0eVtrZXldID0gaXRlbVtrZXldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShzaW5nbGVTZWN1cml0eSkpIHtcbiAgICAgICAgICAgICAgICBhdXRoc0Fyci5wdXNoKHNpbmdsZVNlY3VyaXR5KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoc2luZ2xlT2F1dGgyU2VjdXJpdHkpKXtcbiAgICAgICAgICAgICAgICBvYXV0aDJBcnIucHVzaChzaW5nbGVPYXV0aDJTZWN1cml0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhdXRocyA6IGF1dGhzQXJyLFxuICAgICAgICAgICAgb2F1dGgyOiBvYXV0aDJBcnIsXG4gICAgICAgICAgICBzY29wZXM6IHNjb3Blc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBwYXJzZU9hdXRoMlNjb3BlczogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHNjb3BlcyA9IE9iamVjdC5hc3NpZ24oe30sIGRhdGEpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh7c2NvcGU6IGtleSwgZGVzY3JpcHRpb246IHNjb3Blc1trZXldfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBzYW5pdGl6ZTogZnVuY3Rpb24oaHRtbCkge1xuICAgICAgICAvLyBTdHJpcCB0aGUgc2NyaXB0IHRhZ3MgZnJvbSB0aGUgaHRtbCBhbmQgaW5saW5lIGV2ZW5oYW5kbGVyc1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKC88c2NyaXB0XFxiW148XSooPzooPyE8XFwvc2NyaXB0Pik8W148XSopKjxcXC9zY3JpcHQ+L2dpLCAnJyk7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoLyhvblxcdys9XCJbXlwiXSpcIikqKG9uXFx3Kz0nW14nXSonKSoob25cXHcrPVxcdypcXChcXHcqXFwpKSovZ2ksICcnKTtcblxuICAgICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG59OyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5BcGlLZXlBdXRoTW9kZWwgPSBCYWNrYm9uZS5Nb2RlbC5leHRlbmQoe1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgICdpbic6ICcnLFxuICAgICAgICBuYW1lOiAnJyxcbiAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICB2YWx1ZTogJydcbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLnZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbGlkID0gISF0aGlzLmdldCgndmFsdWUnKTtcblxuICAgICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkFwaUtleUF1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoeyAvLyBUT0RPOiBhcHBlbmQgdGhpcyB0byBnbG9iYWwgU3dhZ2dlclVpXG5cbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NoYW5nZSAuaW5wdXRfYXBpS2V5X2VudHJ5JzogJ2FwaUtleUNoYW5nZSdcbiAgICB9LFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIGFwaWtleUlucHV0OiAnLmlucHV0X2FwaUtleV9lbnRyeSdcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmFwaWtleV9hdXRoLFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCl7XG4gICAgICAgIHRoaXMuJGVsLmh0bWwodGhpcy50ZW1wbGF0ZSh0aGlzLm1vZGVsLnRvSlNPTigpKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGFwaUtleUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuYXBpa2V5SW5wdXQpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoJ3ZhbHVlJywgdmFsKTtcbiAgICB9LFxuXG4gICAgaXNWYWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC52YWxpZGF0ZSgpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuJCh0aGlzLnNlbGVjdG9ycy5hcGlrZXlJbnB1dCkuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhCdXR0b25WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmF1dGhvcml6ZV9fYnRuJzogJ2F1dGhvcml6ZUJ0bkNsaWNrJ1xuICAgIH0sXG5cbiAgICB0cGxzOiB7XG4gICAgICAgIHBvcHVwOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wb3B1cCxcbiAgICAgICAgYXV0aEJ0bjogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYXV0aF9idXR0b24sXG4gICAgICAgIGF1dGhCdG5PcGVyYXRpb246IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfYnV0dG9uX29wZXJhdGlvblxuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIHRoaXMub3B0aW9ucy5kYXRhID0gdGhpcy5vcHRpb25zLmRhdGEgfHwge307XG4gICAgICAgIHRoaXMuaXNPcGVyYXRpb24gPSB0aGlzLm9wdGlvbnMuaXNPcGVyYXRpb247XG4gICAgICAgIHRoaXMubW9kZWwgPSB0aGlzLm1vZGVsIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgICAgIHRoaXMuYXV0aHMgPSB0aGlzLm9wdGlvbnMuZGF0YS5vYXV0aDIuY29uY2F0KHRoaXMub3B0aW9ucy5kYXRhLmF1dGhzKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0cGxOYW1lID0gdGhpcy5pc09wZXJhdGlvbiA/ICdhdXRoQnRuT3BlcmF0aW9uJyA6ICdhdXRoQnRuJztcblxuICAgICAgICB0aGlzLiRhdXRoRWwgPSB0aGlzLnJlbmRlckF1dGhzKHRoaXMuYXV0aHMpO1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudHBsc1t0cGxOYW1lXSh0aGlzLm1vZGVsKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGF1dGhvcml6ZUJ0bkNsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgYXV0aHNNb2RlbDtcblxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgYXV0aHNNb2RlbCA9IHtcbiAgICAgICAgICAgIHRpdGxlOiAnQXZhaWxhYmxlIGF1dGhvcml6YXRpb25zJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6IHRoaXMuJGF1dGhFbFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRoZSBjb250ZW50IG9mIHRoZSBwb3B1cCBpcyByZW1vdmVkIGFuZCBhbGwgZXZlbnRzIHVuYm91bmQgYWZ0ZXIgY2xpY2tpbmcgdGhlICdDYW5jZWwnIGJ1dHRvbiBvZiB0aGUgcG9wdXAuXG4gICAgICAgIC8vIFdlJ2xsIGhhdmUgdG8gcmUtcmVuZGVyIHRoZSBjb250ZW50cyBiZWZvcmUgY3JlYXRpbmcgYSBuZXcgcG9wdXAgdmlldy5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICB0aGlzLnBvcHVwID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5Qb3B1cFZpZXcoe21vZGVsOiBhdXRoc01vZGVsfSk7XG4gICAgICAgIHRoaXMucG9wdXAucmVuZGVyKCk7XG4gICAgfSxcblxuICAgIHJlbmRlckF1dGhzOiBmdW5jdGlvbiAoYXV0aHMpIHtcbiAgICAgICAgdmFyICRlbCA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIHZhciBpc0xvZ291dCA9IGZhbHNlO1xuXG4gICAgICAgIGF1dGhzLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHZhciBhdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aFZpZXcoe2RhdGE6IGF1dGgsIHJvdXRlcjogdGhpcy5yb3V0ZXJ9KTtcbiAgICAgICAgICAgIHZhciBhdXRoRWwgPSBhdXRoVmlldy5yZW5kZXIoKS5lbDtcbiAgICAgICAgICAgICRlbC5hcHBlbmQoYXV0aEVsKTtcbiAgICAgICAgICAgIGlmIChhdXRoVmlldy5pc0xvZ291dCkge1xuICAgICAgICAgICAgICAgIGlzTG9nb3V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5tb2RlbC5pc0xvZ291dCA9IGlzTG9nb3V0O1xuXG4gICAgICAgIHJldHVybiAkZWw7XG4gICAgfVxuXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLkNvbGxlY3Rpb25zLkF1dGhzQ29sbGVjdGlvbiA9IEJhY2tib25lLkNvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgICAgICBhcmdzWzBdID0gdGhpcy5wYXJzZShhcmdzWzBdKTtcblxuICAgICAgICBCYWNrYm9uZS5Db2xsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0sXG5cbiAgICBhZGQ6IGZ1bmN0aW9uIChtb2RlbCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWwpKSB7XG4gICAgICAgICAgICBhcmdzWzBdID0gXy5tYXAobW9kZWwsIGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZU9uZSh2YWwpO1xuICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcmdzWzBdID0gdGhpcy5oYW5kbGVPbmUobW9kZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgQmFja2JvbmUuQ29sbGVjdGlvbi5wcm90b3R5cGUuYWRkLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0sXG5cbiAgICBoYW5kbGVPbmU6IGZ1bmN0aW9uIChtb2RlbCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbW9kZWw7XG5cbiAgICAgICAgaWYgKCEgKG1vZGVsIGluc3RhbmNlb2YgQmFja2JvbmUuTW9kZWwpICkge1xuICAgICAgICAgICAgc3dpdGNoIChtb2RlbC50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnb2F1dGgyJzpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN3YWdnZXJVaS5Nb2RlbHMuT2F1dGgyTW9kZWwobW9kZWwpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLkJhc2ljQXV0aE1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnYXBpS2V5JzpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN3YWdnZXJVaS5Nb2RlbHMuQXBpS2V5QXV0aE1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJhY2tib25lLk1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbGlkID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLm1vZGVscy5mb3JFYWNoKGZ1bmN0aW9uKG1vZGVsKSB7XG4gICAgICAgICAgICBpZiAoIW1vZGVsLnZhbGlkYXRlKCkpIHtcbiAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfSxcblxuICAgIGlzQXV0aG9yaXplZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IHRoaXMud2hlcmUoeyBpc0xvZ291dDogdHJ1ZSB9KS5sZW5ndGg7XG4gICAgfSxcblxuICAgIGlzUGFydGlhbGx5QXV0aG9yaXplZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aGVyZSh7IGlzTG9nb3V0OiB0cnVlIH0pLmxlbmd0aCA+IDA7XG4gICAgfSxcblxuICAgIHBhcnNlOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgYXV0aHogPSB7fTtcblxuICAgICAgICBpZih0eXBlb2Ygd2luZG93LnN3YWdnZXJVaSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGF1dGh6ID0gT2JqZWN0LmFzc2lnbih7fSwgd2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHopO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIF8ubWFwKGRhdGEsIGZ1bmN0aW9uIChhdXRoLCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgaXNCYXNpYyA9IGF1dGh6W25hbWVdICYmIGF1dGgudHlwZSA9PT0gJ2Jhc2ljJyAmJiBhdXRoeltuYW1lXS51c2VybmFtZSAmJiBhdXRoeltuYW1lXS5wYXNzd29yZDtcblxuICAgICAgICAgICAgXy5leHRlbmQoYXV0aCwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBuYW1lXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGF1dGh6W25hbWVdIHx8IGlzQmFzaWMpIHtcbiAgICAgICAgICAgICAgICBfLmV4dGVuZChhdXRoLCB7XG4gICAgICAgICAgICAgICAgICAgIGlzTG9nb3V0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXNCYXNpYyA/IHVuZGVmaW5lZCA6IGF1dGh6W25hbWVdLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB1c2VybmFtZTogaXNCYXNpYyA/IGF1dGh6W25hbWVdLnVzZXJuYW1lIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBwYXNzd29yZDogaXNCYXNpYyA/IGF1dGh6W25hbWVdLnBhc3N3b3JkIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB2YWxpZDogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYXV0aDtcbiAgICAgICAgfSk7XG4gICAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuQXV0aHNDb2xsZWN0aW9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5vcHRpb25zLmRhdGEgPSB0aGlzLm9wdGlvbnMuZGF0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuXG4gICAgICAgIHRoaXMuY29sbGVjdGlvbiA9IG5ldyBTd2FnZ2VyVWkuQ29sbGVjdGlvbnMuQXV0aHNDb2xsZWN0aW9uKG9wdHMuZGF0YSk7XG5cbiAgICAgICAgdGhpcy4kaW5uZXJFbCA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIHRoaXMuYXV0aFZpZXdzID0gW107XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbGxlY3Rpb24uZWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJPbmVBdXRoKGF1dGgpO1xuICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMuJGlubmVyRWwuaHRtbCgpID8gdGhpcy4kaW5uZXJFbCA6ICcnKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgcmVuZGVyT25lQXV0aDogZnVuY3Rpb24gKGF1dGhNb2RlbCkge1xuICAgICAgICB2YXIgYXV0aFZpZXdFbCwgYXV0aFZpZXcsIGF1dGhWaWV3TmFtZTtcbiAgICAgICAgdmFyIHR5cGUgPSBhdXRoTW9kZWwuZ2V0KCd0eXBlJyk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICBhdXRoVmlld05hbWUgPSAnQXBpS2V5QXV0aFZpZXcnO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdiYXNpYycgJiYgdGhpcy4kaW5uZXJFbC5maW5kKCcuYmFzaWNfYXV0aF9jb250YWluZXInKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGF1dGhWaWV3TmFtZSA9ICdCYXNpY0F1dGhWaWV3JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgYXV0aFZpZXdOYW1lID0gJ09hdXRoMlZpZXcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF1dGhWaWV3TmFtZSkge1xuICAgICAgICAgICAgYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzW2F1dGhWaWV3TmFtZV0oe21vZGVsOiBhdXRoTW9kZWwsIHJvdXRlcjogdGhpcy5yb3V0ZXJ9KTtcbiAgICAgICAgICAgIGF1dGhWaWV3RWwgPSBhdXRoVmlldy5yZW5kZXIoKS5lbDtcbiAgICAgICAgICAgIHRoaXMuYXV0aFZpZXdzLnB1c2goYXV0aFZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy4kaW5uZXJFbC5hcHBlbmQoYXV0aFZpZXdFbCk7XG4gICAgfSxcblxuICAgIGhpZ2hsaWdodEludmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoVmlld3MuZm9yRWFjaChmdW5jdGlvbiAodmlldykge1xuICAgICAgICAgICAgdmlldy5oaWdobGlnaHRJbnZhbGlkKCk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCByZWRpcmVjdF91cmk6dHJ1ZSAqL1xuLyogZ2xvYmFsIGNsaWVudElkICovXG4vKiBnbG9iYWwgc2NvcGVTZXBhcmF0b3IgKi9cbi8qIGdsb2JhbCBhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXMgKi9cbi8qIGdsb2JhbCBjbGllbnRTZWNyZXQgKi9cbi8qIGdsb2JhbCBvbk9BdXRoQ29tcGxldGUgKi9cbi8qIGdsb2JhbCByZWFsbSAqL1xuLypqc2hpbnQgdW51c2VkOmZhbHNlKi9cblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmF1dGhfc3VibWl0X19idXR0b24nOiAnYXV0aG9yaXplQ2xpY2snLFxuICAgICAgICAnY2xpY2sgLmF1dGhfbG9nb3V0X19idXR0b24nOiAnbG9nb3V0Q2xpY2snXG4gICAgfSxcblxuICAgIHRwbHM6IHtcbiAgICAgICAgbWFpbjogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYXV0aF92aWV3XG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBpbm5lckVsOiAnLmF1dGhfaW5uZXInLFxuICAgICAgICBhdXRoQnRuOiAnLmF1dGhfc3VibWl0X19idXR0b24nXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgb3B0cy5kYXRhID0gb3B0cy5kYXRhIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG5cbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5BdXRoc0NvbGxlY3Rpb25WaWV3KHtkYXRhOiBvcHRzLmRhdGF9KTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudHBscy5tYWluKHtcbiAgICAgICAgICAgIGlzTG9nb3V0OiB0aGlzLmF1dGhzQ29sbGVjdGlvblZpZXcuY29sbGVjdGlvbi5pc0F1dGhvcml6ZWQoKSxcbiAgICAgICAgICAgIGlzQXV0aG9yaXplZDogdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKClcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLiRpbm5lckVsID0gdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmlubmVyRWwpO1xuICAgICAgICB0aGlzLmlzTG9nb3V0ID0gdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRpbm5lckVsLmh0bWwodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LnJlbmRlcigpLmVsKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgYXV0aG9yaXplQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBpZiAodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmF1dGhvcml6ZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmhpZ2hsaWdodEludmFsaWQoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBhdXRob3JpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uZm9yRWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdmFyIGtleUF1dGgsIGJhc2ljQXV0aDtcbiAgICAgICAgICAgIHZhciB0eXBlID0gYXV0aC5nZXQoJ3R5cGUnKTtcblxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICAgICAga2V5QXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24oXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCduYW1lJyksXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCd2YWx1ZScpLFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgnaW4nKVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKGF1dGguZ2V0KCd0aXRsZScpLCBrZXlBdXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jhc2ljJykge1xuICAgICAgICAgICAgICAgIGJhc2ljQXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbihhdXRoLmdldCgndXNlcm5hbWUnKSwgYXV0aC5nZXQoJ3Bhc3N3b3JkJykpO1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQoYXV0aC5nZXQoJ3RpdGxlJyksIGJhc2ljQXV0aCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVPYXV0aDJMb2dpbihhdXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5yb3V0ZXIubG9hZCgpO1xuICAgIH0sXG5cbiAgICBsb2dvdXRDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLnJlbW92ZShhdXRoLmdldCgndGl0bGUnKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGVyLmxvYWQoKTtcbiAgICB9LFxuXG4gICAgLy8gdGFrZW4gZnJvbSBsaWIvc3dhZ2dlci1vYXV0aC5qc1xuICAgIGhhbmRsZU9hdXRoMkxvZ2luOiBmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICB2YXIgaG9zdCA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgICAgdmFyIHBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWUuc3Vic3RyaW5nKDAsIGxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpO1xuICAgICAgICB2YXIgZGVmYXVsdFJlZGlyZWN0VXJsID0gaG9zdC5wcm90b2NvbCArICcvLycgKyBob3N0Lmhvc3QgKyBwYXRobmFtZSArICcvbzJjLmh0bWwnO1xuICAgICAgICB2YXIgcmVkaXJlY3RVcmwgPSB3aW5kb3cub0F1dGhSZWRpcmVjdFVybCB8fCBkZWZhdWx0UmVkaXJlY3RVcmw7XG4gICAgICAgIHZhciB1cmwgPSBudWxsO1xuICAgICAgICB2YXIgc2NvcGVzID0gXy5tYXAoYXV0aC5nZXQoJ3Njb3BlcycpLCBmdW5jdGlvbiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGlmKHNjb3BlLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGUuc2NvcGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gd2luZG93LnN3YWdnZXJVaUF1dGggfHwgKHdpbmRvdy5zd2FnZ2VyVWlBdXRoID0ge30pO1xuICAgICAgICB2YXIgc3RhdGUsIGRldHMsIGVwO1xuICAgICAgICBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkgPSBhdXRoLmdldCgndGl0bGUnKTtcblxuICAgICAgICB3aW5kb3cuZW5hYmxlZFNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgdmFyIGZsb3cgPSBhdXRoLmdldCgnZmxvdycpO1xuXG4gICAgICAgIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdpbXBsaWNpdCcgfHwgZmxvdyA9PT0gJ2FjY2Vzc0NvZGUnKSkge1xuICAgICAgICAgICAgZGV0cyA9IGF1dGguYXR0cmlidXRlcztcbiAgICAgICAgICAgIHVybCA9IGRldHMuYXV0aG9yaXphdGlvblVybCArICc/cmVzcG9uc2VfdHlwZT0nICsgKGZsb3cgPT09ICdpbXBsaWNpdCcgPyAndG9rZW4nIDogJ2NvZGUnKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbk5hbWUgPSBkZXRzLnRva2VuTmFtZSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIGNvbnRhaW5lci50b2tlblVybCA9IChmbG93ID09PSAnYWNjZXNzQ29kZScgPyBkZXRzLnRva2VuVXJsIDogbnVsbCk7XG4gICAgICAgICAgICBzdGF0ZSA9IGNvbnRhaW5lci5PQXV0aFNjaGVtZUtleTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdhcHBsaWNhdGlvbicpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGRldHMudG9rZW5OYW1lIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgdGhpcy5jbGllbnRDcmVkZW50aWFsc0Zsb3coc2NvcGVzLCBkZXRzLnRva2VuVXJsLCBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ2dyYW50VHlwZXMnKSkge1xuICAgICAgICAgICAgLy8gMS4yIHN1cHBvcnRcbiAgICAgICAgICAgIHZhciBvID0gYXV0aC5nZXQoJ2dyYW50VHlwZXMnKTtcbiAgICAgICAgICAgIGZvcih2YXIgdCBpbiBvKSB7XG4gICAgICAgICAgICAgICAgaWYoby5oYXNPd25Qcm9wZXJ0eSh0KSAmJiB0ID09PSAnaW1wbGljaXQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRldHMgPSBvW3RdO1xuICAgICAgICAgICAgICAgICAgICBlcCA9IGRldHMubG9naW5FbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IGRldHMubG9naW5FbmRwb2ludC51cmwgKyAnP3Jlc3BvbnNlX3R5cGU9dG9rZW4nO1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZGV0cy50b2tlbk5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG8uaGFzT3duUHJvcGVydHkodCkgJiYgdCA9PT0gJ2FjY2Vzc0NvZGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRldHMgPSBvW3RdO1xuICAgICAgICAgICAgICAgICAgICBlcCA9IGRldHMudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICAgICAgICB1cmwgPSBkZXRzLnRva2VuUmVxdWVzdEVuZHBvaW50LnVybCArICc/cmVzcG9uc2VfdHlwZT1jb2RlJztcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGRldHMudG9rZW5OYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJlZGlyZWN0X3VyaSA9IHJlZGlyZWN0VXJsO1xuXG4gICAgICAgIHVybCArPSAnJnJlZGlyZWN0X3VyaT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlZGlyZWN0VXJsKTtcbiAgICAgICAgdXJsICs9ICcmcmVhbG09JyArIGVuY29kZVVSSUNvbXBvbmVudChyZWFsbSk7XG4gICAgICAgIHVybCArPSAnJmNsaWVudF9pZD0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGNsaWVudElkKTtcbiAgICAgICAgdXJsICs9ICcmc2NvcGU9JyArIGVuY29kZVVSSUNvbXBvbmVudChzY29wZXMuam9pbihzY29wZVNlcGFyYXRvcikpO1xuICAgICAgICB1cmwgKz0gJyZzdGF0ZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHN0YXRlKTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGFkZGl0aW9uYWxRdWVyeVN0cmluZ1BhcmFtcykge1xuICAgICAgICAgICAgdXJsICs9ICcmJyArIGtleSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXNba2V5XSk7XG4gICAgICAgIH1cblxuICAgICAgICB3aW5kb3cub3Blbih1cmwpO1xuICAgIH0sXG5cbiAgICAvLyB0YWtlbiBmcm9tIGxpYi9zd2FnZ2VyLW9hdXRoLmpzXG4gICAgY2xpZW50Q3JlZGVudGlhbHNGbG93OiBmdW5jdGlvbiAoc2NvcGVzLCB0b2tlblVybCwgT0F1dGhTY2hlbWVLZXkpIHtcbiAgICAgICAgdmFyIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICdjbGllbnRfaWQnOiBjbGllbnRJZCxcbiAgICAgICAgICAgICdjbGllbnRfc2VjcmV0JzogY2xpZW50U2VjcmV0LFxuICAgICAgICAgICAgJ3Njb3BlJzogc2NvcGVzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgICdncmFudF90eXBlJzogJ2NsaWVudF9jcmVkZW50aWFscydcbiAgICAgICAgfTtcbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybCA6IHRva2VuVXJsLFxuICAgICAgICAgICAgdHlwZTogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YTogcGFyYW1zLFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGRhdGEpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb25PQXV0aENvbXBsZXRlKGRhdGEsIE9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBvbk9BdXRoQ29tcGxldGUoJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuTW9kZWxzLkJhc2ljQXV0aE1vZGVsID0gQmFja2JvbmUuTW9kZWwuZXh0ZW5kKHtcbiAgICBkZWZhdWx0czoge1xuICAgICAgICB1c2VybmFtZTogJycsXG4gICAgICAgIHBhc3N3b3JkOiAnJyxcbiAgICAgICAgdGl0bGU6ICdiYXNpYydcbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLnZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbGlkID0gISF0aGlzLmdldCgncGFzc3dvcmQnKSAmJiAhIXRoaXMuZ2V0KCd1c2VybmFtZScpO1xuXG4gICAgICAgIHRoaXMuc2V0KCd2YWxpZCcsIHZhbGlkKTtcblxuICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuQmFzaWNBdXRoVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIHRoaXMucm91dGVyID0gdGhpcy5vcHRpb25zLnJvdXRlcjtcbiAgICB9LFxuXG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjaGFuZ2UgLmF1dGhfaW5wdXQnOiAnaW5wdXRDaGFuZ2UnXG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICB1c2VybmFtZUlucHV0OiAnLmJhc2ljX2F1dGhfX3VzZXJuYW1lJyxcbiAgICAgICAgcGFzc3dvcmRJbnB1dDogJy5iYXNpY19hdXRoX19wYXNzd29yZCdcbiAgICB9LFxuXG4gICAgY2xzOiB7XG4gICAgICAgIGVycm9yOiAnZXJyb3InXG4gICAgfSxcblxuICAgIHRlbXBsYXRlOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5iYXNpY19hdXRoLFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgICAgICAkKHRoaXMuZWwpLmh0bWwodGhpcy50ZW1wbGF0ZSh0aGlzLm1vZGVsLnRvSlNPTigpKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGlucHV0Q2hhbmdlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgJGVsID0gJChlLnRhcmdldCk7XG4gICAgICAgIHZhciB2YWwgPSAkZWwudmFsKCk7XG4gICAgICAgIHZhciBhdHRyID0gJGVsLnByb3AoJ25hbWUnKTtcblxuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAkZWwucmVtb3ZlQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoYXR0ciwgdmFsKTtcbiAgICB9LFxuXG4gICAgaXNWYWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC52YWxpZGF0ZSgpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5tb2RlbC5nZXQoJ3VzZXJuYW1lJykpIHtcbiAgICAgICAgICAgIHRoaXMuJCh0aGlzLnNlbGVjdG9ycy51c2VybmFtZUlucHV0KS5hZGRDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkNvbnRlbnRUeXBlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7fSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gIFx0dGhpcy5tb2RlbC5jb250ZW50VHlwZUlkID0gJ2N0JyArIE1hdGgucmFuZG9tKCk7XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLmNvbnRlbnRfdHlwZSh0aGlzLm1vZGVsKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkhlYWRlclZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGV2ZW50czoge1xuICAgICdjbGljayAjc2hvdy1wZXQtc3RvcmUtaWNvbicgICAgOiAnc2hvd1BldFN0b3JlJyxcbiAgICAnY2xpY2sgI2V4cGxvcmUnICAgICAgICAgICAgICAgIDogJ3Nob3dDdXN0b20nLFxuICAgICdzdWJtaXQgI2FwaV9zZWxlY3RvcicgICAgICAgICAgOiAnc2hvd0N1c3RvbScsXG4gICAgJ2tleXVwICNpbnB1dF9iYXNlVXJsJyAgICAgICAgICA6ICdzaG93Q3VzdG9tT25LZXl1cCcsXG4gICAgJ2tleXVwICNpbnB1dF9hcGlLZXknICAgICAgICAgICA6ICdzaG93Q3VzdG9tT25LZXl1cCdcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbigpe30sXG5cbiAgc2hvd1BldFN0b3JlOiBmdW5jdGlvbigpe1xuICAgIHRoaXMudHJpZ2dlcigndXBkYXRlLXN3YWdnZXItdWknLCB7XG4gICAgICB1cmw6J2h0dHA6Ly9wZXRzdG9yZS5zd2FnZ2VyLmlvL3YyL3N3YWdnZXIuanNvbidcbiAgICB9KTtcbiAgfSxcblxuICBzaG93Q3VzdG9tT25LZXl1cDogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUua2V5Q29kZSA9PT0gMTMpIHtcbiAgICAgIHRoaXMuc2hvd0N1c3RvbSgpO1xuICAgIH1cbiAgfSxcblxuICBzaG93Q3VzdG9tOiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIHRoaXMudHJpZ2dlcigndXBkYXRlLXN3YWdnZXItdWknLCB7XG4gICAgICB1cmw6ICQoJyNpbnB1dF9iYXNlVXJsJykudmFsKClcbiAgICB9KTtcbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uKHVybCwgYXBpS2V5LCB0cmlnZ2VyKXtcbiAgICBpZiAodHJpZ2dlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0cmlnZ2VyID0gZmFsc2U7XG4gICAgfVxuXG4gICAgJCgnI2lucHV0X2Jhc2VVcmwnKS52YWwodXJsKTtcblxuICAgIGlmICh0cmlnZ2VyKSB7XG4gICAgICB0aGlzLnRyaWdnZXIoJ3VwZGF0ZS1zd2FnZ2VyLXVpJywge3VybDp1cmx9KTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuTWFpblZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGFwaXNTb3J0ZXIgOiB7XG4gICAgYWxwaGEgICA6IGZ1bmN0aW9uKGEsYil7IHJldHVybiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpOyB9XG4gIH0sXG4gIG9wZXJhdGlvbnNTb3J0ZXJzIDoge1xuICAgIGFscGhhICAgOiBmdW5jdGlvbihhLGIpeyByZXR1cm4gYS5wYXRoLmxvY2FsZUNvbXBhcmUoYi5wYXRoKTsgfSxcbiAgICBtZXRob2QgIDogZnVuY3Rpb24oYSxiKXsgcmV0dXJuIGEubWV0aG9kLmxvY2FsZUNvbXBhcmUoYi5tZXRob2QpOyB9XG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpe1xuICAgIHZhciBzb3J0ZXJPcHRpb24sIHNvcnRlckZuLCBrZXksIHZhbHVlO1xuICAgIG9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gICAgdGhpcy5yb3V0ZXIgPSBvcHRzLnJvdXRlcjtcblxuICAgIC8vIFNvcnQgQVBJc1xuICAgIGlmIChvcHRzLnN3YWdnZXJPcHRpb25zLmFwaXNTb3J0ZXIpIHtcbiAgICAgIHNvcnRlck9wdGlvbiA9IG9wdHMuc3dhZ2dlck9wdGlvbnMuYXBpc1NvcnRlcjtcbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyT3B0aW9uKSkge1xuICAgICAgICBzb3J0ZXJGbiA9IHNvcnRlck9wdGlvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNvcnRlckZuID0gdGhpcy5hcGlzU29ydGVyW3NvcnRlck9wdGlvbl07XG4gICAgICB9XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlckZuKSkge1xuICAgICAgICB0aGlzLm1vZGVsLmFwaXNBcnJheS5zb3J0KHNvcnRlckZuKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gU29ydCBvcGVyYXRpb25zIG9mIGVhY2ggQVBJXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMub3BlcmF0aW9uc1NvcnRlcikge1xuICAgICAgc29ydGVyT3B0aW9uID0gb3B0cy5zd2FnZ2VyT3B0aW9ucy5vcGVyYXRpb25zU29ydGVyO1xuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJPcHRpb24pKSB7XG4gICAgICAgIHNvcnRlckZuID0gc29ydGVyT3B0aW9uO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc29ydGVyRm4gPSB0aGlzLm9wZXJhdGlvbnNTb3J0ZXJzW3NvcnRlck9wdGlvbl07XG4gICAgICB9XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlckZuKSkge1xuICAgICAgICBmb3IgKGtleSBpbiB0aGlzLm1vZGVsLmFwaXNBcnJheSkge1xuICAgICAgICAgIHRoaXMubW9kZWwuYXBpc0FycmF5W2tleV0ub3BlcmF0aW9uc0FycmF5LnNvcnQoc29ydGVyRm4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2V0IHVwIHRoZSBVSSBmb3IgaW5wdXRcbiAgICB0aGlzLm1vZGVsLmF1dGhzID0gW107XG5cbiAgICBmb3IgKGtleSBpbiB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhbHVlID0gdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zW2tleV07XG5cbiAgICAgIHRoaXMubW9kZWwuYXV0aHMucHVzaCh7XG4gICAgICAgIG5hbWU6IGtleSxcbiAgICAgICAgdHlwZTogdmFsdWUudHlwZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoJ3ZhbGlkYXRvclVybCcgaW4gb3B0cy5zd2FnZ2VyT3B0aW9ucykge1xuICAgICAgLy8gVmFsaWRhdG9yIFVSTCBzcGVjaWZpZWQgZXhwbGljaXRseVxuICAgICAgdGhpcy5tb2RlbC52YWxpZGF0b3JVcmwgPSBvcHRzLnN3YWdnZXJPcHRpb25zLnZhbGlkYXRvclVybDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwudXJsLmluZGV4T2YoJ2xvY2FsaG9zdCcpID4gMCB8fCB0aGlzLm1vZGVsLnVybC5pbmRleE9mKCcxMjcuMC4wLjEnKSA+IDApIHtcbiAgICAgIC8vIExvY2FsaG9zdCBvdmVycmlkZVxuICAgICAgdGhpcy5tb2RlbC52YWxpZGF0b3JVcmwgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGVsLnZhbGlkYXRvclVybCA9ICcvL29ubGluZS5zd2FnZ2VyLmlvL3ZhbGlkYXRvcic7XG4gICAgfVxuXG4gICAgLy8gSlNvbkVkaXRvciByZXF1aXJlcyB0eXBlPSdvYmplY3QnIHRvIGJlIHByZXNlbnQgb24gZGVmaW5lZCB0eXBlcywgd2UgYWRkIGl0IGlmIGl0J3MgbWlzc2luZ1xuICAgIC8vIGlzIHRoZXJlIGFueSB2YWxpZCBjYXNlIHdlcmUgaXQgc2hvdWxkIG5vdCBiZSBhZGRlZCA/XG4gICAgdmFyIGRlZjtcbiAgICBmb3IoZGVmIGluIHRoaXMubW9kZWwuZGVmaW5pdGlvbnMpe1xuICAgICAgaWYgKCF0aGlzLm1vZGVsLmRlZmluaXRpb25zW2RlZl0udHlwZSl7XG4gICAgICAgIHRoaXMubW9kZWwuZGVmaW5pdGlvbnNbZGVmXS50eXBlID0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfVxuXG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLm1haW4odGhpcy5tb2RlbCkpO1xuICAgIHRoaXMuaW5mbyA9IHRoaXMuJCgnLmluZm8nKVswXTtcblxuICAgIGlmICh0aGlzLmluZm8pIHtcbiAgICAgIHRoaXMuaW5mby5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25MaW5rQ2xpY2ssIHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9ucyA9IHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9ucyB8fCB7fTtcblxuICAgIC8vIFJlbmRlciBlYWNoIHJlc291cmNlXG5cbiAgICB2YXIgcmVzb3VyY2VzID0ge307XG4gICAgdmFyIGNvdW50ZXIgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb2RlbC5hcGlzQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByZXNvdXJjZSA9IHRoaXMubW9kZWwuYXBpc0FycmF5W2ldO1xuICAgICAgdmFyIGlkID0gcmVzb3VyY2UubmFtZTtcbiAgICAgIHdoaWxlICh0eXBlb2YgcmVzb3VyY2VzW2lkXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWQgPSBpZCArICdfJyArIGNvdW50ZXI7XG4gICAgICAgIGNvdW50ZXIgKz0gMTtcbiAgICAgIH1cbiAgICAgIHJlc291cmNlLmlkID0gc2FuaXRpemVIdG1sKGlkKTtcbiAgICAgIHJlc291cmNlc1tpZF0gPSByZXNvdXJjZTtcbiAgICAgIHRoaXMuYWRkUmVzb3VyY2UocmVzb3VyY2UsIHRoaXMubW9kZWwuYXV0aHMpO1xuICAgIH1cblxuICAgICQoJy5wcm9wV3JhcCcpLmhvdmVyKGZ1bmN0aW9uIG9uSG92ZXIoKXtcbiAgICAgICQoJy5vcHRpb25zV3JhcHBlcicsICQodGhpcykpLnNob3coKTtcbiAgICB9LCBmdW5jdGlvbiBvZmZob3Zlcigpe1xuICAgICAgJCgnLm9wdGlvbnNXcmFwcGVyJywgJCh0aGlzKSkuaGlkZSgpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGFkZFJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSwgYXV0aHMpe1xuICAgIC8vIFJlbmRlciBhIHJlc291cmNlIGFuZCBhZGQgaXQgdG8gcmVzb3VyY2VzIGxpXG4gICAgcmVzb3VyY2UuaWQgPSByZXNvdXJjZS5pZC5yZXBsYWNlKC9cXHMvZywgJ18nKTtcblxuICAgIC8vIE1ha2UgYWxsIGRlZmluaXRpb25zIGF2YWlsYWJsZSBhdCB0aGUgcm9vdCBvZiB0aGUgcmVzb3VyY2Ugc28gdGhhdCB0aGV5IGNhblxuICAgIC8vIGJlIGxvYWRlZCBieSB0aGUgSlNvbkVkaXRvclxuICAgIHJlc291cmNlLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcblxuICAgIHZhciByZXNvdXJjZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc291cmNlVmlldyh7XG4gICAgICBtb2RlbDogcmVzb3VyY2UsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgdGFnTmFtZTogJ2xpJyxcbiAgICAgIGlkOiAncmVzb3VyY2VfJyArIHJlc291cmNlLmlkLFxuICAgICAgY2xhc3NOYW1lOiAncmVzb3VyY2UnLFxuICAgICAgYXV0aHM6IGF1dGhzLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJyNyZXNvdXJjZXMnLCB0aGlzLmVsKS5hcHBlbmQocmVzb3VyY2VWaWV3LnJlbmRlcigpLmVsKTtcbiAgfSxcblxuICBjbGVhcjogZnVuY3Rpb24oKXtcbiAgICAkKHRoaXMuZWwpLmh0bWwoJycpO1xuICB9LFxuXG4gIG9uTGlua0NsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBlbCA9IGUudGFyZ2V0O1xuXG4gICAgaWYgKGVsLnRhZ05hbWUgPT09ICdBJyAmJiBlbC5ocmVmICYmICFlbC50YXJnZXQpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB3aW5kb3cub3BlbihlbC5ocmVmLCAnX2JsYW5rJyk7XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5PYXV0aDJNb2RlbCA9IEJhY2tib25lLk1vZGVsLmV4dGVuZCh7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgc2NvcGVzOiB7fVxuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmKHRoaXMuYXR0cmlidXRlcyAmJiB0aGlzLmF0dHJpYnV0ZXMuc2NvcGVzKSB7XG4gICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IF8uY2xvbmVEZWVwKHRoaXMuYXR0cmlidXRlcyk7XG4gICAgICAgICAgICB2YXIgaSwgc2NvcGVzID0gW107XG4gICAgICAgICAgICBmb3IoaSBpbiBhdHRyaWJ1dGVzLnNjb3Blcykge1xuICAgICAgICAgICAgICAgIHZhciBzY29wZSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzY29wZS5kZXNjcmlwdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzW3Njb3BlXSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBzY29wZXMucHVzaChhdHRyaWJ1dGVzLnNjb3Blc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXR0cmlidXRlcy5zY29wZXMgPSBzY29wZXM7XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMudmFsaWRhdGUpO1xuICAgIH0sXG5cbiAgICBzZXRTY29wZXM6IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHtcbiAgICAgICAgdmFyIGF1dGggPSBfLmV4dGVuZCh7fSwgdGhpcy5hdHRyaWJ1dGVzKTtcbiAgICAgICAgdmFyIGluZGV4ID0gXy5maW5kSW5kZXgoYXV0aC5zY29wZXMsIGZ1bmN0aW9uKG8pIHtcbiAgICAgICAgICAgIHJldHVybiBvLnNjb3BlID09PSBuYW1lO1xuICAgICAgICB9KTtcbiAgICAgICAgYXV0aC5zY29wZXNbaW5kZXhdLmNoZWNrZWQgPSB2YWw7XG5cbiAgICAgICAgdGhpcy5zZXQoYXV0aCk7XG4gICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWxpZCA9IGZhbHNlO1xuICAgICAgdmFyIHNjcCA9IHRoaXMuZ2V0KCdzY29wZXMnKTtcbiAgICAgIHZhciBpZHggPSAgXy5maW5kSW5kZXgoc2NwLCBmdW5jdGlvbiAobykge1xuICAgICAgICAgcmV0dXJuIG8uY2hlY2tlZCA9PT0gdHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICBpZihzY3AubGVuZ3RoID4gMCAmJiBpZHggPj0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYoc2NwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PYXV0aDJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2hhbmdlIC5vYXV0aC1zY29wZSc6ICdzY29wZUNoYW5nZSdcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLm9hdXRoMixcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBzY29wZUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnByb3AoJ2NoZWNrZWQnKTtcbiAgICAgICAgdmFyIHNjb3BlID0gJChlLnRhcmdldCkuZGF0YSgnc2NvcGUnKTtcblxuICAgICAgICB0aGlzLm1vZGVsLnNldFNjb3BlcyhzY29wZSwgdmFsKTtcbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PcGVyYXRpb25WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbnZvY2F0aW9uVXJsOiBudWxsLFxuXG4gIGV2ZW50czoge1xuICAgICdzdWJtaXQgLnNhbmRib3gnICAgICAgICAgOiAnc3VibWl0T3BlcmF0aW9uJyxcbiAgICAnY2xpY2sgLnN1Ym1pdCcgICAgICAgICAgIDogJ3N1Ym1pdE9wZXJhdGlvbicsXG4gICAgJ2NsaWNrIC5yZXNwb25zZV9oaWRlcicgICA6ICdoaWRlUmVzcG9uc2UnLFxuICAgICdjbGljayAudG9nZ2xlT3BlcmF0aW9uJyAgOiAndG9nZ2xlT3BlcmF0aW9uQ29udGVudCcsXG4gICAgJ21vdXNlZW50ZXIgLmFwaS1pYycgICAgICA6ICdtb3VzZUVudGVyJyxcbiAgICAnZGJsY2xpY2sgLmN1cmwnICAgICAgICAgIDogJ3NlbGVjdFRleHQnLFxuICAgICdjaGFuZ2UgW25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nIDogJ3Nob3dTbmlwcGV0J1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuICAgIHRoaXMuYXV0aHMgPSBvcHRzLmF1dGhzO1xuICAgIHRoaXMucGFyZW50SWQgPSB0aGlzLm1vZGVsLnBhcmVudElkO1xuICAgIHRoaXMubmlja25hbWUgPSB0aGlzLm1vZGVsLm5pY2tuYW1lO1xuICAgIHRoaXMubW9kZWwuZW5jb2RlZFBhcmVudElkID0gZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMucGFyZW50SWQpO1xuXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZyA9IG9wdHMuc3dhZ2dlck9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nO1xuXG4gICAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5zaG93UmVxdWVzdEhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5zaG93UmVxdWVzdEhlYWRlcnMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzZWxlY3RUZXh0OiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBkb2MgPSBkb2N1bWVudCxcbiAgICAgICAgdGV4dCA9IGV2ZW50LnRhcmdldC5maXJzdENoaWxkLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgc2VsZWN0aW9uO1xuICAgIGlmIChkb2MuYm9keS5jcmVhdGVUZXh0UmFuZ2UpIHtcbiAgICAgIHJhbmdlID0gZG9jdW1lbnQuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTtcbiAgICAgIHJhbmdlLm1vdmVUb0VsZW1lbnRUZXh0KHRleHQpO1xuICAgICAgcmFuZ2Uuc2VsZWN0KCk7XG4gICAgfSBlbHNlIGlmICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSB7XG4gICAgICBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dCk7XG4gICAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICAgIH1cbiAgfSxcblxuICBtb3VzZUVudGVyOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW0gPSAkKHRoaXMuZWwpLmZpbmQoJy5jb250ZW50Jyk7XG4gICAgdmFyIHggPSBlLnBhZ2VYO1xuICAgIHZhciB5ID0gZS5wYWdlWTtcbiAgICB2YXIgc2NYID0gJCh3aW5kb3cpLnNjcm9sbExlZnQoKTtcbiAgICB2YXIgc2NZID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuICAgIHZhciBzY01heFggPSBzY1ggKyAkKHdpbmRvdykud2lkdGgoKTtcbiAgICB2YXIgc2NNYXhZID0gc2NZICsgJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgIHZhciB3ZCA9IGVsZW0ud2lkdGgoKTtcbiAgICB2YXIgaGdoID0gZWxlbS5oZWlnaHQoKTtcblxuICAgIGlmICh4ICsgd2QgPiBzY01heFgpIHtcbiAgICAgIHggPSBzY01heFggLSB3ZDtcbiAgICB9XG5cbiAgICBpZiAoeCA8IHNjWCkge1xuICAgICAgeCA9IHNjWDtcbiAgICB9XG5cbiAgICBpZiAoeSArIGhnaCA+IHNjTWF4WSkge1xuICAgICAgeSA9IHNjTWF4WSAtIGhnaDtcbiAgICB9XG5cbiAgICBpZiAoeSA8IHNjWSkge1xuICAgICAgeSA9IHNjWTtcbiAgICB9XG5cbiAgICB2YXIgcG9zID0ge307XG4gICAgcG9zLnRvcCA9IHk7XG4gICAgcG9zLmxlZnQgPSB4O1xuICAgIGVsZW0uY3NzKHBvcyk7XG4gIH0sXG5cbiAgLy8gTm90ZTogY29waWVkIGZyb20gQ29mZmVlU2NyaXB0IGNvbXBpbGVkIGZpbGVcbiAgLy8gVE9ETzogcmVmYWN0b3JcbiAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYSwgYXV0aCwgYXV0aHMsIGNvZGUsIGNvbnRlbnRUeXBlTW9kZWwsIGlzTWV0aG9kU3VibWlzc2lvblN1cHBvcnRlZCwgaywga2V5LCBsLCBsZW4sIGxlbjEsIGxlbjIsIGxlbjMsIGxlbjQsIG0sIG1vZGVsQXV0aHMsIG4sIG8sIHAsIHBhcmFtLCBxLCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LCByZXNwb25zZVNpZ25hdHVyZVZpZXcsIHNjaGVtYSwgc2NoZW1hT2JqLCBzY29wZUluZGV4LCBzaWduYXR1cmVNb2RlbCwgc3RhdHVzQ29kZSwgc3VjY2Vzc1Jlc3BvbnNlLCB0eXBlLCB2LCB2YWx1ZSwgcHJvZHVjZXMsIGlzWE1MLCBpc0pTT047XG4gICAgaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkID0galF1ZXJ5LmluQXJyYXkodGhpcy5tb2RlbC5tZXRob2QsIHRoaXMubW9kZWwuc3VwcG9ydGVkU3VibWl0TWV0aG9kcygpKSA+PSAwO1xuICAgIGlmICghaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLm1vZGVsLmlzUmVhZE9ubHkgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbiB8fCB0aGlzLm1vZGVsLm5vdGVzO1xuICAgIHRoaXMubW9kZWwub2F1dGggPSBudWxsO1xuICAgIG1vZGVsQXV0aHMgPSB0aGlzLm1vZGVsLmF1dGhvcml6YXRpb25zIHx8IHRoaXMubW9kZWwuc2VjdXJpdHk7XG4gICAgaWYgKG1vZGVsQXV0aHMpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsQXV0aHMpKSB7XG4gICAgICAgIGZvciAobCA9IDAsIGxlbiA9IG1vZGVsQXV0aHMubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgICAgICBhdXRocyA9IG1vZGVsQXV0aHNbbF07XG4gICAgICAgICAgZm9yIChrZXkgaW4gYXV0aHMpIHtcbiAgICAgICAgICAgIGZvciAoYSBpbiB0aGlzLmF1dGhzKSB7XG4gICAgICAgICAgICAgIGF1dGggPSB0aGlzLmF1dGhzW2FdO1xuICAgICAgICAgICAgICBpZiAoa2V5ID09PSBhdXRoLm5hbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXV0aC50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aCA9IHt9O1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgIHJlZjEgPSBhdXRoLnZhbHVlLnNjb3BlcztcbiAgICAgICAgICAgICAgICAgIGZvciAoayBpbiByZWYxKSB7XG4gICAgICAgICAgICAgICAgICAgIHYgPSByZWYxW2tdO1xuICAgICAgICAgICAgICAgICAgICBzY29wZUluZGV4ID0gYXV0aHNba2V5XS5pbmRleE9mKGspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NvcGVJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlOiBrLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHZcbiAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzLnB1c2gobyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoayBpbiBtb2RlbEF1dGhzKSB7XG4gICAgICAgICAgdiA9IG1vZGVsQXV0aHNba107XG4gICAgICAgICAgaWYgKGsgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChtID0gMCwgbGVuMSA9IHYubGVuZ3RoOyBtIDwgbGVuMTsgbSsrKSB7XG4gICAgICAgICAgICAgIG8gPSB2W21dO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3Blcy5wdXNoKG8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID0gW107XG4gICAgICByZWYyID0gdGhpcy5tb2RlbC5yZXNwb25zZXM7XG4gICAgICBmb3IgKGNvZGUgaW4gcmVmMikge1xuICAgICAgICB2YWx1ZSA9IHJlZjJbY29kZV07XG4gICAgICAgIHNjaGVtYSA9IG51bGw7XG4gICAgICAgIHNjaGVtYU9iaiA9IHRoaXMubW9kZWwucmVzcG9uc2VzW2NvZGVdLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYU9iaiAmJiBzY2hlbWFPYmouJHJlZikge1xuICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYU9iai4kcmVmO1xuICAgICAgICAgIGlmIChzY2hlbWEuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYS5yZXBsYWNlKC9eLiojXFwvZGVmaW5pdGlvbnNcXC8vLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICBjb2RlOiBjb2RlLFxuICAgICAgICAgIG1lc3NhZ2U6IHZhbHVlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIHJlc3BvbnNlTW9kZWw6IHNjaGVtYSxcbiAgICAgICAgICBoZWFkZXJzOiB2YWx1ZS5oZWFkZXJzLFxuICAgICAgICAgIHNjaGVtYTogc2NoZW1hT2JqXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9IFtdO1xuICAgIH1cbiAgICBzaWduYXR1cmVNb2RlbCA9IG51bGw7XG4gICAgcHJvZHVjZXMgPSB0aGlzLm1vZGVsLnByb2R1Y2VzO1xuICAgIGlzWE1MID0gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ3htbCcpO1xuICAgIGlzSlNPTiA9IGlzWE1MID8gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ2pzb24nKSA6IHRydWU7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5zdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMubW9kZWwuc3VjY2Vzc1Jlc3BvbnNlO1xuICAgICAgZm9yIChrZXkgaW4gc3VjY2Vzc1Jlc3BvbnNlKSB7XG4gICAgICAgIHZhbHVlID0gc3VjY2Vzc1Jlc3BvbnNlW2tleV07XG4gICAgICAgIHRoaXMubW9kZWwuc3VjY2Vzc0NvZGUgPSBrZXk7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWx1ZS5jcmVhdGVKU09OU2FtcGxlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5zdWNjZXNzRGVzY3JpcHRpb24gPSB2YWx1ZS5kZXNjcmlwdGlvbjtcbiAgICAgICAgICB0aGlzLm1vZGVsLmhlYWRlcnMgPSB0aGlzLnBhcnNlUmVzcG9uc2VIZWFkZXJzKHZhbHVlLmhlYWRlcnMpO1xuICAgICAgICAgIHNpZ25hdHVyZU1vZGVsID0ge1xuICAgICAgICAgICAgc2FtcGxlSlNPTjogaXNKU09OID8gSlNPTi5zdHJpbmdpZnkoU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVKU09OU2FtcGxlKHZhbHVlKSwgdm9pZCAwLCAyKSA6IGZhbHNlLFxuICAgICAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgICAgICBzYW1wbGVYTUw6IGlzWE1MID8gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVYTUxTYW1wbGUodmFsdWUubmFtZSwgdmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzKSA6IGZhbHNlLFxuICAgICAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldE1vZGVsU2lnbmF0dXJlKHZhbHVlLm5hbWUsIHZhbHVlLmRlZmluaXRpb24sIHZhbHVlLm1vZGVscywgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0UHJpbWl0aXZlU2lnbmF0dXJlKHZhbHVlKVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSAmJiB0aGlzLm1vZGVsLnJlc3BvbnNlQ2xhc3NTaWduYXR1cmUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgICAgc2FtcGxlSlNPTjogdGhpcy5tb2RlbC5yZXNwb25zZVNhbXBsZUpTT04sXG4gICAgICAgIGlzUGFyYW06IGZhbHNlLFxuICAgICAgICBzaWduYXR1cmU6IHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZVxuICAgICAgfTtcbiAgICB9XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLm9wZXJhdGlvbih0aGlzLm1vZGVsKSk7XG4gICAgaWYgKHNpZ25hdHVyZU1vZGVsKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbC5kZWZhdWx0UmVuZGVyaW5nID0gdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nO1xuICAgICAgcmVzcG9uc2VTaWduYXR1cmVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHtcbiAgICAgICAgbW9kZWw6IHNpZ25hdHVyZU1vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICB0YWdOYW1lOiAnZGl2J1xuICAgICAgfSk7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlU2lnbmF0dXJlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9ICdzdHJpbmcnO1xuICAgICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsICQodGhpcy5lbCkpLmh0bWwodGhpcy5tb2RlbC50eXBlKTtcbiAgICB9XG4gICAgY29udGVudFR5cGVNb2RlbCA9IHtcbiAgICAgIGlzUGFyYW06IGZhbHNlXG4gICAgfTtcbiAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gdGhpcy5tb2RlbC5jb25zdW1lcztcbiAgICBjb250ZW50VHlwZU1vZGVsLnByb2R1Y2VzID0gdGhpcy5tb2RlbC5wcm9kdWNlcztcbiAgICByZWYzID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAobiA9IDAsIGxlbjIgPSByZWYzLmxlbmd0aDsgbiA8IGxlbjI7IG4rKykge1xuICAgICAgcGFyYW0gPSByZWYzW25dO1xuICAgICAgdHlwZSA9IHBhcmFtLnR5cGUgfHwgcGFyYW0uZGF0YVR5cGUgfHwgJyc7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHNjaGVtYSA9IHBhcmFtLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYSAmJiBzY2hlbWEuJHJlZikge1xuICAgICAgICAgIHJlZiA9IHNjaGVtYS4kcmVmO1xuICAgICAgICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgICAgICAgdHlwZSA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0eXBlID0gcmVmO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHR5cGUgJiYgdHlwZS50b0xvd2VyQ2FzZSgpID09PSAnZmlsZScpIHtcbiAgICAgICAgaWYgKCFjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzKSB7XG4gICAgICAgICAgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFyYW0udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyh7XG4gICAgICBtb2RlbDogY29udGVudFR5cGVNb2RlbCxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXJcbiAgICB9KTtcbiAgICAkKCcucmVzcG9uc2UtY29udGVudC10eXBlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICByZWY0ID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAocCA9IDAsIGxlbjMgPSByZWY0Lmxlbmd0aDsgcCA8IGxlbjM7IHArKykge1xuICAgICAgcGFyYW0gPSByZWY0W3BdO1xuICAgICAgdGhpcy5hZGRQYXJhbWV0ZXIocGFyYW0sIGNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMpO1xuICAgIH1cbiAgICByZWY1ID0gdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzO1xuICAgIGZvciAocSA9IDAsIGxlbjQgPSByZWY1Lmxlbmd0aDsgcSA8IGxlbjQ7IHErKykge1xuICAgICAgc3RhdHVzQ29kZSA9IHJlZjVbcV07XG4gICAgICBzdGF0dXNDb2RlLmlzWE1MID0gaXNYTUw7XG4gICAgICBzdGF0dXNDb2RlLmlzSlNPTiA9IGlzSlNPTjtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzdGF0dXNDb2RlLmhlYWRlcnMpKSB7XG4gICAgICAgIHN0YXR1c0NvZGUuaGVhZGVycyA9IHRoaXMucGFyc2VIZWFkZXJzVHlwZShzdGF0dXNDb2RlLmhlYWRlcnMpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZGRTdGF0dXNDb2RlKHN0YXR1c0NvZGUpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMubW9kZWwuc2VjdXJpdHkpKSB7XG4gICAgICB2YXIgYXV0aHNNb2RlbCA9IFN3YWdnZXJVaS51dGlscy5wYXJzZVNlY3VyaXR5RGVmaW5pdGlvbnModGhpcy5tb2RlbC5zZWN1cml0eSwgdGhpcy5tb2RlbC5wYXJlbnQuc2VjdXJpdHlEZWZpbml0aW9ucyk7XG5cbiAgICAgIGF1dGhzTW9kZWwuaXNMb2dvdXQgPSAhXy5pc0VtcHR5KHRoaXMubW9kZWwuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHopO1xuICAgICAgdGhpcy5hdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aEJ1dHRvblZpZXcoe1xuICAgICAgICBkYXRhOiBhdXRoc01vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICBpc09wZXJhdGlvbjogdHJ1ZSxcbiAgICAgICAgbW9kZWw6IHtcbiAgICAgICAgICBzY29wZXM6IGF1dGhzTW9kZWwuc2NvcGVzXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy4kKCcuYXV0aG9yaXplLXdyYXBwZXInKS5hcHBlbmQodGhpcy5hdXRoVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfVxuXG4gICAgdGhpcy5zaG93U25pcHBldCgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHBhcnNlSGVhZGVyc1R5cGU6IGZ1bmN0aW9uIChoZWFkZXJzKSB7XG4gICAgdmFyIG1hcCA9IHtcbiAgICAgICdzdHJpbmcnOiB7XG4gICAgICAgICdkYXRlLXRpbWUnOiAnZGF0ZVRpbWUnLFxuICAgICAgICAnZGF0ZScgICAgIDogJ2RhdGUnXG4gICAgICB9XG4gICAgfTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICBoZWFkZXIgPSBoZWFkZXIgfHwge307XG4gICAgICB2YWx1ZSA9IG1hcFtoZWFkZXIudHlwZV0gJiYgbWFwW2hlYWRlci50eXBlXVtoZWFkZXIuZm9ybWF0XTtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgaGVhZGVyLnR5cGUgPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAocHJvZHVjZXMsIHR5cGUpIHtcbiAgICByZXR1cm4gcHJvZHVjZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICh2YWwuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pLmxlbmd0aDtcbiAgfSxcblxuICBwYXJzZVJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB2YXIgSEVBREVSU19TRVBBUkFUT1IgPSAnOyAnO1xuICAgIHZhciBoZWFkZXJzID0gXy5jbG9uZShkYXRhKTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgb3RoZXIgPSBbXTtcbiAgICAgIF8uZm9yRWFjaChoZWFkZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0gWyd0eXBlJywgJ2Rlc2NyaXB0aW9uJ107XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmluZGV4T2Yoa2V5LnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICAgIG90aGVyLnB1c2goa2V5ICsgJzogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG90aGVyLmpvaW4oSEVBREVSU19TRVBBUkFUT1IpO1xuICAgICAgaGVhZGVyLm90aGVyID0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaGVhZGVycztcbiAgfSxcblxuICBhZGRQYXJhbWV0ZXI6IGZ1bmN0aW9uKHBhcmFtLCBjb25zdW1lcykge1xuICAgIC8vIFJlbmRlciBhIHBhcmFtZXRlclxuICAgIHBhcmFtLmNvbnN1bWVzID0gY29uc3VtZXM7XG4gICAgcGFyYW0uZGVmYXVsdFJlbmRlcmluZyA9IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZztcblxuICAgIC8vIENvcHkgdGhpcyBwYXJhbSBKU09OIHNwZWMgc28gdGhhdCBpdCB3aWxsIGJlIGF2YWlsYWJsZSBmb3IgSnNvbkVkaXRvclxuICAgIGlmKHBhcmFtLnNjaGVtYSl7XG4gICAgICAkLmV4dGVuZCh0cnVlLCBwYXJhbS5zY2hlbWEsIHRoaXMubW9kZWwuZGVmaW5pdGlvbnNbcGFyYW0udHlwZV0pO1xuICAgICAgcGFyYW0uc2NoZW1hLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcbiAgICAgIC8vIFRoaXMgaXMgcmVxdWlyZWQgZm9yIEpzb25FZGl0b3IgdG8gZGlzcGxheSB0aGUgcm9vdCBwcm9wZXJseVxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50eXBlKXtcbiAgICAgICAgcGFyYW0uc2NoZW1hLnR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICAgIC8vIFRoaXMgaXMgdGhlIHRpdGxlIHRoYXQgd2lsbCBiZSB1c2VkIGJ5IEpzb25FZGl0b3IgZm9yIHRoZSByb290XG4gICAgICAvLyBTaW5jZSB3ZSBhbHJlYWR5IGRpc3BsYXkgdGhlIHBhcmFtZXRlcidzIG5hbWUgaW4gdGhlIFBhcmFtZXRlciBjb2x1bW5cbiAgICAgIC8vIFdlIHNldCB0aGlzIHRvIHNwYWNlLCB3ZSBjYW4ndCBzZXQgaXQgdG8gbnVsbCBvciBzcGFjZSBvdGhlcndpc2UgSnNvbkVkaXRvclxuICAgICAgLy8gd2lsbCByZXBsYWNlIGl0IHdpdGggdGhlIHRleHQgXCJyb290XCIgd2hpY2ggd29uJ3QgbG9vayBnb29kIG9uIHNjcmVlblxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50aXRsZSl7XG4gICAgICAgIHBhcmFtLnNjaGVtYS50aXRsZSA9ICcgJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcGFyYW1WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJWaWV3KHtcbiAgICAgIG1vZGVsOiBwYXJhbSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByZWFkT25seTogdGhpcy5tb2RlbC5pc1JlYWRPbmx5LFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJy5vcGVyYXRpb24tcGFyYW1zJywgJCh0aGlzLmVsKSkuYXBwZW5kKHBhcmFtVmlldy5yZW5kZXIoKS5lbCk7XG4gIH0sXG5cbiAgYWRkU3RhdHVzQ29kZTogZnVuY3Rpb24oc3RhdHVzQ29kZSkge1xuICAgIC8vIFJlbmRlciBzdGF0dXMgY29kZXNcbiAgICBzdGF0dXNDb2RlLmRlZmF1bHRSZW5kZXJpbmcgPSB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmc7XG4gICAgdmFyIHN0YXR1c0NvZGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TdGF0dXNDb2RlVmlldyh7XG4gICAgICBtb2RlbDogc3RhdHVzQ29kZSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyXG4gICAgfSk7XG4gICAgJCgnLm9wZXJhdGlvbi1zdGF0dXMnLCAkKHRoaXMuZWwpKS5hcHBlbmQoc3RhdHVzQ29kZVZpZXcucmVuZGVyKCkuZWwpO1xuICB9LFxuXG4gIC8vIE5vdGU6IGNvcGllZCBmcm9tIENvZmZlZVNjcmlwdCBjb21waWxlZCBmaWxlXG4gIC8vIFRPRE86IHJlZGFjdG9yXG4gIHN1Ym1pdE9wZXJhdGlvbjogZnVuY3Rpb24oZSkge1xuICAgIHZhciBlcnJvcl9mcmVlLCBmb3JtLCBpc0ZpbGVVcGxvYWQsIG1hcCwgb3B0cztcbiAgICBpZiAoZSAhPT0gbnVsbCkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBmb3JtID0gJCgnLnNhbmRib3gnLCAkKHRoaXMuZWwpKTtcbiAgICBlcnJvcl9mcmVlID0gdHJ1ZTtcbiAgICBmb3JtLmZpbmQoJ2lucHV0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9ybS5maW5kKCd0ZXh0YXJlYS5yZXF1aXJlZDp2aXNpYmxlJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZvcm0uZmluZCgnc2VsZWN0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEluZGV4ID09PSAtMSkge1xuICAgICAgICAkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuICAgICAgICAkKHRoaXMpLndpZ2dsZSh7XG4gICAgICAgICAgY2FsbGJhY2s6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChlcnJvcl9mcmVlKSB7XG4gICAgICBtYXAgPSB0aGlzLmdldElucHV0TWFwKGZvcm0pO1xuICAgICAgaXNGaWxlVXBsb2FkID0gdGhpcy5pc0ZpbGVVcGxvYWQoZm9ybSk7XG4gICAgICBvcHRzID0ge1xuICAgICAgICBwYXJlbnQ6IHRoaXNcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAgIGZvcih2YXIga2V5IGluIHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucykge1xuICAgICAgICAgIG9wdHNba2V5XSA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1trZXldO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBwaTtcbiAgICAgIGZvcihwaSA9IDA7IHBpIDwgdGhpcy5tb2RlbC5wYXJhbWV0ZXJzLmxlbmd0aDsgcGkrKyl7XG4gICAgICAgIHZhciBwID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzW3BpXTtcbiAgICAgICAgaWYoIHAuanNvbkVkaXRvciAmJiBwLmpzb25FZGl0b3IuaXNFbmFibGVkKCkpe1xuICAgICAgICAgIHZhciBqc29uID0gcC5qc29uRWRpdG9yLmdldFZhbHVlKCk7XG4gICAgICAgICAgbWFwW3AubmFtZV0gPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgPSAkKCdkaXYgc2VsZWN0W25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nLCAkKHRoaXMuZWwpKS52YWwoKTtcbiAgICAgIG9wdHMucmVxdWVzdENvbnRlbnRUeXBlID0gJCgnZGl2IHNlbGVjdFtuYW1lPXBhcmFtZXRlckNvbnRlbnRUeXBlXScsICQodGhpcy5lbCkpLnZhbCgpO1xuICAgICAgJCgnLnJlc3BvbnNlX3Rocm9iYmVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICAgaWYgKGlzRmlsZVVwbG9hZCkge1xuICAgICAgICAkKCcucmVxdWVzdF91cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPjwvcHJlPicpO1xuICAgICAgICAkKCcucmVxdWVzdF91cmwgcHJlJywgJCh0aGlzLmVsKSkudGV4dCh0aGlzLmludm9jYXRpb25VcmwpO1xuXG4gICAgICAgIG9wdHMudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgICAgICAgbWFwLnBhcmFtZXRlckNvbnRlbnRUeXBlID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGdldElucHV0TWFwOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciBtYXAsIHJlZjEsIGwsIGxlbiwgbywgcmVmMiwgbSwgbGVuMSwgdmFsLCByZWYzLCBuLCBsZW4yO1xuICAgIG1hcCA9IHt9O1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoKG8udmFsdWUgIT09IG51bGwpICYmIGpRdWVyeS50cmltKG8udmFsdWUpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSBvLnZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKG8udHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIG1hcFtvLm5hbWVdID0gby5maWxlc1swXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMiA9IGZvcm0uZmluZCgndGV4dGFyZWEnKTtcbiAgICBmb3IgKG0gPSAwLCBsZW4xID0gcmVmMi5sZW5ndGg7IG0gPCBsZW4xOyBtKyspIHtcbiAgICAgIG8gPSByZWYyW21dO1xuICAgICAgdmFsID0gdGhpcy5nZXRUZXh0QXJlYVZhbHVlKG8pO1xuICAgICAgaWYgKCh2YWwgIT09IG51bGwpICYmIGpRdWVyeS50cmltKHZhbCkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMyA9IGZvcm0uZmluZCgnc2VsZWN0Jyk7XG4gICAgZm9yIChuID0gMCwgbGVuMiA9IHJlZjMubGVuZ3RoOyBuIDwgbGVuMjsgbisrKSB7XG4gICAgICBvID0gcmVmM1tuXTtcbiAgICAgIHZhbCA9IHRoaXMuZ2V0U2VsZWN0ZWRWYWx1ZShvKTtcbiAgICAgIGlmICgodmFsICE9PSBudWxsKSAmJiBqUXVlcnkudHJpbSh2YWwpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSB2YWw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXA7XG4gIH0sXG5cbiAgaXNGaWxlVXBsb2FkOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciByZWYxLCBsLCBsZW4sIG87XG4gICAgdmFyIGlzRmlsZVVwbG9hZCA9IGZhbHNlO1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoby50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgaXNGaWxlVXBsb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzRmlsZVVwbG9hZDtcbiAgfSxcblxuICBzdWNjZXNzOiBmdW5jdGlvbihyZXNwb25zZSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dDb21wbGV0ZVN0YXR1cyhyZXNwb25zZSk7XG4gIH0sXG5cbiAgLy8gd3JhcHMgYSBqcXVlcnkgcmVzcG9uc2UgYXMgYSBzaHJlZCByZXNwb25zZVxuICB3cmFwOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgdmFyIGgsIGhlYWRlckFycmF5LCBoZWFkZXJzLCBpLCBsLCBsZW4sIG87XG4gICAgaGVhZGVycyA9IHt9O1xuICAgIGhlYWRlckFycmF5ID0gZGF0YS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxyJyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gaGVhZGVyQXJyYXkubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgIGkgPSBoZWFkZXJBcnJheVtsXTtcbiAgICAgIGggPSBpLm1hdGNoKC9eKFteOl0qPyk6KC4qKSQvKTtcbiAgICAgIGlmICghaCkge1xuICAgICAgICBoID0gW107XG4gICAgICB9XG4gICAgICBoLnNoaWZ0KCk7XG4gICAgICBpZiAoaFswXSAhPT0gdm9pZCAwICYmIGhbMV0gIT09IHZvaWQgMCkge1xuICAgICAgICBoZWFkZXJzW2hbMF0udHJpbSgpXSA9IGhbMV0udHJpbSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBvID0ge307XG4gICAgby5jb250ZW50ID0ge307XG4gICAgby5jb250ZW50LmRhdGEgPSBkYXRhLnJlc3BvbnNlVGV4dDtcbiAgICBvLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIG8ucmVxdWVzdCA9IHt9O1xuICAgIG8ucmVxdWVzdC51cmwgPSB0aGlzLmludm9jYXRpb25Vcmw7XG4gICAgby5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXR1cm4gbztcbiAgfSxcblxuICBnZXRTZWxlY3RlZFZhbHVlOiBmdW5jdGlvbihzZWxlY3QpIHtcbiAgICBpZiAoIXNlbGVjdC5tdWx0aXBsZSkge1xuICAgICAgcmV0dXJuIHNlbGVjdC52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9wdGlvbnMgPSBbXTtcbiAgICAgIGZvciAodmFyIGwgPSAwLCBsZW4gPSBzZWxlY3Qub3B0aW9ucy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgICB2YXIgb3B0ID0gc2VsZWN0Lm9wdGlvbnNbbF07XG4gICAgICAgIGlmIChvcHQuc2VsZWN0ZWQpIHtcbiAgICAgICAgICBvcHRpb25zLnB1c2gob3B0LnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBoaWRlIHJlc3BvbnNlIGxpbmtcbiAgaGlkZVJlc3BvbnNlOiBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVVcCgpO1xuICAgICQoJy5yZXNwb25zZV9oaWRlcicsICQodGhpcy5lbCkpLmZhZGVPdXQoKTtcbiAgfSxcblxuICAvLyBTaG93IHJlc3BvbnNlIGZyb20gc2VydmVyXG4gIHNob3dSZXNwb25zZTogZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICB2YXIgcHJldHR5SnNvbiA9IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLCBudWxsLCAnXFx0JykucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5odG1sKF8uZXNjYXBlKHByZXR0eUpzb24pKTtcbiAgfSxcblxuICAvLyBTaG93IGVycm9yIGZyb20gc2VydmVyXG4gIHNob3dFcnJvclN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dTdGF0dXMoZGF0YSk7XG4gIH0sXG5cbiAgLy8gc2hvdyB0aGUgc3RhdHVzIGNvZGVzXG4gIHNob3dDb21wbGV0ZVN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KXtcbiAgICBwYXJlbnQuc2hvd1N0YXR1cyhkYXRhKTtcbiAgfSxcblxuICAvLyBBZGFwdGVkIGZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjg5MzI1OS80NTQwMDRcbiAgLy8gTm90ZTogZGlyZWN0bHkgcG9ydGVkIGZyb20gQ29mZmVlU2NyaXB0XG4gIC8vIFRPRE86IENsZWFudXAgQ29mZmVlU2NyaXB0IGFydGlmYWN0c1xuICBmb3JtYXRYbWw6IGZ1bmN0aW9uKHhtbCkge1xuICAgIHZhciBjb250ZXhwLCBmbiwgZm9ybWF0dGVkLCBpbmRlbnQsIGwsIGxhc3RUeXBlLCBsZW4sIGxpbmVzLCBsbiwgcGFkLCByZWcsIHRyYW5zaXRpb25zLCB3c2V4cDtcbiAgICByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gICAgd3NleHAgPSAvWyBdKiguKilbIF0rXFxuL2c7XG4gICAgY29udGV4cCA9IC8oPC4rPikoLitcXG4pL2c7XG4gICAgeG1sID0geG1sLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykucmVwbGFjZShyZWcsICckMVxcbiQyJDMnKS5yZXBsYWNlKHdzZXhwLCAnJDFcXG4nKS5yZXBsYWNlKGNvbnRleHAsICckMVxcbiQyJyk7XG4gICAgcGFkID0gMDtcbiAgICBmb3JtYXR0ZWQgPSAnJztcbiAgICBsaW5lcyA9IHhtbC5zcGxpdCgnXFxuJyk7XG4gICAgaW5kZW50ID0gMDtcbiAgICBsYXN0VHlwZSA9ICdvdGhlcic7XG4gICAgdHJhbnNpdGlvbnMgPSB7XG4gICAgICAnc2luZ2xlLT5zaW5nbGUnOiAwLFxuICAgICAgJ3NpbmdsZS0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ3NpbmdsZS0+b3BlbmluZyc6IDAsXG4gICAgICAnc2luZ2xlLT5vdGhlcic6IDAsXG4gICAgICAnY2xvc2luZy0+c2luZ2xlJzogMCxcbiAgICAgICdjbG9zaW5nLT5jbG9zaW5nJzogLTEsXG4gICAgICAnY2xvc2luZy0+b3BlbmluZyc6IDAsXG4gICAgICAnY2xvc2luZy0+b3RoZXInOiAwLFxuICAgICAgJ29wZW5pbmctPnNpbmdsZSc6IDEsXG4gICAgICAnb3BlbmluZy0+Y2xvc2luZyc6IDAsXG4gICAgICAnb3BlbmluZy0+b3BlbmluZyc6IDEsXG4gICAgICAnb3BlbmluZy0+b3RoZXInOiAxLFxuICAgICAgJ290aGVyLT5zaW5nbGUnOiAwLFxuICAgICAgJ290aGVyLT5jbG9zaW5nJzogLTEsXG4gICAgICAnb3RoZXItPm9wZW5pbmcnOiAwLFxuICAgICAgJ290aGVyLT5vdGhlcic6IDBcbiAgICB9O1xuICAgIGZuID0gZnVuY3Rpb24obG4pIHtcbiAgICAgIHZhciBmcm9tVG8sIGosIGtleSwgcGFkZGluZywgdHlwZSwgdHlwZXMsIHZhbHVlO1xuICAgICAgdHlwZXMgPSB7XG4gICAgICAgIHNpbmdsZTogQm9vbGVhbihsbi5tYXRjaCgvPC4rXFwvPi8pKSxcbiAgICAgICAgY2xvc2luZzogQm9vbGVhbihsbi5tYXRjaCgvPFxcLy4rPi8pKSxcbiAgICAgICAgb3BlbmluZzogQm9vbGVhbihsbi5tYXRjaCgvPFteIT9dLio+LykpXG4gICAgICB9O1xuICAgICAgdHlwZSA9ICgoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZXN1bHRzO1xuICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIHR5cGVzKSB7XG4gICAgICAgICAgdmFsdWUgPSB0eXBlc1trZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSkoKSlbMF07XG4gICAgICB0eXBlID0gdHlwZSA9PT0gdm9pZCAwID8gJ290aGVyJyA6IHR5cGU7XG4gICAgICBmcm9tVG8gPSBsYXN0VHlwZSArICctPicgKyB0eXBlO1xuICAgICAgbGFzdFR5cGUgPSB0eXBlO1xuICAgICAgcGFkZGluZyA9ICcnO1xuICAgICAgaW5kZW50ICs9IHRyYW5zaXRpb25zW2Zyb21Ub107XG4gICAgICBwYWRkaW5nID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG0sIHJlZjEsIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChqID0gbSA9IDAsIHJlZjEgPSBpbmRlbnQ7IDAgPD0gcmVmMSA/IG0gPCByZWYxIDogbSA+IHJlZjE7IGogPSAwIDw9IHJlZjEgPyArK20gOiAtLW0pIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goJyAgJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKS5qb2luKCcnKTtcbiAgICAgIGlmIChmcm9tVG8gPT09ICdvcGVuaW5nLT5jbG9zaW5nJykge1xuICAgICAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQuc3Vic3RyKDAsIGZvcm1hdHRlZC5sZW5ndGggLSAxKSArIGxuICsgJ1xcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JtYXR0ZWQgKz0gcGFkZGluZyArIGxuICsgJ1xcbic7XG4gICAgICB9XG4gICAgfTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSBsaW5lcy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbG4gPSBsaW5lc1tsXTtcbiAgICAgIGZuKGxuKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZDtcbiAgfSxcblxuICAvLyBwdXRzIHRoZSByZXNwb25zZSBkYXRhIGluIFVJXG4gIHNob3dTdGF0dXM6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgdmFyIHVybCwgY29udGVudDtcbiAgICBpZiAocmVzcG9uc2UuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250ZW50ID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudCA9IHJlc3BvbnNlLmNvbnRlbnQuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnJlcXVlc3QudXJsO1xuICAgIH1cbiAgICB2YXIgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb250ZW50ID0galF1ZXJ5LnRyaW0oY29udGVudCk7XG4gICAgfVxuXG4gICAgLy8gaWYgc2VydmVyIGlzIG5pY2UsIGFuZCBzZW5kcyBjb250ZW50LXR5cGUgYmFjaywgd2UgY2FuIHVzZSBpdFxuICAgIHZhciBjb250ZW50VHlwZSA9IG51bGw7XG4gICAgaWYgKGhlYWRlcnMpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ10gfHwgaGVhZGVyc1snY29udGVudC10eXBlJ107XG4gICAgICBpZiAoY29udGVudFR5cGUpIHtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZS5zcGxpdCgnOycpWzBdLnRyaW0oKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdqc29uJyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygneG1sJyk7XG5cbiAgICB2YXIgc3VwcG9ydHNBdWRpb1BsYXliYWNrID0gZnVuY3Rpb24oY29udGVudFR5cGUpe1xuICAgICAgdmFyIGF1ZGlvRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2F1ZGlvJyk7XG4gICAgICByZXR1cm4gISEoYXVkaW9FbGVtZW50LmNhblBsYXlUeXBlICYmIGF1ZGlvRWxlbWVudC5jYW5QbGF5VHlwZShjb250ZW50VHlwZSkucmVwbGFjZSgvbm8vLCAnJykpO1xuICAgIH07XG5cbiAgICB2YXIgcHJlO1xuICAgIHZhciBjb2RlO1xuICAgIGlmICghY29udGVudCkge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dCgnbm8gY29udGVudCcpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cImpzb25cIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gSlNPTlxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyB8fFxuICAgICAgICBoZWFkZXJzWydDb250ZW50LURpc3Bvc2l0aW9uJ10gJiYgKC9hdHRhY2htZW50LykudGVzdChoZWFkZXJzWydDb250ZW50LURpc3Bvc2l0aW9uJ10pIHx8XG4gICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZGlzcG9zaXRpb24nXSAmJiAoL2F0dGFjaG1lbnQvKS50ZXN0KGhlYWRlcnNbJ2NvbnRlbnQtZGlzcG9zaXRpb24nXSkgfHxcbiAgICAgICAgaGVhZGVyc1snQ29udGVudC1EZXNjcmlwdGlvbiddICYmICgvRmlsZSBUcmFuc2Zlci8pLnRlc3QoaGVhZGVyc1snQ29udGVudC1EZXNjcmlwdGlvbiddKSB8fFxuICAgICAgICBoZWFkZXJzWydjb250ZW50LWRlc2NyaXB0aW9uJ10gJiYgKC9GaWxlIFRyYW5zZmVyLykudGVzdChoZWFkZXJzWydjb250ZW50LWRlc2NyaXB0aW9uJ10pKSB7XG5cbiAgICAgIGlmICgnQmxvYicgaW4gd2luZG93KSB7XG4gICAgICAgIHZhciB0eXBlID0gY29udGVudFR5cGUgfHwgJ3RleHQvaHRtbCc7XG4gICAgICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgICB2YXIgaHJlZjtcblxuICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseShjb250ZW50KSA9PT0gJ1tvYmplY3QgQmxvYl0nKSB7XG4gICAgICAgICAgaHJlZiA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGNvbnRlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBiaW5hcnlEYXRhID0gW107XG4gICAgICAgICAgYmluYXJ5RGF0YS5wdXNoKGNvbnRlbnQpO1xuICAgICAgICAgIGhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihiaW5hcnlEYXRhLCB7dHlwZTogdHlwZX0pKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZmlsZU5hbWUgPSByZXNwb25zZS51cmwuc3Vic3RyKHJlc3BvbnNlLnVybC5sYXN0SW5kZXhPZignLycpICsgMSk7XG4gICAgICAgIHZhciBkb3dubG9hZCA9IFt0eXBlLCBmaWxlTmFtZSwgaHJlZl0uam9pbignOicpO1xuXG4gICAgICAgIC8vIFVzZSBmaWxlbmFtZSBmcm9tIHJlc3BvbnNlIGhlYWRlclxuICAgICAgICB2YXIgZGlzcG9zaXRpb24gPSBoZWFkZXJzWydjb250ZW50LWRpc3Bvc2l0aW9uJ10gfHwgaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddO1xuICAgICAgICBpZih0eXBlb2YgZGlzcG9zaXRpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlRmlsZW5hbWUgPSAvZmlsZW5hbWU9KFteO10qKTs/Ly5leGVjKGRpc3Bvc2l0aW9uKTtcbiAgICAgICAgICBpZihyZXNwb25zZUZpbGVuYW1lICE9PSBudWxsICYmIHJlc3BvbnNlRmlsZW5hbWUubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgZG93bmxvYWQgPSByZXNwb25zZUZpbGVuYW1lWzFdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdkb3dubG9hZCcsIGRvd25sb2FkKTtcbiAgICAgICAgYS5pbm5lclRleHQgPSAnRG93bmxvYWQgJyArIGZpbGVOYW1lO1xuXG4gICAgICAgIHByZSA9ICQoJzxkaXYvPicpLmFwcGVuZChhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoJ0Rvd25sb2FkIGhlYWRlcnMgZGV0ZWN0ZWQgYnV0IHlvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGRvd25sb2FkaW5nIGJpbmFyeSB2aWEgWEhSIChCbG9iKS4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgL1xcK2pzb24kLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgdmFyIGpzb24gPSBudWxsO1xuICAgICAgdHJ5IHtcbiAgICAgICAganNvbiA9IEpTT04uc3RyaW5naWZ5KEpTT04ucGFyc2UoY29udGVudCksIG51bGwsICcgICcpO1xuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIGpzb24gPSAnY2FuXFwndCBwYXJzZSBKU09OLiAgUmF3IHJlc3VsdDpcXG5cXG4nICsgY29udGVudDtcbiAgICAgIH1cbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoanNvbik7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBYTUxcbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24veG1sJyB8fCAvXFwreG1sJC8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQodGhpcy5mb3JtYXRYbWwoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBIVE1MXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ3RleHQvaHRtbCcpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLmh0bWwoXy5lc2NhcGUoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBQbGFpbiBUZXh0XG4gICAgfSBlbHNlIGlmICgvdGV4dFxcL3BsYWluLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJwbGFpblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBJbWFnZVxuICAgIH0gZWxzZSBpZiAoL15pbWFnZVxcLy8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIHZhciB1cmxDcmVhdG9yID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMO1xuICAgICAgdmFyIGltYWdlVXJsID0gdXJsQ3JlYXRvci5jcmVhdGVPYmplY3RVUkwoY29udGVudCk7XG5cbiAgICAgIHByZSA9ICQoJzxpbWc+JykuYXR0ciggJ3NyYycsIGltYWdlVXJsKTtcbiAgICAgIC8vIEF1ZGlvXG4gICAgfSBlbHNlIGlmICgvXmF1ZGlvXFwvLy50ZXN0KGNvbnRlbnRUeXBlKSAmJiBzdXBwb3J0c0F1ZGlvUGxheWJhY2soY29udGVudFR5cGUpKSB7XG4gICAgICBwcmUgPSAkKCc8YXVkaW8gY29udHJvbHM+JykuYXBwZW5kKCQoJzxzb3VyY2U+JykuYXR0cignc3JjJywgdXJsKS5hdHRyKCd0eXBlJywgY29udGVudFR5cGUpKTtcbiAgICB9IGVsc2UgaWYoaGVhZGVycy5sb2NhdGlvbiB8fCBoZWFkZXJzLkxvY2F0aW9uKSB7XG4gICAgICAvLyBMb2NhdGlvbiBoZWFkZXIgYmFzZWQgcmVkaXJlY3QgZG93bmxvYWRcbiAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHJlc3BvbnNlLnVybDtcblxuICAgICAgLy8gQW55dGhpbmcgZWxzZSAoQ09SUylcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoY29kZSk7XG4gICAgfVxuICAgIHZhciByZXNwb25zZV9ib2R5ID0gcHJlO1xuICAgICQoJy5yZXF1ZXN0X3VybCcsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+PC9wcmU+Jyk7XG4gICAgJCgnLnJlcXVlc3RfdXJsIHByZScsICQodGhpcy5lbCkpLnRleHQodXJsKTtcbiAgICAkKCcucmVzcG9uc2VfY29kZScsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+JyArIHJlc3BvbnNlLnN0YXR1cyArICc8L3ByZT4nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLmh0bWwocmVzcG9uc2VfYm9keSk7XG4gICAgJCgnLnJlc3BvbnNlX2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXNwb25zZS5oZWFkZXJzLCBudWxsLCAnICAnKSkucmVwbGFjZSgvXFxuL2csICc8YnI+JykgKyAnPC9wcmU+Jyk7XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVEb3duKCk7XG4gICAgJCgnLnJlc3BvbnNlX2hpZGVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5yZXNwb25zZV90aHJvYmJlcicsICQodGhpcy5lbCkpLmhpZGUoKTtcblxuXG4gICAgLy8gYWRkcyBjdXJsIG91dHB1dFxuICAgIHZhciBjdXJsQ29tbWFuZCA9IHRoaXMubW9kZWwuYXNDdXJsKHRoaXMubWFwLCB7cmVzcG9uc2VDb250ZW50VHlwZTogY29udGVudFR5cGV9KTtcbiAgICBjdXJsQ29tbWFuZCA9IGN1cmxDb21tYW5kLnJlcGxhY2UoJyEnLCAnJiMzMzsnKTtcbiAgICAkKCAnZGl2LmN1cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShjdXJsQ29tbWFuZCkgKyAnPC9wcmU+Jyk7XG5cbiAgICAvLyBvbmx5IGhpZ2hsaWdodCB0aGUgcmVzcG9uc2UgaWYgcmVzcG9uc2UgaXMgbGVzcyB0aGFuIHRocmVzaG9sZCwgZGVmYXVsdCBzdGF0ZSBpcyBoaWdobGlnaHQgcmVzcG9uc2VcbiAgICB2YXIgb3B0cyA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucztcblxuICAgIGlmIChvcHRzLnNob3dSZXF1ZXN0SGVhZGVycykge1xuICAgICAgdmFyIGZvcm0gPSAkKCcuc2FuZGJveCcsICQodGhpcy5lbCkpLFxuICAgICAgICAgIG1hcCA9IHRoaXMuZ2V0SW5wdXRNYXAoZm9ybSksXG4gICAgICAgICAgcmVxdWVzdEhlYWRlcnMgPSB0aGlzLm1vZGVsLmdldEhlYWRlclBhcmFtcyhtYXApO1xuICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICAgICQoJy5yZXF1ZXN0X2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXF1ZXN0SGVhZGVycywgbnVsbCwgJyAgJykpLnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpICsgJzwvcHJlPicpO1xuICAgIH1cblxuICAgIHZhciByZXNwb25zZV9ib2R5X2VsID0gJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKVswXTtcbiAgICAvLyBvbmx5IGhpZ2hsaWdodCB0aGUgcmVzcG9uc2UgaWYgcmVzcG9uc2UgaXMgbGVzcyB0aGFuIHRocmVzaG9sZCwgZGVmYXVsdCBzdGF0ZSBpcyBoaWdobGlnaHQgcmVzcG9uc2VcbiAgICBpZiAob3B0cy5oaWdobGlnaHRTaXplVGhyZXNob2xkICYmIHR5cGVvZiByZXNwb25zZS5kYXRhICE9PSAndW5kZWZpbmVkJyAmJiByZXNwb25zZS5kYXRhLmxlbmd0aCA+IG9wdHMuaGlnaGxpZ2h0U2l6ZVRocmVzaG9sZCkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlX2JvZHlfZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBobGpzLmhpZ2hsaWdodEJsb2NrKHJlc3BvbnNlX2JvZHlfZWwpO1xuICAgIH1cbiAgfSxcblxuICB0b2dnbGVPcGVyYXRpb25Db250ZW50OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgZWxlbSA9ICQoJyMnICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUodGhpcy5wYXJlbnRJZCArICdfJyArIHRoaXMubmlja25hbWUgKyAnX2NvbnRlbnQnKSk7XG4gICAgaWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpe1xuICAgICAgJC5iYnEucHVzaFN0YXRlKCcjLycsIDIpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIERvY3MuY29sbGFwc2VPcGVyYXRpb24oZWxlbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIERvY3MuZXhwYW5kT3BlcmF0aW9uKGVsZW0pO1xuICAgIH1cbiAgfSxcblxuICBnZXRUZXh0QXJlYVZhbHVlOiBmdW5jdGlvbih0ZXh0QXJlYSkge1xuICAgIHZhciBwYXJhbSwgcGFyc2VkLCByZXN1bHQsIGk7XG4gICAgaWYgKHRleHRBcmVhLnZhbHVlID09PSBudWxsIHx8IGpRdWVyeS50cmltKHRleHRBcmVhLnZhbHVlKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBwYXJhbSA9IHRoaXMuZ2V0UGFyYW1CeU5hbWUodGV4dEFyZWEubmFtZSk7XG4gICAgaWYgKHBhcmFtICYmIHBhcmFtLnR5cGUgJiYgcGFyYW0udHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJzZWQgPSB0ZXh0QXJlYS52YWx1ZS5zcGxpdCgnXFxuJyk7XG4gICAgICByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBhcnNlZFtpXSAhPT0gbnVsbCAmJiBqUXVlcnkudHJpbShwYXJzZWRbaV0pLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXN1bHQucHVzaChwYXJzZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0Lmxlbmd0aCA+IDAgPyByZXN1bHQgOiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGV4dEFyZWEudmFsdWU7XG4gICAgfVxuICB9LFxuXG4gIHNob3dTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlRWwgPSB0aGlzLiQoJ1tuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyk7XG4gICAgdmFyIHhtbFNuaXBwZXRFbCA9IHRoaXMuJCgnLm9wZXJhdGlvbi1zdGF0dXMgLnNuaXBwZXRfeG1sLCAucmVzcG9uc2UtY2xhc3MgLnNuaXBwZXRfeG1sJyk7XG4gICAgdmFyIGpzb25TbmlwcGV0RWwgPSB0aGlzLiQoJy5vcGVyYXRpb24tc3RhdHVzIC5zbmlwcGV0X2pzb24sIC5yZXNwb25zZS1jbGFzcyAuc25pcHBldF9qc29uJyk7XG4gICAgdmFyIGNvbnRlbnRUeXBlO1xuXG4gICAgaWYgKCFjb250ZW50VHlwZUVsLmxlbmd0aCkgeyByZXR1cm47IH1cbiAgICBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlRWwudmFsKCk7XG5cbiAgICBpZiAoY29udGVudFR5cGUuaW5kZXhPZigneG1sJykgPiAtMSkge1xuICAgICAgeG1sU25pcHBldEVsLnNob3coKTtcbiAgICAgIGpzb25TbmlwcGV0RWwuaGlkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBqc29uU25pcHBldEVsLnNob3coKTtcbiAgICAgIHhtbFNuaXBwZXRFbC5oaWRlKCk7XG4gICAgfVxuICB9LFxuXG4gIGdldFBhcmFtQnlOYW1lOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIGk7XG4gICAgaWYgKHRoaXMubW9kZWwucGFyYW1ldGVycykge1xuICAgICAgZm9yKGkgPSAwOyBpIDwgdGhpcy5tb2RlbC5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnBhcmFtZXRlcnNbaV0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnBhcmFtZXRlcnNbaV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICAoKSB7fSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy5tb2RlbC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkID0gJ3BjdCcgKyBNYXRoLnJhbmRvbSgpO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbWV0ZXJfY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBldmVudHM6IHtcbiAgICAnY2hhbmdlIFtuYW1lPXBhcmFtZXRlckNvbnRlbnRUeXBlXScgOiAndG9nZ2xlUGFyYW1ldGVyU25pcHBldCdcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbigpe1xuICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lzQXJyYXknLCBmdW5jdGlvbihwYXJhbSwgb3B0cykge1xuICAgICAgdmFyIHBhcmFtVHlwZSA9IHBhcmFtLnR5cGUgJiYgcGFyYW0udHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKHBhcmFtVHlwZSA9PT0gJ2FycmF5JyB8fCBwYXJhbS5hbGxvd011bHRpcGxlKSB7XG4gICAgICAgIHJldHVybiBvcHRzLmZuKHRoaXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG9wdHMuaW52ZXJzZSh0aGlzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0eXBlID0gdGhpcy5tb2RlbC50eXBlIHx8IHRoaXMubW9kZWwuZGF0YVR5cGU7XG4gICAgdmFyIG1vZGVsVHlwZSA9IHRoaXMubW9kZWwubW9kZWxTaWduYXR1cmUudHlwZTtcbiAgICB2YXIgbW9kZWxEZWZpbml0aW9ucyA9IHRoaXMubW9kZWwubW9kZWxTaWduYXR1cmUuZGVmaW5pdGlvbnM7XG4gICAgdmFyIHNjaGVtYSA9IHRoaXMubW9kZWwuc2NoZW1hIHx8IHt9O1xuICAgIHZhciBjb25zdW1lcyA9IHRoaXMubW9kZWwuY29uc3VtZXMgfHwgW107XG4gICAgdmFyIHNhbXBsZUpTT04sIHNpZ25hdHVyZVZpZXc7XG5cbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuICAgICAgICBpZiAocmVmLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgICAgICB0eXBlID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHlwZSA9IHJlZjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubW9kZWwudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5tb2RlbC5wYXJhbVR5cGUgPSB0aGlzLm1vZGVsLmluIHx8IHRoaXMubW9kZWwucGFyYW1UeXBlO1xuICAgIHRoaXMubW9kZWwuaXNCb2R5ID0gdGhpcy5tb2RlbC5wYXJhbVR5cGUgPT09ICdib2R5JyB8fCB0aGlzLm1vZGVsLmluID09PSAnYm9keSc7XG4gICAgdGhpcy5tb2RlbC5pc0ZpbGUgPSB0eXBlICYmIHR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ2ZpbGUnO1xuXG4gICAgLy8gQWxsb3cgZm9yIGRlZmF1bHQgPT09IGZhbHNlXG4gICAgaWYodHlwZW9mIHRoaXMubW9kZWwuZGVmYXVsdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVmYXVsdCA9IHRoaXMubW9kZWwuZGVmYXVsdFZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMubW9kZWwuaGFzRGVmYXVsdCA9ICh0eXBlb2YgdGhpcy5tb2RlbC5kZWZhdWx0ICE9PSAndW5kZWZpbmVkJyk7XG4gICAgdGhpcy5tb2RlbC52YWx1ZUlkID0gJ20nICsgdGhpcy5tb2RlbC5uYW1lICsgTWF0aC5yYW5kb20oKTtcblxuICAgIGlmICh0aGlzLm1vZGVsLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgdGhpcy5tb2RlbC5pc0xpc3QgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBpc1hNTCA9IHRoaXMuY29udGFpbnMoY29uc3VtZXMsICd4bWwnKTtcbiAgICB2YXIgaXNKU09OID0gaXNYTUwgPyB0aGlzLmNvbnRhaW5zKGNvbnN1bWVzLCAnanNvbicpIDogdHJ1ZTtcbiAgICBzYW1wbGVKU09OID0gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlKG1vZGVsVHlwZSwgbW9kZWxEZWZpbml0aW9ucyk7XG5cbiAgICB2YXIgdGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlKCk7XG4gICAgJCh0aGlzLmVsKS5odG1sKHRlbXBsYXRlKHRoaXMubW9kZWwpKTtcblxuICAgIHZhciBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgIHNhbXBsZUpTT046IGlzSlNPTiA/IHNhbXBsZUpTT04gOiBmYWxzZSxcbiAgICAgIHNhbXBsZVhNTDogc2FtcGxlSlNPTiAmJiBpc1hNTCA/IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlWE1MU2FtcGxlKCcnLCBzY2hlbWEsIG1vZGVsRGVmaW5pdGlvbnMsIHRydWUpIDogZmFsc2UsXG4gICAgICBpc1BhcmFtOiB0cnVlLFxuICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlKG1vZGVsVHlwZSwgbW9kZWxEZWZpbml0aW9ucyksXG4gICAgICBkZWZhdWx0UmVuZGVyaW5nOiB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmdcbiAgICB9O1xuXG4gICAgaWYgKHNhbXBsZUpTT04pIHtcbiAgICAgIHNpZ25hdHVyZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe21vZGVsOiBzaWduYXR1cmVNb2RlbCwgdGFnTmFtZTogJ2Rpdid9KTtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5hcHBlbmQoc2lnbmF0dXJlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsICQodGhpcy5lbCkpLmh0bWwodGhpcy5tb2RlbC5zaWduYXR1cmUpO1xuICAgIH1cblxuICAgIHZhciBpc1BhcmFtID0gZmFsc2U7XG5cbiAgICBpZiggdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zLmpzb25FZGl0b3IgJiYgdGhpcy5tb2RlbC5pc0JvZHkgJiYgdGhpcy5tb2RlbC5zY2hlbWEpe1xuICAgICAgdmFyICRzZWxmID0gJCh0aGlzLmVsKTtcbiAgICAgIHRoaXMubW9kZWwuanNvbkVkaXRvciA9XG4gICAgICAgIC8qIGdsb2JhbCBKU09ORWRpdG9yICovXG4gICAgICAgIG5ldyBKU09ORWRpdG9yKCQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICB7c2NoZW1hOiB0aGlzLm1vZGVsLnNjaGVtYSwgc3RhcnR2YWwgOiB0aGlzLm1vZGVsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBhamF4OnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlX3Byb3BlcnRpZXM6dHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVfZWRpdF9qc29uOnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ubGliOiAnc3dhZ2dlcicgfSk7XG4gICAgICAvLyBUaGlzIGlzIHNvIHRoYXQgdGhlIHNpZ25hdHVyZSBjYW4gc2VuZCBiYWNrIHRoZSBzYW1wbGUgdG8gdGhlIGpzb24gZWRpdG9yXG4gICAgICAvLyBUT0RPOiBTaWduYXR1cmVWaWV3IHNob3VsZCBleHBvc2UgYW4gZXZlbnQgXCJvblNhbXBsZUNsaWNrZWRcIiBpbnN0ZWFkXG4gICAgICBzaWduYXR1cmVNb2RlbC5qc29uRWRpdG9yID0gdGhpcy5tb2RlbC5qc29uRWRpdG9yO1xuICAgICAgJCgnLmJvZHktdGV4dGFyZWEnLCAkc2VsZikuaGlkZSgpO1xuICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuc2hvdygpO1xuICAgICAgJCgnLnBhcmFtZXRlci1jb250ZW50LXR5cGUnLCAkc2VsZilcbiAgICAgICAgLmNoYW5nZShmdW5jdGlvbihlKXtcbiAgICAgICAgICAgIGlmKGUudGFyZ2V0LnZhbHVlID09PSAnYXBwbGljYXRpb24veG1sJyl7XG4gICAgICAgICAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLnNob3coKTtcbiAgICAgICAgICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuaGlkZSgpO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IuZGlzYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICAgICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuc2hvdygpO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IuZW5hYmxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG5cbiAgICBpZiAodGhpcy5tb2RlbC5pc0JvZHkpIHtcbiAgICAgIGlzUGFyYW0gPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBjb250ZW50VHlwZU1vZGVsID0ge1xuICAgICAgaXNQYXJhbTogaXNQYXJhbVxuICAgIH07XG5cbiAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gdGhpcy5tb2RlbC5jb25zdW1lcztcblxuICAgIGlmIChpc1BhcmFtKSB7XG4gICAgICB2YXIgcGFyYW1ldGVyQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcoe21vZGVsOiBjb250ZW50VHlwZU1vZGVsfSk7XG4gICAgICAkKCcucGFyYW1ldGVyLWNvbnRlbnQtdHlwZScsICQodGhpcy5lbCkpLmFwcGVuZChwYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgICAgdGhpcy50b2dnbGVQYXJhbWV0ZXJTbmlwcGV0KCk7XG4gICAgfVxuXG4gICAgZWxzZSB7XG4gICAgICB2YXIgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc3BvbnNlQ29udGVudFR5cGVWaWV3KHttb2RlbDogY29udGVudFR5cGVNb2RlbH0pO1xuICAgICAgJCgnLnJlc3BvbnNlLWNvbnRlbnQtdHlwZScsICQodGhpcy5lbCkpLmFwcGVuZChyZXNwb25zZUNvbnRlbnRUeXBlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgICB0aGlzLnRvZ2dsZVJlc3BvbnNlU25pcHBldCgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAoY29uc3VtZXMsIHR5cGUpIHtcbiAgICByZXR1cm4gY29uc3VtZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICh2YWwuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pLmxlbmd0aDtcbiAgfSxcblxuICB0b2dnbGVQYXJhbWV0ZXJTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gdGhpcy4kKCdbbmFtZT1wYXJhbWV0ZXJDb250ZW50VHlwZV0nKS52YWwoKTtcblxuICAgIHRoaXMudG9nZ2xlU25pcHBldChjb250ZW50VHlwZSk7XG4gIH0sXG5cbiAgdG9nZ2xlUmVzcG9uc2VTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRFbCA9IHRoaXMuJCgnW25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nKTtcblxuICAgIGlmICghY29udGVudEVsLmxlbmd0aCkgeyByZXR1cm47IH1cblxuICAgIHRoaXMudG9nZ2xlU25pcHBldChjb250ZW50RWwudmFsKCkpO1xuICB9LFxuXG4gIHRvZ2dsZVNuaXBwZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgdHlwZSA9IHR5cGUgfHwgJyc7XG4gICAgaWYgKHR5cGUuaW5kZXhPZigneG1sJykgPiAtMSkge1xuICAgICAgdGhpcy4kKCcuc25pcHBldF94bWwnKS5zaG93KCk7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X2pzb24nKS5oaWRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfanNvbicpLnNob3coKTtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfeG1sJykuaGlkZSgpO1xuICAgIH1cbiAgfSxcblxuICAvLyBSZXR1cm4gYW4gYXBwcm9wcmlhdGUgdGVtcGxhdGUgYmFzZWQgb24gaWYgdGhlIHBhcmFtZXRlciBpcyBhIGxpc3QsIHJlYWRvbmx5LCByZXF1aXJlZFxuICB0ZW1wbGF0ZTogZnVuY3Rpb24oKXtcbiAgICBpZiAodGhpcy5tb2RlbC5pc0xpc3QpIHtcbiAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9saXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnJlYWRPbmx5KSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtX3JlYWRvbmx5X3JlcXVpcmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9yZWFkb25seTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMubW9kZWwucmVxdWlyZWQpIHtcbiAgICAgICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fcmVxdWlyZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoganNoaW50IC1XMTIyICovXG5Td2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlID0gKGZ1bmN0aW9uICgpIHtcbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciByZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hLnNjaGVtYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjaGVtYTtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIHNpbXBsZVJlZiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKCcjL2RlZmluaXRpb25zLycubGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgZ2V0SW5saW5lTW9kZWwgPSBmdW5jdGlvbihpbmxpbmVTdHIpIHtcbiAgICBpZigvXklubGluZSBNb2RlbCBcXGQrJC8udGVzdChpbmxpbmVTdHIpICYmIHRoaXMuaW5saW5lTW9kZWxzKSB7XG4gICAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICAgIHZhciBtb2RlbCA9IHRoaXMuaW5saW5lTW9kZWxzW2lkXTtcbiAgICAgIHJldHVybiBtb2RlbDtcbiAgICB9XG4gICAgLy8gSSdtIHJldHVybmluZyBudWxsIGhlcmUsIHNob3VsZCBJIHJhdGhlciB0aHJvdyBhbiBlcnJvcj9cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGZvcm1hdFhtbCA9IGZ1bmN0aW9uKHhtbCkge1xuICAgIHZhciBjb250ZXhwLCBmbiwgZm9ybWF0dGVkLCBpbmRlbnQsIGwsIGxhc3RUeXBlLCBsZW4sIGxpbmVzLCBsbiwgcGFkLCByZWcsIHRyYW5zaXRpb25zLCB3c2V4cDtcbiAgICByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gICAgd3NleHAgPSAvWyBdKiguKilbIF0rXFxuL2c7XG4gICAgY29udGV4cCA9IC8oPC4rPikoLitcXG4pL2c7XG4gICAgeG1sID0geG1sLnJlcGxhY2UocmVnLCAnJDFcXG4kMiQzJykucmVwbGFjZSh3c2V4cCwgJyQxXFxuJykucmVwbGFjZShjb250ZXhwLCAnJDFcXG4kMicpO1xuICAgIHBhZCA9IDA7XG4gICAgZm9ybWF0dGVkID0gJyc7XG4gICAgbGluZXMgPSB4bWwuc3BsaXQoJ1xcbicpO1xuICAgIGluZGVudCA9IDA7XG4gICAgbGFzdFR5cGUgPSAnb3RoZXInO1xuICAgIHRyYW5zaXRpb25zID0ge1xuICAgICAgJ3NpbmdsZS0+c2luZ2xlJzogMCxcbiAgICAgICdzaW5nbGUtPmNsb3NpbmcnOiAtMSxcbiAgICAgICdzaW5nbGUtPm9wZW5pbmcnOiAwLFxuICAgICAgJ3NpbmdsZS0+b3RoZXInOiAwLFxuICAgICAgJ2Nsb3NpbmctPnNpbmdsZSc6IDAsXG4gICAgICAnY2xvc2luZy0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ2Nsb3NpbmctPm9wZW5pbmcnOiAwLFxuICAgICAgJ2Nsb3NpbmctPm90aGVyJzogMCxcbiAgICAgICdvcGVuaW5nLT5zaW5nbGUnOiAxLFxuICAgICAgJ29wZW5pbmctPmNsb3NpbmcnOiAwLFxuICAgICAgJ29wZW5pbmctPm9wZW5pbmcnOiAxLFxuICAgICAgJ29wZW5pbmctPm90aGVyJzogMSxcbiAgICAgICdvdGhlci0+c2luZ2xlJzogMCxcbiAgICAgICdvdGhlci0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ290aGVyLT5vcGVuaW5nJzogMCxcbiAgICAgICdvdGhlci0+b3RoZXInOiAwXG4gICAgfTtcbiAgICBmbiA9IGZ1bmN0aW9uKGxuKSB7XG4gICAgICB2YXIgZnJvbVRvLCBqLCBrZXksIHBhZGRpbmcsIHR5cGUsIHR5cGVzLCB2YWx1ZTtcbiAgICAgIHR5cGVzID0ge1xuICAgICAgICBzaW5nbGU6IEJvb2xlYW4obG4ubWF0Y2goLzwuK1xcLz4vKSksXG4gICAgICAgIGNsb3Npbmc6IEJvb2xlYW4obG4ubWF0Y2goLzxcXC8uKz4vKSksXG4gICAgICAgIG9wZW5pbmc6IEJvb2xlYW4obG4ubWF0Y2goLzxbXiE/XS4qPi8pKVxuICAgICAgfTtcbiAgICAgIHR5cGUgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGtleSBpbiB0eXBlcykge1xuICAgICAgICAgIHZhbHVlID0gdHlwZXNba2V5XTtcbiAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChrZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpWzBdO1xuICAgICAgdHlwZSA9IHR5cGUgPT09IHZvaWQgMCA/ICdvdGhlcicgOiB0eXBlO1xuICAgICAgZnJvbVRvID0gbGFzdFR5cGUgKyAnLT4nICsgdHlwZTtcbiAgICAgIGxhc3RUeXBlID0gdHlwZTtcbiAgICAgIHBhZGRpbmcgPSAnJztcbiAgICAgIGluZGVudCArPSB0cmFuc2l0aW9uc1tmcm9tVG9dO1xuICAgICAgcGFkZGluZyA9ICgoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtLCByZWYxLCByZXN1bHRzO1xuICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoaiA9IG0gPSAwLCByZWYxID0gaW5kZW50OyAwIDw9IHJlZjEgPyBtIDwgcmVmMSA6IG0gPiByZWYxOyBqID0gMCA8PSByZWYxID8gKyttIDogLS1tKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKCcgICcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSkoKSkuam9pbignJyk7XG4gICAgICBpZiAoZnJvbVRvID09PSAnb3BlbmluZy0+Y2xvc2luZycpIHtcbiAgICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnN1YnN0cigwLCBmb3JtYXR0ZWQubGVuZ3RoIC0gMSkgKyBsbiArICdcXG4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9ybWF0dGVkICs9IHBhZGRpbmcgKyBsbiArICdcXG4nO1xuICAgICAgfVxuICAgIH07XG4gICAgZm9yIChsID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgIGxuID0gbGluZXNbbF07XG4gICAgICBmbihsbik7XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWQ7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBnZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChuYW1lLCBzY2hlbWEsIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gICAgdmFyIHN0cm9uZ09wZW4gPSAnPHNwYW4gY2xhc3M9XCJzdHJvbmdcIj4nO1xuICAgIHZhciBzdHJvbmdDbG9zZSA9ICc8L3NwYW4+JztcblxuICAgIHZhciBvcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xuICAgIH07XG5cblxuICAgIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICAgIGlmKF8uaXNPYmplY3QoYXJndW1lbnRzWzBdKSkge1xuICAgICAgbmFtZSA9IHZvaWQgMDtcbiAgICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIG1vZGVscyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGFyZ3VtZW50c1syXTtcbiAgICB9XG5cbiAgICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICAgIGlmKF8uaXNFbXB0eShzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArICdFbXB0eScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG5cbiAgICAvLyBEZXJlZmVyZW5jZSAkcmVmIGZyb20gJ21vZGVscydcbiAgICBpZih0eXBlb2Ygc2NoZW1hLiRyZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lID0gc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICAgIGlmKHR5cGVvZiBzY2hlbWEgPT09ICd1bmRlZmluZWQnKVxuICAgICAge1xuICAgICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCc7XG4gICAgfVxuXG4gICAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICAgIGlmKHNjaGVtYS5kZWZpbml0aW9uKSB7XG4gICAgICBzY2hlbWEgPSBzY2hlbWEuZGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICAgIHZhciBzZWVuTW9kZWxzID0gW107XG4gICAgdmFyIGlubGluZU1vZGVscyA9IDA7XG5cbiAgICAvLyBHZW5lcmF0ZSBjdXJyZW50IEhUTUxcbiAgICB2YXIgaHRtbCA9IHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuXG4gICAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gICAgd2hpbGUgKF8ua2V5cyhyZWZlcmVuY2VzKS5sZW5ndGggPiAwKSB7XG4gICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgICB2YXIgc2Vlbk1vZGVsID0gXy5pbmRleE9mKHNlZW5Nb2RlbHMsIG5hbWUpID4gLTE7XG5cbiAgICAgICAgZGVsZXRlIHJlZmVyZW5jZXNbbmFtZV07XG5cbiAgICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG5cbiAgICAgICAgICBodG1sICs9ICc8YnIgLz4nICsgcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbDtcblxuXG4gICAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgICAgdmFyIG1vZGVsTmFtZSA9IG5hbWU7XG4gICAgICB2YXIgbW9kZWw7XG5cbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgICAgbW9kZWwgPSBtb2RlbHNbc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG4gICAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwgJyArICgrK2lubGluZU1vZGVscyk7XG4gICAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgICB9XG5cbiAgICAgIGlmIChza2lwUmVmICE9PSB0cnVlKSB7XG4gICAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbW9kZWxOYW1lO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW1pdGl2ZVRvSFRNTChzY2hlbWEpIHtcbiAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcFR5cGVcIj4nO1xuICAgICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSwgc2ltcGxlUmVmKHNjaGVtYS4kcmVmKSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGh0bWwgKz0gXy5tYXAoc2NoZW1hLml0ZW1zLCBhZGRSZWZlcmVuY2UpLmpvaW4oJywnKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSAmJiBfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgc2NoZW1hLml0ZW1zLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBzaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHNjaGVtYSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICAgIH1cblxuICAgICAgICBodG1sICs9ICddJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJzwvc3Bhbj4nO1xuXG4gICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgaHRtbCkge1xuICAgICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgICB2YXIgaXNBcnJheSA9IHR5cGUgPT09ICdhcnJheSc7XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVzY3JpcHRpb24pKSB7XG4gICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHNjaGVtYS5kZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5lbnVtKSB7XG4gICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgICAgdHlwZSA9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRGVmYXVsdCcsIHNjaGVtYS5kZWZhdWx0KTtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICBpZiAoc2NoZW1hLm1pbkxlbmd0aCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4TGVuZ3RoKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5wYXR0ZXJuKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgIGlmIChzY2hlbWEubWluaW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tYXhpbXVtKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLm11bHRpcGxlT2YpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIGlmIChzY2hlbWEubWluSXRlbXMpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tYXhJdGVtcykge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgICAgIHZhciBlbnVtU3RyaW5nO1xuXG4gICAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgICAgZW51bVN0cmluZyA9IHNjaGVtYS5lbnVtLmpvaW4oJywgJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRW51bScsIGVudW1TdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBodG1sO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpIHtcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgICAgdmFyIGh0bWwgPSBzdHJvbmdPcGVuICsgbmFtZSArICcgJyArIChpc0FycmF5ID8gJ1snIDogJ3snKSArIHN0cm9uZ0Nsb3NlO1xuICAgICAgdmFyIGNvbnRlbnRzO1xuXG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIF8ubWFwKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICAgIGlmIChfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgdHlwZSkgPiAtMSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBfLmlzVW5kZWZpbmVkKGl0ZW0ucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoaXRlbSwgdHlwZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSwgc2ltcGxlUmVmKGl0ZW0uJHJlZikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICAgIGlmICgoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgfHwgc2NoZW1hLml0ZW1zLnR5cGUgPT09ICdvYmplY3QnKSAmJiBfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYS5pdGVtcywgc2NoZW1hLml0ZW1zLnR5cGUpICsgJzwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIHNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSkgKyAnPC9kaXY+JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgICAgdmFyIHByb3BlcnR5SXNSZXF1aXJlZCA9IChfLmluZGV4T2Yoc2NoZW1hLnJlcXVpcmVkLCBuYW1lKSA+PSAwKTtcbiAgICAgICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wTmFtZSAnICsgcmVxdWlyZWRDbGFzcyArICdcIj4nICsgbmFtZSArICc8L3NwYW4+ICgnO1xuICAgICAgICAgICAgICB2YXIgbW9kZWw7XG5cbiAgICAgICAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICAgIGNQcm9wZXJ0eSA9IHJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKGNQcm9wZXJ0eS4kcmVmKSkge1xuICAgICAgICAgICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihjUHJvcGVydHkuJHJlZildO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSAmJiBfLmluZGV4T2YoW3VuZGVmaW5lZCwgJ2FycmF5JywgJ29iamVjdCddLCBtb2RlbC5kZWZpbml0aW9uLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgICBjUHJvcGVydHkgPSByZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgaWYoIXByb3BlcnR5SXNSZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wT3B0S2V5XCI+b3B0aW9uYWw8L3NwYW4+JztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmKHByb3BlcnR5LnJlYWRPbmx5KSB7XG4gICAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcFJlYWRPbmx5XCI+cmVhZCBvbmx5PC9zcGFuPic7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBodG1sICs9ICcpJztcblxuICAgICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgICAgfSkuam9pbignLDwvZGl2PicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgdHlwZSkgKyAnPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gaHRtbCArIHN0cm9uZ09wZW4gKyAoaXNBcnJheSA/ICddJyA6ICd9JykgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG5cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIHNjaGVtYVRvSlNPTiA9IGZ1bmN0aW9uIChzY2hlbWEsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAgIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgICByZXR1cm4gKHByb3AgfHwge30pLmRlZmF1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIG1vZGVsc1RvSWdub3JlPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGZvcm1hdCA9IHNjaGVtYS5mb3JtYXQ7XG4gICAgdmFyIG1vZGVsO1xuICAgIHZhciBvdXRwdXQ7XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmV4YW1wbGUpKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZXhhbXBsZTtcbiAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSAmJiBfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZW51bVswXTtcbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChvdXRwdXQpKSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgbW9kZWwgPSBtb2RlbHNbc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG5cbiAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdKSkge1xuICAgICAgICAgICAgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0gPSBtb2RlbDtcbiAgICAgICAgICAgIG91dHB1dCA9IHNjaGVtYVRvSlNPTihtb2RlbC5kZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICAgICAgZGVsZXRlIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAobW9kZWwudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgICBvdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG91dHB1dCA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgICAgb3V0cHV0ID0gc2NoZW1hLmRlZmF1bHQ7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0cHV0ID0gJ3N0cmluZyc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICAgIG91dHB1dCA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG91dHB1dCA9IDAuMDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIG91dHB1dCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIG91dHB1dCA9IHt9O1xuXG4gICAgICAgIF8uZm9yRWFjaChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKHByb3BlcnR5KTtcblxuICAgICAgICAgIG91dHB1dFtuYW1lXSA9IHNjaGVtYVRvSlNPTihjUHJvcGVydHksIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgIG91dHB1dCA9IFtdO1xuXG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIF8uZm9yRWFjaChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oaXRlbSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oc2NoZW1hLml0ZW1zLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaCh7fSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHByb3BlcnR5IGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgY3JlYXRlSlNPTlNhbXBsZSA9IGZ1bmN0aW9uICh2YWx1ZSwgbW9kZWxzVG9JZ25vcmUpIHtcbiAgICBtb2RlbHNUb0lnbm9yZSA9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gICAgbW9kZWxzVG9JZ25vcmVbdmFsdWUubmFtZV0gPSB2YWx1ZTtcblxuICAgIC8vIFJlc3BvbnNlIHN1cHBvcnRcbiAgICBpZiAodmFsdWUuZXhhbXBsZXMgJiYgXy5pc1BsYWluT2JqZWN0KHZhbHVlLmV4YW1wbGVzKSkge1xuICAgICAgdmFsdWUgPSBfLmNsb25lRGVlcCh2YWx1ZSk7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlLmV4YW1wbGVzKTtcblxuICAgICAgXy5mb3JFYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZihrZXkuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICAgICAgdmFyIGV4YW1wbGUgPSB2YWx1ZS5leGFtcGxlc1trZXldO1xuICAgICAgICAgIGlmIChfLmlzU3RyaW5nKGV4YW1wbGUpKSB7XG4gICAgICAgICAgICBleGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKGV4YW1wbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZS5kZWZpbml0aW9uLmV4YW1wbGUgPSBleGFtcGxlO1xuICAgICAgICAgIHJldHVybiBzY2hlbWFUb0pTT04odmFsdWUuZGVmaW5pdGlvbiwgZXhhbXBsZSwgbW9kZWxzVG9JZ25vcmUsIHZhbHVlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5leGFtcGxlcykge1xuICAgICAgdmFsdWUgPSBfLmNsb25lRGVlcCh2YWx1ZSk7XG4gICAgICB2YXIgZXhhbXBsZSA9IHZhbHVlLmV4YW1wbGVzO1xuICAgICAgaWYgKF8uaXNTdHJpbmcoZXhhbXBsZSkpIHtcbiAgICAgICAgZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZChleGFtcGxlKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlLmRlZmluaXRpb24uZXhhbXBsZSA9IGV4YW1wbGU7XG4gICAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIGV4YW1wbGUsIG1vZGVsc1RvSWdub3JlLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH1cblxuICAgIHJldHVybiBzY2hlbWFUb0pTT04odmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb25zKSB7XG4gICAgICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGxpc3RUeXBlID0gdHJ1ZTtcbiAgICAgICAgdHlwZSA9IHR5cGVbMF07XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnZlcnQgdW5kZWZpbmVkIHRvIHN0cmluZyBvZiAndW5kZWZpbmVkJ1xuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0eXBlID0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgICAgIC8vIGEgbW9kZWwgZGVmIGV4aXN0cz9cbiAgICAgICAgdHlwZSA9IGRlZmluaXRpb25zW3R5cGVdOyAvKiBNb2RlbCAqL1xuICAgICAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gICAgICB9IGVsc2UgaWYgKGdldElubGluZU1vZGVsKHR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBnZXRJbmxpbmVNb2RlbCh0eXBlKTsgLyogTW9kZWwgKi9cbiAgICAgICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gV2UgZGVmYXVsdCB0byBwcmltaXRpdmVcbiAgICAgICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNQcmltaXRpdmUpIHtcbiAgICAgICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gJ0FycmF5WycgKyBnZXRNb2RlbFNpZ25hdHVyZSh0eXBlLm5hbWUsIHR5cGUuZGVmaW5pdGlvbiwgdHlwZS5tb2RlbHMsIHR5cGUubW9kZWxQcm9wZXJ0eU1hY3JvKSArICddJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZ2V0TW9kZWxTaWduYXR1cmUodHlwZS5uYW1lLCB0eXBlLmRlZmluaXRpb24sIHR5cGUubW9kZWxzLCB0eXBlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGUgPSBmdW5jdGlvbiAodHlwZSwgbW9kZWxzKSB7XG4gICAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gICAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gICAgbGlzdFR5cGUgPSAodHlwZSBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gICAgaWYobW9kZWxzW2lubmVyVHlwZV0pIHtcbiAgICAgIHNhbXBsZUpzb24gPSBjcmVhdGVKU09OU2FtcGxlKG1vZGVsc1tpbm5lclR5cGVdKTtcbiAgICB9IGVsc2UgaWYgKGdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgICAgc2FtcGxlSnNvbiA9IGNyZWF0ZUpTT05TYW1wbGUoZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKSk7IC8vIG1heSByZXR1cm4gbnVsbCwgaWYgdHlwZSBpc24ndCBjb3JyZWN0XG4gICAgfVxuXG5cbiAgICBpZiAoc2FtcGxlSnNvbikge1xuICAgICAgc2FtcGxlSnNvbiA9IGxpc3RUeXBlID8gW3NhbXBsZUpzb25dIDogc2FtcGxlSnNvbjtcblxuICAgICAgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdChzYW1wbGVKc29uKSkge1xuICAgICAgICB2YXIgdCA9IHNhbXBsZUpzb247XG5cbiAgICAgICAgaWYgKHNhbXBsZUpzb24gaW5zdGFuY2VvZiBBcnJheSAmJiBzYW1wbGVKc29uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0ID0gc2FtcGxlSnNvblswXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0Lm5vZGVOYW1lICYmIHR5cGVvZiB0ID09PSAnTm9kZScpIHtcbiAgICAgICAgICB2YXIgeG1sU3RyaW5nID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh0KTtcblxuICAgICAgICAgIHJldHVybiBmb3JtYXRYbWwoeG1sU3RyaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgd3JhcFRhZyA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgYXR0cnMpIHtcbiAgICB2YXIgc3RyLCBhdHRyaWJ1dGVzO1xuXG4gICAgYXR0cnMgPSBhdHRycyB8fCBbXTtcblxuICAgIGF0dHJpYnV0ZXMgPSBhdHRycy5tYXAoZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgIHJldHVybiAnICcgKyBhdHRyLm5hbWUgKyAnPVwiJyArIGF0dHIudmFsdWUgKyAnXCInO1xuICAgIH0pLmpvaW4oJycpO1xuXG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCdOb2RlIG5hbWUgaXMgbm90IHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgc3RyID0gW1xuICAgICAgJzwnLCBuYW1lLFxuICAgICAgYXR0cmlidXRlcyxcbiAgICAgICc+JyxcbiAgICAgIHZhbHVlLFxuICAgICAgJzwvJywgbmFtZSwgJz4nXG4gICAgXTtcblxuICAgIHJldHVybiBzdHIuam9pbignJyk7XG4gIH07XG5cbiAgdmFyIGdldE5hbWUgPSBmdW5jdGlvbiAobmFtZSwgeG1sKSB7XG4gICAgdmFyIHJlc3VsdCA9IG5hbWUgfHwgJyc7XG5cbiAgICB4bWwgPSB4bWwgfHwge307XG5cbiAgICBpZiAoeG1sLm5hbWUpIHtcbiAgICAgIHJlc3VsdCA9IHhtbC5uYW1lO1xuICAgIH1cblxuICAgIGlmICh4bWwucHJlZml4KSB7XG4gICAgICByZXN1bHQgPSB4bWwucHJlZml4ICsgJzonICsgcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGdldE5hbWVzcGFjZSA9IGZ1bmN0aW9uICh4bWwpIHtcbiAgICB2YXIgbmFtZXNwYWNlID0gJyc7XG4gICAgdmFyIG5hbWUgPSAneG1sbnMnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5uYW1lc3BhY2UpIHtcbiAgICAgIG5hbWVzcGFjZSA9IHhtbC5uYW1lc3BhY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuYW1lc3BhY2U7XG4gICAgfVxuXG4gICAgaWYgKHhtbC5wcmVmaXgpIHtcbiAgICAgIG5hbWUgKz0gJzonICsgeG1sLnByZWZpeDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHZhbHVlOiBuYW1lc3BhY2VcbiAgICB9O1xuICB9O1xuXG4gIHZhciBjcmVhdGVBcnJheVhNTCA9IGZ1bmN0aW9uIChkZXNjcmlwdG9yKSB7XG4gICAgdmFyIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWU7XG4gICAgdmFyIGNvbmZpZyA9IGRlc2NyaXB0b3IuY29uZmlnO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBtb2RlbHMgPSBkZXNjcmlwdG9yLm1vZGVscztcbiAgICB2YXIgdmFsdWU7XG4gICAgdmFyIGl0ZW1zID0gZGVmaW5pdGlvbi5pdGVtcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG5cbiAgICBpZiAoIWl0ZW1zKSB7IHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTsgfVxuXG4gICAgdmFsdWUgPSBjcmVhdGVTY2hlbWFYTUwobmFtZSwgaXRlbXMsIG1vZGVscywgY29uZmlnKTtcblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmICh4bWwud3JhcHBlZCkge1xuICAgICAgdmFsdWUgPSB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgdmFyIGdldFByaW1pdGl2ZVNpZ25hdHVyZSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgICB2YXIgdHlwZSwgaXRlbXM7XG5cbiAgICBzY2hlbWEgPSBzY2hlbWEgfHwge307XG4gICAgaXRlbXMgPSBzY2hlbWEuaXRlbXMgfHwge307XG4gICAgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICcnO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdvYmplY3QnOiByZXR1cm4gJ09iamVjdCBpcyBub3QgYSBwcmltaXRpdmUnO1xuICAgICAgY2FzZSAnYXJyYXknIDogcmV0dXJuICdBcnJheVsnICsgKGl0ZW1zLmZvcm1hdCB8fCBpdGVtcy50eXBlKSArICddJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBzY2hlbWEuZm9ybWF0IHx8IHR5cGU7XG4gICAgfVxuICB9O1xuXG4gIHZhciBjcmVhdGVQcmltaXRpdmVYTUwgPSBmdW5jdGlvbiAoZGVzY3JpcHRvcikge1xuICAgIHZhciBuYW1lID0gZGVzY3JpcHRvci5uYW1lO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBwcmltaXRpdmVzTWFwID0ge1xuICAgICAgJ3N0cmluZyc6IHtcbiAgICAgICAgJ2RhdGUnOiBuZXcgRGF0ZSgxKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0sXG4gICAgICAgICdkYXRlLXRpbWUnIDogbmV3IERhdGUoMSkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgJ2RlZmF1bHQnOiAnc3RyaW5nJ1xuICAgICAgfSxcbiAgICAgICdpbnRlZ2VyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDFcbiAgICAgIH0sXG4gICAgICAnbnVtYmVyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDEuMVxuICAgICAgfSxcbiAgICAgICdib29sZWFuJzoge1xuICAgICAgICAnZGVmYXVsdCc6IHRydWVcbiAgICAgIH1cbiAgICB9O1xuICAgIHZhciB0eXBlID0gZGVmaW5pdGlvbi50eXBlO1xuICAgIHZhciBmb3JtYXQgPSBkZWZpbml0aW9uLmZvcm1hdDtcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG4gICAgdmFyIHZhbHVlO1xuXG4gICAgaWYgKF8ua2V5cyhwcmltaXRpdmVzTWFwKS5pbmRleE9mKHR5cGUpIDwgMCkgeyByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCk7IH1cblxuICAgIGlmIChfLmlzQXJyYXkoZGVmaW5pdGlvbi5lbnVtKSl7XG4gICAgICB2YWx1ZSA9IGRlZmluaXRpb24uZW51bVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmV4YW1wbGUgfHwgcHJpbWl0aXZlc01hcFt0eXBlXVtmb3JtYXRdIHx8IHByaW1pdGl2ZXNNYXBbdHlwZV0uZGVmYXVsdDtcbiAgICB9XG5cbiAgICBpZiAoeG1sLmF0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuIHtuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWV9O1xuICAgIH1cblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIHJldHVybiB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVPYmplY3RYTUwgKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IGRlc2NyaXB0b3IuZGVmaW5pdGlvbjtcbiAgICB2YXIgY29uZmlnID0gZGVzY3JpcHRvci5jb25maWc7XG4gICAgdmFyIG1vZGVscyA9IGRlc2NyaXB0b3IubW9kZWxzO1xuICAgIHZhciBpc1BhcmFtID0gZGVzY3JpcHRvci5jb25maWcuaXNQYXJhbTtcbiAgICB2YXIgc2VyaWFsaXplZFByb3BlcnRpZXM7XG4gICAgdmFyIGF0dHJzID0gW107XG4gICAgdmFyIHByb3BlcnRpZXMgPSBkZWZpbml0aW9uLnByb3BlcnRpZXM7XG4gICAgdmFyIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gZGVmaW5pdGlvbi5hZGRpdGlvbmFsUHJvcGVydGllcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWw7XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuXG4gICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgYXR0cnMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmICghcHJvcGVydGllcyAmJiAhYWRkaXRpb25hbFByb3BlcnRpZXMpIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG5cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyB8fCB7fTtcblxuICAgIHNlcmlhbGl6ZWRQcm9wZXJ0aWVzID0gXy5tYXAocHJvcGVydGllcywgZnVuY3Rpb24gKHByb3AsIGtleSkge1xuICAgICAgdmFyIHhtbCwgcmVzdWx0O1xuXG4gICAgICBpZiAoaXNQYXJhbSAmJiBwcm9wLnJlYWRPbmx5KSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgeG1sID0gcHJvcC54bWwgfHwge307XG4gICAgICByZXN1bHQgPSBjcmVhdGVTY2hlbWFYTUwoa2V5LCBwcm9wLCBtb2RlbHMsIGNvbmZpZyk7XG5cbiAgICAgIGlmICh4bWwuYXR0cmlidXRlKSB7XG4gICAgICAgIGF0dHJzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pLmpvaW4oJycpO1xuXG4gICAgaWYgKGFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB7XG4gICAgICBzZXJpYWxpemVkUHJvcGVydGllcyArPSAnPCEtLSBhZGRpdGlvbmFsIGVsZW1lbnRzIGFsbG93ZWQgLS0+JztcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFRhZyhuYW1lLCBzZXJpYWxpemVkUHJvcGVydGllcywgYXR0cnMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SW5maW5pdGVMb29wTWVzc2FnZSAobmFtZSwgbG9vcFRvKSB7XG4gICAgcmV0dXJuIHdyYXBUYWcobmFtZSwgJzwhLS0gSW5maW5pdGUgbG9vcCAkcmVmOicgKyBsb29wVG8gKyAnIC0tPicpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlIChkZXRhaWxzKSB7XG4gICAgZGV0YWlscyA9IGRldGFpbHMgPyAnOiAnICsgZGV0YWlscyA6ICcnO1xuICAgIHJldHVybiAnPCEtLSBpbnZhbGlkIFhNTCcgKyBkZXRhaWxzICsgJyAtLT4nO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2NoZW1hWE1MIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIHZhciAkcmVmID0gXy5pc09iamVjdChkZWZpbml0aW9uKSA/IGRlZmluaXRpb24uJHJlZiA6IG51bGw7XG4gICAgdmFyIG91dHB1dCwgaW5kZXg7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZSA9IGNvbmZpZy5tb2RlbHNUb0lnbm9yZSB8fCBbXTtcbiAgICB2YXIgZGVzY3JpcHRvciA9IF8uaXNTdHJpbmcoJHJlZikgPyBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpXG4gICAgICAgIDogZ2V0RGVzY3JpcHRvcihuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyk7XG5cbiAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgIHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRlc2NyaXB0b3IudHlwZSkge1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVBcnJheVhNTChkZXNjcmlwdG9yKTsgYnJlYWs7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVPYmplY3RYTUwoZGVzY3JpcHRvcik7IGJyZWFrO1xuICAgICAgY2FzZSAnbG9vcCc6XG4gICAgICAgIG91dHB1dCA9IGdldEluZmluaXRlTG9vcE1lc3NhZ2UoZGVzY3JpcHRvci5uYW1lLCBkZXNjcmlwdG9yLmNvbmZpZy5sb29wVG8pOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG91dHB1dCA9IGNyZWF0ZVByaW1pdGl2ZVhNTChkZXNjcmlwdG9yKTtcbiAgICB9XG5cbiAgICBpZiAoJHJlZiAmJiBkZXNjcmlwdG9yLnR5cGUgIT09ICdsb29wJykge1xuICAgICAgaW5kZXggPSBjb25maWcubW9kZWxzVG9JZ25vcmUuaW5kZXhPZigkcmVmKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBEZXNjcmlwdG9yIChuYW1lLCB0eXBlLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb25maWcgPSBjb25maWcgfHwge307XG4gICAgdGhpcy5jb25maWcubW9kZWxzVG9JZ25vcmUgPSB0aGlzLmNvbmZpZy5tb2RlbHNUb0lnbm9yZSB8fCBbXTtcbiAgICB0aGlzLm5hbWUgPSBnZXROYW1lKG5hbWUsIGRlZmluaXRpb24ueG1sKTtcbiAgICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uO1xuICAgIHRoaXMubW9kZWxzID0gbW9kZWxzO1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpIHtcbiAgICB2YXIgbW9kZWxUeXBlID0gc2ltcGxlUmVmKCRyZWYpO1xuICAgIHZhciBtb2RlbCA9IG1vZGVsc1ttb2RlbFR5cGVdIHx8IHt9O1xuICAgIHZhciB0eXBlID0gbW9kZWwuZGVmaW5pdGlvbiAmJiBtb2RlbC5kZWZpbml0aW9uLnR5cGUgPyBtb2RlbC5kZWZpbml0aW9uLnR5cGUgOiAnb2JqZWN0JztcbiAgICBuYW1lID0gbmFtZSB8fCBtb2RlbC5uYW1lO1xuXG4gICAgaWYgKGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5pbmRleE9mKCRyZWYpID4gLTEpIHtcbiAgICAgIHR5cGUgPSAnbG9vcCc7XG4gICAgICBjb25maWcubG9vcFRvID0gbW9kZWxUeXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25maWcubW9kZWxzVG9JZ25vcmUucHVzaCgkcmVmKTtcbiAgICB9XG5cbiAgICBpZiAoIW1vZGVsLmRlZmluaXRpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGVzY3JpcHRvcihuYW1lLCB0eXBlLCBtb2RlbC5kZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyl7XG4gICAgdmFyIHR5cGUgPSBkZWZpbml0aW9uLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICBpZiAoIWRlZmluaXRpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGVzY3JpcHRvcihuYW1lLCB0eXBlLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVYTUxTYW1wbGUgKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgaXNQYXJhbSkge1xuICAgIHZhciBwcm9sb2cgPSAnPD94bWwgdmVyc2lvbj1cIjEuMFwiPz4nO1xuXG4gICAgcmV0dXJuIGZvcm1hdFhtbChwcm9sb2cgKyBjcmVhdGVTY2hlbWFYTUwobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCB7IGlzUGFyYW06IGlzUGFyYW0gfSApKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgICBnZXRNb2RlbFNpZ25hdHVyZTogZ2V0TW9kZWxTaWduYXR1cmUsXG4gICAgICBjcmVhdGVKU09OU2FtcGxlOiBjcmVhdGVKU09OU2FtcGxlLFxuICAgICAgZ2V0UGFyYW1ldGVyTW9kZWxTaWduYXR1cmU6IGdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlLFxuICAgICAgY3JlYXRlUGFyYW1ldGVySlNPTlNhbXBsZTogY3JlYXRlUGFyYW1ldGVySlNPTlNhbXBsZSxcbiAgICAgIGNyZWF0ZVNjaGVtYVhNTDogY3JlYXRlU2NoZW1hWE1MLFxuICAgICAgY3JlYXRlWE1MU2FtcGxlOiBjcmVhdGVYTUxTYW1wbGUsXG4gICAgICBnZXRQcmltaXRpdmVTaWduYXR1cmU6IGdldFByaW1pdGl2ZVNpZ25hdHVyZVxuICB9O1xuXG59KSgpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUG9wdXBWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmFwaS1wb3B1cC1jYW5jZWwnOiAnY2FuY2VsQ2xpY2snXG4gICAgfSxcblxuICAgIHRlbXBsYXRlOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wb3B1cCxcbiAgICBjbGFzc05hbWU6ICdhcGktcG9wdXAtZGlhbG9nJyxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBjb250ZW50OiAnLmFwaS1wb3B1cC1jb250ZW50JyxcbiAgICAgICAgbWFpbiAgIDogJyNzd2FnZ2VyLXVpLWNvbnRhaW5lcidcbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXtcbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRlbXBsYXRlKHRoaXMubW9kZWwpKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuJCh0aGlzLnNlbGVjdG9ycy5jb250ZW50KS5hcHBlbmQodGhpcy5tb2RlbC5jb250ZW50KTtcbiAgICAgICAgJCh0aGlzLnNlbGVjdG9ycy5tYWluKS5maXJzdCgpLmFwcGVuZCh0aGlzLmVsKTtcbiAgICAgICAgdGhpcy5zaG93UG9wdXAoKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgc2hvd1BvcHVwOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuJGVsLnNob3coKTtcbiAgICB9LFxuXG4gICAgY2FuY2VsQ2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoKTtcbiAgICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUmVzb3VyY2VWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgb3B0cyA9IG9wdHMgfHwge307XG4gICAgdGhpcy5yb3V0ZXIgPSBvcHRzLnJvdXRlcjtcbiAgICB0aGlzLmF1dGhzID0gb3B0cy5hdXRocztcbiAgICBpZiAoJycgPT09IHRoaXMubW9kZWwuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMubW9kZWwuZGVzY3JpcHRpb24gPSBudWxsO1xuICAgIH1cbiAgICBpZiAodGhpcy5tb2RlbC5kZXNjcmlwdGlvbikge1xuICAgICAgdGhpcy5tb2RlbC5zdW1tYXJ5ID0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbjtcbiAgICB9XG4gICAgdGhpcy5udW1iZXIgPSAwO1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICB2YXIgbWV0aG9kcyA9IHt9O1xuXG5cbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMucmVzb3VyY2UodGhpcy5tb2RlbCkpO1xuXG4gICAgLy8gUmVuZGVyIGVhY2ggb3BlcmF0aW9uXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vZGVsLm9wZXJhdGlvbnNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG9wZXJhdGlvbiA9IHRoaXMubW9kZWwub3BlcmF0aW9uc0FycmF5W2ldO1xuICAgICAgdmFyIGNvdW50ZXIgPSAwO1xuICAgICAgdmFyIGlkID0gb3BlcmF0aW9uLm5pY2tuYW1lO1xuXG4gICAgICB3aGlsZSAodHlwZW9mIG1ldGhvZHNbaWRdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZCA9IGlkICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgY291bnRlciArPSAxO1xuICAgICAgfVxuXG4gICAgICBtZXRob2RzW2lkXSA9IG9wZXJhdGlvbjtcblxuICAgICAgb3BlcmF0aW9uLm5pY2tuYW1lID0gaWQ7XG4gICAgICBvcGVyYXRpb24ucGFyZW50SWQgPSB0aGlzLm1vZGVsLmlkO1xuICAgICAgb3BlcmF0aW9uLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9uczsgLy8gbWFrZSBKc29uIFNjaGVtYSBhdmFpbGFibGUgZm9yIEpTb25FZGl0b3IgaW4gdGhpcyBvcGVyYXRpb25cbiAgICAgIHRoaXMuYWRkT3BlcmF0aW9uKG9wZXJhdGlvbik7XG4gICAgfVxuXG4gICAgJCgnLnRvZ2dsZUVuZHBvaW50TGlzdCcsIHRoaXMuZWwpLmNsaWNrKHRoaXMuY2FsbERvY3MuYmluZCh0aGlzLCAndG9nZ2xlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UnKSk7XG4gICAgJCgnLmNvbGxhcHNlUmVzb3VyY2UnLCB0aGlzLmVsKS5jbGljayh0aGlzLmNhbGxEb2NzLmJpbmQodGhpcywgJ2NvbGxhcHNlT3BlcmF0aW9uc0ZvclJlc291cmNlJykpO1xuICAgICQoJy5leHBhbmRSZXNvdXJjZScsIHRoaXMuZWwpLmNsaWNrKHRoaXMuY2FsbERvY3MuYmluZCh0aGlzLCAnZXhwYW5kT3BlcmF0aW9uc0ZvclJlc291cmNlJykpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgYWRkT3BlcmF0aW9uOiBmdW5jdGlvbihvcGVyYXRpb24pIHtcblxuICAgIG9wZXJhdGlvbi5udW1iZXIgPSB0aGlzLm51bWJlcjtcblxuICAgIC8vIFJlbmRlciBhbiBvcGVyYXRpb24gYW5kIGFkZCBpdCB0byBvcGVyYXRpb25zIGxpXG4gICAgdmFyIG9wZXJhdGlvblZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLk9wZXJhdGlvblZpZXcoe1xuICAgICAgbW9kZWw6IG9wZXJhdGlvbixcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICB0YWdOYW1lOiAnbGknLFxuICAgICAgY2xhc3NOYW1lOiAnZW5kcG9pbnQnLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucyxcbiAgICAgIGF1dGhzOiB0aGlzLmF1dGhzXG4gICAgfSk7XG5cbiAgICAkKCcuZW5kcG9pbnRzJywgJCh0aGlzLmVsKSkuYXBwZW5kKG9wZXJhdGlvblZpZXcucmVuZGVyKCkuZWwpO1xuXG4gICAgdGhpcy5udW1iZXIrKztcblxuICB9LFxuICAvLyBHZW5lcmljIEV2ZW50IGhhbmRsZXIgKGBEb2NzYCBpcyBnbG9iYWwpXG5cblxuICBjYWxsRG9jczogZnVuY3Rpb24oZm5OYW1lLCBlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIERvY3NbZm5OYW1lXShlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbigpe30sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHRoaXMubW9kZWwucmVzcG9uc2VDb250ZW50VHlwZUlkID0gJ3JjdCcgKyBNYXRoLnJhbmRvbSgpO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5yZXNwb25zZV9jb250ZW50X3R5cGUodGhpcy5tb2RlbCkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBldmVudHM6IHtcbiAgICAnY2xpY2sgYS5kZXNjcmlwdGlvbi1saW5rJyAgICAgICA6ICdzd2l0Y2hUb0Rlc2NyaXB0aW9uJyxcbiAgICAnY2xpY2sgYS5zbmlwcGV0LWxpbmsnICAgICAgICAgICA6ICdzd2l0Y2hUb1NuaXBwZXQnLFxuICAgICdtb3VzZWRvd24gLnNuaXBwZXRfanNvbicgICAgICAgICAgOiAnanNvblNuaXBwZXRNb3VzZURvd24nLFxuICAgICdtb3VzZWRvd24gLnNuaXBwZXRfeG1sJyAgICAgICAgICA6ICd4bWxTbmlwcGV0TW91c2VEb3duJ1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG5cbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMuc2lnbmF0dXJlKHRoaXMubW9kZWwpKTtcblxuICAgIGlmICh0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmcgPT09ICdtb2RlbCcpIHtcbiAgICAgIHRoaXMuc3dpdGNoVG9EZXNjcmlwdGlvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN3aXRjaFRvU25pcHBldCgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIHNob3cgc2lnbmF0dXJlXG4gIHN3aXRjaFRvRGVzY3JpcHRpb246IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgJCgnLnNuaXBwZXQnLCAkKHRoaXMuZWwpKS5oaWRlKCk7XG4gICAgJCgnLmRlc2NyaXB0aW9uJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5kZXNjcmlwdGlvbi1saW5rJywgJCh0aGlzLmVsKSkuYWRkQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gICAgJCgnLnNuaXBwZXQtbGluaycsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdzZWxlY3RlZCcpO1xuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIHNob3cgc2FtcGxlXG4gIHN3aXRjaFRvU25pcHBldDogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAkKCcuc25pcHBldCcsICQodGhpcy5lbCkpLnNob3coKTtcbiAgICAkKCcuZGVzY3JpcHRpb24nLCAkKHRoaXMuZWwpKS5oaWRlKCk7XG4gICAgJCgnLnNuaXBwZXQtbGluaycsICQodGhpcy5lbCkpLmFkZENsYXNzKCdzZWxlY3RlZCcpO1xuICAgICQoJy5kZXNjcmlwdGlvbi1saW5rJywgJCh0aGlzLmVsKSkucmVtb3ZlQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gIH0sXG5cbiAgLy8gaGFuZGxlciBmb3Igc25pcHBldCB0byB0ZXh0IGFyZWFcbiAgc25pcHBldFRvVGV4dEFyZWE6IGZ1bmN0aW9uKHZhbCkge1xuICAgIHZhciB0ZXh0QXJlYSA9ICQoJ3RleHRhcmVhJywgJCh0aGlzLmVsLnBhcmVudE5vZGUucGFyZW50Tm9kZS5wYXJlbnROb2RlKSk7XG5cbiAgICAvLyBGaXggZm9yIGJ1ZyBpbiBJRSAxMC8xMSB3aGljaCBjYXVzZXMgcGxhY2Vob2xkZXIgdGV4dCB0byBiZSBjb3BpZWQgdG8gXCJ2YWx1ZVwiXG4gICAgaWYgKCQudHJpbSh0ZXh0QXJlYS52YWwoKSkgPT09ICcnIHx8IHRleHRBcmVhLnByb3AoJ3BsYWNlaG9sZGVyJykgPT09IHRleHRBcmVhLnZhbCgpKSB7XG4gICAgICB0ZXh0QXJlYS52YWwodmFsKTtcbiAgICAgIC8vIFRPRE8gbW92ZSB0aGlzIGNvZGUgb3V0c2lkZSBvZiB0aGUgdmlldyBhbmQgZXhwb3NlIGFuIGV2ZW50IGluc3RlYWRcbiAgICAgIGlmKCB0aGlzLm1vZGVsLmpzb25FZGl0b3IgJiYgdGhpcy5tb2RlbC5qc29uRWRpdG9yLmlzRW5hYmxlZCgpKXtcbiAgICAgICAgdGhpcy5tb2RlbC5qc29uRWRpdG9yLnNldFZhbHVlKEpTT04ucGFyc2UodGhpcy5tb2RlbC5zYW1wbGVKU09OKSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGpzb25TbmlwcGV0TW91c2VEb3duOiBmdW5jdGlvbiAoZSkge1xuICAgIGlmICh0aGlzLm1vZGVsLmlzUGFyYW0pIHtcbiAgICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgICB0aGlzLnNuaXBwZXRUb1RleHRBcmVhKHRoaXMubW9kZWwuc2FtcGxlSlNPTik7XG4gICAgfVxuICB9LFxuXG4gIHhtbFNuaXBwZXRNb3VzZURvd246IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHRoaXMubW9kZWwuaXNQYXJhbSkge1xuICAgICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAgIHRoaXMuc25pcHBldFRvVGV4dEFyZWEodGhpcy5tb2RlbC5zYW1wbGVYTUwpO1xuICAgIH1cbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuU3RhdHVzQ29kZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHZhciByZXNwb25zZU1vZGVsLCByZXNwb25zZU1vZGVsVmlldztcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnJvdXRlci5hcGkubW9kZWxzW3RoaXMubW9kZWwucmVzcG9uc2VNb2RlbF07XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnN0YXR1c19jb2RlKHRoaXMubW9kZWwpKTtcblxuICAgIGlmICh0aGlzLnJvdXRlci5hcGkubW9kZWxzLmhhc093blByb3BlcnR5KHRoaXMubW9kZWwucmVzcG9uc2VNb2RlbCkpIHtcbiAgICAgIHJlc3BvbnNlTW9kZWwgPSB7XG4gICAgICAgIHNhbXBsZUpTT046IEpTT04uc3RyaW5naWZ5KFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlSlNPTlNhbXBsZSh2YWx1ZSksIHZvaWQgMCwgMiksXG4gICAgICAgIHNhbXBsZVhNTDogdGhpcy5tb2RlbC5pc1hNTCA/IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlWE1MU2FtcGxlKCcnLCB0aGlzLm1vZGVsLnNjaGVtYSwgdGhpcy5yb3V0ZXIuYXBpLm1vZGVscykgOiBmYWxzZSxcbiAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRNb2RlbFNpZ25hdHVyZSh0aGlzLm1vZGVsLnJlc3BvbnNlTW9kZWwsIHZhbHVlLCB0aGlzLnJvdXRlci5hcGkubW9kZWxzKSxcbiAgICAgICAgZGVmYXVsdFJlbmRlcmluZzogdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNwb25zZU1vZGVsID0ge1xuICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0UHJpbWl0aXZlU2lnbmF0dXJlKHRoaXMubW9kZWwuc2NoZW1hKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXNwb25zZU1vZGVsVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuU2lnbmF0dXJlVmlldyh7bW9kZWw6IHJlc3BvbnNlTW9kZWwsIHRhZ05hbWU6ICdkaXYnfSk7XG4gICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsIHRoaXMuJGVsKS5hcHBlbmQocmVzcG9uc2VNb2RlbFZpZXcucmVuZGVyKCkuZWwpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59KTsiXX0=